首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >匹配文档与text2vec -缩放问题

匹配文档与text2vec -缩放问题
EN

Stack Overflow用户
提问于 2018-02-16 07:21:19
回答 1查看 562关注 0票数 0

我有几个问题,缩放一个文本匹配程序。我使用的是text2vec,它提供了非常好和快速的结果。

我遇到的主要问题是操作一个由text2vec::sim2()函数返回的大型矩阵。

首先,我的硬件/ OS设置的一些细节: Windows 7,有12个核心,大约3.5 GHz和128 Gb内存。这是台不错的机器。

第二,一些我的R计划试图实现的基本细节。

我们有一个数据库,为每个家庭/企业地址提供1000万个独特的规范地址。这些参考地址还包含每个条目的纬度和经度信息。

我试图将这些参考地址与我们数据库中的客户地址相匹配。我们有大约60万个客户地址。这些客户地址的质量不好。一点都不好!它们作为一个字符串字段存储,对输入的检查绝对为零。

匹配这些地址的技术策略非常简单。创建两个客户地址和引用地址的文档术语矩阵(DTM),并使用余弦相似度来查找与特定客户地址最相似的参考地址。有些客户地址太差,会导致很低的余弦相似度--因此,对于这些地址,将分配“不匹配”。

尽管是一个相当简单的解决办法,但所取得的结果是非常令人鼓舞的。

但是,我在缩放东西的时候有问题.?我想知道是否有人有任何建议。

下面有我的代码副本。很简单。显然,我不能包括真实的数据,但它应该为读者提供一个清楚的概念,我想做什么。

A节-即使在完整的60万*1000万输入数据集上也能很好地工作。

B节-- text2vec::sim2()函数在词汇表超过14万个标记(即列)时导致SECTION关闭。为了避免这种情况,我处理了大约200块的客户地址。

C部分-这是最贵的部分。当处理200块地址时,A节和B节大约需要2分钟。但是C部分,使用(我认为是超级快速的函数)大约需要5分钟来处理一个1000万行* 200列矩阵。

加在一起,A:C处理200个地址大约需要7分钟。由于有60万个地址需要处理,这将需要14天左右的时间。

它们是让代码运行更快的主意吗.?

代码语言:javascript
复制
rm(list = ls())
library(text2vec)
library(dplyr)


# Create some test data

# example is 10 entries.  
# but in reality we have 10 million addresses
vct_ref_address <- c("15 smith street beaconsfield 2506 NSW", 
"107 orange grove linfield 2659 NSW",
"88 melon drive calton 3922 VIC", 
"949 eyre street sunnybank 4053 QLD",
"12 black avenue kingston 2605 ACT", 
"5 sweet lane 2004 wynyard NSW",
"32 mugga way 2688 manuka ACT",
"4 black swan avenue freemantle 5943 WA",
"832 big street narrabeet 2543 NSW", 
"5 dust road 5040 NT")


# example is 4 entries
# but in reality, we have 1.5 million addresses
vct_test_address <- c("949 eyre street sunnybank 4053 QLD",  
"1113 completely invalid suburb with no post code QLD", 
"12 black road kingston 2605 ACT",  
"949 eyre roaod sunnybank 4053 QLD" )

# ==========================
# SECTION A ===== prepare data
# A.1 create vocabulary 
t2v_token <- text2vec::itoken(c(vct_test_address, vct_ref_address),  progressbar = FALSE)
t2v_vocab <- text2vec::create_vocabulary(t2v_token)
t2v_vectorizer <- text2vec::vocab_vectorizer(t2v_vocab)
# A.2 create document term matrices dtm
t2v_dtm_test <- text2vec::create_dtm(itoken(vct_test_address, progressbar = FALSE), t2v_vectorizer)
t2v_dtm_reference <- text2vec::create_dtm(itoken(vct_ref_address, progressbar = FALSE), t2v_vectorizer)

# ===========================
# SECTION B ===== similarity matrix
mat_sim <- text2vec::sim2(t2v_dtm_reference, t2v_dtm_test,  method = 'cosine', norm = 'l2')

# ===========================
# SECTION C ===== process matrix
vct_which_reference <- apply(mat_sim, 2, which.max)
vct_sim_score <- apply(mat_sim, 2, max)

# ============================
# SECTION D ===== apply results
# D.1 assemble results
df_results <- data.frame(
test_addr = vct_test_address,
matched_addr = vct_ref_address[vct_which_reference],
similarity =  vct_sim_score )

# D.2 print results
df_results %>% arrange(desc(similarity))
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-16 16:40:13

步骤C中的问题是,mat_sim是稀疏的,所有apply调用都进行列/行子集设置,这是超慢的(并将稀疏向量转换为稠密)。

可以有几种解决办法:

  1. 如果mat_sim不是很大,用as.matrix转换为密集,然后使用apply
  2. 更好的方法是将mat_sim转换为as(mat_sim, "TsparseMatrix")格式的稀疏矩阵,然后使用data.table获取最大元素的索引。下面是一个示例: 库(Text2vec)库(矩阵)数据(“movie_review”) it = itoken(movie_review$review,tolower,word_tokenizer) dtm = create_dtm(it,hash_vectorizer(2**14)) mat_sim =sim2(dtm 1:100,dtm 101:5000,) mat_sim = as(mat_sim,"TsparseMatrix")库(data.table)#我们添加了1,因为矩阵包中稀疏矩阵中的索引从1 mat_sim_dt = data.table(row_index = mat_sim@i + 1L,,col_index = mat_sim@j + 1L,value = mat_sim@x) res = mat_sim_dt[,{k=which.max(值);list(max_sim = value[k],row_index = row_index[k]) },keyby = col_index] res

另外,作为一个附带建议,我建议尝试使用ngram(例如,char_tokenizer()的大小c(3, 3))来“模糊”匹配不同的拼写和地址缩写。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48821866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档