R:当一个文档中有多个句子时,使用 dfm 查找 ngram
R: find ngram using dfm when there are multiple sentences in one document
我有一个大数据集(> 100 万行),每一行都是多句文本。例如,以下是 2 行的示例:
mydat <- data.frame(text=c('I like apple. Me too','One two. Thank you'),stringsAsFactors = F)
我试图做的是提取每行中的二元词项(“.”将能够分隔 ngram 词项)。如果我只是使用 dfm 函数:
mydfm = dfm(mydat$text,toLower = T,removePunct = F,ngrams=2)
dtm = as.DocumentTermMatrix(mydfm)
txt_data = as.data.frame(as.matrix(dtm))
这些是我得到的条件:
"i_like" "like_apple" "apple_." "._me" "me_too" "one_two" "two_." "._thank" "thank_you"
这些是我所期望的,基本上是“。”被跳过并用于分隔术语:
"i_like" "like_apple" "me_too" "one_two" "thank_you"
相信编写慢循环也可以解决这个问题,但鉴于它是一个巨大的数据集,我更喜欢类似于 quanteda 中的 dfm() 的有效方法来解决这个问题。如有任何建议,我们将不胜感激!
如果您的目标只是提取那些双字母组,那么您可以使用 tokens
两次。一次标记为句子,然后再次为每个句子制作 ngrams。
library("quanteda")
mydat$text %>%
tokens(mydat$text, what = "sentence") %>%
as.character() %>%
tokens(ngrams = 2, remove_punct = TRUE) %>%
as.character()
#[1] "I_like" "like_apple" "Me_too" "One_two" "Thank_you"
如果您愿意,可以在第一个 tokens()
调用之后插入一个 tokens_tolower()
,或者在最后使用 char_tolower()
。
@Jota 的回答有效,但有一种方法可以更精细地控制标记化,同时只调用一次:
(toks <- tokenize(toLower(mydat$text), removePunct = 2, ngrams = 2))
## tokenizedText object from 2 documents.
## Component 1 :
## [1] "i_like" "like_apple" "apple_me" "me_too"
##
## Component 2 :
## [1] "one_two" "two_thank" "thank_you"
dfm(toks)
## Document-feature matrix of: 2 documents, 7 features.
## 2 x 7 sparse Matrix of class "dfmSparse"
## features
## docs i_like like_apple apple_me me_too one_two two_thank thank_you
## text1 1 1 1 1 0 0 0
## text2 0 0 0 0 1 1 1
已添加:
然后要删除带有 .
标点符号的任何 ngram,您可以使用:以下内容,默认为 valuetype = "glob"
:
removeFeatures(toks2, "*.*")
## tokenizedText object from 2 documents.
## Component 1 :
## [1] "i_like" "like_apple" "me_too"
##
## Component 2 :
## [1] "one_two" "thank_you"
我有一个大数据集(> 100 万行),每一行都是多句文本。例如,以下是 2 行的示例:
mydat <- data.frame(text=c('I like apple. Me too','One two. Thank you'),stringsAsFactors = F)
我试图做的是提取每行中的二元词项(“.”将能够分隔 ngram 词项)。如果我只是使用 dfm 函数:
mydfm = dfm(mydat$text,toLower = T,removePunct = F,ngrams=2)
dtm = as.DocumentTermMatrix(mydfm)
txt_data = as.data.frame(as.matrix(dtm))
这些是我得到的条件:
"i_like" "like_apple" "apple_." "._me" "me_too" "one_two" "two_." "._thank" "thank_you"
这些是我所期望的,基本上是“。”被跳过并用于分隔术语:
"i_like" "like_apple" "me_too" "one_two" "thank_you"
相信编写慢循环也可以解决这个问题,但鉴于它是一个巨大的数据集,我更喜欢类似于 quanteda 中的 dfm() 的有效方法来解决这个问题。如有任何建议,我们将不胜感激!
如果您的目标只是提取那些双字母组,那么您可以使用 tokens
两次。一次标记为句子,然后再次为每个句子制作 ngrams。
library("quanteda")
mydat$text %>%
tokens(mydat$text, what = "sentence") %>%
as.character() %>%
tokens(ngrams = 2, remove_punct = TRUE) %>%
as.character()
#[1] "I_like" "like_apple" "Me_too" "One_two" "Thank_you"
如果您愿意,可以在第一个 tokens()
调用之后插入一个 tokens_tolower()
,或者在最后使用 char_tolower()
。
@Jota 的回答有效,但有一种方法可以更精细地控制标记化,同时只调用一次:
(toks <- tokenize(toLower(mydat$text), removePunct = 2, ngrams = 2))
## tokenizedText object from 2 documents.
## Component 1 :
## [1] "i_like" "like_apple" "apple_me" "me_too"
##
## Component 2 :
## [1] "one_two" "two_thank" "thank_you"
dfm(toks)
## Document-feature matrix of: 2 documents, 7 features.
## 2 x 7 sparse Matrix of class "dfmSparse"
## features
## docs i_like like_apple apple_me me_too one_two two_thank thank_you
## text1 1 1 1 1 0 0 0
## text2 0 0 0 0 1 1 1
已添加:
然后要删除带有 .
标点符号的任何 ngram,您可以使用:以下内容,默认为 valuetype = "glob"
:
removeFeatures(toks2, "*.*")
## tokenizedText object from 2 documents.
## Component 1 :
## [1] "i_like" "like_apple" "me_too"
##
## Component 2 :
## [1] "one_two" "thank_you"