zoukankan      html  css  js  c++  java
  • 中文文本预处理流程(带你分析每一步)

    标签:中文文本预处理
    作者:炼己者

    欢迎大家访问我的简书以及我的博客,大家如果感觉格式看着不舒服,也可以去看我的简书,里面也会有发布
    本博客所有内容以学习、研究和分享为主,如需转载,请联系本人,标明作者和出处,并且是非商业用途,谢谢!


    摘要

    • 机器学习我的理解就是把各种原始的东西变成机器可以理解的东西,然后再用各种机器学习算法来做操作。机器可以理解的东西是什么呢?——向量 。所以不管是图片还是文字,要用机器学习算法对它们进行处理,就要把它们转为向量。
    • 网上大部分都是处理英文文本的资料,本文就以中文文本为例,将原始的文本经过预处理得到文本向量

    目录

    • 去除指定无用的符号
    • 让文本只保留汉字
    • 对文本进行jieba分词
    • 去除停用词
    • 将文本转为tfidf向量并输入到算法中

    操作流程

    1.去除指定无用的符号

    我们拿到的文本有时候很有很多空格,或者你不想要的符号,那么你就可以用这个方法去掉所有你不想要的符号。在这里我以空格为例

    content = ['  欢迎来到  炼己者的博客','炼己者     带你入门NLP  ']
    # 去掉文本中的空格
    def process(our_data):
        m1 = map(lambda s: s.replace(' ', ''), our_data)
        return list(m1)
    print(process(content))
    

    传入的参数our_data是个列表,此函数可以把文本中的所有空格全部去掉。看一下输出的结果。可以发现,所有的空格都被删掉了

    ['欢迎来到炼己者的博客', '炼己者带你入门NLP']
    

    2.让文本只保留汉字

    这个操作我最喜欢,他可以去掉所有的符号,包括数字、标点、字母等等

    content = ['如果这篇文章对你有所帮助,那就点个赞呗!!!','如果想联系炼己者的话,那就打电话:110!!!','想学习NLP,那就来关注呀!^-^']
    # 让文本只保留汉字
    def is_chinese(uchar):
        if uchar >= u'u4e00' and uchar <= u'u9fa5':
            return True
        else:
            return False
    
    def format_str(content):
        content_str = ''
        for i in content:
            if is_chinese(i):
                content_str = content_str + i
        return content_str
    
    # 参函数传入的是每一句话
    chinese_list = []
    for line in content:
        chinese_list.append(format_str(line))
    print(chinese_list)
    

    然后我们来看一下输出的内容,你会发现只剩下中文了。这个操作实在太骚了

    ['如果这篇文章对你有所帮助那就点个赞呗', '如果想联系炼己者的话那就打电话', '想学习那就来关注呀']
    

    3. 对文本进行jieba分词

    首先你得下载jieba这个库,直接pip install jieba即可。
    我们就以上面处理好的那句话作为例子来操作

    chinese_list = ['如果这篇文章对你有所帮助那就点个赞呗', '如果想联系炼己者的话那就打电话', '想学习那就来关注呀']
    
    # 对文本进行jieba分词
    import jieba
    def fenci(datas):
        cut_words = map(lambda s: list(jieba.cut(s)), datas)
        return list(cut_words)
    
    print(fenci(chinese_list))
    
    

    然后你就可以得到分词的结果了

    [['如果', '这', '篇文章', '对', '你', '有所', '帮助', '那', '就', '点个', '赞', '呗'],
     ['如果', '想', '联系', '炼己', '者', '的话', '那', '就', '打电话'],
     ['想', '学习', '那', '就', '来', '关注', '呀']]
    

    4.去除停用词

    首先你得上网下载一个停用词表,也可以关注我的微信公众号
    ZhangyhPico,回复停用词表,就可以拿到了。然后把这份停用词转换为列表
    为了方便大家理解,在这里我就假设一个停用词表了,我们以上面分好词的数据为例

    # 分好词的数据
    fenci_list = [['如果', '这', '篇文章', '对', '你', '有所', '帮助', '那', '就', '点个', '赞', '呗'],
     ['如果', '想', '联系', '炼己', '者', '的话', '那', '就', '打电话'],
     ['想', '学习', '那', '就', '来', '关注', '呀']]
    
    # 停用词表
    stopwords = ['的','呀','这','那','就','的话','如果']
    
    # 去掉文本中的停用词
    def drop_stopwords(contents, stopwords):
        contents_clean = []
        for line in contents:
            line_clean = []
            for word in line:
                if word in stopwords:
                    continue
                line_clean.append(word)
            contents_clean.append(line_clean)
        return contents_clean
    
    print(drop_stopwords(fenci_list,stopwords))
    

    我们来一下结果,对比发现少了一些停用词

    [['篇文章', '对', '你', '有所', '帮助', '点个', '赞', '呗'],
     ['想', '联系', '炼己', '者', '打电话'],
     ['想', '学习', '来', '关注']]
    

    我觉得上面的操作也可应用在去除一些你不想要的符号上面,你可以把没有用的符号添加到停用词表里,那么它也会被去掉

    5.将文本转为tfidf向量并输入到算法中

    最后这一步你可以参照这篇文章操作,使用不同的方法计算TF-IDF值

    不过为了完整起见,我在这里给大家再演示一遍操作流程。咱们就以上面去掉停用词的数据为例

    word_list = [['篇文章', '对', '你', '有所', '帮助', '点个', '赞', '呗'],
     ['想', '联系', '炼己', '者', '打电话'],
     ['想', '学习', '来', '关注']]
    
    from gensim import corpora,models
    dictionary = corpora.Dictionary(word_list)
    new_corpus = [dictionary.doc2bow(text) for text in word_list]
    tfidf = models.TfidfModel(new_corpus)
    
    tfidf_vec = []
    for i in range(len(words)):
        string = words[i]
        string_bow = dictionary.doc2bow(string.split())
        string_tfidf = tfidf[string_bow]
        tfidf_vec.append(string_tfidf)
    print(tfidf_vec)
    

    在这里我们就可以得到tfidf向量,这里调用的是gensim库计算的tfidf向量,你也可以直接调用sklearn库来计算tfidf向量,怎么操作看上面的那篇文章,里面都有介绍。我们来看一下得到的tfidf向量长什么样子

    [[(0, 0.35355339059327373),
      (1, 0.35355339059327373),
      (2, 0.35355339059327373),
      (3, 0.35355339059327373),
      (4, 0.35355339059327373),
      (5, 0.35355339059327373),
      (6, 0.35355339059327373),
      (7, 0.35355339059327373)],
     [(8, 0.18147115159841573),
      (9, 0.49169813431045906),
      (10, 0.49169813431045906),
      (11, 0.49169813431045906),
      (12, 0.49169813431045906)],
     [(8, 0.2084041054460164),
      (13, 0.5646732768699807),
      (14, 0.5646732768699807),
      (15, 0.5646732768699807)]]
    

    很明显,句子的长度不一样,所以得到的tfidf向量的维度也不一样。那么我们该怎么操作呢?——可以用lsi向量来保证向量的维度一致

    # num_topics参数可以用来指定维度
    lsi_model = models.LsiModel(corpus = tfidf_vec,id2word = dictionary,num_topics=2)
    
    lsi_vec = []
    for i in range(len(words)):
        string = words[i]
        string_bow = dictionary.doc2bow(string.split())
        string_lsi = lsi_model[string_bow]
        lsi_vec.append(string_lsi)
    print(lsi_vec)
    

    看一下结果

    [[(1, 2.8284271247461907)],
     [(0, 1.6357709481422218)],
     [(0, 1.4464385059387106)]]
    

    sklearn库的机器学习算法很齐全,你可以调用这些算法包来进行操作。但是sklearn里的算法要求数据的格式必须是array格式,所以我们得想办法把gensim计算的tfidf向量格式转化为array格式。按照下面操作即可

    from scipy.sparse import csr_matrix
    data = []
    rows = []
    cols = []
    line_count = 0
    for line in lsi_vec:
        for elem in line:
            rows.append(line_count)
            cols.append(elem[0])
            data.append(elem[1])
        line_count += 1
    lsi_sparse_matrix = csr_matrix((data,(rows,cols))) # 稀疏向量
    lsi_matrix = lsi_sparse_matrix.toarray() # 密集向量
    print(lsi_matrix)
    

    结果长这样

    array([[0.        , 2.82842712],
           [1.63577095, 0.        ],
           [1.44643851, 0.        ]])
    

    我们的目的已经达到。肯定有人会问,你为啥不直接调用sklearn里计算tfidf向量的方法,那多方便,多直接。何必这样转换来转换去的。

    这是有原因的,假设你的数据量很大,几百万条,那么用sklearn计算的tfidf向量维度会非常大,最后调用机器学习算法包的时候就会报错。如果你调用gensim来计算tfidf向量,然后再采用上述的方法,就可以对向量进行降维了,而且你还可以指定维度。在lsi向量那一步进行操作,num_topics参数可以用来指定维度

    总结

    以上便是整个中文文本的预处理了,这个流程可以应付大多数的文本处理任务。你把文本转换为向量之后,后面的操作就很容易了,调用sklearn算法包,或者自己写一个机器学习的算法,这些都是有章法可循的。

    希望可以帮助到大家,如果你觉得这篇文章对你有一定的帮助,那就点个赞支持一下吧!如果有什么问题的话也可以在文章下面评论,我们一起交流解决问题!

    欢迎扫码关注

  • 相关阅读:
    hdu 1166 敌军布阵
    UVA 100
    dfs和bfs 变形课
    hdu 1002 A + B Problem II
    连连看 杭电1175
    跳格子 DFS 加 奇偶截枝
    c语言 判断两直线段是否相交
    poj 3067 Japan
    数状数组
    UVA 10881 Piotr's Ants
  • 原文地址:https://www.cnblogs.com/lookfor404/p/9784630.html
Copyright © 2011-2022 走看看