计算两个配置文件之间的相似性以获得共同特征的数量

Posted

技术标签:

【中文标题】计算两个配置文件之间的相似性以获得共同特征的数量【英文标题】:calculating similarity between two profiles for number of common features 【发布时间】:2015-07-13 12:18:49 【问题描述】:

我正在研究社交网络个人资料的聚类问题,每个个人资料文档都由个人资料描述中“感兴趣的词”出现的次数表示。为了有效地进行聚类,我试图在两个配置文件之间找到正确的相似性度量(或距离函数)。

假设我有以下个人资料表

            basketball  cricket python
profile1        4           2     1
profile2        2           1     3
profile3        2           1     0

现在,通过计算欧几里得距离,我得到

distance (profile1,profile2) = 3
distance (profile2,profile3) = 3
distance (profile3,profile1) = 2.45

现在,这很好,但我想到了两个问题

在这里,我们忽略了常见特征的数量,例如,尽管个人资料 1 和个人资料 3 是最近的,但根据人类直觉,个人资料 1 和个人资料 2 至少在所有三个兴趣中都有一些价值 - 篮球、板球和 python,因此这两个配置文件可能更相似,而不是配置文件 1 和配置文件 3,其中一个(配置文件 3)在配置文件中没有提到 python。我也不想只计算距离的相似特征,这肯定会产生错误的结果。

我的第一个问题 - 有什么方法可以通过任何已建立的方式来适应这种直觉吗?

我的第二个问题 - 可能有一些个人资料作者比其他人更冗长,如何调整?因为具有 4 次出现 python 的配置文件的详细作者可能与不太详细的作者 2 次出现 python 相同。

我无法为这个问题想出好的标题。很抱歉,如果它令人困惑。

【问题讨论】:

【参考方案1】:

首先,按照您的做法计算您的个人资料。那么关键的一步将是某种标准化。您可以将数字除以它们的总数,使数字总和为 1,也可以将它们除以欧几里得范数,使它们的欧几里得范数为 1。

例如,使用总和归一化,第一个配置文件将变为(四舍五入)

0.57, 0.29, 0.14

使用欧几里得归一化,它会变成

0.87, 0.44, 0.22

这将确保所有配置文件都在相同的数字范围内表示,并会处理“过于冗长的配置文件作者”。


下面是一个示例 IPython 会话,它显示了如何按行总和对行进行归一化,以及如何计算归一化行之间的欧几里德距离。您会看到,在归一化之后,配置文件 1 和 3 更加接近,正如您所期望的那样。

In [22]: p = array([[4,2,1],[2,1,3],[2,1,0]])

In [23]: p
Out[23]: 
array([[4, 2, 1],
       [2, 1, 3],
       [2, 1, 0]])

In [24]: p = p / p.sum(axis=1)[:,newaxis]

In [25]: p
Out[25]: 
array([[ 0.57142857,  0.28571429,  0.14285714],
       [ 0.33333333,  0.16666667,  0.5       ],
       [ 0.66666667,  0.33333333,  0.        ]])

In [26]: p.sum(axis=1)
Out[26]: array([ 1.,  1.,  1.])

In [27]: norm(p[0] - p[1])   # distance 1-2
Out[27]: 0.44543540318737401

In [28]: norm(p[0] - p[2])   # distance 1-3
Out[28]: 0.17817416127494959

In [29]: norm(p[1] - p[2])   # distance 2-3
Out[29]: 0.62360956446232352

最后,如果您想更加重视个人资料是否完全提及兴趣,而不是提及它的频率,您可以在规范化之前做一个额外的步骤:只需为每个元素计算 pow(x, alpha) @ 987654325@ 的配置文件向量,其中alpha 是介于 0 和 1 之间的参数。这里,1 表示和以前一样的标准线性加权,当你使 alpha 接近 0 时,它意味着只提及兴趣计数,而不是多久提及一次。例如,使用alpha = 0.5(取配置文件的平方根),我们得到:

In [32]: p = array([[4,2,1],[2,1,3],[2,1,0]])

In [33]: p = sqrt(p)

In [34]: p
Out[34]: 
array([[ 2.        ,  1.41421356,  1.        ],
       [ 1.41421356,  1.        ,  1.73205081],
       [ 1.41421356,  1.        ,  0.        ]])

In [35]: p = p / p.sum(axis=1)[:,newaxis]

In [37]: norm(p[0] - p[1])   # distance 1-2
Out[37]: 0.2353133053319465

In [38]: norm(p[0] - p[2])   # distance 1-3
Out[38]: 0.27881275777438091

In [39]: norm(p[1] - p[2])   # distance 2-3
Out[39]: 0.51412606310632747

现在配置文件 1 和 2 是最接近的匹配项,因为我们更加强调他们都提到 Python 的事实,而不是他们提到它的频率。

【讨论】:

好的。但是问题1呢?如何计算共同特征的数量和距离? @Kognizant:这解决了这两个问题。只需计算这些归一化向量的距离。 对不起,我不明白。您能否详细说明它是如何解决第一个问题的? @Kognizant:我已经用示例代码更新了答案。 @Kognizant:我还添加了一个非线性加权想法,它应该可以满足您的需求。

以上是关于计算两个配置文件之间的相似性以获得共同特征的数量的主要内容,如果未能解决你的问题,请参考以下文章

计算两个数组之间余弦相似度的正确方法?

如何从TfidfVectorizer计算余弦相似度?

推荐算法学习实践:基于物品相似度

如何从 TfidfVectorizer 计算余弦相似度?

minHash最小哈希原理

两个音频序列之间的感知相似度