【问题标题】:How to convert the items of a list column into their own columns to find cosine similarity in R?如何将列表列的项目转换为自己的列以在 R 中查找余弦相似度?
【发布时间】:2018-12-19 16:57:45
【问题描述】:

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

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 函数似乎是一种很好/简单的方法,但是我需要将每个文档表示为一列。我想简单地做data %&gt;% t() 以获得我想要的结果,但这不起作用。我也尝试过首先使用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 中。

【问题讨论】:

标签: r list cosine-similarity doc2vec


【解决方案1】:
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="," 来做到这一点(否则所有列表将被粘贴在一起)。

一旦我们有了它,只需进行分组、添加行索引列(并将数字转换回数字),然后展开以实现所需的格式。

【讨论】:

  • 谢谢,我看到的唯一问题是这消除了负数
  • 修复了我的回答中的问题。现在底片被保留了。
猜你喜欢
  • 2014-11-02
  • 2021-06-13
  • 2021-07-15
  • 2019-08-02
  • 1970-01-01
  • 2022-01-16
  • 2021-08-02
  • 2021-04-02
  • 1970-01-01
相关资源
最近更新 更多