文章目录
1. 分词
1.1 分词概念
1.2 词、字符频率统计
2. unigram、bigram、trigram
2.1 语言模型中unigram、bigram、trigram的概念
2.2 unigram、bigram频率统计;(可以使用Python中的collections.Counter模块,也可以自己寻找其他好用的库)
3. 文本矩阵化:要求采用词袋模型且是词级别的矩阵化
3.1 分词(采用结巴分词来进行分词操作)
3.2 去停用词;构造词表
3.3 每篇文档的向量化
参考
1. 分词
1.1 分词概念
现有的分词算法可分为三大类:基于字符串匹配的分词方法、基于理解的分词方法和基于统计的分词方法。基于字符串匹配的分词方法又被称为机械式分词方法或基于字典的分词方法,它是按照一定策略将待分析的汉字串与一个“充分大的”机器词典中的词条进行匹配,若在词典中找到某个字符串,则匹配成功。根据扫描方向的不同,这种分词方法分为正向匹配、逆向匹配和双向匹配,常见的匹配原则有逐词匹配、最大匹配、最小匹配和最佳匹配。
此部分参考原文:https://blog.csdn.net/selinda001/article/details/79345072
正向最大匹配法
在词典中进行扫描,尽可能地选择与词典中最长单词匹配的词作为目标分词,然后进行下一次匹配。
算法流程:
假设词典中最长的单词为 n 个,那么最大匹配的起始子串字数也为 n 个
(1)扫描字典,测试读入的子串是否在字典中
(2)如果存在,则从输入中删除掉该子串,重新按照规则取子串,重复(1)
(3)如果不存在于字典中,则从右向左减少子串长度,重复(1)
逆向最大匹配法
在词典中进行扫描,尽可能地选择与词典中最长单词匹配的词作为目标分词,然后进行下一次匹配。
算法流程:
假设词典中最长的单词为 n 个,那么最大匹配的起始子串字数也为 n 个
(1)扫描字典,测试读入的子串是否在字典中
(2)如果存在,则从输入中删除掉该子串,重新按照规则取子串,重复(1)
(3)如果不存在于字典中,则从左向右减少子串长度,重复(1)
双向最大匹配法
分词目标:
将正向最大匹配算法和逆向最大匹配算法进行比较,从而确定正确的分词方法。
算法流程:
(1) 比较正向最大匹配和逆向最大匹配结果
(2) 如果分词数量结果不同,那么取分词数量较少的那个
(3) 如果分词数量结果相同
分词结果相同,可以返回任何一个
分词结果不同,返回单字数比较少的那个
1.2 词、字符频率统计
2. unigram、bigram、trigram
2.1 语言模型中unigram、bigram、trigram的概念
n-gram是一种基于统计语言模型的算法。在自然语言处理中,我们经常需要用到n元语法模型。n-gram第N个词的出现只与前面N-1个词相关,而与其它任何词都不相关,整句的概率就是各个词出现概率的乘积。这些概率可以通过直接从语料中统计N个词同时出现的次数得到。
其中,有关中文分词的一些概念是我们需要掌握的,譬如:
unigram 一元分词,把句子分成一个一个的汉字,每个词之间没有关联关系;
bigram 二元分词,把句子从头到尾每两个字组成一个词语,当前词只和上一个词有关系;
trigram 三元分词,把句子从头到尾每三个字组成一个词语,当前词只和前两个词有关系。
2.2 unigram、bigram频率统计;(可以使用Python中的collections.Counter模块,也可以自己寻找其他好用的库)
这里我借助nltk对IMDB数据集(英文)训练集neg部分做了一个简单的统计,先构造了一个字典,然后做的词频统计。得到的结果如下:
3. 文本矩阵化:要求采用词袋模型且是词级别的矩阵化
3.1 分词(采用结巴分词来进行分词操作)
THUCNews数据集比较大的还是,这里为了方便观察先借助Pandas获取一下训练数据集中的内容;
import pandas as pd
train_data = pd.read_csv('G:/PycharmCode/NLP/cnews/cnews.train.txt', sep='\t', names=['label', 'content'])
print(train_data.head())
1
2
3
然后,借助jieba分词对内容部分进行分词;
def cut_content(contents):
return " ".join(jieba.cut(contents))
train_content = train_data['content'].apply(cut_content)
1
2
3
3.2 去停用词;构造词表
去除停用词需要借助停用词表,目前网上已经有许多整理好的中文停用词表,可根据需要自行下载。
这里是我下载的停用词表的部分截图:
接着,对上面处理好的分词后的内容部分去除停用词,并将去除后的内容保存到csv文件;
stopwords = stopwordslist('G:/PycharmCode/NLP/cnews/stopword.txt')
content_clean = []
for i in train_content:
if i not in stopwords:
content_clean.append(i)
new_content = pd.DataFrame(content_clean, columns=['content'])
train_data = pd.concat([train_data['label'], new_content], axis=1)
train_data.to_csv('train_data.csv', index=False, encoding='utf_8_sig')
1
2
3
4
5
6
7
8
得到的去除停用词后的所有内容如下:
构造词表,之前没做过,开始的时候没明白什么意思,这部分参考了 https://github.com/watchtree/nlpLearning/blob/master/task3_0410/README.md
这里我从上边分词好的csv文件开始执行,
train_data = pd.read_csv('train_data.csv')
# print(train_data['content'].head())
# 统计每个词出现的次数
data = train_data['content'].head()
wordList = {}
for i in data:
# print(i)
for j in i.split(' '):
# print(j.split('\n'))
if j in wordList:
wordList[j] += 1
else:
wordList[j] = 1
# print(wordList)
#创建词表
count = 0
dic = {}
for i, j in wordList.items():
if j > 2:
dic[i] = count
count += 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
得到的部分词表如下图所示:
3.3 每篇文档的向量化
有了上面词表的基础,文档的向量化就很简单了(Ps: 赞叹一下,参考大佬的代码很简洁啊)
UNKNOW = 0
for i in range(len(data)):
data[i] = [dic[j] if j in dic else UNKNOW for j in data[i]]
print(data[i])
1
2
3
4
得到的向量化后的文档如下图: