前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何准备电影评论数据进行情感分析

如何准备电影评论数据进行情感分析

作者头像
anthlu
修改2018-02-07 17:18:07
4.2K0
修改2018-02-07 17:18:07
举报
文章被收录于专栏:AI

每个问题的文本数据准备是不同的。

准备工作从简单的步骤开始,比如加载数据,但是对于正在使用的数据非常特定的清理任务很快就会变得很困难。您需要从何处开始,以及通过从原始数据到准备建模的数据的步骤来执行什么操作。

在本教程中,您将逐步了解如何为情感分析准备电影评论文本数据。

完成本教程后,您将知道:

  • 如何加载文本数据并清理它以去除标点符号和其他非单词。
  • 如何开发词汇,定制词汇,并将其保存到文件中。
  • 如何使用干净的和预定义的词汇来准备电影评论,并将其保存到可供建模的新文件中。

让我们开始吧。

  • 2017年10月更新:修正了跳过不匹配文件的小错误,感谢Jan Zett。
  • 2017年12月更新:修正了一个小错字,感谢Ray和Zain。
如何准备电影评论数据进行情感分析  照片来自Kenneth Lu,保留一些权利。
如何准备电影评论数据进行情感分析 照片来自Kenneth Lu,保留一些权利。

教程概述

本教程分为5个部分; 他们是:

  1. 电影评论数据集
  2. 加载文本数据
  3. 清理文本数据
  4. 开发词汇
  5. 保存准备好的数据

1.电影评论数据集

“电影评论数据”是由Bo Pang和Lillian Lee于21世纪初从imdb.com网站上收集的电影评论。这些评论被收集并作为自然语言处理研究的一部分提供。

评论最初是在2002年发布的,但2004年发布了一个更新和清理的版本,称为“ v2.0 ”。

该数据集由IMDB托管的rec.arts.movi​​es.reviews新闻组档案中的1,000个正面评论和1,000个负面评论组成。作者将这个数据集称为“ 极性数据集 ”。

我们的数据包含了所有在2002年之前编写的1000个正面评论和1000个负面评论,每个作者每篇作者共有20篇评论(共312位作者)。我们将这个语料库称为极性数据集。

- 情感教育:基于最小切割的主观性总结的情感分析,2004。

数据已经被清理了一些,例如:

  • 数据集仅包含英文评论。
  • 所有的文本都被转换成了小写字母。
  • 标点符号周围有空格,逗号和括号。
  • 文本每行被分成一个句子。

这些数据已被用于一些相关的自然语言处理任务。对于分类,经典模型(如支持向量机)对数据的性能在70%到80%(例如78%到82%)的范围内。

通过10倍交叉验证,更复杂的数据准备可能会看到高达86%的结果。如果我们希望在现代方法的实验中使用这个数据集,那么这就给了我们一个80年代中期的概念。

... ...取决于下游极性分类器的选择,我们可以达到统计学高度的显著改善(从82.8%至86.4%)

- 情感教育:基于最小切割的主观性总结的情感分析,2004。

你可以从这里下载数据集:

解压文件后,你将会得到一个名为“ txt_sentoken ”的目录,其中有两个子目录,分别是负面和正面评论的文字“ neg ”和“ pos ”。每个评论文件存储即每个neg和pos有一个命名约定cv000cv999

接下来,让我们看看加载文本数据。

2.加载文本数据

在本节中,我们将着眼于加载单个文本文件,然后处理文件的目录。

我们将假定评论数据被下载并在文件夹“ txt_sentoken ” 中的当前工作目录中可用。

我们可以通过打开它,读取ASCII文本再关闭文件来加载单个文本文件。这是标准的文件处理方法。例如,我们可以加载第一个负面评论文件“ cv000_29416.txt ”,如下所示:

代码语言:js
复制
# 加载单个文件
filename = 'txt_sentoken/neg/cv000_29416.txt'
# 以只读方式打开文件
file = open(filename, 'r')
# 读取所有文本
text = file.read()
# 关闭文件
file.close()

这将文档加载为ASCII并保留任何空白,如新行。

我们可以把它变成一个名为load_doc()的函数,它接受文档的文件名来加载并返回文本。

代码语言:js
复制
# 加载文档到内存
def load_doc(filename):
	# 以只读方式打开文件
	file = open(filename, 'r')
	# 读取所有文本
	text = file.read()
	# 关闭文件
	file.close()
	return text

我们有两个目录,每个目录有1000个文件。我们可以依次处理每个目录,首先使用 listdir()函数 获取目录中的文件列表,然后依次加载每个文件。

例如,我们可以使用load_doc()函数加载负面评论目录中的每个文档。

代码语言:js
复制
from os import listdir
 
# 加载文档到内存
def load_doc(filename):
    # 以只读方式打开文件
    file = open(filename, 'r')
    # 读取所有文本
    text = file.read()
    # 关闭文件
    file.close()
    return text
 
# 指定目录加载
directory = 'txt_sentoken/neg'
# 遍历文件夹中的所有文件
for filename in listdir(directory):
    # 跳过没有正确扩展名的文件
    if not filename.endswith(".txt"):
        continue
    # 创建要打开的文件的完整路径
    path = directory + '/' + filename
    # 加载文档
    doc = load_doc(path)
    print('Loaded %s' % filename)

运行此示例打印每个已加载的评论文件的文件名。

代码语言:js
复制
...
Loaded cv995_23113.txt
Loaded cv996_12447.txt
Loaded cv997_5152.txt
Loaded cv998_15691.txt
Loaded cv999_14636.txt

我们可以将文档的处理转换为一个函数,稍后将其用作模板来开发一个函数来清理文件夹中的所有文档。例如,下面我们定义一个process_docs()函数来做同样的事情。

代码语言:js
复制
from os import listdir
 
# 加载文档到内存
def load_doc(filename):
    # 以只读方式打开文件
    file = open(filename, 'r')
    # 读取所有文本
    text = file.read()
    # 关闭文件
    file.close()
    return text
 
# 加载目录中所有文档
def process_docs(directory):
    # 遍历文件夹中的所有文件
    for filename in listdir(directory):
        # 跳过没有正确扩展名的文件
        if not filename.endswith(".txt"):
            continue
        # 创建要打开的文件的完整路径
        path = directory + '/' + filename
        # 加载文档
        doc = load_doc(path)
        print('Loaded %s' % filename)
 
# 指定目录加载
directory = 'txt_sentoken/neg'
process_docs(directory)

现在我们知道如何加载电影评论文本数据,让我们看看如何来清理它。

3.清理文本数据

在本节中,我们来看看我们可能想要对电影评论数据进行哪些数据清理。

我们将假设我们将使用一个词袋模型或者一个嵌入的词,而不需要太多的准备。

拆分为词条

首先,我们加载一个文件,看看由空格分割的原始词条。我们将使用前一节中开发的load_doc()函数。我们可以使用split()函数将加载的文档分割成由空格分隔的词条。

代码语言:js
复制
# 加载文档到内存
def load_doc(filename):
    # 以只读方式打开文件
    file = open(filename, 'r')
    # 读取所有文本
    text = file.read()
    # 关闭文件
    file.close()
    return text
 
# 加载文档
filename = 'txt_sentoken/neg/cv000_29416.txt'
text = load_doc(filename)
# 以空格来拆分词条
tokens = text.split()
print(tokens)

运行这个例子给出了一个很好的来自文档的原始词条的列表。

代码语言:js
复制
 'years', 'ago', 'and', 'has', 'been', 'sitting', 'on', 'the', 'shelves', 'ever', 'since', '.', 'whatever', '.', '.', '.', 'skip', 'it', '!', "where's", 'joblo', 'coming', 'from', '?', 'a', 'nightmare', 'of', 'elm', 'street', '3', '(', '7/10', ')', '-', 'blair', 'witch', '2', '(', '7/10', ')', '-', 'the', 'crow', '(', '9/10', ')', '-', 'the', 'crow', ':', 'salvation', '(', '4/10', ')', '-', 'lost', 'highway', '(', '10/10', ')', '-', 'memento', '(', '10/10', ')', '-', 'the', 'others', '(', '9/10', ')', '-', 'stir', 'of', 'echoes', '(', '8/10', ')']

只要看一下原始词条就可以给我们很多想要尝试的想法,比如:

  • 从单词中删除标点符号(例如 'what's')
  • 删除仅标点符号的词条(例如 '-')
  • 删除包含数字的词条(例如 '10/10')
  • 删除具有一个字符的词条(例如 'a')
  • 删除没有太多意义的词条(例如 'and')

一些想法:

  • 我们可以使用字符串translate()函数从标记中过滤掉标点符号。
  • 我们可以通过在每个词条上使用isalpha()检查来移除标点符号或包含数字的词条。
  • 我们可以使用使用NLTK加载的列表来删除英文停用词。
  • 我们可以通过检查它们的长度来过滤掉短的词条。

以下是清理此评论的更新版本。

代码语言:js
复制
from nltk.corpus import stopwords
import string
 
# 加载文档到内存
def load_doc(filename):
    # 以只读方式打开文件
    file = open(filename, 'r')
    # 读取所有文本
    text = file.read()
    # 关闭文件
    file.close()
    return text
 
# 加载文档
filename = 'txt_sentoken/neg/cv000_29416.txt'
text = load_doc(filename)
# 以空格来拆分词条
tokens = text.split()
# 从每个词条中移除标点符号
table = str.maketrans('', '', string.punctuation)
tokens = [w.translate(table) for w in tokens]
# 从剩余词条中移除非字母的项
tokens = [word for word in tokens if word.isalpha()]
# 过滤出停用词
stop_words = set(stopwords.words('english'))
tokens = [w for w in tokens if not w in stop_words]
# 过滤出短的词条
tokens = [word for word in tokens if len(word) > 1]
print(tokens)

运行这个例子给出了一个看起来更清晰的词条列表

代码语言:js
复制
 'explanation', 'craziness', 'came', 'oh', 'way', 'horror', 'teen', 'slasher', 'flick', 'packaged', 'look', 'way', 'someone', 'apparently', 'assuming', 'genre', 'still', 'hot', 'kids', 'also', 'wrapped', 'production', 'two', 'years', 'ago', 'sitting', 'shelves', 'ever', 'since', 'whatever', 'skip', 'wheres', 'joblo', 'coming', 'nightmare', 'elm', 'street', 'blair', 'witch', 'crow', 'crow', 'salvation', 'lost', 'highway', 'memento', 'others', 'stir', 'echoes']

我们可以把它放到一个名为clean_doc()的函数中,并在另一个评论中进行测试,这次是一个正面的评论。

代码语言:js
复制
from nltk.corpus import stopwords
import string
 
# 加载文档到内存
def load_doc(filename):
    # 以只读方式打开文件
    file = open(filename, 'r')
    # 读取所有文本
    text = file.read()
    # 关闭文件
    file.close()
    return text
 
# 将文档变成干净的词条
def clean_doc(doc):
    # 以空格来拆分词条
    tokens = doc.split()
    # 从每个词条中移除标点符号
    table = str.maketrans('', '', string.punctuation)
    tokens = [w.translate(table) for w in tokens]
    # 从剩余词条中移除非字母的项
    tokens = [word for word in tokens if word.isalpha()]
    # 过滤出停用词
    stop_words = set(stopwords.words('english'))
    tokens = [w for w in tokens if not w in stop_words]
    # 过滤出短的词条
    tokens = [word for word in tokens if len(word) > 1]
    return tokens
 
# 加载文档
filename = 'txt_sentoken/pos/cv000_29590.txt'
text = load_doc(filename)
tokens = clean_doc(text)
print(tokens)

再次,清理程序似乎产生了一套很好的词条,至少作为第一次的切割。

代码语言:js
复制
 'comic', 'oscar', 'winner', 'martin', 'childs', 'shakespeare', 'love', 'production', 'design', 'turns', 'original', 'prague', 'surroundings', 'one', 'creepy', 'place', 'even', 'acting', 'hell', 'solid', 'dreamy', 'depp', 'turning', 'typically', 'strong', 'performance', 'deftly', 'handling', 'british', 'accent', 'ians', 'holm', 'joe', 'goulds', 'secret', 'richardson', 'dalmatians', 'log', 'great', 'supporting', 'roles', 'big', 'surprise', 'graham', 'cringed', 'first', 'time', 'opened', 'mouth', 'imagining', 'attempt', 'irish', 'accent', 'actually', 'wasnt', 'half', 'bad', 'film', 'however', 'good', 'strong', 'violencegore', 'sexuality', 'language', 'drug', 'content']

还有更多的清理步骤,我们可以使用,但我留下给你们想。

接下来,我们来看看如何管理词条的首选词汇表。

4.开发词汇

在处理文本的预测模型时,如词袋模型,减小词汇量的大小是有压力的。

词汇越大,每个单词或文档的表示越稀疏。

为情感分析准备文本的一部分涉及定义和剪裁模型支持的单词的词汇。

我们可以通过加载数据集中的所有文档并构建一组单词来实现这一点。我们可能决定支持所有这些话,或者放弃一些话。然后可以将最终选择的词汇保存到文件中供以后使用,例如以后在新文档中过滤词语。

我们可以跟踪计数器中的词汇,这是一个单词词典和他们的计数与一些额外的便利功能。

我们需要开发一个新的功能来处理一个文档并将其添加到词汇表中。该函数需要通过调用之前开发的load_doc()函数来加载文档。它需要使用先前开发的clean_doc()函数清理加载的文档,然后它需要将所有的词条添加到计数器,并更新计数。我们可以通过调用counter对象上的update()函数来完成最后一步。

下面是一个名为add_doc_to_vocab()的函数,它将文档文件名和计数器词汇作为参数。

代码语言:js
复制
# 加载文档并添加到词汇表中
def add_doc_to_vocab(filename, vocab):
    # 加载文档
    doc = load_doc(filename)
    # 清理文档
    tokens = clean_doc(doc)
    # 更新计数
    vocab.update(tokens)

最后,我们可以使用上面的模板来处理名为process_docs()的目录中的所有文档,并更新它以调用add_doc_to_vocab()

代码语言:js
复制
# 加载目录中的所有文档
def process_docs(directory, vocab):
    # 遍历文件夹中的所有文件
    for filename in listdir(directory):
        # 跳过没有正确扩展名的文件
        if not filename.endswith(".txt"):
            continue
        # 创建要打开的文件的完整路径
        path = directory + '/' + filename
        # 加载文档到词汇表中
        add_doc_to_vocab(path, vocab)

我们可以将所有这些放在一起,并从数据集中的所有文档开发完整的词汇表。

代码语言:js
复制
from string import punctuation
from os import listdir
from collections import Counter
from nltk.corpus import stopwords
 
# 加载文档到内存
def load_doc(filename):
    # 以只读方式打开文件
    file = open(filename, 'r')
    # 读取所有文本
    text = file.read()
    # 关闭文件
    file.close()
    return text
 
# 将文档变成干净的词条
def clean_doc(doc):
    # 以空格来拆分词条
    tokens = doc.split()
    # 从每个词条中移除标点符号
    table = str.maketrans('', '', punctuation)
    tokens = [w.translate(table) for w in tokens]
    # 从剩余词条中移除非字母的项
    tokens = [word for word in tokens if word.isalpha()]
    # 过滤出停用词
    stop_words = set(stopwords.words('english'))
    tokens = [w for w in tokens if not w in stop_words]
    # 过滤出短的词条
    tokens = [word for word in tokens if len(word) > 1]
    return tokens
 
# 加载文档并添加到词汇表中
def add_doc_to_vocab(filename, vocab):
    # 加载文档
    doc = load_doc(filename)
    # 清理文档
    tokens = clean_doc(doc)
    # 更新计数
    vocab.update(tokens)
 
# 加载目录中所有文档
def process_docs(directory, vocab):
    # 遍历文件夹中的所有文件
    for filename in listdir(directory):
        # 跳过没有正确扩展名的文件
        if not filename.endswith(".txt"):
            continue
        # 创建要打开的文件的完整路径
        path = directory + '/' + filename
        # 添加文档到词汇表
        add_doc_to_vocab(path, vocab)
 
# 定义vocab
vocab = Counter()
# 添加所有文档到词汇表中
process_docs('txt_sentoken/neg', vocab)
process_docs('txt_sentoken/pos', vocab)
# 打印词汇表的大小
print(len(vocab))
# 打印词汇表中的热门单词
print(vocab.most_common(50))

运行示例将创建包含数据集中所有文档的词汇表,包括正面和负面评论。

我们可以看到,在所有的评论中有超过46000个独特的单词,前三个单词是'film', 'one''movie'

代码语言:js
复制
 46557
[('film', 8860), ('one', 5521), ('movie', 5440), ('like', 3553), ('even', 2555), ('good', 2320), ('time', 2283), ('story', 2118), ('films', 2102), ('would', 2042), ('much', 2024), ('also', 1965), ('characters', 1947), ('get', 1921), ('character', 1906), ('two', 1825), ('first', 1768), ('see', 1730), ('well', 1694), ('way', 1668), ('make', 1590), ('really', 1563), ('little', 1491), ('life', 1472), ('plot', 1451), ('people', 1420), ('movies', 1416), ('could', 1395), ('bad', 1374), ('scene', 1373), ('never', 1364), ('best', 1301), ('new', 1277), ('many', 1268), ('doesnt', 1267), ('man', 1266), ('scenes', 1265), ('dont', 1210), ('know', 1207), ('hes', 1150), ('great', 1141), ('another', 1111), ('love', 1089), ('action', 1078), ('go', 1075), ('us', 1065), ('director', 1056), ('something', 1048), ('end', 1047), ('still', 1038)]

也许最不常用的词,那些在所有评论中只出现一次的词,都不是预测性的。也许一些最常用的词语也没用。

这些都是很好的问题,应该用一个特定的预测模型进行测试。

一般而言,在2000条评论中只出现一次或几次的词语可能不具有预测性,可以从词汇表中删除,大大减少了我们需要建模的词条。

我们可以通过单词和他们的计数且只有在计数高于所选阈值的情况下才能做到这一点。这里我们将使用5次发生。

代码语言:js
复制
# 保持词条出现次数 > 5
min_occurane = 5
tokens = [k for k,c in vocab.items() if c >= min_occurane]
print(len(tokens))

这将词汇量从46557个大幅下降到14803个单词。也许最少有五次是过于激进的; 你可以尝试不同的值。

然后,我们可以将所选单词的词汇保存到一个新文件中。我喜欢将这个由每行一个单词组成的词汇表保存为ASCII。

下面定义了一个名为save_list()的函数,用于保存项目列表,在这种情况下,保存词条为文件,每行一个。

代码语言:js
复制
def save_list(lines, filename):
    data = '\n'.join(lines)
    file = open(filename, 'w')
    file.write(data)
    file.close()

下面列出了定义和保存词汇的完整示例。

代码语言:js
复制
from string import punctuation
from os import listdir
from collections import Counter
from nltk.corpus import stopwords
 
# 加载文档到内存
    def load_doc(filename):
    # 以只读方式打开文件
    file = open(filename, 'r')
    # 读取所有文本
    text = file.read()
    # 关闭文件
    file.close()
    return text
 
# 将文档变成干净的词条
def clean_doc(doc):
    # 以空格来拆分词条
    tokens = doc.split()
    # 从每个词条中移除标点符号
    table = str.maketrans('', '', punctuation)
    tokens = [w.translate(table) for w in tokens]
    # 从剩余词条中移除非字母的项
    tokens = [word for word in tokens if word.isalpha()]
    # 过滤出停用词
    stop_words = set(stopwords.words('english'))
    tokens = [w for w in tokens if not w in stop_words]
    # 过滤出短的词条
    tokens = [word for word in tokens if len(word) > 1]
    return tokens
 
# 加载文档并添加到词汇表中
def add_doc_to_vocab(filename, vocab):
    # 加载文档
    doc = load_doc(filename)
    # 清理文档
    tokens = clean_doc(doc)
    # 更新计数
    vocab.update(tokens)
 
# 加载目录中的所有文件
def process_docs(directory, vocab):
    # 遍历文件夹中的所有文件
    for filename in listdir(directory):
        # 跳过没有正确扩展名的文件
        if not filename.endswith(".txt"):
            continue
        # 创建要打开的文件的完整路径
        path = directory + '/' + filename
        # 添加文档到vocab
        add_doc_to_vocab(path, vocab)
 
# 保存list到文件
def save_list(lines, filename):
    data = '\n'.join(lines)
    file = open(filename, 'w')
    file.write(data)
    file.close()
 
# 定义vocab
vocab = Counter()
# 添加所有文档到词汇表
process_docs('txt_sentoken/neg', vocab)
process_docs('txt_sentoken/pos', vocab)
# 打印词汇表的大小
print(len(vocab))
# 打印词汇表中的热门单词
print(vocab.most_common(50))
# 保持词条出现次数 > 5
min_occurane = 5
tokens = [k for k,c in vocab.items() if c >= min_occurane]
print(len(tokens))
# 保存词条到词汇表文件
save_list(tokens, 'vocab.txt')

在创建词汇表后运行这个最后的片段将会保存所选择单词到文件中。

查看,甚至学习你选择的词汇是一个好主意,以便获得更好的准备,以便将来更好地准备这些数据或文本数据。

代码语言:js
复制
hasnt
updating
figuratively
symphony
civilians
might
fisherman
hokum
witch
buffoons
...

接下来,我们可以看看使用词汇来创建电影评论数据集的准备版本。

5.保存准备好的数据

我们可以使用数据清理和选择词汇来准备每个电影评论,并保存准备建模的评论数据准备版本。

这是一个很好的做法,因为它可以将数据准备与建模分离开来,如果您有新的想法,使您可以专注于建模并回到数据准备。

我们可以从加载词汇表“vocab.txt” 开始。

代码语言:js
复制
# 加载文档到内存
def load_doc(filename):
    # 以只读方式打开文件
    file = open(filename, 'r')
    # 读取所有文本
    text = file.read()
    # 关闭文件
    file.close()
    return text
 
# 加载词汇表文件
vocab_filename = 'review_polarity/vocab.txt'
vocab = load_doc(vocab_filename)
vocab = vocab.split()
vocab = set(vocab)

接下来,我们可以清理评论,使用加载的vocab来过滤不需要的词条,并将干净的评论保存在一个新文件中。

一种方法可以是将所有正面评论保存在一个文件中,将所有负面评论保存在另一个文件中,对于每个评论,在单独的行上将过滤的词条用空格分开。

首先,我们可以定义一个函数来处理一个文档,清理它,过滤它,并将它作为一个可以保存在文件中的单行返回。下面定义了doc_to_line()函数,将文件名和词汇(作为一个集合)作为参数。

它调用之前定义的load_doc()函数来加载文档,并使用clean_doc()来标记文档。

代码语言:js
复制
# 加载文档、清理并返回词条行
def doc_to_line(filename, vocab):
    # 加载文档
    doc = load_doc(filename)
    # 清理文档
    tokens = clean_doc(doc)
    # 通过词汇表过滤
    tokens = [w for w in tokens if w in vocab]
    return ' '.join(tokens)

接下来,我们可以定义一个新版本的process_docs()来遍历文件夹中的所有评论,并通过调用doc_to_line()为每个文档将它们转换为行。然后返回行的列表。

代码语言:js
复制
# 加载目录中所有文档
def process_docs(directory, vocab):
    lines = list()
    # 遍历文件夹中的所有文件
    for filename in listdir(directory):
        # 跳过没有正确扩展名的文件
        if not filename.endswith(".txt"):
            continue
        # 创建要打开的文件的完整路径
        path = directory + '/' + filename
        # 加载并清理文档
        line = doc_to_line(path, vocab)
        # 添加到list
        lines.append(line)
    return lines

然后,我们可以调用process_docs()作为正面和负面评论的目录,然后调用上一节中的save_list()将每个处理的评论列表保存到一个文件中。

下面提供了完整的代码清单。

代码语言:js
复制
from string import punctuation
from os import listdir
from collections import Counter
from nltk.corpus import stopwords
 
# 加载文档到内存
def load_doc(filename):
    # 以只读方式打开文件
    file = open(filename, 'r')
    # 读取所有文本
    text = file.read()
    # 关闭文件
    file.close()
    return text
 
# 将文档变成干净的词条
def clean_doc(doc):
    # 以空格来拆分词条
    tokens = doc.split()
    # 从每个词条中移除标点符号
    table = str.maketrans('', '', punctuation)
    tokens = [w.translate(table) for w in tokens]
    # 从剩余词条中移除非字母的项
    tokens = [word for word in tokens if word.isalpha()]
    # 过滤出停用词
    stop_words = set(stopwords.words('english'))
    tokens = [w for w in tokens if not w in stop_words]
    # 过滤出短的词条
    tokens = [word for word in tokens if len(word) > 1]
    return tokens
 
# 保存list到文件
def save_list(lines, filename):
    data = '\n'.join(lines)
    file = open(filename, 'w')
    file.write(data)
    file.close()
 
# 加载文档、清理并返回词条行
def doc_to_line(filename, vocab):
    # 加载文档
    doc = load_doc(filename)
    # 清理文档
    tokens = clean_doc(doc)
    # 通过词汇表过滤
    tokens = [w for w in tokens if w in vocab]
    return ' '.join(tokens)
 
# 加载目录中的所有文件
def process_docs(directory, vocab):
    lines = list()
    # 遍历文件夹中的所有文件
    for filename in listdir(directory):
        # 跳过没有正确扩展名的文件
        if not filename.endswith(".txt"):
            continue
        # 创建要打开的文件的完整路径
        path = directory + '/' + filename
        # 加载并清理文档
        line = doc_to_line(path, vocab)
        # 添加到list
        lines.append(line)
    return lines
 
# 加载词汇表文件
vocab_filename = 'vocab.txt'
vocab = load_doc(vocab_filename)
vocab = vocab.split()
vocab = set(vocab)
# 准备负面评论
negative_lines = process_docs('txt_sentoken/neg', vocab)
save_list(negative_lines, 'negative.txt')
# 准备正面评论
positive_lines = process_docs('txt_sentoken/pos', vocab)
save_list(positive_lines, 'positive.txt')

运行示例保存两个新文件,分别为“ negative.txt ”和“ positive.txt ”,分别包含准备好的正面和负面评论。

数据已经准备好用在一个词袋模型甚至是文字嵌入模型中。

扩展

本节列出了您可能希望探索的一些扩展。

  • 压缩。我们可以使用像Porter stemmer这样的词干算法将文档中的每个单词都缩减为词干。
  • N-Grams。我们可以用单词对的词汇,而不是单独使用单词,这样称为bigrams。我们还可以调查更大的使用群体,如三元组(trigram)和更多(n-gram)。
  • 编码词。我们可以保存单词的整数编码,而不是按原样保存词条,其中词汇表中单词的索引表示该单词的唯一整数。这将使建模时更容易处理数据。
  • 编码文件。我们不用在文档中保存标记,而是使用词袋模型对文档进行编码,并将每个单词编码为布尔型存在/不存在标记或使用更复杂的评分,如TF-IDF。

我很想知道,如果你尝试任何这些扩展。 在评论中分享你的结果。

扩展阅读

如果您正在深入研究,本节将提供更多有关该主题的资源。

数据集

API

概要

在本教程中,您将逐步了解如何为观点分析准备电影评论文本数据。

具体来说,你已了解到:

  • 如何加载文本数据并清理它以去除标点符号和其他非单词。
  • 如何开发词汇,定制词汇,并将其保存到文件中。
  • 如何使用清理和预定义的词汇来准备电影评论,并将其保存到新的文件中以供建模。

有任何其他的问题吗?

在评论中提出你的问题,我将尽力回答。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 教程概述
  • 1.电影评论数据集
  • 2.加载文本数据
  • 3.清理文本数据
  • 4.开发词汇
  • 5.保存准备好的数据
  • 扩展
  • 扩展阅读
    • 数据集
      • API
      • 概要
      相关产品与服务
      NLP 服务
      NLP 服务(Natural Language Process,NLP)深度整合了腾讯内部的 NLP 技术,提供多项智能文本处理和文本生成能力,包括词法分析、相似词召回、词相似度、句子相似度、文本润色、句子纠错、文本补全、句子生成等。满足各行业的文本智能需求。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档