###前提・実現したいこと
Pythonでクラスタリングについて勉強しています。
コードはhttps://github.com/joelgrus/data-science-from-scratch/blob/master/code/clustering.py
にあります。
現段階でできているのはクラスタの中心を求めること、クラスタリングせずにグラフへの表示です。
したいことは3つのクラスタに分けてクラスタ毎にクラスタの点の種類を変更して表示したいです。
###発生している問題・エラーメッセージ
3つのクラスタに分けることができません。
###該当のソースコード
Python
1from __future__ import division 2#from linear_algebra import squared_distance, vector_mean, distance 3import math, random 4import matplotlib.image as mpimg 5import matplotlib.pyplot as plt 6from functools import reduce 7import re, math, random 8from collections import defaultdict, Counter 9 10# 11# functions for working with vectors 12# 13 14def vector_add(v, w): 15 """adds two vectors componentwise""" 16 return [v_i + w_i for v_i, w_i in zip(v,w)] 17 18def vector_subtract(v, w): 19 """subtracts two vectors componentwise""" 20 return [v_i - w_i for v_i, w_i in zip(v,w)] 21 22def vector_sum(vectors): 23 return reduce(vector_add, vectors) 24 25def scalar_multiply(c, v): 26 return [c * v_i for v_i in v] 27 28# this isn't right if you don't from __future__ import division 29def vector_mean(vectors): 30 """compute the vector whose i-th element is the mean of the 31 i-th elements of the input vectors""" 32 n = len(vectors) 33 return scalar_multiply(1/n, vector_sum(vectors)) 34 35def dot(v, w): 36 """v_1 * w_1 + ... + v_n * w_n""" 37 return sum(v_i * w_i for v_i, w_i in zip(v, w)) 38 39def sum_of_squares(v): 40 """v_1 * v_1 + ... + v_n * v_n""" 41 return dot(v, v) 42 43def magnitude(v): 44 return math.sqrt(sum_of_squares(v)) 45 46def squared_distance(v, w): 47 return sum_of_squares(vector_subtract(v, w)) 48 49def distance(v, w): 50 return math.sqrt(squared_distance(v, w)) 51 52class KMeans: 53 """performs k-means clustering""" 54 55 def __init__(self, k): 56 self.k = k # number of clusters 57 self.means = None # means of clusters 58 59 60 def classify(self, input): 61 """return the index of the cluster closest to the input""" 62 #print(range(self.k)) 63 #print( min(range(self.k), 64 #key=lambda i: squared_distance(input, self.means[i])), squared_distance()) 65 66 return min(range(self.k), 67 key=lambda i: squared_distance(input, self.means[i])) 68 69 def train(self, inputs): 70 71 self.means = random.sample(inputs, self.k) 72 #print(self.means) 73 assignments = None 74 75 while True: 76 # Find new assignments 77 new_assignments = map(self.classify, inputs) 78 79 # If no assignments have changed, we're done. 80 if assignments == new_assignments: 81 return 82 83 # Otherwise keep the new assignments, 84 assignments = new_assignments 85 86 for i in range(self.k): 87 i_points = [p for p, a in zip(inputs, assignments) if a == i] 88 # avoid divide-by-zero if i_points is empty 89 if i_points: 90 self.means[i] = vector_mean(i_points) 91 92 93if __name__ == "__main__": 94 95 inputs = [[-14,-5],[13,13],[20,23],[-19,-11],[-9,-16],[21,27],[-49,15],[26,13],[-46,5],[-34,-1],[11,15],[-49,0],[-22,-16],[19,28],[-12,-8],[-13,-19],[-41,8],[-11,-6],[-25,-9],[-18,-3]] 96 97 98 random.seed(0) # so you get the same results as me 99 clusterer = KMeans(3) 100 try: 101 clusterer.train(inputs) 102 except: 103 val =+ 1 104 print ("3-means:") 105 print (clusterer.means) 106 107#first = [-14,13,20,-19,-9,21,-49,26,-46,-34,11,-49,-22,19,-12,-13,-41,-11,-25,-18] 108#second = [-5,13,23,-11,-16,27,15,13,5,-1,15,0,-16,28,-8,-19,8,-6,-9,-3,] 109 110first,second = zip(*inputs) 111plt.scatter(first,second) 112plt.show()
###補足情報(言語/FW/ツール等のバージョンなど)
Pyhon3.5
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/05/25 06:36 編集
2017/05/30 09:21
2017/05/30 10:09
2017/05/30 14:30