使用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进行文本数据聚类的主要内容,如果未能解决你的问题,请参考以下文章