更新类属性值

2024-10-06 08:34:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我在将值从一个类调用到该类之外的新迭代循环时遇到了一个问题。代码如下所示:(data和newdata是向量)

class A:
    def __init__(self, k, tol=0.0001, max_iter=300):
        self.k = k
        self.tol = tol
        self.max_iter = max_iter

    def fit(self, data):

        self.centroids = {}

        for i in range(self.k):
            self.centroids[i] = data[i+50]

        for i in range(self.max_iter):
            self.classifications = {}

            for i in range(self.k):
                self.classifications[i] = []

            for featureset in data:
                distances = [np.linalg.norm(featureset - self.centroids[centroid]) for centroid in self.centroids]
                classification = distances.index(min(distances))
                self.classifications[classification].append(featureset)
            prev_centroids = dict(self.centroids)

            for classification in self.classifications:
                self.centroids[classification] = np.average(self.classifications[classification], axis=0)

            optimized = True

            for c in self.centroids:
                original_centroid = prev_centroids[c]
                current_centroid = self.centroids[c]
                if np.sum((current_centroid - original_centroid) / original_centroid * 100.0) > self.tol:
                    #print(np.sum((current_centroid - original_centroid) / original_centroid * 100.0))
                    optimized = False

            if optimized:
                break
            
    def cluster_labels(self,data):
        cluster_labels = []
        for featureset in data:
            distances=[np.linalg.norm(featureset - self.centroids[centroid]) for centroid in self.centroids]
            cluster_labels.append(distances.index(min(distances)))
        return cluster_labels

    def predict(self, data):
        distances = [np.linalg.norm(data - self.centroids[centroid]) for centroid in self.centroids]
        classification = distances.index(min(distances))
        return classification

    def update(self, new_data, delta):
        for featureset in new_data:
            distances = [np.linalg.norm(featureset - self.centroids[centroid]) for centroid in self.centroids]

            if min(distances) < delta:
                classification = distances.index(min(distances))
                self.classifications[classification].append(featureset)
                self.centroids[classification] = np.average(self.classifications[classification], axis=0)
                
            else:
                self.centroids[self.k] = featureset
                self.classifications[self.k] = []
                self.classifications[self.k].append(featureset)   
                self.k = self.k + 1
                k = self.k
        print (k)
        return k

class Recorder:
    def __init__(rec):
        rec.p = pyaudio.PyAudio()
        rec.stream = rec.p.open(format = pyaudio.paInt16, channels = 1, rate = 44100, input = True, input_device_index = 2, frames_per_buffer = chunk)
    def write():
        a = A(k=3)
        a.fit(data)
        k=a.update(newdata,20)

for num in range(1,100):
rec.Recorder()
rec.write()

最初,我想设置k=3。然后,k的值应该用k=a.update(newdata,20)更新,但是现在对于每次运行,k的值都保持在3。如果我在类之外设置k=3,它总是显示错误:

 UnboundLocalError: local variable 'k' referenced before assignment

我怎样才能解决这个问题


Tags: inselffordataindexdefnpmin
1条回答
网友
1楼 · 发布于 2024-10-06 08:34:33

问题在于这一职能:

def update(self, new_data, delta):
    for featureset in new_data:
        distances = [np.linalg.norm(featureset - self.centroids[centroid]) for centroid in self.centroids]

        if min(distances) < delta:
            classification = distances.index(min(distances))
            self.classifications[classification].append(featureset)
            self.centroids[classification] = np.average(self.classifications[classification], axis=0)
            
        else:
            self.centroids[self.k] = featureset
            self.classifications[self.k] = []
            self.classifications[self.k].append(featureset)   
            self.k = self.k + 1
            k = self.k

您仅在“else”块内设置“k”值。忽略任何不相关的内容,看起来是这样的:

def update(self, new_data, delta):
    for featureset in new_data:
        ...
        if min(distances) < delta:
            ...
        else:
            ...
            k = self.k
    print (k)  # <  error here
    return k  # <  error here

min(dinstances) >= delta的情况下,将不会设置k,您将得到报告的错误

您有两个选择:

  • k = ...行添加到if块中,其中min(distances) < delta
  • 在if块(仍在for块内)的正上方添加k = ...,以设置k的“默认”值

在查看时,您也可能只需要返回self.k,而不是只返回k

相关问题 更多 >