文本预处理的基本步骤包括以下几个:
以今日头条中文新闻(短文本)分类数据集为例。其包含38万条短新闻,包含于15个类中。
头条新闻数据集下载
数据格式如下所示:
6551700932705387022_!_101_!_news_culture_!_京城最值得你来场文化之旅的博物馆_!_保利集团,马未都,中国科学技术馆,博物馆,新中国
每行为一条数据,以_!_分割的个字段,从前往后分别是 新闻ID,分类code(见下文),分类名称(见下文),新闻字符串(仅含标题),新闻关键词。
下面读取数据,并且切除ID,分类code,分类名称,新闻关键字,只保留标题文本。
# 导入包
import re
# 定义要去掉的标点
punc = '[~`!#$%^&*()_+-=|\';":/.,?><~·!@#¥%……&*()——+-=“:’;、。,?》《{}]'
with open('toutiao_cat_data.txt', 'r', encoding='utf') as f:
lines = f.readlines()
for i in range(len(lines)):
lines[i] = lines[i].strip().split('_!_')[3]
lines[i]= re.sub(punc, '', lines[i]) # 将文本中的标点用空字符代替
print(f'文本总行数:{len(lines)}')
for i in range(5):
print(lines[i])
结果如下:
文本总行数:382688
京城最值得你来场文化之旅的博物馆
发酵床的垫料种类有哪些哪种更好
上联黄山黄河黄皮肤黄土高原怎么对下联
林徽因什么理由拒绝了徐志摩而选择梁思成为终身伴侣
黄杨木是什么树
在语言学中,词是具备独立意义的最小单位。由合适的词进行排列组合形成有意义的句子。对文本信息进行处理的第一步就是进行分词。
如果是英文文本的话,分词就简单许多了,由于英文的语法特性,其句子中的每个词都用空格分开,因此英文分词就直接利用python自带的split()函数以空格分割就行。
如果文本是中文的话,情况就要复杂一些了。一个分词策略就是:我们先准备一个很大很大词典,对一句话中的第一个字进行查询,如果它能够在词典中查到,说明它是词,那就取前两个字,再进行查询,一直到无法查询位置,然后再将下标移动到查不到词的最后一个字,重复。
感觉自己实现有一点复杂,还好python有相应的库——jieba (得自己下载)。利用jieba.lcut()就可以进行分词。
import jieba
# 提高jieba的日志等级,我也不知道为啥,不提高就会警告
import logging
jieba.setLogLevel(logging.INFO)
# 创建一个空列表来储存分词后的结果
token_lines = []
for line in lines:
token_lines.append(jieba.lcut(line))
# 打印两条看看效果
print(token_lines[0])
print(token_lines[1])
结果如下:
['京城', '最', '值得', '你', '来场', '文化', '之旅', '的', '博物馆']
['发酵', '床', '的', '垫料', '种类', '有', '哪些', '哪', '种', '更好']
我们通过头条新闻数据集来构建一个自己的词表。
首先将分词结果都添加到一个列表中,再将重复的单词去掉,最后再将其变成字典的形式方便索引,因为学习模型无法处理字符串,只能处理数字。
# 创建一个空列表保存所有词
token = []
for token_line in token_lines:
token.extend(token_line)
# 利用collections.Counter()来统计一下词频,它会将统计结果返回为一个字典的形式
import collections
vocab = collections.Counter(token)
# 可视化按词频排序的前3000个单词的出现频率
from matplotlib import pyplot as plt
x = [i for i in range(3000)]
y = list(vocab.values())[0:3000]
plt.plot(x, y)
plt.show()
# 创建一个空字典来存储词和其对应的索引
vocab_dict = {}
for i, j in enumerate(vocab):
vocab_dict[j] = i
print(vocab_dict['你'])
print(vocab_dict['文化'])
结果如下:
3
5
词频图如下: