标签:中文文本预处理
做者:炼己者
---
欢迎你们访问个人简书以及个人博客,你们若是感受格式看着不舒服,也能够去看个人简书,里面也会有发布
本博客全部内容以学习、研究和分享为主,如需转载,请联系本人,标明做者和出处,而且是非商业用途,谢谢!算法
- 机器学习个人理解就是把各类原始的东西变成机器能够理解的东西,而后再用各类机器学习算法来作操做。机器能够理解的东西是什么呢?——向量 。因此不论是图片仍是文字,要用机器学习算法对它们进行处理,就要把它们转为向量。
- 网上大部分都是处理英文文本的资料,本文就以中文文本为例,将原始的文本通过预处理获得文本向量
- 去除指定无用的符号
- 让文本只保留汉字
- 对文本进行jieba分词
- 去除停用词
- 将文本转为tfidf向量并输入到算法中
咱们拿到的文本有时候颇有不少空格,或者你不想要的符号,那么你就能够用这个方法去掉全部你不想要的符号。在这里我以空格为例微信
content = [' 欢迎来到 炼己者的博客','炼己者 带你入门NLP '] # 去掉文本中的空格 def process(our_data): m1 = map(lambda s: s.replace(' ', ''), our_data) return list(m1) print(process(content))
传入的参数our_data是个列表,此函数能够把文本中的全部空格所有去掉。看一下输出的结果。能够发现,全部的空格都被删掉了app
['欢迎来到炼己者的博客', '炼己者带你入门NLP']
这个操做我最喜欢,他能够去掉全部的符号,包括数字、标点、字母等等机器学习
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)
而后咱们来看一下输出的内容,你会发现只剩下中文了。这个操做实在太骚了函数
['若是这篇文章对你有所帮助那就点个赞呗', '若是想联系炼己者的话那就打电话', '想学习那就来关注呀']
首先你得下载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))
而后你就能够获得分词的结果了spa
[['若是', '这', '篇文章', '对', '你', '有所', '帮助', '那', '就', '点个', '赞', '呗'], ['若是', '想', '联系', '炼己', '者', '的话', '那', '就', '打电话'], ['想', '学习', '那', '就', '来', '关注', '呀']]
首先你得上网下载一个停用词表,也能够关注个人微信公众号:
ZhangyhPico,回复停用词表,就能够拿到了。而后把这份停用词转换为列表
为了方便你们理解,在这里我就假设一个停用词表了,咱们以上面分好词的数据为例code
# 分好词的数据 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))
咱们来一下结果,对比发现少了一些停用词orm
[['篇文章', '对', '你', '有所', '帮助', '点个', '赞', '呗'], ['想', '联系', '炼己', '者', '打电话'], ['想', '学习', '来', '关注']]
我以为上面的操做也可应用在去除一些你不想要的符号上面,你能够把没有用的符号添加到停用词表里,那么它也会被去掉blog
最后这一步你能够参照这篇文章操做,使用不一样的方法计算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算法包,或者本身写一个机器学习的算法,这些都是有章法可循的。
但愿能够帮助到你们,若是你以为这篇文章对你有必定的帮助,那就点个赞支持一下吧!若是有什么问题的话也能够在文章下面评论,咱们一块儿交流解决问题!
欢迎扫码关注