zoukankan      html  css  js  c++  java
  • NLP-中文分词-预处理

    规则分词:机械的分词方法,主要是通过维护词典,每次分割时将词语中每个字符串与词典表中的词逐一比较,确定是否切割(很费时)。按照切分方式,主要有正向最大匹配法,逆向最大匹配法,及双向最大匹配法。

    1.正向

    从左至右取切分汉语的m个字符串作为匹配字段,m是需要设置的字典中最大词条长度;

    在词典中进行查找,若匹配成功则将匹配字段作为切分词提取出来;若不成功,去掉最后一个字,新的字段再从新去词典里匹配,直到切分完成。

    2.逆向

    3.正逆向


    4.词袋模型

    三部曲:分词(tokenizing),统计修订词特征值(counting)与标准化(normalizing)

    它仅仅考虑了词频,没有考虑上下文的关系。

    scikit-learn的CountVectorizer类来完成,这个类可以帮我们完成文本的词频统计与向量化:

    from sklearn.feature_extraction.text import CountVectorizer
    
    vectorizer = CountVectorizer()
    corpus = ["I come to China to travel",
              "This is a car polupar in China",
              "I love tea and Apple ",
              "The work is to write some papers in science"]
    print('文档号及词频')
    # (0,16) 1:0号文档,字典中16号词 ,频率1
    doc = vectorizer.fit_transform(corpus)
    print(doc)
    print('文本词向量')
    print(doc.toarray())
    print('词典')
    # I是停用词,自动过滤
    print(vectorizer.get_feature_names())
    
    #
    文档号及词频
      (0, 16)	1
      (0, 3)	1
      (0, 15)	2
      (0, 4)	1
      (1, 5)	1
      (1, 9)	1
      (1, 2)	1
      (1, 6)	1
      (1, 14)	1
      (1, 3)	1
      (2, 1)	1
      (2, 0)	1
      (2, 12)	1
      (2, 7)	1
      (3, 10)	1
      (3, 8)	1
      (3, 11)	1
      (3, 18)	1
      (3, 17)	1
      (3, 13)	1
      (3, 5)	1
      (3, 6)	1
      (3, 15)	1
    文本词向量
    [[0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 2 1 0 0]
     [0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0]
     [1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0]
     [0 0 0 0 0 1 1 0 1 0 1 1 0 1 0 1 0 1 1]]
    词典
    ['and', 'apple', 'car', 'china', 'come', 'in', 'is', 'love', 'papers', 'polupar', 'science', 'some', 'tea', 'the', 'this', 'to', 'travel', 'work', 'write']

    scikit-learn的HashingVectorizer类中,实现了基于signed hash trick的算法,其定义一个维度远小于词汇表的哈西维度,看作是降维,任意词哈西映射到一个位置,然后词频累加,有些不同的词会被累加在一起。结果里面有负数,这是因为哈希函数可以哈希到1或者-1导致的。和PCA类似,Hash Trick降维后的特征我们已经不知道它代表的特征名字和意义。此时不能知道每一列的意义,所以Hash Trick的解释性不强。

    from sklearn.feature_extraction.text import HashingVectorizer
    
    corpus = ["I come to China to travel",
              "This is a car polupar in China",
              "I love tea and Apple ",
              "The work is to write some papers in science"]
    
    vectorizer2 = HashingVectorizer(n_features=6, norm=None)
    print(vectorizer2.fit_transform(corpus))
    #
      (0, 1)	2.0
      (0, 2)	-1.0
      (0, 4)	1.0
      (0, 5)	-1.0
      (1, 0)	1.0
      (1, 1)	1.0
      (1, 2)	-1.0
      (1, 5)	-1.0
      (2, 0)	2.0
      (2, 5)	-2.0
      (3, 0)	0.0
      (3, 1)	4.0
      (3, 2)	-1.0
      (3, 3)	1.0
      (3, 5)	-1.0

    5.词频-逆文本频率TF-IDF

    出现频率大的词语,反而重要性不高,to,from,......。IDF来反应这个词的重要性,或者,反应一个词在所有文本中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低,如“to”。而反过来如果一个词在比较少的文本中出现,那么它的IDF值应该高。比如一些专业的名词如“Machine Learning”。这样的词IDF值应该高。

    IDF(x) = logfrac{N+1}{N(x)+1} + 1

    from sklearn.feature_extraction.text import TfidfTransformer
    from sklearn.feature_extraction.text import CountVectorizer
    
    corpus = ["I come to China to travel",
              "This is a car polupar in China",
              "I love tea and Apple ",
              "The work is to write some papers in science"]
    
    # 文本向量化
    vectorizer = CountVectorizer()
    #  Tfidf转换器
    transformer = TfidfTransformer()
    # 处理向量化的文本为逆文本频率
    tfidf = transformer.fit_transform(vectorizer.fit_transform(corpus))
    print('词频', tfidf)
    print('词典', vectorizer.get_feature_names())
    
    
    # --------一步到位---------
    from sklearn.feature_extraction.text import TfidfVectorizer
    
    tfidf2 = TfidfVectorizer()
    re = tfidf2.fit_transform(corpus)
    print('词频', re)
    print('词典', tfidf2.get_feature_names())

    6 中文分词流程

    1.数据收集

        在文本挖掘之前,我们需要得到文本语料库,需要自己爬取或者下载网站的公开语料库。

    2.除去数据中非文本部分

        这一步主要是针对我们用爬虫收集的语料数据,由于爬下来的内容中有很多html的一些标签,需要去掉。少量的非文本内容的可以直接用Python的正则表达式(re)删除, 复杂的则可以用beautifulsoup来去除。去除掉这些非文本的内容后,我们就可以进行真正的文本预处理了。

    3. 处理中文编码问题

        由于Python2不支持unicode的处理,因此我们使用Python2做中文文本预处理时需要遵循的原则是,存储数据都用utf8,读出来进行中文相关处理时,使用GBK之类的中文编码。

    4. 中文分词

        常用的中文分词软件有很多,jieba分词比较流行,pip install jieba。三步曲:分词后的文件,停用词列表,TFIDF转换

    jieba分词:

    
    import jieba
    
    # 加入人工设定的人名,地名
    jieba.suggest_freq('沙瑞金', True)
    jieba.suggest_freq('易学习', True)
    jieba.suggest_freq('王大路', True)
    jieba.suggest_freq('京州', True)
    
    with open('./nlp_test2.txt', encoding='utf-8') as f:
        document = f.read()
    
        document_decode = document.encode('utf-8')
        # 全模式
        # document_cut = jieba.cut(document_decode,cut_all=True)
        # 精确模式
        # document_cut = jieba.cut(document_decode, cut_all=False)
        # 搜索引擎模式
        document_cut = jieba.cut_for_search(document_decode)
        result = ' '.join(document_cut)
        result = result.encode('utf-8')
        with open('./nlp_test3.txt', 'w') as f2:
            f2.write(str(result, encoding='utf-8'))
    

    利用分词后的文本,利用停用词,进行Tfidf转换: 

    # 读取分词文件
    with open('./nlp_test1.txt') as f3:
        res1 = f3.read()
    with open('./nlp_test3.txt') as f4:
        res2 = f4.read()
    
    from sklearn.feature_extraction.text import TfidfVectorizer
    
    # ===========分词文件============
    corpus = [res1, res2]
    
    # =========停用词表==========
    stpwrdpath = 'stop_words.txt'
    with open(stpwrdpath) as f5:
        stpwrd_content = f5.read()
        # 将停用词表转换为list
        stpwrdlst = stpwrd_content.splitlines()
    
    vector = TfidfVectorizer(stop_words=stpwrdlst)
    tfidf = vector.fit_transform(corpus)
    # print(tfidf)
    
    wordlist = vector.get_feature_names()  # 获取词袋模型中的所有词
    # 文档数 X 词典数 矩阵
    weightlist = tfidf.toarray()
    num_doc = len(weightlist)
    for i in range(num_doc):
        print("-------第", i, "段文本的词语tf-idf权重------")
        for j in range(len(wordlist)):
            print('第', j, '个词', wordlist[j], weightlist[i][j])
    
    
    #
    -------第 0 段文本的词语tf-idf权重------
    第 0 个词 一起 0.23276132724875156
    第 1 个词 万块 0.23276132724875156
    第 2 个词 三人 0.23276132724875156
    
    第 52 个词 道口 0.11638066362437578
    第 53 个词 金山 0.11638066362437578
    第 54 个词 降职 0.11638066362437578
    第 55 个词 风生水 0.11638066362437578
    -------第 1 段文本的词语tf-idf权重------
    第 0 个词 一起 0.0
    第 1 个词 万块 0.0
    第 2 个词 三人 0.0
    第 3 个词 三套 0.14811780175932843
    第 54 个词 降职 0.0
    第 55 个词 风生水 0.0
  • 相关阅读:
    第3章 对象基础
    [置顶] CSDN博客客户端(非官方)
    javascript 修改对象
    Print2Flash出现"System Error. Code:1722. RPC服务器不可用."错误解决办法
    ConfigHelper 配置文件辅助类
    多个委托方法的顺序执行
    javascript Table
    字符串拼接方式(待商榷)
    CSDN博客客户端(非官方)
    javascript 对象继承
  • 原文地址:https://www.cnblogs.com/onenoteone/p/12441697.html
Copyright © 2011-2022 走看看