python中的散点图表示更接近质心的点,用于K均值聚类

时间:2017-05-05 16:00:20

标签: python-3.x matplotlib

我正在编写一个简单的K-means算法用于聚类,我正在尝试渲染一个散点图,显示样本数据(从CSV文件加载到numpy矩阵X中的样本数据行)。

让我们说X是一个numpy矩阵,每行包含具有10个特征的示例数据。对于我的情况,它们是包含src IP地址,目标IP地址,src端口或目标端口的网络流的属性。 我还计算了K均值的质心(其中K是总质心)。我有一个列表idx,它只是个别X行所属的质心的索引。例如,如果X numpy矩阵的第5行属于centroid = 3,则将具有idx [4] = 3(因为我们从0开始)。 有了这个,包含10个特征的单个数据记录的每行X都属于唯一的质心。 我想绘制散点图,X中的数据点分别为每个质心着色。 例如,如果X的第5行,第8行更靠近质心3,我想用不同的颜色为它们着色。 如果我在Octave中这样做,我可以编写如下代码: -

function plotPoints(X,idx,K)
  p= hsv(K+1) % palette
  c= p(idx,:) % color
  scatter(X(:,1),X(:,2),15,c) % plot the scatter plot

然而在python中,我不知道如何实现相同的,以便我可以显示具有相同索引赋值的数据样本具有相同的颜色。我的代码当前显示红色的所有X行和蓝色的所有质心,如下所示: -

def plotPoints(X,idx,K,centroids):
    srcport=X[:,5]
    dstport=X[:,6]

    fig = plt.figure()
    ax=fig.add_subplot(111,projection='3d')
    ax.scatter(srcport,dstport,c='r',marker='x')
    ax.scatter(centroids[:,5],centroids[:,6],c='b',marker='o', s=160)
    ax.set_xlabel('Source port')
    ax.set_xlabel('Destination port')
    plt.show()

请注意:我只在x& amp; y轴而不是所有10个功能。我应该早点提到。

2 个答案:

答案 0 :(得分:2)

SeabornPandas可以很好地协同进行这种绘图 如果您可以使用它们,请考虑以下解决方案:

# generate sample data
import numpy as np
values = np.random.random(500).reshape(50,10) * 10
centroid = np.random.choice(np.arange(5), size=50).reshape(-1,1)
data = np.concatenate((values, centroid), axis=1)

# convert to DataFrame
import pandas as pd
colnames = ['a','b','c','d','e','f','g','h','i','j','centroid']
df = pd.DataFrame(data, columns=colnames)

# data frame looks like:
df.head()

   a  b  c  d  e  f  g  h  i  j  centroid
0  6  9  9  9  1  2  4  0  8  9         4
1  9  1  0  0  7  9  9  3  7  2         1
2 10  4  8  7  2  8  9  4  6  8         3
3  2  6  5  2  8  4  9  3  9  5         4
4  9  7  5  1  3  2  1  8  3  4         4

# plot with Seaborn
import seaborn as sns
sns.lmplot(x='a', y='b', hue='centroid', data=df, scatter=True, fit_reg=False)

scatter plot by centroid

如果你只限于那些模块,这是一个纯粹的Numpy / Pyplot版本:

from matplotlib import pyplot as plt
fig, ax = plt.subplots()

colors = {0:'purple', 1:'red', 2:'blue', 3:'green', 4:'black'}

ax.scatter(x=data[:,0], y=data[:,1], c=[colors[x] for x in data[:,10]])

scatter2-pyplot-only

答案 1 :(得分:2)

查看发布Scatter plot and Color mapping in Python的答案。我想你的质心'索引对应于集群。在这种情况下,您可以使用简单数组作为颜色:

ax.scatter(srcport, dstport, c=idx, marker='x')
ax.scatter(centroids[:,5], centroids[:,6], c=np.arange(K), marker='o', s=160)

或使用colormap

ax.scatter(srcport, dstport, c=plt.cm.viridis(idx / K), marker='x')
ax.scatter(centroids[:,5], centroids[:,6], c=plt.cm.viridis(np.arange(K) / K),
            marker='o', s=160)