1

Я работаю над проблемой кластеризации профилей социальных сетей, и каждый документ профиля представлен числом раз, когда в описании профиля присутствует «срок интереса». Чтобы эффективно выполнять кластеризацию, я пытаюсь найти правильную меру подобия (или функцию расстояния) между двумя профилями.вычисляет сходство между двумя профилями для числа общих черт

Так позволяет сказать, что я следующий таблицей профилей

  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 a nd profile 2, по крайней мере, имеют некоторое значение во всех трех интересах: баскетбол, крикет и питон, и, следовательно, эти два профиля скорее похожи друг на друга, чем на профиль 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) для каждого элемента x ваших векторов профиля, где alpha - это параметр от 0 до 1.Здесь 1 означает стандартное линейное взвешивание, как и раньше, и поскольку вы делаете альфа близким к 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, не так как часто они упоминают об этом.

+0

ОК. Но как насчет вопроса 1? Как определить количество общих функций и расстояние? – Yantraguru

+1

@ Kognizant: Это касается обеих проблем. Просто вычислите расстояние на этих нормализованных векторах. – cfh

+0

извините, но я не понял. Не могли бы вы рассказать, как это касается первой проблемы? – Yantraguru