使用python进行文本数据聚类

Posted

技术标签:

【中文标题】使用python进行文本数据聚类【英文标题】:Text data clustering with python 【发布时间】:2021-06-27 06:09:45 【问题描述】:

我目前正在尝试使用 python 根据它们的相似性对序列列表进行聚类。

例如:

DFKLKSLFD

DLFKFKDLD

LDPELDKSL ...

我预处理数据的方式是使用例如Levenshtein distance 计算成对距离。在计算所有成对距离并创建距离矩阵后,我想将其用作聚类算法的输入。

我已经尝试过使用Affinity Propagation,但收敛性有点不可预测,我想解决这个问题。

对于这种情况下的其他合适的聚类算法,是否有人有任何建议?

谢谢!!

【问题讨论】:

有一个完整的算法列表,scikit-learn.org/stable/modules/clustering.html,没有说明你的目标或预期结果..我认为这里很难提供具体答案 这些是我拥有的一些目标/条件:我不知道我想要的集群数量。我想摆脱异常值。考虑最大距离对序列进行聚类(即,聚类内任何对之间的距离不能优于 x)。 【参考方案1】:

sklearn 实际上确实使用 DBSCAN 显示了这个示例,就像 Luke 曾经在这里回答一样。

这是基于该示例,使用!pip install python-Levenshtein。 但如果您预先计算了所有距离,您可以更改自定义指标,如下所示。

from Levenshtein import distance

import numpy as np
from sklearn.cluster import dbscan

data = ["DFKLKSLFD", "DLFKFKDLD", "LDPELDKSL"]

def z:
    i, j = int(x[0]), int(y[0])     # extract indices
    return distance(data[i], data[j])

X = np.arange(len(data)).reshape(-1, 1)

dbscan(X, metric=lev_metric, eps=5, min_samples=2)

如果您预先计算,您可以按照以下方式定义pre_lev_metric(x, y)

def pre_lev_metric(x, y):
    i, j = int(x[0]), int(y[0])     # extract indices
    return DISTANCES[i,j]

基于K-Medoids 使用sklearn_extra.cluster.KMedoids 的替代答案。 K-Medoids 还没有那么出名,但也只需要距离。

我必须这样安装

!pip uninstall -y enum34
!pip install scikit-learn-extra

比我能够创建集群;

from sklearn_extra.cluster import KMedoids
import numpy as np
from Levenshtein import distance

data = ["DFKLKSLFD", "DLFKFKDLD", "LDPELDKSL"]

def lev_metric(x, y):
    i, j = int(x[0]), int(y[0])     # extract indices
    return distance(data[i], data[j])

X = np.arange(len(data)).reshape(-1, 1)
kmedoids = KMedoids(n_clusters=2, random_state=0, metric=lev_metric).fit(X)

标签/中心在

kmedoids.labels_
kmedoids.cluster_centers_

【讨论】:

非常感谢您的回答。我设法实现了 DBSCAN,到目前为止的结果非常有希望。我确实对该算法有一个疑问:假设它选择一个随机点开始聚类,并考虑到我将成对距离作为聚类的基础传递给它,那么聚类最终结果会受到多少影响它选择启动进程的第一个随机点? 确实可能略有不同。如果这是一个问题,则搜索 DBSCAN 的确定性变体,但实际上通常这不是问题。通常进行聚类以获取数据的一些摘要。一个边缘点属于集群 A 或 B 不会对项目造成太大影响。【参考方案2】:

试试这个。

import numpy as np
from sklearn.cluster import AffinityPropagation
import distance
    
words = 'XYZ,LDPELDKSL,DFKLKSLFD,ABC,DLFKFKDLD,XYZ,LDPELDKSL,DFKLKSLFD,ABC,DLFKFKDLD,XYZ,LDPELDKSL,XYZ,LDPELDKSL,DFKLKSLFD,ABC,DLFKFKDLD,XYZ,LDPELDKSL,DFKLKSLFD,ABC,DLFKFKDLD,XYZ,LDPELDKSL'.split(',') #Replace this line
words = np.asarray(words) #So that indexing with a list will work
lev_similarity = -1*np.array([[distance.levenshtein(w1,w2) for w1 in words] for w2 in words])

affprop = AffinityPropagation(affinity="precomputed", damping=0.5)
affprop.fit(lev_similarity)
for cluster_id in np.unique(affprop.labels_):
    exemplar = words[affprop.cluster_centers_indices_[cluster_id]]
    cluster = np.unique(words[np.nonzero(affprop.labels_==cluster_id)])
    cluster_str = ", ".join(cluster)
    print(" - *%s:* %s" % (exemplar, cluster_str))

结果:

 - *LDPELDKSL:* LDPELDKSL
 - *DFKLKSLFD:* DFKLKSLFD
 - *XYZ:* ABC, XYZ
 - *DLFKFKDLD:* DLFKFKDLD

【讨论】:

【参考方案3】:
common_words = kmeans.cluster_centers_.argsort()[:,-1:-11:-1]
for num, centroid in enumerate(common_words):
    print(str(num) + ' : ' + ', '.join(words[word] for word in centroid))

【讨论】:

以上是关于使用python进行文本数据聚类的主要内容,如果未能解决你的问题,请参考以下文章

一个简单的文本聚类实现(python)

python中的文本聚类,而不是使用k_means

[转]python进行中文文本聚类(切词以及Kmeans聚类)

机器学习入门-文本数据-使用聚类增加文本的标签属性

python k-means聚类文本

Python中的聚类文本[关闭]