在对文本数据进行聚类时应该使用什么Vectorizer?

时间:2019-09-12 08:36:51

标签: python scikit-learn

我正在使用Python的Scikit-Learn中的Kmeans对文本数据进行聚类。 我对数据进行矢量化有问题,因为当我使用不同的矢量化程序时,得到的结果非常不同。 我想对文本数据进行聚类(数据是有关美国政治的instagram评论),我想找到每个聚类的关键词。但是我不知道我应该使用什么矢量化器

例如,当我使用时:

cv = CountVectorizer(analyzer = 'word', max_features = 8000, preprocessor=None, lowercase=True, tokenizer=None, stop_words = 'english')  

x = cv.fit_transform(x)
#should I scale x value?
#x = scale(x, with_mean=False)
#If I do this I get the graph just one dot and silhouette_score less than 0.01

基于silhouette_score,我得到的最佳簇数为2,得出的分数为0.87。我的图看起来像这样: enter image description here

当我使用时:

cv = TfidfVectorizer(analyzer = 'word',max_features = 8000, preprocessor=None, lowercase=True, tokenizer=None, stop_words = 'english')

x = cv.fit_transform(x)

基于silhouette_score,我得到的最佳簇数为13,得出的分数为0.0159。我的图看起来像这样:

enter image description here

这是我进行集群的方式:

my_list = []
list_of_clusters = []
for i in range(2,15):

    kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 42)
    kmeans.fit(x)
    my_list.append(kmeans.inertia_)

    cluster_labels = kmeans.fit_predict(x)

    silhouette_avg = silhouette_score(x, cluster_labels)
    print(round(silhouette_avg,2))
    list_of_clusters.append(round(silhouette_avg, 1))


plt.plot(range(2,15),my_list)
plt.show()


number_of_clusters = max(list_of_clusters)
number_of_clusters = list_of_clusters.index(number_of_clusters)+2

print('Number of clusters: ', number_of_clusters)
kmeans = KMeans(n_clusters = number_of_clusters, init = 'k-means++', random_state = 42)
kmeans.fit(x)

这就是我绘制数据的方式:

# reduce the features to 2D
pca = PCA(n_components=2, random_state=0)
reduced_features = pca.fit_transform(x.toarray())

# reduce the cluster centers to 2D
reduced_cluster_centers = pca.transform(kmeans.cluster_centers_)

plt.scatter(reduced_features[:,0], reduced_features[:,1], c=kmeans.predict(x), s=3)
plt.scatter(reduced_cluster_centers[:, 0], reduced_cluster_centers[:,1], marker='x', s=50, c='r')
plt.show()

我认为这是非常大的区别,所以我确定我做错了事,但是我不知道是什么。

感谢您的帮助:)

1 个答案:

答案 0 :(得分:0)

剪影得分,来自sklearn:

  

使用平均群集内计算出轮廓系数   每个距离(a)和平均最近集群距离(b)   样品。样本的轮廓系数为(b-a)/ max(a,   b)。为了明确起见,b是样本与最近的样本之间的距离   样本不属于的集群。注意剪影   仅当标签数为2 <= n_labels <=时才定义系数   n_samples-1。

     

此函数返回全部的平均轮廓系数   样品。要获取每个样本的值,请使用silhouette_samples。

     

最佳值为1,最差值为-1。接近0的值表示   重叠的簇。负值通常表示样本   已分配给错误的群集,因为不同的群集更多   相似。

您的最佳值接近于0,这意味着您没有很好的聚类

好的聚类是其中的聚类:

  • 类内相似度很高(集群中的文档相似)。
  • 类间相似度很低(来自两个聚类的文档不相似)。

当然,集群应该告诉您一些有趣的事情。例如,一个群集可以包含链接到特定域的所有单词。但这是集群完成后要做的工作。

更改矢量化意味着您正在更改要进行聚类的功能。

从python sklearn文档中,CountVectorizer

  

CountVectorizer实现标记化和事件计数   在一堂课

基本上,您将令牌记为特征。

代替TfidfVectorizer

  

将原始文档的集合转换为TF-IDF功能矩阵。

这意味着您将Term Frequency - Inverse Document Frequency公式用作文档的特征,其计算公式为:

  

TF(t)=(术语t在文档中出现的次数)/(总计   文档中的术语数)。 IDF(t)= log_e(总数   文档/其中带有术语t的文档数量)

     

TF-IDF = TF(t)* IDF(t)