【问题标题】:How to find clusters a matrix如何找到聚类矩阵
【发布时间】:2016-03-29 19:49:03
【问题描述】:

我对数据挖掘、数据分析或统计分析一无所知,但我认为我需要的是找到“矩阵中的集群”。我有一个约 2 万条记录的数据集,每条记录都有约 40 个特征,所有这些特征要么打开要么关闭。

+--------+------+------+------+------+------+------+
| record | hasA | hasB | hasC | hasD | hasE | hasF |
+--------+------+------+------+------+------+------+
| foo    |    1 |    0 |    1 |    0 |    0 |    0 |
| bar    |    1 |    1 |    0 |    0 |    1 |    1 |
| baz    |    1 |    1 |    1 |    0 |    0 |    0 |
+--------+------+------+------+------+------+------+

我非常相信这 20k 条记录中的大多数都具有属于几个类别之一的特征。必须有办法确定记录“foo”与记录“bar”的相似程度。

那么,我实际上在看什么?我在寻找什么算法?

【问题讨论】:

  • 所有特征都是 0/1 值吗?
  • 这对Cross Validated来说可能是一个更好的问题。
  • @blazs 是的,“打开或关闭”我的意思是 1/0,抱歉。正如您在答案的第一句话中所想的那样。

标签: machine-learning cluster-analysis data-analysis


【解决方案1】:

将每条记录r 转换为二进制向量v(r),这样v(r)i-th 分量设置为1,如果r 具有i-th 特征,并且0否则。

现在在Hamming distanceJaccard distance下的这组向量上运行hierarchical clustering算法,无论你认为哪个更合适;还要确保根据基本距离定义集群之间的距离概念(请参阅linkage criteria)。

然后根据常识决定在哪里剪切生成的dendrogram。切割树状图的位置会影响簇的数量。

层次聚类的一个缺点是它相当慢。通常需要O(n^3) 时间,因此在大型数据集上需要相当长的时间。对于单一链接和完整链接,您可以将时间缩短到 O(n^2)

层次聚类很容易在 Python 等语言中实现。您还可以使用 scipy 库中的实现。

示例:Python 中的层次聚类

这里有一个代码 sn-p 可以帮助您入门。我假设S 是转换为二进制向量的记录集(即S 中的每个列表对应于您数据集中的一条记录)。

import numpy as np
import scipy
import scipy.cluster.hierarchy as sch
import matplotlib.pylab as plt

# This is the set of binary vectors, each of which would
# correspond to a record in your case.
S = [
        [0, 0, 0, 1, 1], # 0
        [0, 0, 0, 0, 1], # 1
        [0, 0, 0, 1, 0], # 2
        [1, 1, 1, 0, 0], # 3
        [1, 0, 1, 0, 0], # 4
        [0, 1, 1, 0, 0]] # 5

# Use Hamming distance with complete linkage.
Z = sch.linkage(sch.distance.pdist(S, metric='hamming'), 'complete')

# Compute the dendrogram
P = sch.dendrogram(Z)

plt.show()

结果如您所料:在 0.5 处切割得到两个簇,前三个向量中的一个(开头有 1,结尾有 0)和后三个向量中的另一个(有 1最后,开头为零)。这是图片:

层次聚类从每个向量都是它自己的聚类开始。在每个连续的步骤中,它都会合并最近的集群。它会重复此操作,直到剩下一个集群。

树状图本质上是对整个聚类过程进行编码。一开始,每个向量都是它自己的集群。然后{3}{5}合并成{3,5}{0}{2}合并成{0,2}。接下来,{4}{3,5} 合并为{3,4,5}{1}{0,2} 合并为{0,1,2}。最后{0,1,2}{3,4,5}合并成{0,1,2,3,4,5}

从树状图中,您通常可以看到在哪个点切割最有意义——这将定义您的集群。

我鼓励您尝试各种距离(例如 Hamming 距离、Jaccard 距离)和链接(例如单链接、完全链接)以及各种表示(例如二元向量)。

【讨论】:

  • 谢谢,足够思考和阅读的食物,看来我的直觉还没有完全消失。
  • @MarcelStör 没问题。我提供了一个简单的代码,一旦您将数据转换为上面的S 形式,就可以轻松使用。
  • 这将勉强扩展到 20k 个实例,如果 OP 增加他的数据集大小,则更多。但最终,他可能根本不需要聚类——而只是相似性搜索。
【解决方案2】:

您确定要进行聚类分析吗?

查找相似记录,您不需要聚类分析。只需使用任何距离度量(例如 Jaccard 相似度或 Hamming 距离(两者都用于二进制数据))查找相似记录。或余弦距离,以便您可以使用例如Lucene 可以快速找到相似的记录。

要找到常见模式,使用频繁项集挖掘可能会产生更有意义的结果,因为这些只能对属性子集起作用。例如,在超市中,Noodles、Tomato、Basil、Cheese 列可能构成频繁模式。

大多数聚类算法都试图将数据分成 k 个组。虽然这乍一看似乎是个好主意(获取 k 个目标组),但它很少与真实数据包含的内容相匹配。例如客户:为什么每个客户都只属于一个受众?如果观众是例如汽车爱好者、枪支爱好者、足球爱好者、足球妈妈——您确定不想让这些群体重叠吗? 此外,聚类分析的一个问题是它非常容易使用不当。它不会“严重失败”——你总会得到一个结果,但你可能没有意识到这是一个糟糕的结果......

【讨论】:

  • “只需使用任何距离度量(例如 Jaccard 相似度或汉明距离)查找相似记录”,这从树状图中很明显。
  • 对于不好的结果,用户应该总是亲自动手看看数据“看起来像”什么(例如运行初步计算)以及结果是否有意义。如果没有,她应该改变表示/改变距离函数/等。 (使用常识)。
  • 频繁项集挖掘(例如association rule learning)在这种情况下可能是个好主意。
  • 您不需要树状图(仅扩展到几十个实例)即可找到相似的对象。事实上,你首先需要找到相似的对象才能进行层次聚类。
  • 我知道层次聚类是如何工作的。我现在认为他应该使用局部敏感哈希。
猜你喜欢
  • 2023-03-12
  • 2015-01-07
  • 2020-01-23
  • 1970-01-01
  • 1970-01-01
  • 2017-08-06
  • 2016-10-01
  • 1970-01-01
相关资源
最近更新 更多