##学校でK-MEANS(k平均法)をpython3で実装する課題をやっています。
クラスタリングの箇所がうまくいかなくて悩んでいます。
ipython-notebookを用いています。
irisデータをクラスタリングします。
↓最初にユークリッド関数を定義して
lang
1def EucDist(a,b) 2 """ 3 ユーグリット距離を求める関数 4 """ 5 return np.sqrt(np.power(a-b, 2).sum()) 6
↓irisデータを読み込んで
f = open("iris.data","r") text = f.read() f.close
↓カンマで区切って
a=text.replace("\n",",")#改行をカンマに変える b=a.split(",")#カンマで区切る c=[b[i:i+5] for i in range(0,752,5)]#4次元の座標データとクラスター c
↓座標点とクラスに分けて
data=[] for i in range(150): i=i*5 cb = [[float(b[i]),float(b[i+1]),float(b[i+2]),float(b[i+3])],b[i+4]] data.append(cb) data
↓座標点だけ取りだして
cd = []#irisデータの座表点のみ格納するリスト for i in range(len(data)): cd.append(data[i][0]) cd
↓重心の初期値をirisデータからランダムに選んで
k=3 cent=[] for i in range(k): cent.append(random.choice(cd))#cdからランダムに重心を3つ取り出す cent
↓クラスタリング
cmp=[]#ユークリッド距離を一時的に格納するリスト k0=[]#クラスタ1を格納するリスト k1=[]#クラスタ2を格納するリスト k2=[]#クラスタ3を格納するリスト for i in range(len(cd)): a=np.array(cd[i])#irisデータの座標 for j in range(k): b=np.array(cent[j])#初期の重心値 if len(cmp) != 3:#cmpには入っているデータ数が3になるまでcontinue文以下の処理を無視 continue if cmp.index(min(cmp)) == 0: k0.append(cent[0])# cmp[:] elif cmp.index(min(cmp)) == 1: k1.append(cent[1]) cmp[:] else: k2.append(cent[2]) cmp[:] else: cmp.append(EucDist(a,b))#ユークリッド距離を求め、結果をリストcmpに格納 print("クラスタ1: ",k0) print("クラスタ2: ",k1) print("クラスタ3: ",k2)
実行すると各クラスタのリストに何も要素が入らなかったです。
この後、各リストに入っている座標の平均を求め、それを新たな重心値として上記のソースコードの処理
を繰り返したいんですが、どうすればいいでしょうか。
意味のわからない説明で申し訳有りません。
ややコードが見づらいので、Markdown記法でシンタックスハイライトしていただけると見やすくなるかと思います。