Python中文分詞處理小結
來自專欄機器學習與數據挖掘6 人贊了文章
最近在寫股票預測,大致是根據每天的文章及股票漲跌來預測未來的股票走勢。
這裡的中文文章就少不了分詞的處理,我把自己寫作業用的兩種記錄一下:
- 自己N-gram分詞,然後再根據tf、tfidf等來進行篩選
- 使用正則表達式抽取中文部分,然後使用jieba分詞
N-gram分詞
先來講講N-gram分詞,上代碼
#Get N-gram term List of the article set and we delete the term if its term frequency is less than 3 in the articledef getNgramTermList(n, records): termList = [] lenOfRecords = len(records) for content in records[:lenOfRecords]: names = "[
|.|,||?|"|%|`|(|)|d|_|!|;|#|\|/|$|&|*|{|}|-|@|:|,|、|。|(|)]|「|」|!| |?|;|.|:|》|《|○" others ="[0|1|2|3|4|5|6|7|8|9|『|』|◆|?||=|~|-|—|─|…|/|】|【| | |xa0|*]" exclude = string.digits + string.punctuation + string.ascii_letters + names + others charList = [ch for ch in content if ch not in exclude] if len(charList)>n-1: frame = DataFrame([.join(ch) for ch in [charList[i:i+n] for i in range(0, len(charList)-n+1)]]) bigramSeries = frame[0].value_counts() newBigram = bigramSeries.to_dict() termList.append(newBigram) return termList
這個大致的意思是:
- 讀進一篇文章,將文章中的英文、數字、標點符號都去掉
- 上面的others、names...其實不需要,看實際需求,而且中文標點符號在string中也有
- 把每個字都按順序分別存進一個list中,這裡叫charList
- 將字元按照順序,按順序將其拼接成n-gram的模式,例如2 gram的話,就按charList順序兩兩組合起來,再存進DataFrame
- 這裡用DataFrame是因為我這裡主要計算的是往後的tfidf,所以,你根據自己的需求存
所以主要部分就是:
charList = [ch for ch in content if ch not in exclude]if len(charList)>n-1: frame = DataFrame([.join(ch) for ch in [charList[i:i+n] for i in range(0, len(charList)-n+1)]])
正則表達式 + jieba分詞
上代碼:
#jieba中文分詞,並獲取tfidf排名前3000詞(未採用),還要解決詞與vocabulary匹配的問題def jieba_Chinese(articles): all_articles2 = [] #使用正則選取文章中漢字的部分, 使用str()是為了防止TypeError: expected string or bytes-like object new_article = re.sub(r[^u4e00-u9fa5], , str(articles)) if new_article == : new_article = ?# new_article2 = jieba.analyse.extract_tags(new_article, topK=3000, withWeight=True, allowPOS=()) new_article2 = jieba.cut(new_article, cut_all=False) for word in new_article2: all_articles2.append(word) articles_dataFrame = DataFrame(all_articles2)[0].value_counts().to_dict() return articles_dataFrame
這個大致的意思是:
- 把文章讀取進來,直接用正則匹配其中的中文字元,保存起來
- 這裡有個小問題,如果有些文章是純英文或者標點符號數字之類的,由於無法匹配到中文字元,可能返回值就會是空字元,後續處理的時候可能會產生NaN的問題
- 所以我這裡加了一個判斷,如果返回的值是空的話,我則用一個生字來代替(不可取的方法,還是想過好的方法來吧)
- 把正則處理後的字元丟進jieba分詞里
- jieba分詞的cut方法,包含幾種模式,具體可以看看這裡[jieba分詞]
- 除了jieba.cut()之外,也可以用jieba.analyse.extract_tages()這個方法,而且可以直接給你返回tfidf值,並進行排序,我這裡自己寫了tfidf的計算,就沒用這個了
- 後面的處理的話,就是先將原來的返回值保存為字典,並轉成DataFrame計算頻率,然後轉成字元對應的字典,即{term : tf}模式
- 當然這部分是我自己的項目需求,跟分詞沒啥關係
所以主要的部分是:
new_article = re.sub(r[^u4e00-u9fa5], , str(articles)) #new_article2 = jieba.analyse.extract_tags(new_article, topK=3000, withWeight=True, allowPOS=())new_article2 = jieba.cut(new_article, cut_all=False)
另外想說,先用正則取出中文字元,是方便後面的jieba分詞,這裡Stop words的部分我也沒有進行處理,jieba提供了很方便的stop words處理,也可到這裡查看[github jieba]
小結
- 以上兩種方法仍然是太naive,用來應付課程作業還可以,但是要用到商業項目的話,還需要進行許多優化
- 當遇到需要中文 + 英文的文章分詞的時候,我還沒有具體用過,不過應該也會有寫好的項目,有空可以找找看
- 最後就是,要考慮程序的開銷問題,當然是資源消耗的越少越好啦
推薦閱讀:
※基於詞典的情感分析——簡單實例
※tensorflow用高級api實現文本分類初嘗試
※採用Graphviz繪製Stanford CoreNLP Parser的成分分析結果
※關於卷積神經網路處理情感分類的一些論文
※用注意力機制進行句子蘊含推理