我正在编写一个简单的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个功能。我应该早点提到。
答案 0 :(得分:2)
Seaborn和Pandas可以很好地协同进行这种绘图 如果您可以使用它们,请考虑以下解决方案:
# 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)
如果你只限于那些模块,这是一个纯粹的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]])
答案 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)