评估聚类效果

A:采用轮廓系数评估基于wordvec和dbscan的聚类结果

ChatGPT: 轮廓系数是一种常用的聚类评估方法,可以用来评估聚类结果的质量。其数学定义为: 轮廓系数(s) = (b-a)/max(a,b) 其中,a表示同簇内样本之间的平均距离,b表示样本与最近其他簇的平均距离。轮廓系数越接近1,表示聚类效果越好;越接近-1,表示聚类效果越差。 对于基于wordvec和dbscan的聚类结果,可以先用轮廓系数评估每个簇的质量,然后计算整个聚类结果的平均轮廓系数。具体步骤如下:

  1. 对于每个簇,计算其中所有样本之间的距离,并求出平均距离a。
  2. 对于每个样本,计算其与最近其他簇的平均距离,并求出平均距离b。
  3. 根据公式计算每个样本的轮廓系数,并将其加权平均得到整个聚类结果的平均轮廓系数。
  4. 根据平均轮廓系数的大小,评估聚类结果的质量。如果平均轮廓系数接近1,则说明聚类效果比较好;如果接近0,则说明聚类效果一般;如果接近-1,则说明聚类效果比较差。 需要注意的是,轮廓系数评估方法并不是绝对可靠的,因为它只能评估聚类结果的局部质量,而不能反映整个数据集的全局结构。因此,在使用轮廓系数评估聚类结果时,需要结合其他方法和领域知识来综合评估。

A: python示例代码

ChatGPT: 示例代码:

###### 评估聚类效果
from sklearn.metrics import silhouette_score

# 直接聚类
for eps in np.arange(0.1, 0.3, 0.02):
    # 使用dbscan进行聚类
    dbscan = DBSCAN(eps=eps, min_samples=10, metric='cosine')
    dbscan.fit(tfidf_pca)
    labels = dbscan.labels_
    score = silhouette_score(tfidf_pca, labels)
    print("eps:", eps,"轮廓系数为:", score)

实际测试eps很低的时候0.015左右,轮廓系数可以达到0.3,但是只能分出来一个类别,其他都是噪声。 eps调到0.15,轮廓系数0.09左右,可以分出来39个类别,所以对于中文文本分析,本来词向量比较稀疏,轮廓系数不能很好地作为评价标准。

A:采用可视化评估基于wordvec和dbscan的聚类结果,python示例

ChatGPT: 下面是一个基于wordvec和dbscan的聚类结果的Python可视化示例

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.manifold import TSNE
from sklearn.cluster import DBSCAN
from gensim.models import Word2Vec

#读入数据
df = pd.read_csv('data.csv')

# 训练word2vec模型
sentences = [s.split() for s in df['text']]
model = Word2Vec(sentences, min_count=1)

# 获取所有词向量
vocab = list(model.wv.vocab)
X = model[vocab]

#降维
tsne = TSNE(n_components=2, random_state=42)
X_tsne = tsne.fit_transform(X)

# 进行聚类
dbscan = DBSCAN(eps=0.5, min_samples=5)
dbscan.fit(X_tsne)

# 可视化
plt.scatter(X_tsne[dbscan.labels_ ==0,0], X_tsne[dbscan.labels_ ==0,1], c='blue', label='Cluster1')
plt.scatter(X_tsne[dbscan.labels_ ==1,0], X_tsne[dbscan.labels_ ==1,1], c='red', label='Cluster2')
plt.scatter(X_tsne[dbscan.labels_ == -1,0], X_tsne[dbscan.labels_ == -1,1], c='green', label='Noise')
plt.legend()
plt.show()

说明:

  • data.csv是包含文本数据的CSV文件; -代码首先读入数据,并使用训练数据训练word2vec模型;
  • TSNE将高维的词向量降到二维;
  • 使用DBSCAN进行聚类,并将结果可视化。其中,标签为0和1的是聚类结果,标签为-1的是噪声点。

我把上面的代码改了下,引入了distinctipy来生成几十种颜色,绘制各个类别:

from distinctipy import distinctipy
# number of colours to generate
N = max(labels)
# generate N visually distinct colours
colors = distinctipy.get_colors(N)
# text = [distinctipy.get_text_color(color) for color in colors]

# 可视化
for i in range(0,N):
    cname='cluster'+str(i)
    plt.scatter(X_pca[labels ==i,0], X_pca[labels ==i,1], c=np.array(colors[i]).reshape(1,-1), label=cname)
# plt.scatter(X_pca[labels == -1,0], X_pca[labels == -1,1], c='green', label='Noise')
plt.legend()
plt.show()

一些bug

使用中会有个warning:

*c* argument looks like a single numeric RGB or RGBA sequence, which should be avoided as value-mapping will have 
precedence in case its length matches with *x* & *y*.  Please use the *color* keyword-argument or provide a 2-D 
array with a single row if you intend to specify the same RGB or RGBA value for all points.

原因是我们上述代码中自定义的颜色是一个元组,不符合规定的二维数组,需将其转换二维数组,采用np.array(colors[i]).reshape(1,-1) 来解决。 将我们的自定颜色的元组转换成一维数组再进行增维:

  • 转换成数组:np.array(color1)
  • 使用reshape进行增维,使用reshape(1,-1)进行行上增维
  • 备注:如果是列上增维度,可以使用reshape(-1,1) 列上维度增加一

最后输出效果:



请遵守《互联网环境法规》文明发言,欢迎讨论问题
扫码反馈

扫一扫,反馈当前页面

咨询反馈
扫码关注
返回顶部