【问题标题】:What Vectorizer should I use when I'm doing clustering of text data?当我对文本数据进行聚类时,我应该使用什么 Vectorizer?
【发布时间】:2020-01-14 02:29:08
【问题描述】:

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

例如当我使用时:

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 的分数。我的图表如下所示:

当我使用时:

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 的分数。我的图表如下所示:

这就是我进行聚类的方式:

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()

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

感谢您的帮助:)

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    剪影分数,来自 sklearn:

    剪影系数是使用平均集群内计算得出的 每个距离 (a) 和平均最近聚类距离 (b) 样本。样本的轮廓系数为 (b - a) / max(a, 乙)。为了澄清,b是样本与最近样本之间的距离 样本不属于的集群。请注意,剪影 仅当标签数为 2

    此函数返回所有的平均轮廓系数 样品。要获取每个样本的值,请使用 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)

    【讨论】:

    • 我想对文本数据进行聚类(数据是关于美国政治的 instagram cmets),我想找到每个聚类的关键词。所以我不知道我应该使用什么矢量化器
    • @taga 你需要做一些特征工程并尝试不同的事情。先验的人不能说一个特征提取是否比另一个更好。我认为你需要做一些特征选择,特征工程。有很多东西可以尝试
    • 无论如何,TF-IDF 是提取集群中最有意义的词的好方法
    • 谢谢,当我有很多列和数字数据时,我知道如何使用特征选择。但是这里我有一列包含文本数据,所以我不知道该怎么做
    • 我想对文本数据进行聚类(数据是关于美国政治的 instagram cmets),我想找到每个聚类的关键词。所以我不知道我应该使用什么矢量化器,你有什么建议?有什么类比我应该在什么时候使用矢量化器? (什么时候应该使用 TfidfVectorizer,什么时候使用 CountVectorizer)
    猜你喜欢
    • 2019-12-12
    • 1970-01-01
    • 2010-10-09
    • 2019-10-04
    • 2011-08-05
    • 2013-06-02
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多