Python 3.x 如何使用质心网格实现均值偏移?

Python 3.x 如何使用质心网格实现均值偏移?,python-3.x,mean-shift,Python 3.x,Mean Shift,这是一节课,我非常感谢你的帮助!我根据收到的评论做了一些更改,但现在又出现了一个错误。。 我需要修改一个实现meanshift算法的现有函数,但该函数不是将所有点初始化为第一组质心,而是基于半径创建一个质心网格。我还需要删除不包含任何数据点的质心。我的问题是,我不知道如何修复我得到的错误 --------------------------------------------------------------------------- IndexError

这是一节课,我非常感谢你的帮助!我根据收到的评论做了一些更改,但现在又出现了一个错误。。 我需要修改一个实现meanshift算法的现有函数,但该函数不是将所有点初始化为第一组质心,而是基于半径创建一个质心网格。我还需要删除不包含任何数据点的质心。我的问题是,我不知道如何修复我得到的错误

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-7-de18ffed728f> in <module>()
     49 centroids = initialize_centroids(x)
     50 
---> 51 new_centroids = update_centroids(x, centroids, r = 1)
     52 
     53 print(len(centroids))
<ipython-input-7-de18ffed728f> in update_centroids(data, centroids, r)
     26         #print(len(centroids))
     27         #print(range(len(centroids)))
---> 28         centroid = centroids[i]
     29         for data_point in data:
     30             if np.linalg.norm(data_point - centroid) < r:
IndexError: index 2 is out of bounds for axis 0 with size 2
---------------------------------------------------------------------------
索引器回溯(最后一次最近调用)
在()
49质心=初始化_质心(x)
50
--->51新的_形心=更新_形心(x,形心,r=1)
52
53打印(透镜(质心))
更新中的质心(数据、质心、r)
26#打印(透镜(质心))
27#打印(范围(透镜(质心)))
--->28质心=质心[i]
29对于数据中的数据点:
30如果np.linalg.norm(数据点-质心)
我尝试使用输入数据集的范围作为网格的边界,点之间用半径隔开

from sklearn import datasets
import numpy as np
import matplotlib.pyplot as plt


def initialize_centroids(data, r = 1):
    '''Creates a grid of centroids with grid based on radius'''

    data = np.array(data)
    xi,yi = min(range(len(data))), max(range(len(data)))
    mx = np.arange(xi,yi,r)
    x,y = np.meshgrid(mx,mx)
    centroids=np.vstack([x.ravel(), y.ravel()])
    return centroids

#update centroids based on mean of points that fall within a specified radius of each centroid

def update_centroids(data, centroids, r = 1):

    new_centroids = []

    for i in centroids:
        in_radius = []
        centroid = centroids[i] #this is where the error occurs
        for data_point in data:
            if np.linalg.norm(data_point - centroid) < radius:
                in_radius.append(data_point) #this list is appended by adding the new centroid to it if the above conition is satisfied. 

        new_centroid = np.mean(in_radius, axis=0) 
        #maybe another way to do the next part
        new_centroids.append(tuple(new_centroid)) 

    unique_centroids = sorted(list(set(new_centroids))) #for element in in_radius, if element in set skip else set.append(element(in_rad)). append does not work with set. 

    new_centroids = {i:np.array(unique_centroids[i]) for i in range(len(unique_centroids))}

    return new_centroids

#test function on:
x, y = datasets.make_blobs(n_samples=300, n_features = 2, centers=[[0, 7], [0, -7], [5,7], [5, 0]])

centroids = initialize_centroids(x)

new_centroids = update_centroids(x, centroids, radius = 2)

print(len(centroids))
print()
print(len(new_centroids))

#code for plotting initially: 
plt.scatter(x[:,0], x[:,1], color = 'k')

for i in range(len(new_centroids)):
    plt.scatter(new_centroids[i][0], new_centroids[i][1], s=200, color = 'r', marker = "*")

#code for plotting updated centroids:
new_centroids = update_centroids(x, new_centroids, radius = 2)

plt.scatter(x[:,0], x[:,1], color = 'k')

for i in range(len(new_centroids)):
    plt.scatter(new_centroids[i][0], new_centroids[i][1], s=200, color = 'r', marker = "*")

#code for iterations:
def iterate_to_conv(data, max_iter=100):

    centroids = initialize_centroids(data)
    iter_count = 0

    while iter_count <= max_iter:
        new_centroids = update_centroids(data, centroids, radius = 2)
        centroids = new_centroids
        iter_count += 1


    return centroids


centroids = iterate_to_conv(x)

plt.scatter(x[:,0], x[:,1], color = 'k')

for i in range(len(centroids)):
    plt.scatter(centroids[i][0], centroids[i][1], s=200, color = 'r', marker = "*")
从sklearn导入数据集
将numpy作为np导入
将matplotlib.pyplot作为plt导入
def初始化_质心(数据,r=1):
''使用基于半径的网格创建质心网格''
data=np.array(数据)
席,Yi=min(范围(LeN(data))),最大(范围(LEN(数据)))
mx=np.arange(xi,yi,r)
x、 y=np.meshgrid(mx,mx)
质心=np.vstack([x.ravel(),y.ravel()]))
返回质心
#基于位于每个质心指定半径内的点的平均值更新质心
def update_质心(数据,质心,r=1):
新的_形心=[]
对于质心中的i:
单位半径=[]
质心=质心[i]#这是发生错误的地方
对于数据中的数据点:
如果np.linalg.norm(数据点-质心)<半径:
在_radius.append(data_point)#如果满足上述圆锥曲线,则通过向其添加新的质心来追加此列表。
新的_形心=np.平均值(以_半径为单位,轴=0)
#也许是做下一部分的另一种方法
新的_形心。追加(元组(新的_形心))
唯一的_质心=排序(列表(设置(新的_质心)))#对于半径中的元素,如果集合中的元素跳过else集合。追加(元素(在半径中))。附加不适用于集合。
新的_形心={i:np.数组(唯一的_形心[i]),用于范围内的i(len(唯一的_形心))}
返回新的_形心
#测试功能:
x、 y=数据集。生成块(n_样本=300,n_特征=2,中心=[[0,7],[0,-7],[5,7],[5,0]])
质心=初始化_质心(x)
新质心=更新质心(x,质心,半径=2)
打印(透镜(质心))
打印()
打印(透镜(新的_质心))
#初始打印代码:
plt.scatter(x[:,0],x[:,1],颜色='k')
对于范围内的i(len(新的_形心)):
plt.scatter(新的_形心[i][0],新的_形心[i][1],s=200,颜色='r',marker=“*”)
#用于打印更新质心的代码:
新的_质心=更新_质心(x,新的_质心,半径=2)
plt.scatter(x[:,0],x[:,1],颜色='k')
对于范围内的i(len(新的_形心)):
plt.scatter(新的_形心[i][0],新的_形心[i][1],s=200,颜色='r',marker=“*”)
#迭代代码:
def迭代到conv(数据,最大值=100):
质心=初始化_质心(数据)
iter_计数=0

当你运行这个循环时,iter_count:
对于质心中的i
通过质心迭代的i不是一个数字,而是一个向量,这就是为什么会弹出错误。例如,第一个i值可能等于[0 1 2 0 1 2 0 1 2]。因此,对其进行索引是没有意义的。您的代码要做的是取形心=形心[n1 n2 nk]。要修复它,您确实需要更改初始化形心函数的工作方式。Meshgrid也不会创建N维网格,因此您的Meshgrid可能适用于2维,但不适用于N维。我希望这会有所帮助。

由于您的答案似乎是指向好方向的有用注释,而不是真正的答案,因此我建议您使用一些项目符号(采取步骤)重新格式化您的答案,并至少添加一些脚本代码以开始操作。(认识到新手评论的限制)。投票支持期望的脚本代码,让您继续;-)好的,你关于我是向量的观点很有道理。关于meshgrid,我不知道如何创建网格。。我试着用一个循环来创建一个循环,但我还不知道怎么做。