Press "Enter" to skip to content

文本挖掘从小白到精通(一)—语料、向量空间和模型的概念

写在前面:笔者最近在梳理自己的文本挖掘知识结构,借助gensim、sklearn、keras等库的文档做了些扩充,希望在梳理自身知识体系的同时也能对想学习文本挖掘的朋友有一点帮助,这是笔者写该系列的初衷。

 

本文会介绍几个在使用
gensim进行文本挖掘
所需了解的基本概念和术语,并提供一些简单的用法示例。

 

在更高层次上,
gensim
是一种通过检查词汇模式(或更高级别的结构,如语句或文档)来发现文档语义结构(Semantic Structure)的工具。
gensim

通过 语料库
— 一组文本文档,并在语料库中生成文本的向量表示(Vector Representation of the Text)来实现这一点。然后,文本的向量表示可用于训练模型 — 它是用于创建不同的文本数据(蕴含语义)表示的算法。这三个概念是理解
gensim
如何工作的关键,所以让我们花一点时间来解释它们的含义。与此同时,我们将通过一个简单的例子来说明每个概念。

 

一 、语料(Corpus)

 

一个 语料库
是数字文档的集合(A Collection of Digital Documents)。这个集合是
gensim

的输入,它将从中推断文档的结构或主题。从语料库中推断出的潜在结构(Latent Structure)可用于将主题分配给先前不存在于仅用于训练的语料库中的新文档。出于这个原因,我们也将此集合称为
训练语料库

(Training Corpus)
。这个过程不需要人工干预(比如手动给文档打标签) — 因为主题分类是无监督的(Unsupervised)(https://en.wikipedia.org/wiki/Unsupervised_learning)。

 

对于笔者用于示例的语料库,有12个文档,每个文档只有一个语句:

 

import jieba

 

 

jieba.add_word(‘知识图谱’) #防止“知识图谱”被切错词

 

 

raw_corpus = [‘商业新知:知识图谱为内核,构建商业创新服务完整生态。’,

‘如何更好利用知识图谱技术做反欺诈? 360金融首席数据科学家沈赟开讲。’,

‘知识管理 | 基于知识图谱的国际知识管理领域可视化分析。’,

‘一文详解达观数据知识图谱技术与应用。’,

‘知识图谱技术落地金融行业的关键四步。’,

‘一文读懂知识图谱的商业应用进程及技术背景。’,

‘海云数据CPO王斌:打造大数据可视分析与AI应用的高科技企业。’,

‘智能产业|《人工智能标准化白皮书2018》带来创新创业新技术标准。’,

‘国家语委重大科研项目“中华经典诗词知识图谱构建技术研究”开题。’,

‘最全知识图谱介绍:关键技术、开放数据集、应用案例汇总。’,

‘中译语通Jove Mind知识图谱平台 引领企业智能化发展。’,

‘知识图谱:知识图谱赋能企业数字化转型,为企业升级转型注入新能量。’]

 

 

raw_corpus = [‘ ‘.join(jieba.lcut(i)) for i in raw_corpus] #对语料库中的文档进行分词,便于后续处理

raw_corpus

 

['商业 新知 : 知识图谱 为 内核 , 构建 商业 创新 服务 完整 生态 。',
 '如何 更好 利用 知识图谱 技术 做 反 欺诈 ?   360 金融 首席 数据 科学家 沈赟开 讲 。',
 '知识 管理   |   基于 知识图谱 的 国际 知识 管理 领域 可视化 分析 。',
 '一文 详解 达观 数据 知识图谱 技术 与 应用 。',
 '知识图谱 技术 落地 金融 行业 的 关键 四步 。',
 '一文 读 懂 知识图谱 的 商业 应用 进程 及 技术 背景 。',
 '海云数 据 CPO 王斌 : 打造 大数据 可视 分析 与 AI 应用 的 高科技 企业 。',
 '智能 产业 | 《 人工 智能 标准化 白皮 书 2018 》 带来 创新 创业 新技术 标准 。',
 '国家 语委 重大 科研 项目 “ 中华经典 诗词 知识图谱 构建技术 研究 ” 开题 。',
 '最全 知识图谱 介绍 : 关键 技术 、 开放 数据集 、 应用 案例 汇总 。',
 '中译 语通 Jove   Mind 知识图谱 平台   引领 企业 智能化 发展 。',
 '知识图谱 : 知识图谱 赋能 企业 数字化 转型 , 为 企业 升级 转型 注入 新 能量 。']

 

这只是一个很小的语料库,其实你可以用其他的语料库进行替代,比如微信上的文章、微博博文,或者新闻标题等。

 

收集语料库之后,通常会进行一系列的文本预处理。作为示例,为了简洁起见,笔者仅删除语料库中的停用词和在语料库中只出现一次的词汇。在此过程中,笔者将进行分词操作,将文档分解为由词汇组成的列表(在本例中使用空格作为分隔符)。

 

# 移除常用词以及分词

stoplist = [i.strip() for i in open(‘datasets/stopwords_zh.txt’,encoding=’utf-8′).readlines()]

 

 

 

 

#将文档中可能存在的西文字符小写化,按空格进行拆分,且去停用词

texts = [[word for word in document.lower().split() if word not in stoplist]

for document in raw_corpus]

 

 

#计算词频

from collections import defaultdict

frequency = defaultdict(int)

for text in texts:

for token in text:

frequency[token] += 1

 

 

# 仅保留词频数高于1的词汇

processed_corpus = [[token for token in text if frequency[token] > 1] for text in texts]

processed_corpus

 

[['商业', '知识图谱', '商业', '创新'],
 ['知识图谱', '技术', '金融', '数据'],
 ['知识', '管理', '知识图谱', '知识', '管理', '分析'],
 ['一文', '数据', '知识图谱', '技术'],
 ['知识图谱', '技术', '金融', '关键'],
 ['一文', '知识图谱', '商业', '技术'],
 ['分析', '企业'],
 ['智能', '智能', '创新'],
 ['知识图谱'],
 ['知识图谱', '关键', '技术'],
 ['知识图谱', '企业'],

 

[‘知识图谱’, ‘知识图谱’, ‘企业’, ‘转型’, ‘企业’, ‘转型’]]

 

在继续之前,笔者希望将语料库中的每个词汇与唯一的整数ID相关联。我们可以使用
gensim.corpora.Dictionary
这个类来完成。这个词典定义了笔者之前预处理后的语料中的词汇。

 

from gensim import corpora

 

dictionary = corpora.Dictionary(processed_corpus)

print(dictionary)

 

Dictionary(14 unique tokens: [‘创新’, ‘商业’, ‘知识图谱’, ‘技术’, ‘数据’]…)

 

因为笔者给定的语料较小, 只有14个不同的词汇在这个
Dictionary
中。对于较大的语料库,词典中会包含成千上万的词汇,数量庞大。

 

二 、 向量空间(Vector Space)

为了推断语料库中的
潜在结构(Latent Structure)

,我们需要一种可用于数学操作(比如,加减乘除等运算)的文档表示方法。一种方法是将每个文档表示为向量。有各种用于创建文档的向量表示的方法,其中一个简单的方法是 词袋模型(Bag-of-Words Model)

 

在词袋模型下,每个文档由包含字典中每个单词的频率计数的向量表示。例如,给定一个包含词汇[‘咖啡’,’牛奶’,’糖果’,’勺子’]的字典,那幺,一个由字符串’咖啡 牛奶 糖果 勺子’组成的文档可以用向量表示为[2 ,1,0,0],其中向量的元素(按顺序)对应文档中出现的“咖啡”,“牛奶”,“糖”和“勺子”。向量的长度是字典中的词汇数。词袋模型的一个主要特性是它完全忽略了编码文档(the Encoded Document )中的词汇顺序,这就是词袋模型的由来。

 

我们处理过的语料库中有14个不同的词汇,这意味着语料库中的每个文档将由这个14维向量的词袋模型来表示。我们可以使用字典将分词后的文档转换为14维向量。由此,我们可以看到这些ID对应的词汇:

 

print(dictionary.token2id)

 

{‘创新’: 0, ‘商业’: 1, ‘知识图谱’: 2, ‘技术’: 3, ‘数据’: 4, ‘金融’: 5, ‘分析’: 6, ‘知识’: 7, ‘管理’: 8, ‘一文’: 9, ‘关键’: 10, ‘企业’: 11, ‘智能’: 12, ‘转型’: 13}

 

例如,假设我们想要对“知识图谱为企业转型助力”这个语句进行向量化(请注意,该语句不在我们原来的语料库中)。我们可以使用dictionary的 doc2bow
方法为该语句创建词袋表示,该方法返回词汇计数的稀疏表示:

 

new_doc = “知识图谱 为 企业 转型 助力” #已分词,便于后续处理

new_vec = dictionary.doc2bow(new_doc.lower().split())

new_vec

 

<em>[(2, 1), (11, 1), (13, 1)]</em>

 

每个元组中的第一个元素对应字典中的词汇ID,第二个条目对应于该词汇的计数。

 

请注意,原始语料库中没有出现“为”、“助力”,因此它们将不包含于新生成的向量表示中。另请注意,此向量仅包含实际出现在文档中的词汇。因为任何给定文档只包含字典中许多单词中的几个单词,所以未参与向量化的词汇会直接被剔除,以节省空间。

 

我们可以将整个原始语料库转换为向量列表:

 

bow_corpus = [dictionary.doc2bow(text) for text in processed_corpus]

bow_corpus

 

[[(0, 1), (1, 2), (2, 1)],
 [(2, 1), (3, 1), (4, 1), (5, 1)],
 [(2, 1), (6, 1), (7, 2), (8, 2)],
 [(2, 1), (3, 1), (4, 1), (9, 1)],
 [(2, 1), (3, 1), (5, 1), (10, 1)],
 [(1, 1), (2, 1), (3, 1), (9, 1)],
 [(6, 1), (11, 1)],
 [(0, 1), (12, 2)],
 [(2, 1)],
 [(2, 1), (3, 1), (10, 1)],
 [(2, 1), (11, 1)],
 [(2, 2), (11, 2), (13, 2)]]

 

请注意,虽然此列表完全保存在内存中,但在大多数的应用场景,你需要更具伸缩性的解决方案(A More Scalable Solution)。幸运的是,
gensim
允许流式迭代器。后面笔者会谈及。

 

三 、 模型(Model)

 

现在,我们已经对测试语料库进行了向量化,我们可以开始使用 models
对其进行转换了。我们使用模型作为抽象术语,指的是从一个文档表示到另一个文档表示的转换。在
gensim
中,文档表示为向量,因而模型可以被认为是两个向量空间之间的转换。从训练语料库中学习这种转换的细节。

 

一个简单的模型示例是TF-IDF。TF-IDF模型将向量从词袋表示(Bag-of-Words Representation)转换为向量空间,其中频率计数根据语料库中每个单词的相对稀有度(the relative rarity of each word in the corpus)进行加权。

 

这是一个简单的例子。让我们初始化tf-idf模型,在测试语料库上进行训练,然后对字符串“知识图谱这种技术是企业转型的利器”进行转换:

 

from gensim import models

# 训练模型

tfidf = models.TfidfModel(bow_corpus)

# 对”知识图谱这种技术是企业转型的利器”进行转换

tfidf[dictionary.doc2bow(“知识图谱 这种 技术 是 企业 转型 的 利器”.split())]

 

[(2, 0.06112717038912965),
 (3, 0.29351946977430854),
 (11, 0.46478459877035777),
 (13, 0.8331176787522306)]

 

TF-IDF
模型再次返回元组列表,每个元组的第一个元素是词汇ID,第二个条目是TF-IDF加权值。注意,对应于“知识图谱”的ID(在训练语料库中出现10次)的加权值低于对应于“转型”的ID(在训练语料库中出现2次)权重值。

gensim
提供了许多不同的模型/转换。有关详细信息,请看笔者后续的文章。

 

注:以上内容大部分来自gensim的英文文档,笔者只是用中文语料进行了新的诠释,后续还会有更多的内容,笔者将不定期更新,动力来自于读者的热情,想让笔者持续更新的请在下方留言,可以说说自己感兴趣的点,比如文本聚类和文本分类…

Be First to Comment

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注