文本挖掘介绍
文本挖掘:“自动化或半自动化处理文本的过程”,包含了文档聚类、文档分类、自然语言处理、文本变化分析及网络挖掘等领域内容。
对于文本处理过程首先需要有分析的语料(text corpus),然后根据这些语料建立半结构化的文本库(text database)。最后生成包含语频的结构化的词条——文档卷着那(term-document matrix)。
这个一般性数据结构会被用于后续的分析:
- 文本分析,比如根据现有的文本分类情况,对未知文本进行归类;
- 语法分析;
- 信息提取和修复
- 文档信息汇总,比如提取相关有代表性的关键词、句子等
自然语言处理
安装Snowball
包,zip文件下载地址
依赖的包:RWeka
、RWekajars
、rJava
识别某个英文单词,需要对其进行词干化(stemming)
SnowballStemmer(c(‘functions‘,‘stemming‘,‘liked‘,‘doing‘))
记号化(Tokenization)是将一段文本分割成叫做token(象征)过程。
NGramTokenizer(‘我 站在 六里桥 的 柳树下‘)
中文分词
在英文结构中,每个表意的单词都是独立的,但中文表意的字符之间没有空格连接。
Rwordseg
包,调用Java分词程序对语句进行分词。安装方法:
install.packages("Rwordseg", repos = "http://R-Forge.R-project.org")
分词结果:
segmentCN(‘花儿为什么这样红‘)
使用Rwordseg
的中文分词,它不但分词的精度较高,且支持词性标注等功能。另外的中文分词引擎有rmmseg4j
。
tm包
数据读入
在tm中主要的管理文件的结构被称为语料库(Corpus),代表了一系列的文档集合。动态语料库(Volatile Corpus,作为R对象保存在内存中)和静态语料库(Permanent Corpus,R外部保存)。
在语料库构成中,x必须有一个说明资料来源(input location)的源对象(Source Object)。
动态语料库:
Corpus(x,readerControl = list(reader = x$DefaultReader,language = "en"),...)
静态语料库,需要使用filehash包来支持:
PCorpus(x,readerControl = list(reader = x$DefaultReader,language = "en"), dbControl = list(dbName = "",dbType = "DB1"),...)
对于这些资料来源(x),tm包提供了一些相关的函数:
DirSource
:处理目录VectorSource
:由文档构成的向量DataFrameSource
:数据框
第二个参数是readerControl
,必须声明reader
和language
两个内容。第一个reader
是指从资料源建立的文本文件。tm
包提供了一系列的函数文件(readPlain()
,readGmane()
,readRCV1()
,readReut21578XMLasPlain()
,readPDF()
,readDOC()
等)。
使用getReaders()
获得这些函数的列表。对于每一类源,都有自己默认的reader
。DirSource
,默认读入输入文件并把内容解释为文本。
第二个language
字符集。
在使用静态语料库条件下,涉及第三个参数dbControl
,用来声明R内存对象外的资料来源。dbType
控制了包filehash
支持的数据库类型。数据库支持可以有效的减少对内容的要求,但数据的访问会受到硬盘的读写能力限制。
读取txt目录下的文档:
txt <- system.file("texts","txt",package = "tm") ovid <- Corpus(DirSource(txt),readerControl = list(language = "lat"))
从字符集向量创建语料库:
docs <- c("This is a text.","This another one.") Corpus(VectorSource(docs))
路透社21578语料库reuters,下载地址
reut21578 <- system.file("texts","crude",package = "tm") reuters <- Corpus(DirSource(reut21578),readerControl = list(reader = readReut21578XML))
数据输出
在R中创建的语料库,使用writeCorpus()
函数保存。
writeCorpus(ovid)
语料库的提取
summary()
函数会提供更多的元数据(meta data)信息,完整信息的提取需要使用inspect()
,比如:
inspect(ovid[1:2])
单个文档的提取需要使用[[,
,既可以通过位置也可以通过名称:
identical(ovid[[2]],ovid[["ovid_2.txt"]])
信息转化
创建语料库,后续文档修改通过函数tm_map()
处理,这个函数可以通过maps
方式将转化函数实施到每一个语料上。
转化为纯文本
在reuters
这个语料库中保存的是XML格式的文本,XML格式文本没有分析的意义,只需要使用其中的文本内容。这个操作可以使用as.PlainTextDocument()
函数来实现:
reuters <- tm_map(reuters,as.PlainTextDocument)
另外一种方式是使用readReut21578XMLasPlain
读取方式,第一步即为纯文本格式。
去除多余的空白
reuters <- tm_map(reuters,stripWhitespace)
小写变化
reuters <- tm_map(reuters,tolower)
停止词去除
reuters <- tm_map(reuters,removeWords,stopwords("english"))
填充
通过以下方式,需要Snowball
包(并行计算)支持:
tm_map(reuters,stemDocument)
过滤
tm_filter
函数选取给定条件下的文档。sFilter适用于一般情况下的用户自定义过滤情况:它整合了适用于元数据的最小查询语句。
元数据管理
元数据是为了标记语料库的附加信息,最简单的使用方式就是调用meta()
函数。这些附加的元数据标签都是独立的附加在单个文档上。从语料库的视角上看,这些元数据标签被独立的存储在每个文档上。除了meta()
函数上,DublinCore()
函数提供了一套介于Simple Dublin Core
元数据和tm
元数据之间的映射机制,用于获得或设置文档的元数据信息。
在tm
包元数据管理体系中,元数据标签对应了两个level:
- 对于语料库(corpus)级别:文档的集合
- 单个文档的元数据
后一种元数据的使用主要是由于一些性能原因,或者是由于一些分析上的需要,比如要对文档进行分类(classification),分类的结果直接和每个文档的标记有关系。
标准操作和函数
对于语料库来说,其标准操作和函数与R的一般函数非常类似:
[, [<-, [[, [[<-, c(), lapply()
对于像c()函数即是连接多个语料库的意思。连接之后,元数据信息也会被更新。
创建词条——文档关系矩阵
文本挖掘需要创建词条-文档关系矩阵
,它是后续构建模型的基础。
在tm
包里,根据词条。文档分别作为行、列或反之,对应有TermDocumentMatrix
和DocumentTermMatrix
两类稀疏矩阵:
dtm <- DocumentTermMatrix(reuters) inspect(dtm[1:5,100:105])
对词条-文档关系矩阵操作
找出发生5次以上的条目,可以使用findFreqTerms()
函数:
findFreqTerms(dtm,5)
使用findAssocs()
找到相关性:
findAssocs(dtm,"opec",0.8)
对于一般矩阵,会将矩阵直接转化为相关阵,这种方式可以实现不同的相关计算方式。词条-文档关系矩阵一般都是非常庞大的数据集,提供了一种删减稀疏条目的方法。
字典
字典是一个字符集合。经常用于在文本挖掘中展现相关的词条时,使用Dictionary()
函数实现。当将字典传递到DocumentTermMatrix()
以后,生成的矩阵会根据字典提取计算。
网页解析的利器——XML包
网页解析
在R中对网页解析(XML、HTML文件,或包含XML、HTML的字符串)有多种方法,比较成熟的方法是使用XML包。这个包能够将XML、HTML网页树(tree)解析成R结构数据。当解析的内容已知为(潜在畸形的)HTML时应当使用HTMLTreeParse
函数,这个函数拥有大量的参数来适应解析需要。它可以在R中或使用内置C-level
节点来创建树,两种方式在不同的环境下都非常有用。
xmlParse
、HTMLParse
分别等价于XMLTreeParse
和HTMLTreeParse
,只是使用了一个默认的值代替了为TRUE
的useInterNodes
参数。
xmlTreeParse(file,ignoreBlanks = T,handlers = NULL, replaceEntities = F,asText = F,trim = T,validate = F,getDTD = T, isURL = F,asTree = F,addAttributeNamespaces = F,useInternalNodes = F, isSchema = F,fullNamespaceInfo = F,encoding = character(), useDotNames = length(grep("^\\.",names(handlers))) > 0,xinclude = T, addFinalizer = T,error = xmlErrorCumulator())
file
,包含XML内容的文件名。可以使用声明用户工作目录,也可以是一个URL(参考isURL)。甚至文件还可以是一个压缩文件(gzip),文件可以被直接读取而不需要用户解压缩(gunzip)。
ignoreBlanks
,逻辑型,在结果“树”中是否包含空白行。
handlers
,选项函数,用于将不同的XML节点映射到R对象中。一般是函数的列表 (list)。它提供了一种通过增加、减少节点来过滤树的方式。一般使用C代码 来做处理。
replaceEntities
, 逻辑值,是否将单位的参考条目进行对于那个文本的替换。默认为False。
asText
, 逻辑值,和第一个参数file相关。file应被作为XML文本处理,而不是文件名称。这 个选项可以允许还原不同的数据源(HTTP、XML-RPC等),并且依旧使用这个解 析器。
trim
,是否删除文本字符串中的空白。
validate
,逻辑值,是否使用一个确认的解析器,或者根据DTD规范检查内容。为TRUE则 DTD的错误告警信息将被展示,但解析仍将继续,除非是致命的错误。
getDTD
,逻辑值,DTD是否被返回(包括内部和外部)。被改变返回的类型。
isURL
,声明file参数是否涉及URL(通过ftp和http)或系统上的常规文件。如果asText
为 TRUE,则这个参数不应该被指定。这个函数试图从数据源中通过grep找到是否有 URL。libxml
解析器处理服务器连接,这并不是R的特性(scan)。
asTree
,仅仅在handlers参数使用时有效。
useInternalNodes
,是否使用XMLInternalNode而不是用XMLNode类。内部节点 (internalnodes)不转化到R时这个参数能使过程变得更快。
encoding
,文档的编码方式。文档应该包含编码信息,如果没有,这个参数可以为解析器指 定文档的编码方式。
使用XML
包进行网页解析,网页源码可以通过readLines
,在exampleData
目录下:
fileName <- system.file("exampleData","include.xml",package = "XML") root <- xmlParse(fileName) test <- getNodeSet(root,‘//para‘)
返回内容是一个list,可以使用lapply
进行批量提取
sapply(test, xmlValue)
将test中para的内容提取出来,使用xmlValue
函数:
vdata <- sapply(test, xmlValue)
函数getNodeSet
提供了使用XPath
语法抽取XML节点信息的功能。
首先解析一个xml
文件,而后在doc的XPath目录下,找到含有status字段的a
节点。
doc <- xmlParse(system.file("exampleData","tagnames.xml",package = "XML")) els <- getNodeSet(doc,"/doc//a[@status]") sapply(els, function(el) xmlGetAttr(el,"status"))
最后通过XMLGetAttr
函数获得a
节点的属性值(Attribute Value)
字符集转化
如果处理的是中文字符,可能会遇到字符编码转换的问题,可以使用iconv
处理:
iconv(x,from = "",to = "",sub = NA,mark = T,toRaw = F)
XML和tm包配合使用(to do)
在得到TermDocument
矩阵后,基本上所有的数据挖掘算法都可以使用,如Cluster
、Classification
、Regression
等,甚至Apriori
、SNA
等技术。
基础分析技术
在tm
包中提供了诸如频数提取(findFreqTerms)、相关性提取(findAssocs)等函数,以及用于计算cosine
距离的dissimilarity
函数。
R中的wordcloud
包提供了绘制文本云的技术,甚至还可以对两个文本云进行比较。
文本聚类
聚类一般会考虑使用层次(Hierarchical)聚类法或分割(Partitioning)聚类,对于层次聚类的核心实际在距离阵的计算,一般会使用欧氏距离、闵式距离等,但在大型数据条件下会优先选择cosine
距离,及dissmilarity
函数。使用kmeans
函数构建K均值聚类模型。
潜变量语义分析(not done)
潜变量语义分析(Latent Semantic Analysis)是一种通过语料的统计计算,对语境的提取和抽象。LSA和神经网络模型非常接近,但它基于奇异值分解(singular value decomposition)。
LSA是一个提取语义的数学(统计)方法,它不是传统的自然语言处理或人工智能,也没有使用任何人类主导的字典、语义网络、语法、词法,而仅仅是把文本解析为有意义的单词。基本步骤如下:
- 第一步是构建词条-文档(文章)矩阵,即每一行代表了词条,每一类代表了文档(文章),每个单元代表了发生的频数;
- 接下来对这个矩阵实施奇异值分解。在奇异值分解中,原始矩阵被分解为三个矩阵,其中的一个矩阵描述了原始的行信息,作为正交基构成的向量;另外一个以相同的方式描述了列的信息;第三个是对角矩阵,包含了标度值(scaling values)。当这三个矩阵相乘时,可以得到原始矩阵。
主题模型
在机器学习和自然语言处理中,主题模型是专门抽象一组文档所表达“主题”的统计技术。LDA主题模型涉及到贝叶斯理论、Dirichlet分布、多项分布、图模型、变分推断、EM算法、Gibbs抽样等知识。
LDA是一个三层的贝叶斯概率模型,且有一个假设:bag of word
。认为文档就是一个词的集合,忽略任何语法或出现顺序关系。
附录
XML文件
XML(eXtensive Markup Language)可扩展的标记语言,是万维网(W3C)定义的一种标准。用户可按照XML规则自定义标记(tags标签)。
可作为跨平台的纯文本通讯数据,且无关语言。其设计目标核心是数据的内容,和显示分离。但XML不能直接用来写网页,即使包含了XML数据,依然要转化为HTML格式才能在浏览器上显示。XML被设计用来传输和存储数据。而HTML被设计用来显示数据。
- XML指可扩展标记语言
- XML是一种标记语言,很类似HTML
- XML的设计宗旨是传输数据,而非显示数据
- XML标签没有被预定义,需要自定定义标签
- XML被设计为具有自我描述性
- XML是W3C的推荐标准
- XML文件由声明、元素、属性、实体、注释构成
正则表达式
Copyright © 吴华锦
雅致寓于高阁渔舟唱晚,古典悠然
格调外发园林绿树萦绕,馥郁清香