Datawhale《深度学习-NLP实践》Task2

1. 基本文本处理技能

1.1 分词的概念(分词的正向最大、逆向最大、双向最大匹配法);

最大匹配是指以词典为依据,取词典中最长单词为第一个次取字数量的扫描串,在词典中进行扫描(为提升扫描效率,还可以跟据字数多少设计多个字典,然后根据字数分别从不同字典中进行扫描)。例如:词典中最长词为“中华人民共和国”共7个汉字,则最大匹配起始字数为7个汉字。然后逐字递减,在对应的词典中进行查找。
下面以“我们在野生动物园玩”详细说明一下这几种匹配方法:

1.1.1 正向最大匹配法:

正向即从前往后取词,从7->1,每次减一个字,直到词典命中或剩下1个单字。

  • 第1轮扫描
    • 第1次:“我们在野生动物”,扫描7字词典,无
    • 第2次:“我们在野生动”,扫描6字词典,无
      。。。。
    • 第6次:“我们”,扫描2字词典,有
    • 扫描中止,输出第1个词为“我们”,去除第1个词后开始第2轮扫描
  • 第2轮扫描:
    • 第1次:“在野生动物园玩”,扫描7字词典,无
    • 第2次:“在野生动物园”,扫描6字词典,无
      。。。。
    • 第6次:“在野”,扫描2字词典,有
    • 扫描中止,输出第2个词为“在野”,去除第2个词后开始第3轮扫描
  • 第3轮扫描:
    • 第1次:“生动物园玩”,扫描5字词典,无
    • 第2次:“生动物园”,扫描4字词典,无
    • 第3次:“生动物”,扫描3字词典,无
    • 第4次:“生动”,扫描2字词典,有
    • 扫描中止,输出第3个词为“生动”,第4轮扫描
  • 第4轮扫描:
    • 第1次:“物园玩”,扫描3字词典,无
    • 第2次:“物园”,扫描2字词典,无
    • 第3次:“物”,扫描1字词典,无
    • 扫描中止,输出第4个词为 ‘’‘’,非字典词数加1,开始第5轮扫描
  • 第5轮扫描:
    • 第1次:“园玩”,扫描2字词典,无
    • 第2次:“园”,扫描1字词典,有
    • 扫描中止,输出第5个词为“”,单字字典词数加1,开始第6轮扫描
  • 第6轮扫描:
    • 第1次:“玩”,扫描1字字典词,有
    • 扫描中止,输出第6个词为“”,单字字典词数加1,整体扫描结束。

正向最大匹配法,最终切分结果为:“我们/在野/生动/物/园/玩”,其中,单字字典词为2,非词典词为1。

1.1.2、逆向最大匹配法:

逆向即从后往前取词,从7->1,每次减一个字,直到词典命中或剩下1个单字。即:

  • 第1轮扫描:“在野生动物园玩”
    • 第1次:“在野生动物园玩”,扫描7字词典,无
    • 第2次:“野生动物园玩”,扫描6字词典,无
      。。。。
    • 第7次:“玩”,扫描1字词典,有
    • 扫描中止,输出“玩”,单字字典词加1,开始第2轮扫描
  • 第2轮扫描:“们在野生动物园”
    • 第1次:“们在野生动物园”,扫描7字词典,无
    • 第2次:“在野生动物园”,扫描6字词典,无
    • 第3次:“野生动物园”,扫描5字词典,有
    • 扫描中止,输出“野生动物园”,开始第3轮扫描
  • 第3轮扫描:“我们在”
    • 第1次:“我们在”,扫描3字词典,无
    • 第2次:“们在”,扫描2字词典,无
    • 第3次:“在”,扫描1字词典,有
    • 扫描中止,输出“在”,单字字典词加1,开始第4轮扫描
  • 第4轮扫描:“我们”
    • 第1次:“我们”,扫描2字词典,有
    • 扫描中止,输出“我们”,整体扫描结束。

逆向最大匹配法,最终切分结果为:“我们/在/野生动物园/玩”,其中,单字字典词为2,非词典词为0。

1.1.3 双向最大匹配法:

正向最大匹配法和逆向最大匹配法,都有其局限性,我举得例子是正向最大匹配法局限性的例子,逆向也同样存在(如:长春药店,逆向切分为“长/春药店”),因此有人又提出了双向最大匹配法,双向最大匹配法。即,两种算法都切一遍,然后根据大颗粒度词越多越好,非词典词和单字词越少越好的原则,选取其中一种分词结果输出。

如:“我们在野生动物园玩”

正向最大匹配法,最终切分结果为:“我们/在野/生动/物/园/玩”,其中,两字词3个,单字字典词为2,非词典词为1。

逆向最大匹配法,最终切分结果为:“我们/在/野生动物园/玩”,其中,五字词1个,两字词1个,单字字典词为2,非词典词为0。

非字典词:正向(1)>逆向(0)(越少越好)

单字字典词:正向(2)=逆向(2)(越少越好)

总词数:正向(6)>逆向(4)(越少越好)

因此最终输出为逆向结果

1.2 词、字符频率统计;(可以使用Python中的collections.Counter模块,也可以自己寻找其他好用的库)

# 计算词频
seg_list = jieba.cut(train_data["content"][0], cut_all=False)
result = []
for seg in seg_list:
    seg = ''.join(seg.split())
    if seg != '' and seg != "\n" and seg != "\n\n" and seg not in stopwords:
        result.append(seg)
word_fre = {}
for i in set(result):
    word_fre[i] = result.count(i)
word_fre = sorted(word_fre.items(), key=lambda item: item[1], reverse=True)

2. 语言模型

2.1 语言模型中unigram、bigram、trigram的概念;

  • unigram 一元分词,把句子分成一个一个的汉字
  • bigram 二元分词,把句子从头到尾每两个字组成一个词语
  • trigram 三元分词,把句子从头到尾每三个字组成一个词语.

自然语言处理中的N-Gram模型介绍

2.2 unigram、bigram频率统计;(可以使用Python中的collections.Counter模块,也可以自己寻找其他好用的库)

3. 文本矩阵化:要求采用词袋模型且是词级别的矩阵化

步骤有:

  • 分词(可采用结巴分词来进行分词操作,其他库也可以);
  • 去停用词;
  • 构造词表。
  • 每篇文档的向量化。

3.1 分词

  • 分词工具采用结巴中文分词,涉及到的算法:
    • 基于Trie树结构实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图(DAG);
    • 采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合;
    • 对于未登录词,采用了基于汉字成词能力的HMM模型,使用了Viterbi算法。
  • 结巴中文分词支持的3种分词模式:
    • 精确模式:试图将句子最精确地切开,适合文本分析;
    • 全模式:把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义问题;
    • 搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。
import jieba
 
# 全模式
text= '昨天,我和施瓦布先生一起与部分企业家进行了交流,大家对中国经济当前、未来发展的态势、走势都十分关心。'
## 去除符号哦
text= re.sub(remove, '', str(text).strip())


seg_list = jieba.cut(text, cut_all=True)
print(u"[全模式]: ", "/ ".join(seg_list))
 
# 精确模式
seg_list = jieba.cut(text, cut_all=False)
print(u"[精确模式]: ", "/ ".join(seg_list))
 
# 默认是精确模式
seg_list = jieba.cut(text)
print(u"[默认模式]: ", "/ ".join(seg_list))
 
# 搜索引擎模式
seg_list = jieba.cut_for_search(text)
print(u"[搜索引擎模式]: ", "/ ".join(seg_list))

# 新词识别
import jieba
 
#新词识别  “杭研”并没有在词典中,但是也被Viterbi算法识别出来了
seg_list = jieba.cut("他来到了网易杭研大厦")
print (u"[新词识别]: ", "/ ".join(seg_list))

  • 分词方式2
# 分词方式2
seg_list = jieba.cut(train_data["content"][0], cut_all=False)
print("Full Mode: " + "/ ".join(seg_list))  # 全模式

3.2 取停用词

# 读取停用词
stopwords = []
with open('stopwords.txt', 'r') as fr:
    for line in fr:
        stopwords.append(line[:-1])

3.3 构造词表


# 计算词频
seg_list = jieba.cut(train_data["content"][0], cut_all=False)
result = []
for seg in seg_list:
    seg = ''.join(seg.split())
    if seg != '' and seg != "\n" and seg != "\n\n" and seg not in stopwords:
        result.append(seg)
word_fre = {}
for i in set(result):
    word_fre[i] = result.count(i)
word_fre = sorted(word_fre.items(), key=lambda item: item[1], reverse=True)

分词2

train_data = train_data[:5]
words = []
for sentence in train_data['content']:
    word = list(jieba.cut(sentence))
    for w in list(set(word) and set(stopwords)):
        while w in word:
            word.remove(w)
    words.append(' '.join(word))
train_data['content_'] = words

3.4 向量化

# 计算 TF-IDF
count_vectorizer = CountVectorizer(max_features=256, min_df=2)
count_vectorizer.fit_transform(train_data['content_'])
fea_vec = count_vectorizer.transform(train_data['content_']).toarray()

4. 参考

结巴分词介绍和使用

你可能感兴趣的:(Python,Tensorflow,NLP)