专栏首页PPV课数据科学社区R包之tm:文本挖掘包

R包之tm:文本挖掘包

  • 简介
  • 安装
  • 数据输入—文集(corpus)
  • 数据输出
  • 查看语料库(corpora)
    • 查看某几条信息
    • 查看单个文档元数据
    • 查看单个文档内容
    • 查看多个文档内容
  • 变换(transformation)
  • 过滤器
  • 元数据管理
  • 标准操作和函数
  • 创建文档-单词矩阵
  • 文档-单词矩阵的操作
  • 字典
  • 关于中文支持

本文参考文档:

  1. tm的使用指南 : http://mirror.bjtu.edu.cn/cran/web/packages/tm/vignettes/tm.pdf
  2. tm手册 : http://mirror.bjtu.edu.cn/cran/web/packages/tm/tm.pdf

简介

tm 即text mining,是用来做文本挖掘的一个R包,是一个进行自然语言处理的基础包。它提供了一些做文本挖掘的基础设施,比如数据输入,文集处理,预处理,元数据管理,创建单词-文本矩阵。

安装

该包的安装方法是install.packages("tm")

数据输入—文集(corpus)

文集代表一个文档集,通常一个文件就是一个文档。多个文档构成一个文集。文集是一个抽象的概念,具体的实现方式有几种,一个是VCorpus(Volatile Corpus),这种文集完全存储在内存中。故而不能很大。这个文集的创建方法为 VCorpus(x,readerControl)。 另一个实现是PCorpus1 (Permanent Corpus),这种实现方式下,内存中只是存储文档的指针,真正的文档存储在磁盘上(文件或者数据库)。

文集创建的第一个参数x必须是一个Source对象,tm提供了一些预定义的source。比如DirSrouce,VectorSource,DataframeSource等,它们分别用来处理一个目录,一个向量(每个元素为一个文档),和数据框结构(比如csv)的文档。可以利用getSources()来得到所有可用的source,用户也可以建立自己的source。

文集创建的第二个参数是readerControl,这个参数必需是一个列表,其中包含组件readerlanguage。其中:

  • reader负责创建一个文档。而文档的来源是source传递过来的每个元素。下面是简单的处理流程 source --> elements ---> reader ---> document 其中,tm包中有几种reader,比如readPlain(),readPDF(),readDOC()等等,可以利用getReaders()来获得所有可以的reader。 每个source都对应有一个缺省的reader,比如DirSource的reader就是读入文件,把文件的内容作为字符串。这个reader是可以被替换的。
  • language 指明文本的语言

因此,对于包tm目录下的texts/txt目录下的文本文件可以这样做成一个文集

library(tm)#> Loading required package: NLPtxt <- system.file("texts","txt",package="tm")
vid = VCorpus(DirSource(txt, encoding = "UTF-8"), readerControl = list(language="lat"))
vid#> <<VCorpus>>#> Metadata:  corpus specific: 0, document level (indexed): 0#> Content:  documents: 5

最简单的VectorSource,可以用来最简单的测试,比如

docs <- c("hello doc1", "hello doc2") 
VCorpus(VectorSource(docs))#> <<VCorpus>>#> Metadata:  corpus specific: 0, document level (indexed): 0#> Content:  documents: 2

最后可以看一个指定外部reader的例子

reut21578 <- system.file("texts", "crude", package = "tm")
reuters <- VCorpus(DirSource(reut21578),                    readerControl = list(reader = readReut21578XMLasPlain))

数据输出

文集中的数据可以直接输出,比如前面读入的文集,可以这样写到磁盘上去writeCorpus(vid), 每个文档会生成一个文件

查看语料库(corpora)

print(vid)只是给出了最简单的信息,要查看更多的信息,可使用inspect()

查看某几条信息

inspect(vid[1:2])#> <<VCorpus>>#> Metadata:  corpus specific: 0, document level (indexed): 0#> Content:  documents: 2#> #> [[1]]#> <<PlainTextDocument>>#> Metadata:  7#> Content:  chars: 676#> #> [[2]]#> <<PlainTextDocument>>#> Metadata:  7#> Content:  chars: 700

查看单个文档元数据

meta(vid[[2]])#>   author       : character(0)#>   datetimestamp: 2016-03-09 01:45:14#>   description  : character(0)#>   heading      : character(0)#>   id           : ovid_2.txt#>   language     : lat#>   origin       : character(0)

查看单个文档内容

as.character(vid[[2]])#>  [1] "    quas Hector sensurus erat, poscente magistro"   #>  [2] "         verberibus iussas praebuit ille manus."    #>  [3] "    Aeacidae Chiron, ego sum praeceptor Amoris:"    #>  [4] "         saevus uterque puer, natus uterque dea."   #>  [5] "    sed tamen et tauri cervix oneratur aratro,"     #>  [6] ""                                                   #>  [7] "         frenaque magnanimi dente teruntur equi;"   #>  [8] "    et mihi cedet Amor, quamvis mea vulneret arcu"  #>  [9] "         pectora, iactatas excutiatque faces."      #> [10] "    quo me fixit Amor, quo me violentius ussit,"    #> [11] "         hoc melior facti vulneris ultor ero:"      #> [12] ""                                                   #> [13] "    non ego, Phoebe, datas a te mihi mentiar artes,"#> [14] "         nec nos aëriae voce monemur avis,"         #> [15] "    nec mihi sunt visae Clio Cliusque sorores"      #> [16] "         servanti pecudes vallibus, Ascra, tuis:"   #> [17] "    usus opus movet hoc: vati parete perito;"

查看多个文档内容

lapply(vid[1:2],as.character)#> $ovid_1.txt#>  [1] "    Si quis in hoc artem populo non novit amandi,"    #>  [2] "         hoc legat et lecto carmine doctus amet."     #>  [3] "    arte citae veloque rates remoque moventur,"       #>  [4] "         arte leves currus: arte regendus amor."      #>  [5] ""                                                     #>  [6] "    curribus Automedon lentisque erat aptus habenis," #>  [7] "         Tiphys in Haemonia puppe magister erat:"     #>  [8] "    me Venus artificem tenero praefecit Amori;"       #>  [9] "         Tiphys et Automedon dicar Amoris ego."       #> [10] "    ille quidem ferus est et qui mihi saepe repugnet:"#> [11] ""                                                     #> [12] "         sed puer est, aetas mollis et apta regi."    #> [13] "    Phillyrides puerum cithara perfecit Achillem,"    #> [14] "         atque animos placida contudit arte feros."   #> [15] "    qui totiens socios, totiens exterruit hostes,"    #> [16] "         creditur annosum pertimuisse senem."         #> #> $ovid_2.txt#>  [1] "    quas Hector sensurus erat, poscente magistro"   #>  [2] "         verberibus iussas praebuit ille manus."    #>  [3] "    Aeacidae Chiron, ego sum praeceptor Amoris:"    #>  [4] "         saevus uterque puer, natus uterque dea."   #>  [5] "    sed tamen et tauri cervix oneratur aratro,"     #>  [6] ""                                                   #>  [7] "         frenaque magnanimi dente teruntur equi;"   #>  [8] "    et mihi cedet Amor, quamvis mea vulneret arcu"  #>  [9] "         pectora, iactatas excutiatque faces."      #> [10] "    quo me fixit Amor, quo me violentius ussit,"    #> [11] "         hoc melior facti vulneris ultor ero:"      #> [12] ""                                                   #> [13] "    non ego, Phoebe, datas a te mihi mentiar artes,"#> [14] "         nec nos aëriae voce monemur avis,"         #> [15] "    nec mihi sunt visae Clio Cliusque sorores"      #> [16] "         servanti pecudes vallibus, Ascra, tuis:"   #> [17] "    usus opus movet hoc: vati parete perito;"

变换(transformation)

变换指通过tm_map函数来对文集中所有的文档作用一个函数的过程。比如停用词剔除等。每个变换只是作用在一个文档 上,tm_map来把它作用到所有的文档。

比如

  • 剔除多余的空白tm_map(vid,stripWhitespace)
  • 转换为小写 tm_map(vid,content_transformer(tolower)) 其中的content_transformer是一个修改文档内容的方便的函数,tolower可以是任何其他的字符串修改函数
  • 移除停用词 reuters <- tm_map(reuters, removeWords, stopwords("english"))

过滤器

过滤器可以移除不感兴趣的(或者感兴趣的)文档。tm提供了tm_filter函数,这个函数的原型为

  1. tm_filter(x, FUN,...)
  2. tm_index(x,FUN,...)

其中的FUN函数出入为一片文档,输出为一个bool值。表示是否接受该文档。第二个版本tm_index 只是返回满足条件的index,前者返回一个文集,下面是一个使用示例:

data("crude")# Full-text searchtm_filter(crude, FUN = function(x) any(grep("co[m]?pany", content(x))))

元数据管理

元数据分为两个层次,一个是文集级别的元数据,一个是文档级别的元数据。要获得元数据,最简单的是 使用meta()函数。每篇文档,有些预定义的元数据(比如author),但是每篇文档也可以添加自定义的 元数据标签。如下所示,分别用DublinCoremeta函数来修改一个文档的元数据

data(crude)DublinCore(crude[[1]], "Creator") <- "Ano Nymous"meta(crude[[1]])#>   author       : Ano Nymous#>   datetimestamp: 1987-02-26 17:00:56#>   description  : #>   heading      : DIAMOND SHAMROCK (DIA) CUTS CRUDE PRICES#>   id           : 127#>   language     : en#>   origin       : Reuters-21578 XML#>   topics       : YES#>   lewissplit   : TRAIN#>   cgisplit     : TRAINING-SET#>   oldid        : 5670#>   places       : usa#>   people       : character(0)#>   orgs         : character(0)#>   exchanges    : character(0)meta(crude[[1]], "author") <- "Jiang Hang"meta(crude[[1]])#>   author       : Jiang Hang#>   datetimestamp: 1987-02-26 17:00:56#>   description  : #>   heading      : DIAMOND SHAMROCK (DIA) CUTS CRUDE PRICES#>   id           : 127#>   language     : en#>   origin       : Reuters-21578 XML#>   topics       : YES#>   lewissplit   : TRAIN#>   cgisplit     : TRAINING-SET#>   oldid        : 5670#>   places       : usa#>   people       : character(0)#>   orgs         : character(0)#>   exchanges    : character(0)

下面是修改文集级别元数据的列子

meta(crude, tag = "url", type = "corpus") <- "http://www.bagualu.net"meta(crude, type = "corpus")#> $url#> [1] "http://www.bagualu.net"#> #> attr(,"class")#> [1] "CorpusMeta"

每个元数据的数据可以是dataframe结构的。

标准操作和函数

标准的操作符[,[[,[<-,[[<-,c(),lapply()可以直接作用在corpora(语料库)上

创建文档-单词矩阵

tm中,函数TermDocumentMatrixDocumentTermMatrix可直接创建文档-单词矩阵,这二者的却别 在于矩阵的行是文档还是单词

dtm <- DocumentTermMatrix(reuters)inspect(dtm[5:10, 740:743])#> <<DocumentTermMatrix (documents: 6, terms: 4)>>#> Non-/sparse entries: 2/22#> Sparsity           : 92%#> Maximal term length: 9#> Weighting          : term frequency (tf)#> #>      Terms#> Docs  needs. negative negotiate neither#>   211      0        0         0       0#>   236      0        0         0       0#>   237      1        0         0       0#>   242      0        0         0       0#>   246      0        0         0       0#>   248      0        1         0       0

文档-单词矩阵的操作

有了矩阵以后,可以有很多R函数可以作用于它,但是tm包提供了一些常用的函数,比如你想找到那些至少 出现了10次的单词,使用findFreqTerms()函数

findFreqTerms(dtm,10)#>  [1] "about"      "and"        "are"        "bpd"        "but"       #>  [6] "crude"      "dlrs"       "for"        "from"       "government"#> [11] "has"        "its"        "kuwait"     "last"       "market"    #> [16] "mln"        "new"        "not"        "official"   "oil"       #> [21] "one"        "opec"       "pct"        "price"      "prices"    #> [26] "reuter"     "said"       "said."      "saudi"      "sheikh"    #> [31] "that"       "the"        "they"       "u.s."       "was"       #> [36] "were"       "will"       "with"       "would"

又比如,要找到与单词opec有0.8以上相关性的单词,使用findAssocs()

findAssocs(dtm,"opec",0.8)#> $opec#>   meeting emergency       oil      15.8  analysts    buyers     above #>      0.88      0.87      0.87      0.85      0.85      0.83      0.82 #>      said   ability #>      0.82      0.80

文档-单词矩阵通常很大。tm提供了移除稀疏元素的函数

inspect(removeSparseTerms(dtm,0.4))#> <<DocumentTermMatrix (documents: 20, terms: 8)>>#> Non-/sparse entries: 140/20#> Sparsity           : 12%#> Maximal term length: 6#> Weighting          : term frequency (tf)#> #>      Terms#> Docs  and for its oil reuter said the was#>   127   1   2   3   5      1    1   5   1#>   144   9   5   6  11      1    9  17   1#>   191   0   2   1   2      1    1   4   0#>   194   1   2   1   1      1    1   4   1#>   211   2   2   1   1      1    3   8   0#>   236   7   4   8   7      1    6  15   7#>   237  11   3   3   3      1    0  30   2#>   242   3   1   0   3      1    3   6   1#>   246   9   6   3   4      1    4  18   2#>   248   6   2   2   9      1    5  27   4#>   273   5   4   0   5      1    5  21   1#>   349   2   0   0   3      1    1   5   0#>   352   3   0   2   5      1    1   7   1#>   353   1   2   2   4      1    1   4   3#>   368   1   0   1   3      1    2  11   2#>   489   5   4   2   4      1    2   8   0#>   502   6   5   2   4      1    2  13   0#>   543   0   3   2   2      1    2   5   1#>   704   5   3   1   3      1    3  21   0#>   708   0   0   0   1      1    0   0   1

字典

字典是字符串的集合,通常用一个字符串向量表示,可以在DocumentTermMatrix函数中指定一个 字典,这样生成的矩阵中,就只有字典中出现的词语,不在字典中的词语不会出现在文档单词矩阵中 如下所示

inspect(DocumentTermMatrix(reuters,                          list(dictionary = c("prices", "crude", "oil"))))#> <<DocumentTermMatrix (documents: 20, terms: 3)>>#> Non-/sparse entries: 41/19#> Sparsity           : 32%#> Maximal term length: 6#> Weighting          : term frequency (tf)#> #>      Terms#> Docs  crude oil prices#>   127     2   5      3#>   144     0  11      3#>   191     2   2      0#>   194     3   1      0#>   211     0   1      0#>   236     1   7      2#>   237     0   3      0#>   242     0   3      1#>   246     0   4      0#>   248     0   9      7#>   273     5   5      4#>   349     2   3      0#>   352     0   5      4#>   353     2   4      1#>   368     0   3      0#>   489     0   4      2#>   502     0   4      2#>   543     2   2      2#>   704     0   3      2#>   708     1   1      0

关于中文支持

利用缺省的reader读入文档时,如果文档为中文,tm还是会以空格作为单词的分割符。这样基本对中文不适用。为了能够处理中文,需要 图换掉缺省的reader。新的reader应该读入文章,并进行分词,然后将分词的结果保存为一个新的文件,该文件中,各中文单词以空格隔开 。然后再利用tm的缺省reader进行处理就可以了。关于自定义reader的格式,详见这篇博客

rmmseg4j 以前在cran中的,后来被移除了,原因是不符合java的源码政策 ( Archived on 2014-08-30 as does not comply with policy on Java sources. )

  1. 对于PCorpus而言,第三个参数dbControl必须是一个列表,它具有组件dbNamedbType (这个dbType必须是filehash包支持的数据库类型)。这里不做详细讨论。

来源: http://www.bagualu.net/wordpress/archives/6112

本文分享自微信公众号 - PPV课数据科学社区(ppvke123)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-08-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 原创:R语言18讲 (二)

    在学习R语言数据分析之前,我们对于R这个软件需要做一些简单的了解,这样对于我们以后编程和数据分析有很大的帮助,简单是说,就是大致了解一下R软件的界面的和操作特性...

    小莹莹
  • 聚类分析:k-means和层次聚类

    尽管我个人非常不喜欢人们被划分圈子,因为这样就有了歧视、偏见、排挤和矛盾,但“物以类聚,人以群分”确实是一种客观的现实——这其中就蕴含着聚类分析的思想。 前面所...

    小莹莹
  • 人工智能来了,哪些人能保住饭碗?听听李开复怎么说

    来源:澎湃新闻,澎湃新闻记者 洪燕华 实习生 李宁琪 来,我们先做几个小测试: 你知道什么是人工智能吗? 手机软件P图?苹果手机的Siri? 打车用的滴滴?特...

    小莹莹
  • Python基础整理操作积累

    Python编程积累 列表内容 Python基础 for变化量的灵活应用 for x,y in [[0,1],[0,2],[1,2]]: d...

    学到老
  • 文档驱动式超敏捷开发

      敏捷开发大家都不陌生,他对文档的态度是偏向于反对,但是也不是说一点文档都没有。他的说法是 代替文档。   那么敏捷开发为什么会这么认为呢?其实大家在做项目开...

    用户1174620
  • NLP︱句子级、词语级以及句子-词语之间相似性(相关名称:文档特征、词特征、词权重)

    关于相似性以及文档特征、词特征有太多种说法。弄得好乱,而且没有一个清晰逻辑与归类,包括一些经典书籍里面也分得概念模糊,所以擅自分一分。

    素质
  • SAP最佳业务实践:ETO–项目装配(240)-8给作业分配技术文档

    image.png CJ20N给作业分配技术文档 为帮助雇员操作,可以将保存在文档管理系统中的文档分配给WBS元素和作业。在这个操作中,会将一份技术图纸分配给一...

    SAP最佳业务实践
  • 【数据挖掘】主题模型——LDA比较通俗的介绍

    一、主题模型 要介绍LDA,首先说说主题模型(Topic Model)的概念。主题模型是一种生成式模型,而且是通过主题来生成的。就是说,我们认为...

    陆勤_数据人网
  • DeepMind推出更难的机器阅读理解数据集,要让AI读懂整本书

    夏乙 发自 凹非寺 量子位 出品 | 公众号 QbitAI 在机器阅读理解界的ImageNet——SQuAD挑战赛中,排在前几名的算法,都能拿到八十多分的成绩。...

    量子位
  • Python循环 - 胖子老板来包烟

    因此,大家在编写程序时,应该尽量养成习惯:除非需求的特殊要求,否则 循环 的计数都从 0 开始

    Devops海洋的渔夫

扫码关注云+社区

领取腾讯云代金券