###前提・実現したいこと
Pythonでk平均法について勉強しようとしています。
本を見ながら進めており、参考コードは以下のURLのgithub上にあります。
https://github.com/joelgrus/data-science-from-scratch/blob/master/code/clustering.py
###発生している問題・エラーメッセージ
このコードを実行したところ、K=3とし3つのクラスタの中心点が結果として表示されているのですがコードがどのように動作して結果が導き出されてているのか分からなくて困っています。
基本的な文法については理解しているつもりです。
###該当のソースコード
from __future__ import division import math, random from functools import reduce import re, math, random from collections import defaultdict, Counter # # functions for working with vectors # def vector_add(v, w): """adds two vectors componentwise""" return [v_i + w_i for v_i, w_i in zip(v,w)] def vector_subtract(v, w): """subtracts two vectors componentwise""" return [v_i - w_i for v_i, w_i in zip(v,w)] def vector_sum(vectors): return reduce(vector_add, vectors) def scalar_multiply(c, v): return [c * v_i for v_i in v] # this isn't right if you don't from __future__ import division def vector_mean(vectors): """compute the vector whose i-th element is the mean of the i-th elements of the input vectors""" n = len(vectors) return scalar_multiply(1/n, vector_sum(vectors)) def dot(v, w): """v_1 * w_1 + ... + v_n * w_n""" return sum(v_i * w_i for v_i, w_i in zip(v, w)) def sum_of_squares(v): """v_1 * v_1 + ... + v_n * v_n""" return dot(v, v) def magnitude(v): return math.sqrt(sum_of_squares(v)) def squared_distance(v, w): return sum_of_squares(vector_subtract(v, w)) def distance(v, w): return math.sqrt(squared_distance(v, w)) class KMeans: """performs k-means clustering""" def __init__(self, k): self.k = k # number of clusters self.means = None # means of clusters def classify(self, input): """return the index of the cluster closest to the input""" return min(range(self.k), key=lambda i: squared_distance(input, self.means[i])) def train(self, inputs): self.means = random.sample(inputs, self.k) #print(self.means) assignments = None while True: # Find new assignments new_assignments = map(self.classify, inputs) # If no assignments have changed, we're done. if assignments == new_assignments: return # Otherwise keep the new assignments, assignments = new_assignments for i in range(self.k): i_points = [p for p, a in zip(inputs, assignments) if a == i] # avoid divide-by-zero if i_points is empty if i_points: self.means[i] = vector_mean(i_points) if __name__ == "__main__": 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]] random.seed(0) # so you get the same results as me clusterer = KMeans(3) try: clusterer.train(inputs) except: val =+ 1 print ("3-means:") print (clusterer.means) 3-means: [[-25.857142857142854, -4.714285714285714], [19, 28], [13, 13]]
###補足情報(言語/FW/ツール等のバージョンなど)
Python3.6を使用しています。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。