Python K均值聚类中的问题

Python K均值聚类中的问题,python,list,numpy,scipy,k-means,Python,List,Numpy,Scipy,K Means,我正在尝试使用K-means集群从CSV文件中对以下数据进行集群 Sample1,Sample2,45 Sample1,Sample3,69 Sample1,Sample4,12 Sample2,Sample2,46 Sample2,Sample1,78 它基本上是一个图,其中样本是节点,数字是边(权重) 我阅读文件如下: fileopening = fopen('data.csv', 'rU') reading = csv.reader(fileopening, delimiter=',')

我正在尝试使用K-means集群从CSV文件中对以下数据进行集群

Sample1,Sample2,45
Sample1,Sample3,69
Sample1,Sample4,12
Sample2,Sample2,46
Sample2,Sample1,78
它基本上是一个图,其中样本是节点,数字是边(权重)

我阅读文件如下:

fileopening = fopen('data.csv', 'rU')
reading = csv.reader(fileopening, delimiter=',')

L = list(reading)
我使用了以下代码:

在这里,集群是基于以下内容构建的:

num_points, dim, k, cutoff, lower, upper = 10, 2, 3, 0.5, 0, 200
points = map( lambda i: makeRandomPoint(dim, lower, upper), range(num_points) )
clusters = kmeans(points, k, cutoff)

for i,c in enumerate(clusters): 
    for p in c.points:
        print " Cluster: ",i,"\t Point :", p 
我用列表L替换了点。但是我得到了很多错误:
AttributeError,“int”对象没有属性“n”
,等等

我需要根据CSV文件的第三个数字列(边)执行K均值聚类。本教程使用随机创建点。但是我不确定,如何使用这个CSV数据作为这个k means函数的输入。如何对我的数据执行k均值(k=2)?如何将CSV文件数据作为输入发送到此k means函数

简而言之,“你不能”

长答覆: K-means仅为欧几里德空间定义,它需要有效的点位置,而它们之间只有距离,可能不是严格的数学意义,而是某种“相似性”。K-means不是设计用来处理相似矩阵的

你能做什么

  • 您可以使用其他方法在欧几里德空间中对点进行加密,使其紧密地重新采样距离,其中一种工具是多维缩放(MDS):
  • 完成第1点后,您可以运行k-means

  • 或者,您也可以通过执行一些内核学习技术来重新采样数据,然后在生成的Gram矩阵上运行内核k-means来构造内核(在Mercer的意义上是有效的)。

    正如lejlot所说,只有点之间的距离不足以运行经典意义上的k-means。如果你了解k-means的本质,这很容易理解。在高层次上,k-means的工作原理如下:

    1) Randomly assign points to cluster.
      (Technically, there are more sophisticated ways of initial  partitioning, 
      but that's not essential right now).
    
    2) Compute centroids of the cluster. 
      (This is where you need the actual coordinates of the points.)
    
    3) Reassign each point to a cluster with the closest centroid.
    
    4) Repeat steps 2)-3) until stop condition is met.
    
    所以,正如你所看到的,在经典解释中,k-均值不起作用,因为不清楚如何计算质心。然而,我对你能做什么有几点建议

    建议1.

    将点嵌入N维空间,其中N是点的数量,因此每个点的坐标是到所有其他点的距离

    例如,您显示的数据:

    Sample1,Sample2,45
    Sample1,Sample3,69
    Sample1,Sample4,12
    Sample2,Sample2,46
    Sample2,Sample1,78
    
    变成:

    Sample1: (0,45,69,12,...)
    Sample2: (78,46,0,0,...)
    
    然后你可以合法地使用欧几里德距离。请注意,不会保留点之间的实际距离,但这可能是一个简单合理的近似值,用于保留点之间的相对距离。另一个缺点是,如果你有很多分数,那么你的内存(和运行时间)需求将是N^2

    建议2.

    尝试k-means而不是k-means。对于这一个,您不需要点的实际坐标,因为您需要计算质心而不是质心。簇的中间点是来自该簇的一个点,它与该簇中所有其他点的平均距离最小。您可以在线查找实现。或者它实际上很容易实现。运行时间也将与N^2成比例

    最后一句话。


    你为什么要用k-means呢?看起来你有一个加权有向图。有专门针对图的聚类算法。这超出了您的问题范围,但也许这是值得考虑的问题?

    您的第一个问题是,您尝试使用的库需要坐标点,但您的数据仅显示点之间的距离。你的数据是二维的吗?三维的?@AndrewJohnson不。它只是一维的。。。第三行显示点A和点B之间的距离。如果是一维的,则您可以选择一个点,比如说
    Sample1
    为零,然后计算每个其他点相对于该点的绝对位置。那么这个库将为kmeans工作。编辑:你仍然无法判断某个值是否大于或小于数字线上的该点,因此不,这不起作用。我认为你是对的。但是我找不到任何用于对加权图进行聚类的代码?