CPU-and-memory efficient NGram extraction with R

CPU-and-memory efficient NGram extraction with R

我写了一个算法,从 50000 个街道地址的列表中提取 NGram(二元语法、三元语法、...直到 5 元语法)。我的目标是为每个地址提供一个布尔向量,表示该地址中是否存在 NGram。因此每个地址都将由一个属性向量来表征,然后我可以对这些地址进行聚类。 该算法以这种方式工作: 我从二元语法开始,计算(a-z 和 0-9 和/和制表)的所有组合:例如:aa,ab,ac,...,a8,a9,a/,a ,ba, bb,... 然后我为每个地址执行一个循环并为所有二元组提取信息 0 或 1(二元组不存在或不存在)。 之后,我计算出现次数最多的二元组。 等等 ... 我的问题是算法达到 运行 所花费的时间。另一个问题:当超过 10000 个 NGram 时,R 达到其最大容量。这很明显,因为 50000*10000 的矩阵很大。 我需要你的想法来优化算法或改变它。谢谢。

其中一些问题在某种程度上已经被 tm 库和 RWeka(用于 n-gram 标记化)解决了。看看那些,它们可能会使您的任务更容易。

对于 运行 内存不足,我看到两个选项:

  1. tm 使用稀疏矩阵,这是一种存储具有许多零元素的矩阵的有效方法。

  2. 您还可以查看 bigmemory 包。虽然,我没用过http://cran.r-project.org/web/packages/bigmemory/index.html

有很多方法可以加速 R 代码。以下是一些操作方法的指南:http://www.r-bloggers.com/faster-higher-stonger-a-guide-to-speeding-up-r-code-for-busy-people/

使用此方法尝试 quanteda 包。如果您只想要标记化的文本,请将 dfm( 替换为 tokenize(

非常想知道它在您的 50,000 个街道地址上的工作原理。我们付出了很多努力使 dfm() 变得非常快速和强大。

myDfm <- dfm(c("1780 wemmel", "2015 schlemmel"), what = "character", 
             ngram = 1:5, concatenator = "", 
             removePunct = FALSE, removeNumbers = FALSE, 
             removeSeparators = FALSE, verbose = FALSE)
t(myDfm) # for easier viewing
#         docs
# features text1 text2
#           1     1
# s         0     1
# sc        0     1
# sch       0     1
# schl      0     1
# w         1     0
# we        1     0
# wem       1     0
# wemm      1     0
# 0         1     1
# 0         1     0
# 0 w       1     0
# 0 we      1     0
# 0 wem     1     0
# 01        0     1
# 015       0     1
# 015       0     1
# 015 s     0     1
# 1         1     1
# 15        0     1
# 15        0     1
# 15 s      0     1
# 15 sc     0     1
# 17        1     0
# 178       1     0
# 1780      1     0
# 1780      1     0
# 2         0     1
# 20        0     1
# 201       0     1
# 2015      0     1
# 2015      0     1
# 5         0     1
# 5         0     1
# 5 s       0     1
# 5 sc      0     1
# 5 sch     0     1
# 7         1     0
# 78        1     0
# 780       1     0
# 780       1     0
# 780 w     1     0
# 8         1     0
# 80        1     0
# 80        1     0
# 80 w      1     0
# 80 we     1     0
# c         0     1
# ch        0     1
# chl       0     1
# chle      0     1
# chlem     0     1
# e         2     2
# el        1     1
# em        1     1
# emm       1     1
# emme      1     1
# emmel     1     1
# h         0     1
# hl        0     1
# hle       0     1
# hlem      0     1
# hlemm     0     1
# l         1     2
# le        0     1
# lem       0     1
# lemm      0     1
# lemme     0     1
# m         2     2
# me        1     1
# mel       1     1
# mm        1     1
# mme       1     1
# mmel      1     1
# s         0     1
# sc        0     1
# sch       0     1
# schl      0     1
# schle     0     1
# w         1     0
# we        1     0
# wem       1     0
# wemm      1     0
# wemme     1     0