38

我有一个推文列表,我想只保留那些是英文的。

我怎样才能做到这一点?

4

7 回答 7

46

textcat软件包执行此操作。它可以检测 74 种“语言”(更准确地说,是语言/编码组合),更多的是其他扩展。详细信息和示例在这篇免费提供的文章中:

Hornik, K.、Mair, P.、Rauch, J.、Geiger, W.、Buchta, C. 和 Feinerer, I.用于 R 中基于 n-Gram 的文本分类的 textcat 包。统计软件杂志,52, 1-17。

这是摘要:

识别所使用的语言通常是大多数自然语言处理任务的第一步。在文献中讨论的各种语言识别方法中,采用 Cavnar 和 Trenkle (1994) 方法基于字符 n-gram 频率进行文本分类的方法特别成功。本文介绍了用于基于 n-gram 的文本分类的 R 扩展包 textcat,它实现了 Cavnar 和 Trenkle 方法以及旨在消除原始方法冗余的简化 n-gram 方法。从 Wikipedia 页面获得的多语言语料库可用于选择主题,用于说明包的功能和所提供语言识别方法的性能。

这是他们的一个例子:

library("textcat")
textcat(c(
  "This is an English sentence.",
  "Das ist ein deutscher Satz.",
  "Esta es una frase en espa~nol."))
[1] "english" "german" "spanish" 
于 2013-05-30T04:15:57.523 回答
26

尝试http://cran.r-project.org/web/packages/cldr/它将 Google Chrome 的语言检测带到 R。

#install from archive
url <- "http://cran.us.r-project.org/src/contrib/Archive/cldr/cldr_1.1.0.tar.gz"
pkgFile<-"cldr_1.1.0.tar.gz"
download.file(url = url, destfile = pkgFile)
install.packages(pkgs=pkgFile, type="source", repos=NULL)
unlink(pkgFile)
# or devtools::install_version("cldr",version="1.1.0")

#usage
library(cldr)
demo(cldr)
于 2013-05-20T16:59:01.123 回答
23

cldrCRAN 上不再提供先前答案中的软件包,并且可能难以安装。cld但是,现在可以通过其他专用包在 R 中使用Google(Chromium 的)库,cld2并且cld3.

在用多种欧洲语言测试了数千条推文之后,我可以说,在可用的选项中,textcat它是迄今为止最不可靠的。我也经常收到textcat错误检测为“middle_frisian”、“rumantsch”、“sanskrit”或其他不寻常语言的推文。它可能与其他类型的文本相对较好,但我认为textcat对于推文来说非常糟糕。

cld2似乎总体上还是比cld3. 如果您想要一种仅包含英语推文的安全方式,您仍然可以同时运行两者cld2cld3并且只保留两者都识别为英语的推文。

这是一个基于 Twitter 搜索的示例,该搜索通常提供多种不同语言的结果,但总是包含一些英文推文。

if (!require("pacman")) install.packages("pacman") # for package manangement
pacman::p_load("tidyverse") 
pacman::p_load("textcat")
pacman::p_load("cld2")
pacman::p_load("cld3")
pacman::p_load("rtweet")

punk <- rtweet::search_tweets(q = "punk") %>% mutate(textcat = textcat(x = text), cld2 = cld2::detect_language(text = text, plain_text = FALSE), cld3 = cld3::detect_language(text = text)) %>% select(text, textcat, cld2, cld3)
View(punk)

# Only English tweets
punk %>% filter(cld2 == "en" & cld3 == "en")

最后,如果这个问题与推文特别相关,我或许应该补充一点:Twitter 通过 API 为推文提供自己的语言检测,而且它似乎非常准确(可以理解,对于非常短的推文来说,情况就不那么准确了)。因此,如果您运行rtweet::search_tweets(q = "punk"),您将看到生成的 data.frame 包含一个“lang”列。如果您通过 API 获取推文,那么您可能更信任 Twitter 自己的检测系统,而不是上面建议的替代解决方案(对于其他文本仍然有效)。

于 2017-10-10T09:56:02.257 回答
15

R 中的一种方法是保留英文单词的文本文件。我有其中几个,其中一个来自http://www.sil.org/linguistics/wordlists/english/。获取 .txt 文件后,您可以使用此文件来匹配每条推文。就像是:

lapply(tweets, function(x) EnglishWordComparisonList %in% x)

你想要有一些阈值百分比来确定它是否是英语(我随意选择了 0.06)。

EnglishWordComparisonList<-as.vector(source(path to the list you downloaded above))

Englishinator<-function(tweet, threshold = .06) {
    TWTS <- which((EnglishWordComparisonList %in% tweet)/length(tweet) > threshold)
    tweet[TWTS]
    #or tweet[TWTS,] if the original tweets is a data frame
}

lapply(tweets, Englishinator)

我实际上并没有使用它,因为我在研究中使用英语单词列表的方式大不相同,但我认为这会起作用。

于 2011-11-10T15:50:42.310 回答
12

tl;drcld2是迄今为止最快的(cld3x 22textcatx 118,手工解决方案 x 252

这里有很多关于准确性的讨论,这对于推文是可以理解的。但是速度呢?

cld2这是,cld3和的基准textcat

我还加入了一些我写的幼稚函数,它计算文本中停用词的出现次数(使用tm::stopwords)。

我认为对于长文本我可能不需要复杂的算法,并且对多种语言进行测试可能是有害的。最后,我的方法最终是最慢的(很可能是因为打包的方法在C.

我把它留在这里,这样我就可以把时间留给那些有同样想法的人。我预计 的Englishinator解决方案Tyler Rinker也会很慢(仅测试一种语言,但要测试更多的单词和类似的代码)。

detect_from_sw <- function(text,candidates){
  sapply(strsplit(text,'[ [:punct:]]'),function(y)
    names(which.max(sapply(candidates,function(x) sum(tm::stopwords(x) %in% y))))
  )
}

基准

data(reuters,package = "kernlab") # a corpus of articles in english
length(reuters)
# [1] 40
sapply(reuters,nchar)
# [1] 1311  800  511 2350  343  388 3705  604  254  239  632  607  867  240
# [15]  234  172  538  887 2500 1030  538 2681  338  402  563 2825 2800  947
# [29] 2156 2103 2283  604  632  602  642  892 1187  472 1829  367
text <- unlist(reuters)

microbenchmark::microbenchmark(
  textcat = textcat::textcat(text),
  cld2 = cld2::detect_language(text),
  cld3 = cld3::detect_language(text),
  detect_from_sw = detect_from_sw(text,c("english","french","german")),
  times=100)

# Unit: milliseconds
# expr                 min         lq      mean     median         uq         max neval
# textcat        212.37624 222.428824 230.73971 227.248649 232.488500  410.576901   100
# cld2             1.67860   1.824697   1.96115   1.955098   2.034787    2.715161   100
# cld3            42.76642  43.505048  44.07407  43.967939  44.579490   46.604164   100
# detect_from_sw 439.76812 444.873041 494.47524 450.551485 470.322047 2414.874973   100

关于textcat' 不准确的说明

我无法评论cld2vs的准确性cld3(@giocomai 声称cld2他的回答更好),但我确认这textcat似乎非常不可靠(在本页的几个地方提到)。所有文本都通过上述所有方法正确分类,除了这个被分类为西班牙语的文本textcat

“阿根廷原油产量从 1986 年 1 月的 13.81 万桶下降到 1987 年 1 月的 10.8% 至 1232 万桶,Yacimientos Petroliferos Fiscales \n说。\n 1987 年 1 月的天然气产量总计 11.5 亿立方米,增加了 3.6% Yacimientos Petroliferos Fiscales 补充说,1986 年 1 月生产了超过 11.1 亿立方米。\n Reuter"

于 2018-02-14T15:31:44.463 回答
4

还有一个运行良好的 R 包,名为“ franc ”。虽然它比其他的慢,但我对它的体验比使用 cld2 尤其是 cld3 更好。

于 2019-07-05T12:49:46.470 回答
3

我不确定 R,但有几个其他语言的库。你可以在这里找到其中一些收集:

http://www.detectlanguage.com/

最近还有一个有趣的项目:

http://blog.mikemccandless.com/2011/10/language-detection-with-googles-compact.html

使用此库生成 Twitter 语言地图:

http://www.flickr.com/photos/walkingsf/6277163176/in/photostream

如果你找不到 R 的库,我建议考虑通过 web 服务使用远程语言检测器。

于 2011-11-10T11:29:38.530 回答