【问题标题】:List of lists of words clustering词聚类列表列表
【发布时间】:2018-10-25 18:07:16
【问题描述】:

假设我有一个单词列表,例如

[['apple','banana'],
 ['apple','orange'],
 ['banana','orange'],
 ['rice','potatoes','orange'],
 ['potatoes','rice']]

这个集合要大得多。我想对通常一起存在的单词具有相同簇的单词进行聚类。所以在这种情况下,集群将是 ['apple', 'banana', 'orange']['rice','potatoes']
归档这种集群的最佳方法是什么?

【问题讨论】:

  • 到目前为止你尝试过什么?通常,“我如何”类型的问题被认为是题外话。此论坛更适合在您遇到特定问题时提供帮助。
  • 也许sklearn clustering 是一个开始的地方
  • 我正在寻找 sklearn 聚类,但我没有可以执行聚类的值。我也尝试了大表,我注意到每个单词存在多少个不同的单词(例如 t[apple,banana]=1, t[rice,potatoes]=2),但它适用于所有单词(它实际上是笛卡尔product) 很慢,我无法在合理的时间内处理它。
  • 对于词向量,您可以尝试使用NLTKGensim 来创建词/文档向量,或者以某些other 的方式将文本向量转换为机器可读

标签: python machine-learning cluster-analysis information-retrieval


【解决方案1】:

我认为将问题视为图表更为自然。

例如,您可以假设apple 是节点 0,banana 是节点 1,第一个列表表示 0 到 1 之间有一条边。

所以首先将标签转换为数字:

from sklearn.preprocessing import LabelEncoder
le=LabelEncoder()
le.fit(['apple','banana','orange','rice','potatoes'])

现在:

l=[['apple','banana'],
 ['apple','orange'],
 ['banana','orange'],
 ['rice','potatoes'], #I deleted orange as edge is between 2 points, you can  transform the triple to 3 pairs or think of different solution
 ['potatoes','rice']]

将标签转换为数字:

edges=[le.transform(x) for x in l]

>>edges

[array([0, 1], dtype=int64),
array([0, 2], dtype=int64),
array([1, 2], dtype=int64),
array([4, 3], dtype=int64),
array([3, 4], dtype=int64)]

现在,开始构建图并添加边:

import networkx as nx #graphs package
G=nx.Graph() #create the graph and add edges
for e in edges:
    G.add_edge(e[0],e[1])

现在您可以使用connected_component_subgraphs 函数来分析连接的顶点。

components = nx.connected_component_subgraphs(G) #analyze connected subgraphs
comp_dict = {idx: comp.nodes() for idx, comp in enumerate(components)}
print(comp_dict)

输出:

{0: [0, 1, 2], 1: [3, 4]}

print([le.inverse_transform(v) for v in comp_dict.values()])

输出:

[array(['apple', 'banana', 'orange']), array(['potatoes', 'rice'])]

这些是您的 2 个集群。

【讨论】:

  • 我正在考虑将问题转换为图形,但我有数千条记录,每条记录至少包含 10 个单词。因此,整个图可能位于一个组件中。我更需要聚类,因为只有经常一起出现的单词才会被考虑。我也在考虑搜索完整的图表,但我还需要考虑单词组合出现的频率。
【解决方案2】:

寻找频繁项集会更有意义。

如果你对这样的组词进行聚类,所有的东西通常只会在几个层次上联系起来:没有共同点,一个共同点,两个共同点。这太粗糙而不能用于聚类。您将获得所有连接或无连接,并且结果可能对数据更改和排序高度敏感。

因此放弃了对数据进行分区的范式 - 改为寻找频繁的组合。

【讨论】:

  • 上面的例子只是一个例子。集合当然更大(数百个单词)并且有数千个集合。
【解决方案3】:

所以,经过大量谷歌搜索后,我发现我实际上不能使用聚类技术,因为我缺少可以对单词进行聚类的特征变量。如果我制作一张表格,其中我注意到每个单词与其他单词(实际上是笛卡尔积)存在的频率实际上是邻接矩阵并且聚类在它上面不起作用。

所以,我一直在寻找的解决方案是图形社区检测。我使用 igraph 库(或 python 的 python-ipgraph 包装器)来查找集群,它运行得非常好和快。

更多信息:

【讨论】:

  • 您可以简单地对数据进行编码:apple 是第 0 列,banana 是第 1 列,...然后每个集合都是一个二进制向量。这行得通,但由于其他原因(数据太粗略),质量会很差。
  • @Anony-Mousse 但我需要对单词进行聚类,而不是对集合本身进行聚类。如果我对单词使用这种方法,我将得到如上所述的邻接矩阵。事实上,社区检测有相当不错的效果。我不明白为什么我会得到这个答案的减分(并且没有任何评论)。
  • 如果你转置矩阵,你也可以根据它们出现的集合对单词进行聚类。但这可能会导致一些难以处理的基于您的语料库的偏见。但是您最初的问题标题表明您想对集合进行聚类...
猜你喜欢
  • 2017-06-16
  • 2022-06-10
  • 2015-06-22
  • 2014-05-07
  • 2014-01-06
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多