Как рассчитать косинусное сходство между вектором и каждой строкой кадра данных в R?

это мой фрейм данных a:

                    ui 194635691 194153563 177382028 177382031 195129144 196972549 196258704 194907960 196950156 194139014 153444738
1 56320e0e55e89c3e14e26d3d      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.01     0.000         0         0
2 563734c3b65dd40e340eaa56      0.01      0.00      0.00      0.00      0.00      0.00      0.00      0.00     0.000         0         0
3 563e12657d4c410c5832579c      0.00      0.00      0.01      0.01      0.00      0.00      0.00      0.00     0.000         0         0
4 565181854c24b410e4891e11      0.00      0.00      0.00      0.00      0.00      0.01      0.00      0.00     0.000         0         0
5 5651b53fec231f1df8482d23      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00     0.027         0         0
6 56548df4b84c321fe4cdfb8f      0.00      0.01      0.00      0.00      0.00      0.00      0.00      0.00     0.000         0         0
7 56549946735e782a885957e6      0.00      0.00      0.00      0.00      0.08      0.00      0.00      0.00     0.000         0         0
8 56549f9bb84c321fe4ce7a37      0.00      0.01      0.00      0.00      0.00      0.00      0.00      0.00     0.000         0         0
9 5654a35a735e782a8859a053      0.00      0.00      0.00      0.00      0.00      0.00      0.01      0.00     0.000         0         0

Что я хочу здесь сделать, так это вычислить косинусное сходство между useridvector и каждой строкой кадра данных a, но без первого столбца (ui). До сих пор я пробовал следующий код:

  user_id=actions_slippers$ui[i]#user_id is coming from another dataframe called action_slippers
  useridvector=a[a$ui %in% user_id, ]
  p=as.vector(cosine(t(a[,2:ncol(a)]))[,1])# this measures cosine similarity between first row of dataframe a and each other of rows from dataframe a

но я хочу рассчитать косинусное сходство между useridvector и каждой строкой фрейма данных a без первого столбца. useridvector выглядит так:

 ui 194635691 194153563 177382028 177382031 195129144 196972549 196258704 194907960 196950156 194139014 153444738
 5651b53fec231f1df8482d23         0         0         0         0         0        0         0         0     0.027         0         0

Может кто подскажет, как это сделать?


person Ozgur Alptekın    schedule 29.12.2015    source источник
comment
Хм, а как насчет 1-skmeans::skmeans_xdist(as.matrix(df[, -1])) или lsa::cosine(t(as.matrix(df[, -1])))? Некоторые пакеты R имеют меры косинусного (дис) сходства. Вы можете исключить первый столбец, используя df[, -1], если ваши данные находятся в df.   -  person lukeA    schedule 29.12.2015
comment
@ lukeA, ваши коды рассчитывают косинусное сходство между useridvector и dataframe?   -  person Ozgur Alptekın    schedule 29.12.2015


Ответы (1)


cosine{lsa} работает. Хочу поделиться своей попыткой.

предположим, вы сохраняете данные в виде dataframe, например:

> data
                        ui X194635691 X194153563 X177382028 X177382031 X195129144 X196972549 X196258704 X194907960 X196950156 X194139014 X153444738
1 56320e0e55e89c3e14e26d3d       0.00       0.00       0.00       0.00       0.00       0.00       0.00       0.01      0.000          0          0
2 563734c3b65dd40e340eaa56       0.01       0.00       0.00       0.00       0.00       0.00       0.00       0.00      0.000          0          0
3 563e12657d4c410c5832579c       0.00       0.00       0.01       0.01       0.00       0.00       0.00       0.00      0.000          0          0
4 565181854c24b410e4891e11       0.00       0.00       0.00       0.00       0.00       0.01       0.00       0.00      0.000          0          0
5 5651b53fec231f1df8482d23       0.00       0.00       0.00       0.00       0.00       0.00       0.00       0.00      0.027          0          0
6 56548df4b84c321fe4cdfb8f       0.00       0.01       0.00       0.00       0.00       0.00       0.00       0.00      0.000          0          0
7 56549946735e782a885957e6       0.00       0.00       0.00       0.00       0.08       0.00       0.00       0.00      0.000          0          0
8 56549f9bb84c321fe4ce7a37       0.00       0.01       0.00       0.00       0.00       0.00       0.00       0.00      0.000          0          0
9 5654a35a735e782a8859a053       0.00       0.00       0.00       0.00       0.00       0.00       0.01       0.00      0.000          0          0 

Используя data[,-1] или subset.data.frame(data, select = names(data)[-1] для удаления первого столбца, затем преобразуйте его в матрицу и используйте cosine{lsa}

> res <- lsa::cosine(t(as.matrix(data[, -1])))
> res
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
 [1,]    1    0    0    0    0    0    0    0    0
 [2,]    0    1    0    0    0    0    0    0    0
 [3,]    0    0    1    0    0    0    0    0    0
 [4,]    0    0    0    1    0    0    0    0    0
 [5,]    0    0    0    0    1    0    0    0    0
 [6,]    0    0    0    0    0    1    0    1    0
 [7,]    0    0    0    0    0    0    1    0    0
 [8,]    0    0    0    0    0    1    0    1    0
 [9,]    0    0    0    0    0    0    0    0    1

PS: установите пакет lsa и см. ?cosine для получения подробной информации

============================ обновление =====

Результирующая матрица выглядит так:

      user1 **user2** user3 **user4**
user1   1    0 
user2        1
user3    ...       1
user4

где element (i, j) означает сходство между пользователем i и пользователем j. и если у вашего userid 2 пользователя, скажите, что это пользователь 2 и пользователь 4. Тогда вы хотите найти сходство между этими двумя пользователями и другими пользователями. которая является подматрицей всей матрицы подобия. Затем используйте res [, c (2,4)], чтобы получить желаемую матрицу.

person Dylan    schedule 29.12.2015
comment
@ Дилан, спасибо за ваш ответ. Но я хочу рассчитать косинусное сходство между useridvector (как вы можете видеть выше в моем вопросе) и dataframe. Я хочу получить результат в виде вектора, и этот вектор должен быть похож на первый элемент, это csoine сходство между useridvector и первой строкой dataframe второй элемент должен быть косинусным сходством между useridvector и второй строкой dataframe, и это продолжается .... на самом деле мой useridvector - это 5 строк кадра данных, но он исходит из другого кадра данных. если вы мне объясните это было бы здорово. большое спасибо заранее - person Ozgur Alptekın; 29.12.2015
comment
@ Дилан, я только что отредактировал свой вопрос. Вы можете увидеть, как выглядит useridvector. Думаю, теперь мой вопрос более ясен. - person Ozgur Alptekın; 30.12.2015
comment
@ OzgurAlptekın, ответ такой же. Если вы хотите сделать это шаг за шагом, используйте 2 цикла for - person Dylan; 30.12.2015