ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

TASK2笔记+代码

2019-03-05 18:04:20  阅读:251  来源: 互联网

标签:tokens TASK2 unigram 代码 扫描 jieba 笔记 content 词典


中文分词之正向最大匹配法 逆向最大匹配法 双向最大匹配法

1.正向最大匹配法:

摘自link
分词算法设计中的几个基本原则:

1、颗粒度越大越好:用于进行语义分析的文本分词,要求分词结果的颗粒度越大,即单词的字数越多,所能表示的含义越确切,如:“公安局长”可以分为“公安 局长”、“公安局 长”、“公安局长”都算对,但是要用于语义分析,则“公安局长”的分词结果最好(当然前提是所使用的词典中有这个词)

2、切分结果中非词典词越少越好,单字字典词数越少越好,这里的“非词典词”就是不包含在词典中的单字,而“单字字典词”指的是可以独立运用的单字,如“的”、“了”、“和”、“你”、“我”、“他”。例如:“技术和服务”,可以分为“技术 和服 务”以及“技术 和 服务”,但“务”字无法独立成词(即词典中没有),但“和”字可以单独成词(词典中要包含),因此“技术 和服 务”有1个非词典词,而“技术 和 服务”有0个非词典词,因此选用后者。

3、总体词数越少越好,在相同字数的情况下,总词数越少,说明语义单元越少,那么相对的单个语义单元的权重会越大,因此准确性会越高。

下面详细说说正向最大匹配法、逆向最大匹配法和双向最大匹配法具体是如何进行的:

先说说什么是最大匹配法:最大匹配是指以词典为依据,取词典中最长单词为第一个次取字数量的扫描串,在词典中进行扫描(为提升扫描效率,还可以跟据字数多少设计多个字典,然后根据字数分别从不同字典中进行扫描)。例如:词典中最长词为“中华人民共和国”共7个汉字,则最大匹配起始字数为7个汉字。然后逐字递减,在对应的词典中进行查找。

下面以“我们在野生动物园玩”详细说明一下这几种匹配方法:

1、正向最大匹配法:

正向即从前往后取词,从7->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。

2、逆向最大匹配法:

逆向即从后往前取词,其他逻辑和正向相同。即:

第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。

3、双向最大匹配法:

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

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

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

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

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

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

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

因此最终输出为逆向结果。

2.语言模型

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

摘自link
N-Gram是一种基于统计语言模型的算法。它的基本思想是将文本里面的内容按照字节进行大小为N的滑动窗口操作,形成了长度是N的字节片段序列。

每一个字节片段称为gram,对所有gram的出现频度进行统计,并且按照事先设定好的阈值进行过滤,形成关键gram列表,也就是这个文本的向量特征空间,列表中的每一种gram就是一个特征向量维度。

例子
比如我们现在使用单元Unigram、二元的Bi-gram和三元的Tri-gram模型来对进行特征提取。

我们的训练样本为:

1)我去了北京天安门

2)我是中国人

那么我们对每一个样本进行单元Unigram、二元的Bi-gram和三元的Tri-gram模型提取。

单元Unigram来说
对于:“我去了北京天安门”

抽取 我 去了 北京 天安门

对于:“我是中国人”

抽取 我 是 中国人

二元Bi-gram
对于:“我去了北京天安门”

抽取 我 去了/ 去了 北京/ 北京 天安门/

对于:“我是中国人”

抽取 我 是 / 是 中国人/

三元Tri-gram
对于:“我去了北京天安门”

抽取 我 去了 北京/ 去了 北京 天安门/

对于:“我是中国人”

抽取 我 是 中国人/

那么从上面可以得出,我们的特征向量包含我在训练数据中利用单元Unigram,二元Bi-gram,以及三元Tri-gram抽取出的不同特征,组成我的特征向量维度。

然后以后对应一句话,直接进行Unigram,Bi-gram,Tri-gram进行抽取特征,出现哪个特征,就统计它的频数,最后填在特征向量中即可。

比如上面的特征向量我列举一下顺序如:

我、是、中国人、去了、北京、天安门、我 是、是 中国人、我 去了、去了 北京、北京 天安门、我 去了 北京、去了 北京 天安门、 我 是 中国人、

抽取特征过程
那么对于一句话“我是中国人”进行N-gram特征抽取的方法是。

单元Unigram来说

对于:“我是中国人”

抽取 我 是 中国人

二元Bi-gram

对于:“我是中国人”

抽取 我 是 / 是 中国人/

三元Tri-gram

对于:“我是中国人”

抽取 我 是 中国人/

于是我们就在出现的词语维度赋值为1,其余没有出现过的特征赋值为0,相当于one-hot特征。得到特征向量如下:

[1,1,1,0,0,0,1,1,0,0,0,0,0,0,1]

得到的上面这个特征向量就是我们使用N-gram提取特征方法提取出来的特征。

总结
如果我们使用N-gram提取特征,使用unigram,bigram,trigram提取特征的情况,在词汇表大小为V的时候,特征向量维度长度为[V(unigram)+V2(bigram)+V3(trigram)]

词、字符频率统计

import pandas as pd 
import numpy as np
import jieba 
from collections import Counter


labels = []
contents = []
file_name = '.\cnews\cnews.train.txt'
with open(file_name,'r', encoding='utf-8', errors='ignore') as f:
    for line in f:
        try:
            label,content = line.strip().split('\t')
            if content:
                contents.append(content)
                labels.append(label)
        except:
            pass
# 结巴分词
jieba_contents = []
for content in contents:
    jieba_contents.append(list(jieba.cut(content)))

# 将分词后的结果全部存到同一个列表中,用作统计词频
jieba_all_content = []
for content in jieba_contents:
    jieba_all_content.extend(content)
    
# 将未分词前的结果全部存到同一个列表中,用作统计单字字频
all_content = []
for content in contents:
    all_content.extend(content)

统计字、词频

from collections import Counter
count1 = Counter(all_content)
count2 = Counter(jieba_all_content)

unigram、bigram频率统计

  unigram、bigram频率统计(分词后)
def _word_ngrams(tokens, stop_words=None,ngram_range=(1,1)):
        """Turn tokens into a sequence of n-grams after stop words filtering"""
        # handle stop words
        if stop_words is not None:
            tokens = [w for w in tokens if w not in stop_words]

        # handle token n-grams
        min_n, max_n = ngram_range
        if max_n != 1:
            original_tokens = tokens
            tokens = []
            n_original_tokens = len(original_tokens)
            for n in range(min_n,
                            min(max_n + 1, n_original_tokens + 1)):
                for i in range(n_original_tokens - n + 1):
                    tokens.append(" ".join(original_tokens[i: i + n]))

        return tokens

    
    
jieba_bigram = []
for con in contents:
    listcut = list(jieba.cut(con))
    n_gramWords = _word_ngrams(tokens = listcut,ngram_range=(2,2))
    jieba_bigram.append(n_gramWords)

# 对bigram展开    
bigram_content = []
for content in jieba_bigram:
    bigram_content.extend(content)
 

jieba_unigram = []
for con in contents:
    listcut = list(jieba.cut(con))
    uni_gramWords = _word_ngrams(tokens = listcut,ngram_range=(1,1))
    jieba_unigram.append(uni_gramWords)

# 对unigram展开
unigram_content = []
for content in jieba_unigram:
    unigram_content.extend(content)
    
    
from collections import Counter
bi_count = Counter(bigram_content)
uni_count = Counter(unigram_content)

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

#  unigram、bigram频率统计(分词后)
def _word_ngrams(tokens, stop_words=None,ngram_range=(1,1)):
        """Turn tokens into a sequence of n-grams after stop words filtering"""
        # handle stop words
        if stop_words is not None:
            tokens = [w for w in tokens if w not in stop_words]

        # handle token n-grams
        min_n, max_n = ngram_range
        if max_n != 1:
            original_tokens = tokens
            tokens = []
            n_original_tokens = len(original_tokens)
            for n in range(min_n,
                            min(max_n + 1, n_original_tokens + 1)):
                for i in range(n_original_tokens - n + 1):
                    tokens.append(" ".join(original_tokens[i: i + n]))

        return tokens

    
    
jieba_bigram = []
for con in contents:
    listcut = list(jieba.cut(con))
    n_gramWords = _word_ngrams(tokens = listcut,ngram_range=(2,2))
    jieba_bigram.append(n_gramWords)

# 对bigram展开    
bigram_content = []
for content in jieba_bigram:
    bigram_content.extend(content)
 

jieba_unigram = []
for con in contents:
    listcut = list(jieba.cut(con))
    uni_gramWords = _word_ngrams(tokens = listcut,ngram_range=(1,1))
    jieba_unigram.append(uni_gramWords)

# 对unigram展开
unigram_content = []
for content in jieba_unigram:
    unigram_content.extend(content)
    
    
from collections import Counter
bi_count = Counter(bigram_content)
uni_count = Counter(unigram_content)

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

from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(min_df=1, token_pattern='(?u)\\b\\w+\\b')
#分词后用Countvectorirzer
to_count_vector = []
for sen in jieba_contents:
    sentence = ' '.join(sen)
    to_count_vector.append(sentence)

# 生成文本矩阵
cv.fit_transform(to_count_vector)

标签:tokens,TASK2,unigram,代码,扫描,jieba,笔记,content,词典
来源: https://blog.csdn.net/jgh2011/article/details/88190896

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有