市场每天都在生成海量的舆情信息,这些信息可以帮助我们识别市场情绪的转变。如果只是人工地去跟踪大量的舆论和研报显然缺乏效率。我们可以试试让机器来完成这个工作。
数据科学在数值领域中很常见,但这个不断壮大的领域现在也可以应用于非数值数据,比如文本。本文将探索一些理解文本数据的关键算法,包括基本文本分析、马尔可夫链和情感分析。
许多数据(比如文本)是非结构化的,需要采用不同的机制来提取洞察。文本分析或文本数据挖掘是采用各种方法从文本中获取信息的过程。本文将探索一些基本技术,分析使用 Natural Language Toolkit (NLTK) 的更高级方法。
安装 NLTK
要使用 NLTK,需要安装 Python V2.7、3.4 或 3.5。安装其中一种 Python 版本后,请执行下边的步骤来安装 NLTK。这些指令使用了 Python 包管理器 pip。
安装 NLTK
要验证是否已正确安装 NLTK,可以尝试通过 Python 交互式地导入 NLTK,如下所示。如果导入失败,则会出现安装问题。
检验安装是否成功
安装 NLTK 后,现在可以跟着接下来 3 节中的示例进行操作了。
基本文本分析
NLTK 提供了一系列功能,但所有功能都需要导入文本来执行任何类型的分析。让我们先来看看文本导入和一些简单分析。
下边提供了一个的导入样本语料库并采用句子和单词两种形式将其标记化的简单示例。我使用
Python 请求库从来自 Project Gutenberg 的查尔斯·达尔文的鸿篇巨制——物种起源 (On the Origin of
Species) 中读取文本。然后对文本回复应用两个分词器(分词器基于边界将字符串分解为子字符串)。在第一个示例中,我使用
sent_tokenize 将文本分解为各个句子(使用句点或句号 [.] 作为边界)。在第二个示例中,我使用 word_tokenize
将文本分解为各个单词(基于空格和标点)。句子和单词列表的长度与一个随机句子和单词一起呈现出来(作为总大小的函数)。
对一个样本语料库执行标记化 (tokens.py)
上面的 Python 脚本的输出如下所示。可以看到,样本文本由 4,901 个句子和 179,661 个单词组成。
来自tokens.py 的标记化脚本的输出
标记化通常是处理文本集合的第一步。在下一个示例中,我将介绍
NLTK 中识别语料库中最常见单词和符号的内置功能。NLTK 包含一个名为 FreqDist
的频率分布类,可以识别在文本中找到的每个标记(单词或标点)的频率。这些标记被存储为元组,其中包含单词及其在文本中出现的次数。在这个示例中,我们使用了
NTLK 内的文本(text7 指的是 The Wall Street Journal 语料库)。我调用 most_common
函数来将输出的元组限制为前 8 个,然后输出这个集合。下边给出了相关代码。
找到最常见的单词和符号 (most_common.py)
most_common.py的输出如下所示。从这里,可以看到样本文本被导入到了 Python 中;最后两行表示最常见标记的输出。毫不奇怪,像逗号 (,) 和句点这样的标点在列表中位于靠前的位置,定冠词 the 也是如此。
来自most_common.py 脚本的输出
在最后一个基本分析示例中,让我们来看看标签。NLTK 包含词性标签器,使我们能够将句子划分到它的词类中(名词、动词等)。此特性通过将语言分解为各个构成部分,形成了自然语言处理的基础。可以使用此功能来开发问答应用程序,并执行情感分析。
下边提供了一个使用
NLTK 的 POS 标签器的简单脚本。我们从 Project Gutenberg
读取物种起源并随机挑选一个句子。该句子被标记化为不同单词,然后通过调用 pos_tag
来添加标签。该脚本输出了以下结果,该结果表示一组元组(单词、标签)。
POS 标签示例
下边提供了
POS 标签示例的输出。首先呈现的是未添加标签的句子,然后是单词/标签元组集合。请注意,标签可能是多种多样的,但在此示例中,它们是人称代词
(PRP)、过去时态动词 (VBD)、介词或连词 (IN)、限定词 (DT)、副词 (RB)、形容词 (JJ)、常用名词复数 (NNS)
和专有名词单数 (NNP)。可以通过调用 nltk.help.upenn_tagset() 来查看 NLTK 中的完整标签集合。
来自POS 标签示例脚本的输出
接下来,我们将深入研究两个更复杂的示例和它们的应用:马尔可夫链和情感分析。
马尔可夫链
马尔可夫链是一个随机模型,用于描述事件的序列,其中某个给定事件的发生概率取决于前一个事件的状态。换言之,对于一个给定状态,可以根据当前状态来预测未来状态。这听起来很简单,但在各种各样的应用中特别有用,包括语音识别、强化学习、预测、DNA 测序和压缩。
一种马尔可夫模型称为“N连词”,它指的是一个符号序列(比如一句话中的单词)。一种简单的 N 连词是双连词,这是一个大小为 2 的 N 连词。如果双连词指的是一对相邻符号,那么三连词指的就是 3 个相邻符号。让我们看看双连词有多有用。
考虑样本句子“I am Sam, Sam I am.”从这句话(忽略标点),可以生成 5 个双连词,一个双连词从一个单词开始并包含下一个单词。第一个单词可以视为当前状态;第二个单词表示预测的下一个状态(参见下图)。
双连词列表和图表样本
所以,如果我们从一个随机单词开始,根据某个概率来选择下一个单词(在本例中,Sam
后面出现它本身的概率为 P(0.5),出现 I 的概率为 P(0.5)),我们可以按样本语料库的样式构造随机句子。从 am 开始并限制到 3
个单词,我们可以生成 {'am', 'Sam', 'Sam'} 或 {'am', 'Sam',
'I'}。这并不仅仅是有趣,但是现在要考虑从一整本书中生成双连词。最终,我们会获得数千个双连词,而且还能生成更合理的句子。下边展示了两个使用来自物种起源的双连词构造的样本句子(通过下边
Python 脚本生成)。
从物种起源生成的句子
我们将把下边的 markov.py 脚本拆分为 3 部分。第一部分是 CreateTuples 函数,它接受一些单词并将它们分解为元组(或双连词)。这些双连词被添加到一个集合中并返回。
第
2 部分是句子生成器,它接受一种条件频率分布(即由单词以及后跟原始单词及其计数的单词组成的列表)。我们从一个初始单词开始(在本例中为
I)并创建我们的句子。然后,我们将迭代 CFD
来生成下一个单词,直到该单词是一个句点(表示句子结束)。我们迭代目标单词后的单词分布,并随机挑选一个单词。这个单词被附加到我们的句子后面,而且所选单词变成了目标单词(我们再次开始这一过程,以查找后续单词)。然后呈现所构造的句子。
在第
3 部分中,我们将处理各种设置。我们从 Project Gutenberg 网站读取物种起源,将文本标记化为一个单词数组,然后将这个数组传递给
CreateTuples 来生成我的双连词。我们使用 NLTK 的 nltk.ConditionalFreqDist 来构造 CFD,然后将此
CFD 传递给
EmitSentence,以便使用已生成的双连词作为概率性引导来生成一个随机句子。从语料库生成的一些句子富有启发性,但是许多可能很长且毫无意义。将我们的示例从双连词扩展到三连词,会增加获得有意义句子的几率。
使用 NLTK 和双连词来构造句子 (markov.py)
此方法很有用处。在字母级别上,我们可以识别单词拼写错误并进行更正。也可以使用双连词或三连词来识别给定作品、给定隐藏签名的文本的作者(单词选择、频率、构造)。
情感分析
在最后一个示例中,我们将介绍情感分析领域。情感分析或观点挖掘是通过计算来识别作者对某段文本的态度是积极、消极还是中性的过程。此反馈可能很有用,比如在自然语言评论中挖掘对某款产品或服务的观点时。
NTLK
包含一个简单的基于规则的情感分析模型,其中组合了词汇特征来识别情感强度。它的使用也很简单。下边 给出了使用 NLTK
情感分析器的样本脚本。我导入必要模块(包括 Vader 情感分析器),创建一个函数来接受某个句子并呈现情感分类。该函数首先对
SentimentIntensityAnalyzer 执行实例化,然后使用传递的句子来调用 polarity_scores
方法。结果是一组浮点值,表示输入文本的正或负价态。这些浮点值是为 4
个类别(正、中性、负和表示一个聚合分数的化合态)而发出的。该脚本最后调用传递的参数来识别情感。
使用 NLTK 执行情感分析 (sentiment.py)
现在来看看如何将NLTK的情感分析器用于一组句子。下边提供了与sentiment.py
中的脚本的一些交互,以及来自情感分析器的输出。第一个句子显然是积极的,第二个句子显然是消极的。两个示例都已正确分类。但是第三个示例演示了分析讽刺语言时可能存在问题(尽管它同时对句子的积极和消极组成部分进行了分类)。
来自sentiment.py的情感分析器脚本的样本输出
当然大多数与财经有关的舆情文本简单直接,会比分析一些修辞复杂的文本更为容易。
情感分析有许多应用,而且考虑到在线内容(博客、推文和其他信息)的不断增加,该方法可成功用于挖掘实时反馈中的观点。
— — — — — — E N D — — — — — —
往期文章:
真格量化可访问:
真格量化微信公众号,长按关注:
遇到了技术问题?欢迎加入真格量化Python技术交流QQ群 726895887