分享

Spark 高级分析:第六章第1节 词语文档矩阵

feilong 2018-5-18 21:36:51 发表于 连载型 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 0 6503
问题导读

1.什么是LSA?为什么需要LSA?
2.什么是SVD?
3.什么是词语文档矩阵?
4.什么是TF-IDF
,有何作用,Spark中是否有其实现?







上一篇:Spark 高级分析:第五章第11,12节 执行聚类
http://www.aboutyun.com/forum.php?mod=viewthread&tid=24492&extra=


第六章 了解维基百科的潜在语义分析


去年斯诺登在哪里?
——尤萨林上尉


数据工程中的大部分工作是将数据组合成某种可查询的格式。结构化数据可以用正式语言查询。列表数据可以用SQL查询。尽管在实践中,这绝不是一项容易的任务,但在高层次上,使表格数据可访问的工作通常是直接的——从各种不同的数据源中提取数据到一个单独的表中,或者在过程中明智地进行清理或融合。非结构化文本数据提供了在结构化数据集中很少遇到的一整套挑战。将数据准备成一种人类可以与之交互的格式的过程,与其说是“汇编”,不如说是“索引”或“强制”,当事情变得丑陋的时候。标准搜索索引允许查找包含一组查询条件的文档集。然而,这种索引往往不能捕获文本主题中的潜在结构。有时,人们希望找到与“算法”相关的概念相关的文档,不管文档是否包含这个特定的单词。

潜在语义分析(LSA)是一种自然语言处理和信息检索技术,旨在更好地理解文档的语料库和这些文档中单词之间的关系。它试图将语料库分割成一系列相关的概念。每个概念都捕获了数据中的一个变化的线程,并且通常对应于主体讨论的主题。在没有深入研究数学的情况下,每个概念都包含三个属性:在语料库中对每个文档的亲和性水平,在语料库中的每一个术语的亲和性,以及一个重要的分数,反映了这个概念在描述数据集中的差异时是多么有用。例如,LSA可能会发现一个与“Asimov”和“robot”一词有很高亲和力的概念,并且对“基础系列”和“科幻小说”有很高的亲和力。

通过只选择最重要的概念,LSA可以用一种更简单的表示方法来描述数据,这种表示近似于它,但却丢弃了一些无关的噪声,并合并了共存的链。

简明的陈述可以帮助完成各种任务。它可以在术语和其他术语之间、文档和其他文档之间以及术语和文档之间提供许多相似之处。通过封装语料库中差异的模式,它可以将这些分数建立在更深层的理解上,而不是简单地计算出单词的出现和出现。这些相似性度量是理想的任务,例如查找与查询条件相关的文档集,将文档分组到主题,并找到相关的单词。

LSA使用一种称为奇异值分解(SVD)的线性代数技术发现了这个低维的表示。奇异值分解可以被认为是更强大的ALS因子分解的版本,在前一章的推荐引擎中描述。它开始于通过计算每个文档的计数字频率生成的一个词语文档矩阵。在这个矩阵中,每个文档对应一个列,每个项对应一行,以及每个元素。

表示单词对文档的重要性。然后,SVD将这个矩阵分解成三个矩阵,其中一个矩阵表达了关于文档的概念,其中一个表达了关于术语的概念,其中一个包含了每个概念的重要性。这些矩阵的结构是这样的,可以通过删除一组与最不重要的概念相对应的行和列来实现原始矩阵的低级近似。也就是这个低秩的矩阵。近似可以相乘产生一个接近于原始的矩阵,随着每一个概念被移除,保真度的损失越来越大。

在本章中,我们将根据其潜在的语义关系,着手进行针对全面的人类知识的查询。更具体地说,我们将把LSA应用于包含在Wikipedia中包含的完整文章集,大约是46 GB的原始文本。我们将讨论如何使用Spark来预处理数据:读取、清理和强制转换为数值格式。我们将展示如何运行SVD统计过程并解释如何解释和使用结果。

SVD在LSA外有广泛的应用。它出现在各种各样的地方,如探测气候趋势(迈克尔·曼著名的曲棍球棒图),面部识别和图像压缩。Spark的实现可以在巨大的数据集上执行矩阵分解,从而将技术打开到一个全新的集合应用程序。

第1节 词语文档矩阵

在执行任何分析之前,LSA要求将主体的原始文本转换为一个term文档矩阵。在这个矩阵中,每一行表示在语料库中出现的一个术语,每一列表示一个文档。松散地,每个位置的值应该对应行对列文档的术语的重要性。提出了一些加权方案,但目前最常见的是termfrequency times逆文档-频率,通常缩写为TF-IDF。
[mw_shl_code=scala,true]def termDocWeight(termFrequencyInDoc: Int, totalTermsInDoc: Int,
termFreqInCorpus: Int, totalDocs: Int): Double = {
val tf = termFrequencyInDoc.toDouble / totalTermsInDoc
val docFreq = totalDocs.toDouble / termFreqInCorpus
val idf = math.log(docFreq)
tf * idf
}[/mw_shl_code]
TF-IDF描述了一个术语与文档相关的两种直觉。首先,人们会期望一个术语在文档中出现的次数越多,它对该文档的重要性就越大。其次,并非所有条款在全球范围内都是平等的。在整个语料库中出现的单词比在大多数文档中出现的一个词更有意义,因此,度规在整个语料库中使用单词在文档中出现的逆。

语料库中单词的频率呈指数级分布。一个普通的单词通常会出现10次,通常是一个普通的单词,而这个单词的出现频率可能是一个罕见单词的10倍或100倍。在原始的逆文档频率上建立一个度量标准,将会给罕见的单词带来巨大的权重,并且实际上忽略了所有其他单词的影响。为了捕获这个分布,该方案使用了逆文档频率的日志。这使得在文档频率上的差异,通过将它们之间的乘法差距转化为附加的差距。

这个模型依赖于一些假设。它把每一份文件当作“一袋单词”,意思是它不注意单词、句子结构或否定的顺序。通过对每一项表示一次,该模型难以处理多义,对多重含义使用同一个词。例如,该模型不能区分“Radiohead是有史以来最好的乐队”和“我打破了一个橡皮筋”乐队的使用。如果这两个句子经常出现在语料库中,它可能会把Radiohead和橡胶联系起来。
这个语料库有一千万份文件。计算晦涩难懂的技术术语,英语中包含了大约100万个术语,其中的一些子集可能有助于理解语料库。由于语料库包含的文档比术语多得多,所以生成术语文档矩阵作为行矩阵是最有意义的,这是一组与文档对应的稀疏向量的集合。

从原始的Wikipedia转储到此表单需要一组预处理步骤。首先,输入由一个巨大的XML文件组成,文件被<page>标记分隔。这需要被分解为下一个步骤,将wiki格式化变成纯文本。然后将普通文本分割为令牌,通过一个称为“lemmatization”的过程将它们从不同的屈折形式转换为根项。这些标记可以用来计算术语频率和文档频率。最后一步将这些频率联系在一起,并构建实际的矢量对象。

第一步可以完全并行地执行每个文档(在Spark中,这意味着作为一组映射函数),但是计算反向文档的频率需要在所有文档之间进行聚合。有许多有用的NLP和wikipedia特定的提取工具可以帮助这些任务。

本帖被以下淘专辑推荐:

没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条