我正在实现K均值聚类算法。到目前为止,这就是我所拥有的:
import copy
import csv
import math
import random
import sys
class Centroid():
def __init__(self, coordinates, _id):
self.id = _id
self.coordinates = coordinates
self.elements = []
def __repr__(self):
return 'Centroid: ' + str(self.id)
@property
def count(self):
return len(self.elements)
def recalculate_coordinates(self):
x = [sum(y)/len(y) for y in zip(*self.elements)]
self.coordinates = x
def reset_elements(self):
self.previous_elements = []
for el in self.elements:
self.previous_elements.append(el)
self.elements = []
class Kmeans():
def __init__(self):
self.k = int(sys.argv[2])
self.prepare_data()
self.iterations = 0
def prepare_data(self):
filename = sys.argv[1]
self.dataset = []
with open(filename, 'rb') as csvfile:
reader = csv.reader(csvfile, delimiter=' ')
for row in reader:
tuplified = tuple(map(float, row))
self.dataset.append(tuplified)
self.create_centroids()
def create_centroids(self):
self.centroids = []
for i in xrange(self.k):
chosen = random.choice(self.dataset)
cent = Centroid(chosen, i+1)
self.centroids.append(cent)
def main():
k = Kmeans()
def iterate(k):
k.iterations += 1
for item in k.dataset:
candidates = []
for centroid in k.centroids:
z = zip(item, centroid.coordinates)
squares = map(lambda x: (x[0]-x[1])**2, z)
added = sum(squares)
edistance = math.sqrt(added)
candidates.append((centroid, edistance))
winner = min(candidates, key=lambda x: x[1])
winner[0].add_element(item)
for centroid in k.centroids:
centroid.reset_elements()
centroid.recalculate_coordinates()
status_list = []
for centroid in k.centroids:
boole = sorted(centroid.elements) == sorted(centroid.previous_elements)
status_list.append(boole)
if False in status_list:
iterate(k)
print k.centroids
print k.iterations
iterate(k)
if __name__ == '__main__':
main()
但是,我一直收到错误RuntimeError: maximum recursion depth exceeded in cmp
。我尝试了几个重构没有成功。谁能告诉我可能是什么问题。提前谢谢。
答案 0 :(得分:0)
如果错误出现在这一行:
boole = sorted(centroid.elements) == sorted(centroid.previous_elements)
最有可能发生的是您在centroids.elements
和centroids.previous_elements
中有循环引用,因此比较操作(在sorted
调用和==
中执行)继续周期性地遍历每个列表。
这种行为的简单演示(在Python 3中):
>>> x = []
>>> y = [x]
>>> x.append(y)
>>> x == y
Traceback (most recent call last)
....
x == y
RecursionError: maximum recursion depth exceeded in comparison