文本挖掘

文本挖掘介绍

文本挖掘:“自动化或半自动化处理文本的过程”,包含了文档聚类、文档分类、自然语言处理、文本变化分析及网络挖掘等领域内容。
对于文本处理过程首先需要有分析的语料(text corpus),然后根据这些语料建立半结构化的文本库(text database)。最后生成包含语频的结构化的词条——文档卷着那(term-document matrix)。

这个一般性数据结构会被用于后续的分析:

  • 文本分析,比如根据现有的文本分类情况,对未知文本进行归类;
  • 语法分析;
  • 信息提取和修复
  • 文档信息汇总,比如提取相关有代表性的关键词、句子等

自然语言处理

安装Snowball包,zip文件下载地址
依赖的包:RWekaRWekajarsrJava

识别某个英文单词,需要对其进行词干化(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,必须声明readerlanguage两个内容。第一个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包里,根据词条。文档分别作为行、列或反之,对应有TermDocumentMatrixDocumentTermMatrix两类稀疏矩阵:

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节点来创建树,两种方式在不同的环境下都非常有用。

xmlParseHTMLParse分别等价于XMLTreeParseHTMLTreeParse,只是使用了一个默认的值代替了为TRUEuseInterNodes参数。

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矩阵后,基本上所有的数据挖掘算法都可以使用,如ClusterClassificationRegression等,甚至AprioriSNA等技术。

基础分析技术

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 © 吴华锦
雅致寓于高阁渔舟唱晚,古典悠然
格调外发园林绿树萦绕,馥郁清香
原文地址:https://www.cnblogs.com/hanqing/p/5479847.html