2017-06-01 10 views
1

私はK means clusteringアルゴリズムを実装しています。今のところ、これは私が持っているものです。RuntimeError:最大再帰深度がcmpを超えました: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

3番目の最後の行を 'def iterate 'にします。 – theFarkle

+0

例外はどの行で発生しますか? – Billy

答えて

0

エラーは、このライン上にある場合:最も可能性の高い発生しているもの

boole = sorted(centroid.elements) == sorted(centroid.previous_elements) 

あなたはcentroids.elementscentroids.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 
+0

ありがとうございました。担当者の原因でも、それをアップヴォートできません – theFarkle

+0

しかし、あなたは受け入れることができます:) – Billy

関連する問題