使用Python中的Scipy Hierarchy Clustering进行文本聚类

时间:2017-04-30 13:42:11

标签: python scipy cluster-analysis text-mining

我有一个文本语料库,每个文章包含1000多篇文章。我试图在python中使用Scipy使用层次结构聚类来生成相关文章的集群。 这是我用来进行聚类的代码

# Agglomerative Clustering
import matplotlib.pyplot as plt
import scipy.cluster.hierarchy as hac
tree = hac.linkage(X.toarray(), method="complete",metric="euclidean")
plt.clf()
hac.dendrogram(tree)
plt.show() 

我得到了这个情节 dendrogram

然后我用fcluster()

切断了第三层的树
from scipy.cluster.hierarchy import fcluster
clustering = fcluster(tree,3,'maxclust')
print(clustering)

我得到了这个输出: [2 2 2 ...,2 2 2]

我的问题是如何在每个群集中找到前10个常用词,以便为每个群集建议一个主题?

2 个答案:

答案 0 :(得分:0)

您可以执行以下操作:

  1. 将您的结果(您的clustering变量)与您的输入(1000多篇文章)对齐。
  2. 使用pandas库,您可以使用groupby function将群集#作为其密钥。
  3. 每组(使用get_group function),为每个填充defaultdict个整数 你遇到的一句话。
  4. 您现在可以按降序对单词计数字典进行排序,并获得所需的最常用单词数。
  5. 祝你好运,如果你正在寻找的话,请接受我的回答。

答案 1 :(得分:0)

我愿意。给定一个带有文章名称和文章文本的 df,例如

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6 entries, 0 to 5
Data columns (total 2 columns):
 #   Column    Non-Null Count  Dtype 
---  ------    --------------  ----- 
 0   Argument  6 non-null      object
 1   Article   6 non-null      object
dtypes: object(2)
memory usage: 224.0+ bytes

创建文章矩阵

from scipy.cluster.hierarchy import linkage, fcluster
from sklearn.feature_extraction.text import CountVectorizer

# initialize
cv = CountVectorizer(stop_words='english') 
cv_matrix = cv.fit_transform(df['Article']) 
# create document term matrix
df_dtm = pd.DataFrame(
    cv_matrix.toarray(), 
    index=df['Argument'].values, 
    columns=cv.get_feature_names()
)
tree = hierarchy.linkage(df_dtm, method="complete", metric="euclidean")

然后得到选择的聚类

clustering = fcluster(tree, 2, 'maxclust')

并将聚类添加到 df_dtm

df_dtm['_cluster_'] = clustering
df_dtm.index.name = '_article_'
df_word_count = df_dtm.groupby('_cluster_').sum().reset_index().melt(
    id_vars=['_cluster_'], var_name='_word_', value_name='_count_'
)

最后取第一个出现频率最高的词

words_1 = df_word_count[df_word_count._cluster_==1].sort_values(
    by=['_count_'], ascending=False).head(3)
words_2 = df_word_count[df_word_count._cluster_==2].sort_values(
    by=['_count_'], ascending=False).head(3)