美文网首页
2020-07-14

2020-07-14

作者: 数据小黑升值记 | 来源:发表于2020-07-14 20:47 被阅读0次

    均值漂移算法。

    目前为止的代码:

    import matplotlib.pyplot as plt
    from matplotlib import style
    style.use('ggplot')
    import numpy as np
    
    X = np.array([[1, 2],
                  [1.5, 1.8],
                  [5, 8 ],
                  [8, 8],
                  [1, 0.6],
                  [9,11],
                  [8,2],
                  [10,2],
                  [9,3],])
    
    ##plt.scatter(X[:,0], X[:,1], s=150)
    ##plt.show()
    
    colors = 10*["g","r","c","b","k"]
    
    class Mean_Shift:
        def __init__(self, radius=4):
            self.radius = radius
    
        def fit(self, data):
            centroids = {}
    
            for i in range(len(data)):
                centroids[i] = data[i]
            
            while True:
                new_centroids = []
                for i in centroids:
                    in_bandwidth = []
                    centroid = centroids[i]
                    for featureset in data:
                        if np.linalg.norm(featureset-centroid) < self.radius:
                            in_bandwidth.append(featureset)
    
                    new_centroid = np.average(in_bandwidth,axis=0)
                    new_centroids.append(tuple(new_centroid))
    
                uniques = sorted(list(set(new_centroids)))
    
                prev_centroids = dict(centroids)
    
                centroids = {}
                for i in range(len(uniques)):
                    centroids[i] = np.array(uniques[i])
    
                optimized = True
    
                for i in centroids:
                    if not np.array_equal(centroids[i], prev_centroids[i]):
                        optimized = False
                    if not optimized:
                        break
                    
                if optimized:
                    break
    
            self.centroids = centroids
    
    
    
    clf = Mean_Shift()
    clf.fit(X)
    
    centroids = clf.centroids
    
    plt.scatter(X[:,0], X[:,1], s=150)
    
    for c in centroids:
        plt.scatter(centroids[c][0], centroids[c][1], color='k', marker='*', s=150)
    
    plt.show()
    

    这个代码能够工作,但是我们决定硬编码的半径不好。我们希望做一些更好的事情。首先,我们会修改我们的__init__方法:

        def __init__(self, radius=None, radius_norm_step = 100):
            self.radius = radius
            self.radius_norm_step = radius_norm_step
    

    所以这里的计划时创建大量的半径,但是逐步处理这个半径,就像带宽一样,或者一些不同长度的半径,我们将其称为步骤。如果特征集靠近半径,它就比远离的点有更大的“权重”。唯一的问题就是,这些步骤应该是什么。现在,开始实现我们的方法:

        def fit(self, data):
    
            if self.radius == None:
                all_data_centroid = np.average(data, axis=0)
                all_data_norm = np.linalg.norm(all_data_centroid)
                self.radius = all_data_norm / self.radius_norm_step
    
            centroids = {}
    
            for i in range(len(data)):
                centroids[i] = data[i]
    

    这里,如果用户没有硬编码半径,我们就打算寻找所有数据的“中心”。之后,我们会计算数据的模,之后假设每个self.radius中的半径都是整个数据长度,再除以我们希望的步骤数量。这里,形心的定义和上面的代码相同。现在我们开始while循环的优化:

            weights = [i for i in range(self.radius_norm_step)][::-1]    
            while True:
                new_centroids = []
                for i in centroids:
                    in_bandwidth = []
                    centroid = centroids[i]
                    
                    for featureset in data:
                        #if np.linalg.norm(featureset-centroid) < self.radius:
                        #    in_bandwidth.append(featureset)
                        distance = np.linalg.norm(featureset-centroid)
                        if distance == 0:
                            distance = 0.00000000001
                        weight_index = int(distance/self.radius)
                        if weight_index > self.radius_norm_step-1:
                            weight_index = self.radius_norm_step-1
    
                        to_add = (weights[weight_index]**2)*[featureset]
                        in_bandwidth +=to_add
                        
    
                    new_centroid = np.average(in_bandwidth,axis=0)
                    new_centroids.append(tuple(new_centroid))
    
                uniques = sorted(list(set(new_centroids)))
    

    要注意权重的定义,之后是数据中特征集的改变。

    相关文章

      网友评论

          本文标题:2020-07-14

          本文链接:https://www.haomeiwen.com/subject/qqfqhktx.html