文本向量化初学者指南

更多深度文章,请关注云计算频道:https://yq.aliyun.com/cloud

自然语言处理(NLP)诞生之初,需要将文本转换成机器可以理解的东西。换句话说,就是将文本转换为有意义的数字向量(或数组)。但是在深度学习的时代,我们只需用一个词袋就可以达到上述操作的效果。

1、词袋

这种方法虽然功能强大但是其背后的理念很简单。首先,我们需要定义一个固定长度向量,其中每个条目和我们预定义的词典中的单词相对应。向量的大小等于字典的大小。然后,我们只需计算出字典里的每一个单词在文本中出现的次数,再将这个数字放在相应的向量项中,这样所得到的向量就表示一个文本。

例如,如果我们的字典包含单词{MonkeyLearn,is,the,not,great},我们想要向量化文本“MonkeyLearn
is great”,我们将会有以下向量:(1,1,0,0, 1)。

为增强它的表现能力,你可以使用一些更先进的技术,如去除省略词lemmatizing word,使用n-gram或使用TF-IDF,来代替计数。

但是这种方法即使使用n-gram,它也不会真正捕捉到文本的含义或单词出现的语境。

2、深度学习正在改变文本向量化

目前,深度学习已经接管了机器学习,它做了很多改变文本向量化方式的尝试,并找到更好的方式来表示文本。

为解决上述问题首先需要找到一种向量化单词(vectorize words)的方式,word2vec的实现为解决这个问题起到了很大的作用,也因此在2013年之后变得非常受欢迎。通过使用大量数据,可以让神经网络学习一些具有理想属性词的向量表示。例如,使用word2vec,您可以执行“king” -
“man”+“woman”,结果会得到一个与向量“Queen”非常相似的向量。这看起来有点魔幻,但是通过这个博客,你将会发现这是有可能发生的。这些向量的每一个维度可以编码出该单词的不同属性,这对于执行和NLP相关的许多任务是有用的。例如,据此你可以描述出该单词是动词还是名词,或者该单词是否为复数形式。

下一步是获取整个句子的向量化,这对于文本分类非常有用。尽管如此这个问题还是没有完全解决,但是在过去几年里,像Skip-Thought Vectors类似技术的实现,在该方面还是取得了很大的进展。

3、转移学习

在机器学习领域,转移学习是指机器将在一个任务中得到的学习观念运用到另一个任务中的能力。对于你面临的每个新问题,你需要从头开始执行所有向量化,这是通过词袋方法进行文本向量化的过程中存在一个问题。

这个问题在人与人的交往中并不存在,我们知道某些词的含义可能随着不同的背景而改变,但是我们不需要每次遇到这个词都重复学习一遍。

而深度学习则具有能够在多个不同问题中使用的文本向量化的能力,不必一次又一次地重复学习。

4、Skip-Thought向量

在这个方向上有很多人研究,其中多伦多大学开发的Skip-Thoughts向量是最好的研究成果之一。在这里你可以了解到Theano这种算法是如何实现的。

这个算法的想法如下:我们可以通过使用一个试图预测一个单词的周围单词的神经网络来获得一个向量表示,然后以同样的方式用一个神经网络预测句子周围的句子。为了得到更好地效果,他们需要在BookCorpus数据集中(这是一些作者编写的尚未发表的免费书)找到大量连续的文本数据。

在他们的论文中,他们表明这些句子向量可以用作非常强大的文本表示。我们将在文本分类问题中尝试这一点,看看它是否值得在现实世界中使用它。

5、一个小例子

接下来我们打算使用本文中给出的Scikit-Learnskip-thoughts算法(使用Theano)将Skip-Thoughts和Bag of Words进行比较。我们使用航空情报数据集作为实验对象、用精度作为评估分类结果的指标。首先我们需要加载数据,并我们将数据集分为两个,然后进行训练和测试:

import csv
import random
 # Load training data
f = open('train.csv')
train_rows = [row for row in csv.reader(f)][1:]  # discard the first row
random.shuffle(train_rows)
tweets_train = [row[0].decode('utf8') for row in train_rows]
classes_train = [row[1] for row in train_rows]
 # Load testing data
f = open('test.csv')
test_rows = [row for row in csv.reader(f)][1:]  # discard the first row
tweets_test = [row[0].decode('utf8') for row in test_rows]
classes_test = [row[1] for row in test_rows]

现在我们将定义一个向量化分类,稍后将在scikit-learn管道中使用:

import skipthoughts
 class SkipThoughtsVectorizer(object):
def __init__(self, **kwargs):
     self.model = skipthoughts.load_model()
     self.encoder = skipthoughts.Encoder(self.model)
def fit_transform(self, raw_documents, y):
     return self.encoder.encode(raw_documents, verbose=False)
def fit(self, raw_documents, y=None):
     self.fit_transform(raw_documents, y)
     return self
def transform(self, raw_documents, copy=True):
     return self.fit_transform(raw_documents, None)

我们将定义三个scikit-learn管道。一个使用我们的(Skip Thoughts Vectorizer),另一个使用TF-IDF袋子的n-gram方法,另外一个使用两者的组合。在他们三个中,我们将使用一个非常简单的Logistic回归模型对我们的数据进行分类。

from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.linear_model import LogisticRegression
from sklearn.feature_extraction.text import TfidfVectorizer

pipeline_skipthought = Pipeline(steps=[('vectorizer', SkipThoughtsVectorizer()), ('classifier', LogisticRegression())])
pipeline_tfidf = Pipeline(steps=[('vectorizer', TfidfVectorizer(ngram_range=(1, 2))),('classifier', LogisticRegression())])
feature_union = ('feature_union', FeatureUnion([
('skipthought', SkipThoughtsVectorizer()),
('tfidf', TfidfVectorizer(ngram_range=(1, 2))),
]))
pipeline_both = Pipeline(steps=[feature_union,
 ('classifier', LogisticRegression())])

最后,我们将对这三条管道用不同大小的数据集对模型进行多次训练,并将它们分开进行测试。我们看看通过用大量的数据训练是否会影响算法的准确性。

for train_size in (20, 50, 100, 200, 500, 1000, 2000, 3000, len(tweets_train)):
print(train_size, '--------------------------------------')
# skipthought
pipeline_skipthought.fit(tweets_train[:train_size], classes_train[:train_size])
print ('skipthought', pipeline_skipthought.score(tweets_test, classes_test))

# tfidf
pipeline_tfidf.fit(tweets_train[:train_size], classes_train[:train_size])
print('tfidf', pipeline_tfidf.score(tweets_test, classes_test))

# both
pipeline_both.fit(tweets_train[:train_size], classes_train[:train_size])
print('skipthought+tfidf', pipeline_both.score(tweets_test, classes_test))

通过下面的图表,我们可以看到在模型运行中精度随着更多数据的加入而出现增长的现象。

您可以在这里得到复制这些结果的完整代码。

6、结果

当可以训练的数据不多(从0到5000个样本)时,由于Skip-Thoughts方法已经有了一些关于单词含义的信息,因此它能利用这些信息提供出比n-grams袋更好的分类结果。由此可以看出,在这项任务中我们利用转移学习,有效地提高了我们的结果。

从另一方面来说,n-grams袋的方法能够更好的“理解”这个数据集特定的信息,虽然有一些关于单词含义的信息可以用来做分类,但是相对的数据集本身,具体信息更有用。因此,当给出完整的训练数据集时,n-grams袋要比另一种方法做的好。

由此可以看到,Skip-Thoughts和n-grams袋在训练数据集信息上具有互补的作用。Skip-Thoughts方法是对于单词含义的一般认识,而n-grams袋中具有更多数据集的特定信息。将这两种方法结合起来,能够提高模型的准确性。

7、文本向量化的未来

转移学习是一个活跃的研究领域,很多大学和公司都在尝试在文本向量化中做出新的成果。最近的一些研究包括Salesforce CoVe,他们已经成功的将机器在翻译任务期间学习的信息构建成文本向量,用于完成之后的分类或问答等任务。

Facebook的InferSent使用类似的方法。但是,他们是运用一个神经网络来学习如何对斯坦福自然语言推理(SNLI)语料库进行分类,这样做的同时,他们也得到了很好的文本向量化的结果。

在不久的将来,我们可能真的会找到一种让机器“理解”人类语言的方法,这将颠覆我们的生活方式。但在那之前,我们还有很长的路要走。

本文由北邮@爱可可-爱生活 老师推荐,阿里云组织翻译。

文章原标题《The Beginner’s Guide to Text Vectorization》

作者:Rodrigo
Stecanella

译者:乌拉乌拉,审校:袁虎。

文章为简译,更为详细的内容,请查看原文文章


时间: 2024-09-18 06:53:20

文本向量化初学者指南的相关文章

《C#初学者指南》一导读

前言 C#初学者指南 欢迎阅读本书. C#(读作"c sharp")是一种易学的.成熟的编程语言.同时,它也是.NET Framework 的一部分..NET Framework是很大的一个技术集合,它包罗万象,以至于初学者往往不知从何入手.如果你也是一名初学者,那么本书非常适合你,因为本书就是专门为.NET初学者所编写的教程. 作为初学者的教程,本书并不会介绍.NET Framework中的每一种技术.相反,本书涵盖C#和.NET Framework 语言中最重要的主题,掌握了这些内

《C#初学者指南》一第1章 初识C#

第1章 初识C C#初学者指南 开发一款C#程序,包括编写代码.把它编译成通用中间语言(Common Intermediate Language ,CIL)编码以及运行CIL编码.作为一名C#程序员,你会不断地重复这个过程,而熟悉和习惯这个过程也是至关重要的.因此,本章的主要目标是,帮助你体验在Visual Studio Express 2012 for Windows Desktop 或Visual C# 2010 Express这两种免费的微软IDE中使用C#来进行软件开发的过程. 编写的代

《C语言编程初学者指南》一第1章 C编程入门

第1章 C编程入门 C语言编程初学者指南 欢迎阅读本书.C 编程语言是培养你的编程职业技能和爱好的一门优秀的基础语言.不管你是计算机专业的学生.自学成才的程序员,或者是一名资深的软件工程师,学习C语言都能够给你丰富的概念知识并培养实践技能,从而很好地帮助你理解其他的计算机相关主题(包括操作系统概念.内存管理和其他高级的编程语言). 在整个本书中,我将引导你学习一系列的示例,这些示例设计来讲解C编程的基础知识.我假设读者没有C编程的经验,也不了解计算机科学的基本概念.阅读本书不需要任何的经验(包括

《C语言编程初学者指南》一导读

前言 C语言编程初学者指南 C语言是一种强大的基于过程的编程语言,它于1972年由Dennis Ritchie在贝尔实验室发明.C语言最初是开发来用于UNIX平台的,但却已经扩展到很多其他的系统和应用中.C语言还影响了很多其他的编程语言,例如C++和Java. 编程初学者,特别是那些进入计算机科学和工程专业学习的人,需要构建有关操作系统.硬件和应用程序开发概念的牢固基础知识.很多的学院教授学生学习如何用C编程,从而使他们能够学习高级概念以及在C的基础上建立起来的其他语言. 学习C语言的很多学生也

《C语言编程——零基础初学者指南(第3版)》一1.3 编程过程

1.3 编程过程 C语言编程--零基础初学者指南(第3版)绝大多数程序员在编写程序时,都按照以下几个基本步骤进行. 确定程序要做什么. 使用编辑器(editor)编写并保存你的程序设计语言指令.编辑器类似于文字处理软件,可以创建和编辑文本.所有流行的C编译器都包含一个集成编辑器和程序设计语言编译器.所有的C程序文件名都以 .c扩展名结束. 编译程序. 检查程序错误.如果出现错误,将其逐一修复并返回步骤3. 执行程序. 注意 计算机程序中的错误被称为bug,处理错误称为调试(debug)程序.花点

《C语言编程——零基础初学者指南(第3版)》一1.2 编写C语言程序需要什么

1.2 编写C语言程序需要什么 C语言编程--零基础初学者指南(第3版)在计算机上编写并执行C语言程序之前,需要一个C编译器(C compiler).C编译器用于创建(build)或编译(compile)C程序(编译是一个技术术语,指将程序转换为计算机可读的内容),让你在需要查看结果时可以运行已编译的程序.现在有许多非常优秀且免费的软件包,可以用它们来编辑并编译你的C程序.通过网络搜索即可找到诸多这样的软件.本书使用的是Code::Blocks(www.codeblocks.org ). 提示

RMAN 初学者指南

初学 RMAN 初学者指南 转自聚贤庄 作者:gototop ============================================ 这篇文章是去年写的了,最初发表在chinaunix.net的oracle论坛里,收录在旧版文集中,可能很多没有看到,总有人写信要,今天乘改版之际就把它单独拿出来了.(gototop 2003.6.24注)   RMAN(Recovery Manager)是DBA的一个重要工具,用于备份.还原和恢复oracle数据库,前一段时间有网友找我要,可惜没

RMAN初学者指南

RMAN初学者指南    RMAN(Recovery Manager)是DBA的一个重要工具,用于备份.还原和恢复oracle数据库,前一段时间有网友找我要,可惜没时间,趁这两天出差在外没什么事,就写了一下,供初学的朋友参考.本文将介绍RMAN的基本操作,更多的信息请参考<Oracle8i Backup & Recovery  Guide>及RMAN手册,或者是OCP Student Guide M09096<Backup and Recovery Workshop>Vol

《SQL初学者指南》——1.8 空值

1.8 空值 SQL初学者指南 表中每个单独列的另一个重要属性是,该列是否允许包含空值.空值表示某个特定的数据元素没有数据.按照字面意思解释就是没包含数据.空值不等同于空格或空白.从逻辑上讲,空值和空格要区分对待.在第8章中,我们会详细介绍如何检索包含空值的数据. 许多SQL数据库在显示带有空值的数据时,使用大写的单词NULL来表示.这么做是要让用户能够识别它包含的是一个空值,而不是一个空格.我也会遵循这个惯例,在书中用NULL来强调它表示一个特殊类型的值. 数据库的主键不能包含NULL值.这是