【问题标题】:How can I write a python program for creating iterative clusters for k-means algorithm?如何编写一个 python 程序来为 k-means 算法创建迭代集群?
【发布时间】:2019-03-10 09:50:41
【问题描述】:
import pandas as pd
import numpy as np
import math
from scipy.spatial import distance
from pandas import DataFrame
a = [2,2,8,5,7,6,1,4]
b = [10,5,4,8,5,4,2,9]
list1=[]
list2=[]
cluster1=[]
cluster2=[]
df1 = pd.DataFrame({'Column 1': a, 'Column 2': b})
print(df1)
x1=int(input("Enter seed point X1: "))
y1=int(input("Enter seed point Y1: "))
x2=int(input("Enter seed point X2: "))
y2=int(input("Enter seed point Y2: "))
#calculate Distance
for i,j in zip(a,b):
        c1=round(math.sqrt(math.pow((x1 - i), 2) + math.pow((y1 - j), 2)),2)
        c2=round(math.sqrt(math.pow((x2 - i), 2) + math.pow((y2 - j), 2)),2)
        list1.append(c1)
        list2.append(c2)
df2 = pd.DataFrame({'Distance 1': list1, 'Distance 2': list2})
print(df2)
for p,q in zip(a,b):
      for i,j in zip(list1,list2):
            if(i<j):
                    cluster1.append((p,q))
print(cluster1)

未正确创建集群。只有 (2,10) 应该在集群 1 中,其余的在集群 2 中。同样,这个过程应该重复多次,直到种子点的平均值变得相同。 最后,答案应该是聚类的数据集。我参考了许多显示可视化集群的在线代码,但我需要一个简单的打印在屏幕上的格式结果。

【问题讨论】:

  • 在代码中添加一些空格。没有正确的格式很难阅读
  • 很抱歉给您带来不便,我还是个初学者。我会按照你说的改进。谢谢。

标签: python


【解决方案1】:

我认为你在第二个 for 循环中的逻辑是关闭的。这是你想要得到的:

import pandas as pd
import numpy as np
import math
from scipy.spatial import distance
from pandas import DataFrame

a = [2, 2, 8, 5, 7, 6, 1, 4]
b = [10, 5, 4, 8, 5, 4, 2, 9]
list1 = []
list2 = []
cluster1 = []
cluster2 = []
df1 = pd.DataFrame({'Column 1': a, 'Column 2': b})
print(df1)
x1 = int(input("Enter seed point X1: "))
y1 = int(input("Enter seed point Y1: "))
x2 = int(input("Enter seed point X2: "))
y2 = int(input("Enter seed point Y2: "))
# calculate Distance
for i, j in zip(a, b):
    c1 = round(math.sqrt(math.pow((x1 - i), 2) + math.pow((y1 - j), 2)), 2)
    c2 = round(math.sqrt(math.pow((x2 - i), 2) + math.pow((y2 - j), 2)), 2)
    list1.append((c1, (i, j)))
    list2.append((c2, (i, j)))
df2 = pd.DataFrame({'Distance 1': list1, 'Distance 2': list2})
print(df2)
for i, j in zip(list1, list2):
    d0, d1 = i[0], j[0]
    if d0 < d1:
        cluster1.append(i[1])
    else:
        cluster2.append(i[1])
print(cluster1)

import matplotlib.pyplot as plt

x1 = [i[0] for i in cluster1]
y1 = [i[1] for i in cluster1]
plt.scatter(x1, y1)
x2 = [i[0] for i in cluster2]
y2 = [i[1] for i in cluster2]
plt.scatter(x2, y2)
plt.show()

如果是这样,这可能不是最优雅的解决方法。

EDIT0:我已包含用于创建原始散点图的代码。

EDIT1:以下是 cmets 中提到的后续问题的代码。这是 k = 2。

import matplotlib.pyplot as plt
import math

a = [2, 2, 8, 5, 7, 6, 1, 4]
b = [10, 5, 4, 8, 5, 4, 2, 9]

x1 = int(input("Enter seed point X1: "))
y1 = int(input("Enter seed point Y1: "))
x2 = int(input("Enter seed point X2: "))
y2 = int(input("Enter seed point Y2: "))

curr_means = [(x1, y1), (x2, y2)]
prev_means = []
while prev_means != curr_means:
    prev_means = curr_means
    x1 = curr_means[0][0]
    y1 = curr_means[0][1]
    x2 = curr_means[1][0]
    y2 = curr_means[1][1]
    list1 = []
    list2 = []
    cluster1 = set()
    cluster2 = set()
    for i, j in zip(a, b):
        c1 = round(math.sqrt(math.pow((x1 - i), 2) + math.pow((y1 - j), 2)), 2)
        c2 = round(math.sqrt(math.pow((x2 - i), 2) + math.pow((y2 - j), 2)), 2)
        list1.append((c1, (i, j)))
        list2.append((c2, (i, j)))

    for i, j in zip(list1, list2):
        d0, d1 = i[0], j[0]
        if d0 < d1:
            cluster1.add(i[1])
        else:
            cluster2.add(i[1])
    print("c1: ", cluster1)
    print("c2: ", cluster2)

    cluster1_mean_x = sum(x[0] for x in cluster1) / len(cluster1)
    cluster1_mean_y = sum(x[1] for x in cluster1) / len(cluster1)
    cluster2_mean_x = sum(x[0] for x in cluster2) / len(cluster2)
    cluster2_mean_y = sum(x[1] for x in cluster2) / len(cluster2)
    curr_means = [(cluster1_mean_x, cluster1_mean_y), (cluster2_mean_x, cluster2_mean_y)]
    print('-----------------------------')

print(cluster1)
print(cluster2)

x1 = [i[0] for i in cluster1]
y1 = [i[1] for i in cluster1]
plt.scatter(x1, y1)
x2 = [i[0] for i in cluster2]
y2 = [i[1] for i in cluster2]
plt.scatter(x2, y2)
plt.show()

如上所述,这段代码效率不高,不再干净。对于有关工作代码的问题(例如如何使代码更高效、更干净、更易读),请尝试使用堆栈交换代码审查。

【讨论】:

  • 您能解释一下第二个 for 循环是如何工作的吗?即我[0]?因为 list1 有两个实体,距离和点。也谢谢,我的 cluster1 现在打印正确的输出。但是如何使它“迭代”,如下所示 - 现在它将计算集群中存在的所有数据点的平均值并将它们作为 x'1,y'1,x'2,y'2,再次重复整个过程直到两次迭代的手段相同并显示最终聚类。例如:在第 2 次迭代中,(2,10) 和 (4,9) 在 cluster1 中,在 cluster2 中休息。
  • list1 和 list2,现在不仅包含数据点到种子点的距离,还包含点本身。所以 list1[i] = ( distance_of_pt_i_to_seed1, (a[i], b[i]) )。换句话说,list[i][0] 是距离,list[i][1] 是数据点本身。对于每个数据点,第二个 for 循环的工作是检查哪个种子点最接近。在确定哪个更接近后,获取数据点 (list1[i][1]) 并将其粘贴到相应的集群中。从技术上讲,您可以只将数据点保存到一个列表中,而不是同时保存。
  • 答案已修改为包括@minsuga 后续问题。
  • 哦,好吧,现在我明白了。谢谢@Perplexabot。是的,我应该将数据点保存到一个列表中。我会做的。?
猜你喜欢
  • 2010-12-05
  • 2016-07-29
  • 2020-10-13
  • 2021-04-19
  • 2022-01-01
  • 1970-01-01
  • 2018-03-04
  • 2018-10-11
  • 2017-08-10
相关资源
最近更新 更多