標籤:中文文本預處理
做者:煉己者
---
歡迎你們訪問個人簡書以及個人博客,你們若是感受格式看着不舒服,也能夠去看個人簡書,裏面也會有發佈
本博客全部內容以學習、研究和分享爲主,如需轉載,請聯繫本人,標明做者和出處,而且是非商業用途,謝謝!算法
- 機器學習個人理解就是把各類原始的東西變成機器能夠理解的東西,而後再用各類機器學習算法來作操做。機器能夠理解的東西是什麼呢?——向量 。因此不論是圖片仍是文字,要用機器學習算法對它們進行處理,就要把它們轉爲向量。
- 網上大部分都是處理英文文本的資料,本文就以中文文本爲例,將原始的文本通過預處理獲得文本向量
- 去除指定無用的符號
- 讓文本只保留漢字
- 對文本進行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算法包,或者本身寫一個機器學習的算法,這些都是有章法可循的。
但願能夠幫助到你們,若是你以爲這篇文章對你有必定的幫助,那就點個贊支持一下吧!若是有什麼問題的話也能夠在文章下面評論,咱們一塊兒交流解決問題!
歡迎掃碼關注