如何将列表列的项目转换为自己的列以查找 R 中的余弦相似度?

How to convert the items of a list column into their own columns to find cosine similarity in R?

我有一个如下所示的数据集:

library(tidyverse)

data <- tibble(id = 1:10,
               vectors = list(rnorm(25)))

# A tibble: 25 x 2
      id vectors   
   <int> <list>    
 1     1 <dbl [25]>
 2     2 <dbl [25]>
 3     3 <dbl [25]>
 4     4 <dbl [25]>
 5     5 <dbl [25]>
 6     6 <dbl [25]>
 7     7 <dbl [25]>
 8     8 <dbl [25]>
 9     9 <dbl [25]>
10    10 <dbl [25]>

我想使用此数据集来查找每一行代表一个文档的余弦相似度。 lsa 包中的 cosine 函数似乎是一种 good/easy 方法,但是我需要将每个文档表示为一列。我想简单地执行 data %>% t() 以获得我想要的结果,但这不起作用。我还尝试了 "spreading" 列表列,首先使用 unestspread。我也试过 flatten 无济于事。我想要的输出的第一行看起来像:

  1    2    3    4    5    6    7    8    9    10
0.1  0.3  0.7  0.3  0.1  0.1  0.3  0.7  0.3  0.1

如果另一个包中有一个函数可以处理这种格式的数据,我无论如何都会使用它来代替,尽管此时我想从好奇的角度来解决这个问题。我看过 R - list to data frame,但不确定如何将其应用到这种情况。

背景是我在 python 中使用 gensim 执行了 doc2vec,但在工作中对我们的环境执行了操作,如果我想为客户构建一些交互式的东西,它需要在 R 中。

require(dplyr)
require(tidyr)
mutate(data,vectors=sapply(vectors, function(x) paste(x,collapse=","))) %>% 
    separate_rows(vectors,sep=",") %>% 
    group_by(id) %>% 
    mutate(numb=row_number(),vectors=as.numeric(vectors)) %>%
    spread(key=numb,value=vectors)

# A tibble: 10 x 26
# Groups:   id [10]
      id   `1`   `2`   `3`   `4`    `5`   `6`    `7`   `8`     `9`  `10`  `11`  `12`   `13`   `14`  `15`   `16`
   <int> <dbl> <dbl> <dbl> <dbl>  <dbl> <dbl>  <dbl> <dbl>   <dbl> <dbl> <dbl> <dbl>  <dbl>  <dbl> <dbl>  <dbl>
 1     1  1.46 0.140 0.209 -3.04 -0.487 -1.09 0.0579  1.10 -0.0256 0.515 0.990 0.303 -0.930 0.0840 0.527 0.0159
 2     2  1.46 0.140 0.209 -3.04 -0.487 -1.09 0.0579  1.10 -0.0256 0.515 0.990 0.303 -0.930 0.0840 0.527 0.0159
 3     3  1.46 0.140 0.209 -3.04 -0.487 -1.09 0.0579  1.10 -0.0256 0.515 0.990 0.303 -0.930 0.0840 0.527 0.0159
 4     4  1.46 0.140 0.209 -3.04 -0.487 -1.09 0.0579  1.10 -0.0256 0.515 0.990 0.303 -0.930 0.0840 0.527 0.0159
 5     5  1.46 0.140 0.209 -3.04 -0.487 -1.09 0.0579  1.10 -0.0256 0.515 0.990 0.303 -0.930 0.0840 0.527 0.0159
 6     6  1.46 0.140 0.209 -3.04 -0.487 -1.09 0.0579  1.10 -0.0256 0.515 0.990 0.303 -0.930 0.0840 0.527 0.0159
 7     7  1.46 0.140 0.209 -3.04 -0.487 -1.09 0.0579  1.10 -0.0256 0.515 0.990 0.303 -0.930 0.0840 0.527 0.0159
 8     8  1.46 0.140 0.209 -3.04 -0.487 -1.09 0.0579  1.10 -0.0256 0.515 0.990 0.303 -0.930 0.0840 0.527 0.0159
 9     9  1.46 0.140 0.209 -3.04 -0.487 -1.09 0.0579  1.10 -0.0256 0.515 0.990 0.303 -0.930 0.0840 0.527 0.0159
10    10  1.46 0.140 0.209 -3.04 -0.487 -1.09 0.0579  1.10 -0.0256 0.515 0.990 0.303 -0.930 0.0840 0.527 0.0159
# ... with 9 more variables: `17` <dbl>, `18` <dbl>, `19` <dbl>, `20` <dbl>, `21` <dbl>, `22` <dbl>, `23` <dbl>,
#   `24` <dbl>, `25` <dbl>

我发现首先将数据收集成长数据格式最容易传播数据。我们使用 separate_rows 实现了这一点。问题在于我们首先需要将向量中的列表转换为 separate_rows 可以使用的东西。我们在 sapply 中使用 pastecollapse="," 来做到这一点(否则所有列表将被粘贴在一起)。

一旦我们有了,这只是分组的问题,添加一个行索引列(并将数字转换回数字),并展开以获得所需的格式。