DTW距離行列そのままk-medoids法に使うクラスタリング
やってみったこと:算出されたDTWの距離行列そのままk-medoids法に使ってクラスタリングすること
phpのコードを参考しながらpythonで関数を書いた.
自分書いたもの忘れないように,コードを載せておきます.
もし間違いがあれば,お気軽にお声掛けてください.
#k-medoids第1段階の関数 #ランダムにデバイスk個を選んで初期のクラスター中心点とする #入力:デバイス間のDTW距離行列,中心点の数 #出力:選んだ中心点のデバイス番号のリスト import random def initialize_medoids(dist_M, k): l=list(range(1,len(dist_M))) medoids=random.sample(l, k) return np.array(medoids) #k-medoids第2段階の関数 #各デバイスを一番近い中心点属するクラスターに割り当てる #入力:デバイス間のDTW距離行列,中心点としてのデバイス番号のリスト #出力:各デバイス属するクラスタの番号のリスト def nearest(d,medoids): mindist=float("inf") nearest=0 k=len(medoids) i=0 while (i<k): n=medoids[i] if d[n]< mindist: mindist=d[n] nearest=i i+=1 return nearest def assign_to_nearest(dist_M,medoids): dist_M_list=dist_M.tolist() indices=[nearest(dist_M_list[m],medoids) for m in range(0,len(dist_M))] return indices #k-medoids第3段階の関数 #各クラスタの中心点を更新する #入力:デバイス間のDTW距離行列,各デバイス属するクラスタの番号のリスト,中心点の数 #出力:中心点のデバイス番号のリスト def update_medoids(dist_M,indices,k): mindists=np.full(k,float("inf")) medoids=np.full(k,float("nan")) i=0 while i<len(dist_M): dist_M_list=dist_M.tolist() m=indices[i] j=0 dist=0 while j<len(dist_M): if indices[j]== m: dist=dist+dist_M_list[i][j] j+=1 dist if dist<mindists[m]: mindists[m]=dist medoids[m]=i i+=1 return medoids.astype(int) #まとめ関数 #入力:デバイス間のDTW距離行列,中心点の数,最大再帰回数 #出力:各デバイス属するクラスタの番号のリスト,各クラスタの中心点のデバイス番号のリスト def kmedoids(dtw_matrix,k,maxiter): medoids=initialize_medoids(dtw_matrix, k) indices=np.full(len(dtw_matrix),float("nan")).tolist() itr=0 while itr<maxiter: nex=assign_to_nearest(dtw_matrix,medoids) if (np.array(nex)==np.array(indices)).all()=='True': break print('brk') indices=nex medoids=update_medoids(dtw_matrix,indices,k) itr+=1 return medoids