Repository for Petra's work at ampli Jan-Feb 2019

clustering.py 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. from util import getQuery, pickleQuery
  2. import numpy as np
  3. import pandas as p
  4. import matplotlib.pyplot as plt
  5. import seaborn as sns
  6. from scipy.spatial.distance import squareform
  7. from scipy.cluster.hierarchy import dendrogram, linkage, cophenet, fcluster
  8. Sourcedata = '../data/2017-sample.pkl'
  9. lableddata = '../data/9-clusters.pkl'
  10. aggdata = '../data/9-clusters.agg.pkl'
  11. clustertable = '../data/9-clusters-sample-table.pkl'
  12. numclusts = 9
  13. df = p.read_pickle(Sourcedata)
  14. dforig = df
  15. # print(df)
  16. print(df.info())
  17. print(df.icp_id.nunique())
  18. print(df.read_time.nunique())
  19. # print(df.groupby('icp_id').read_time.nunique().nunique())
  20. df = df.pivot(index = 'read_time', columns = 'icp_id', values = 'kwh_tot')
  21. print(df.info())
  22. df = df[df.columns[df.max() != df.min()]]
  23. print(df.info())
  24. cmat = df.corr()
  25. print(cmat.info())
  26. lmat = squareform(1 - cmat)
  27. lobj = linkage(lmat, method = 'ward')
  28. print(lobj)
  29. print(cophenet(lobj, lmat))
  30. clabs = [x + 1 for x in range(numclusts)]
  31. cpal = dict(zip(clabs, sns.color_palette("colorblind", numclusts).as_hex()))
  32. clusts = fcluster(lobj, numclusts, criterion='maxclust')
  33. print(clusts)
  34. print(cmat.index.values)
  35. clustdf = p.DataFrame({'icp_id' : cmat.index.values, 'cluster' : clusts})
  36. print(clustdf)
  37. clustdf.to_pickle(clustertable)
  38. mdf = p.merge(clustdf, dforig, on = 'icp_id', how = 'left')
  39. print(mdf)
  40. print(mdf.info())
  41. qlow = lambda x: x.quantile(0.250)
  42. qhigh = lambda x: x.quantile(0.750)
  43. print(mdf.cluster.describe())
  44. mdagg = mdf.groupby(['read_time', 'cluster']).agg({
  45. 'kwh_tot': ['median', 'mean', ('CI_low', qlow), ('CI_high', qhigh)]
  46. }, q = 0.025)
  47. mdagg.columns = ['_'.join(x) for x in mdagg.columns.ravel()]
  48. mdagg = mdagg.reset_index()
  49. print(mdagg)
  50. print(mdagg.info())
  51. print(mdagg.describe())
  52. # mdf.to_csv('~/windows/Documents/clusters-ward.csv')
  53. print("Saving")
  54. mdf.to_pickle(lableddata)
  55. mdagg.to_pickle(aggdata)
  56. print("saved")
  57. # Algorithm via
  58. # <https://stackoverflow.com/questions/38153829/custom-cluster-colors-of-scipy-dendrogram-in-python-link-color-func>
  59. ldict = {icp_id:cpal[cluster] for icp_id, cluster in zip(clustdf.icp_id, clustdf.cluster)}
  60. link_cols = {}
  61. for i, i12 in enumerate(lobj[:,:2].astype(int)):
  62. c1, c2 = (link_cols[x] if x > len(lobj) else ldict[clustdf.icp_id[x]]
  63. for x in i12)
  64. link_cols[i+1+len(lobj)] = c1 if c1 == c2 else '#000000'
  65. plt.figure(figsize = (25, 10))
  66. plt.title('ICP Clustering Dendrogram')
  67. plt.xlabel('ICP ID/(Number of ICPs)')
  68. plt.ylabel('distance')
  69. dendrogram(
  70. lobj,
  71. labels = cmat.index.values,
  72. leaf_rotation=90,
  73. leaf_font_size=8,
  74. # show_leaf_counts = True,
  75. # truncate_mode = 'lastp',
  76. # p = 50,
  77. # show_contracted = True,
  78. link_color_func = lambda x: link_cols[x],
  79. color_threshold = None
  80. )
  81. plt.show()
  82. sns.set()
  83. f, axes = plt.subplots(3,3)
  84. for i, c in enumerate(clabs):
  85. fds = mdagg[mdagg.cluster == c]
  86. sns.lineplot(x = 'read_time', y = 'kwh_tot_mean', color = cpal[c], ax = axes[i//3][i%3], data = fds)
  87. axes[i//3][i%3].fill_between(fds.read_time.dt.to_pydatetime(), fds.kwh_tot_CI_low, fds.kwh_tot_CI_high, alpha = 0.1, color = cpal[c])
  88. plt.show()