自然語言處理--文本二分類

我寫東西一向簡單暴力,因為懶。但nlp說起來算的上一個大工程了。雖然今天就啰嗦一點講一講,當然還是需要一定的統計學基礎和代碼基礎。

自然語言處理里,我先前寫過一個電商情感分析,是個調包俠,snownlp,就是對一類短評文本做一個正負向的情感分類,當然我見過一個情感分析的演算法,算得上簡單,就是有三個類,對情感詞檢索位置,再檢索前面的程度副詞,分配不同的權重。再對不同的數值計算,進行比較,歸類。snownlp的源碼我沒看過,所以也不了解他是基於字典的還是什麼別的什麼。還有文本聚類lda,同樣也是調包gensim。

當然扯遠了。

咱們回歸到文本二分類,有諸如字典類,基於knn,基於svm,當然神經網路NN自然不用說了。

這裡講的是基於字典的,利用字典然後用貝葉斯進行計算概率。

貝葉斯我就不在這裡闡述了,入門的很清楚貝葉斯的偉大。

好了言歸正傳。我們對每一列文本,分詞之後保存,然後計算貝葉斯計算,原理是很簡單,說白了主要還是文本的處理。

今天是一個很簡單的例子:對白話文和文言文分類。這裡懶省事,沒有進行分詞。而是利用單字代替詞,另外也沒有把所有詞都帶進去,只是選取了文言文里常用的虛詞和代詞作為特徵。

算得上是一個懶省事的方法了。當然中間除了貝葉斯還涉及數學裡的拉普拉斯平滑。

上代碼。

#讀取數據import pandasimport numpy as np with open(~train.txt) as traindata: sentences = pandas.read_csv(traindata) y = sentences.yx = sentences.text # 特徵詞字典ancient_chinese_words = set([,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,, ,,,,,,,,,,,,,,,,,,,, ,,,,,,,,,]) # 計算字典中每個字在每個文體中出現的概率sentences_ancient = x[y == 1]sentences_modern = x[y == 0] from collections import defaultdict # 文言文ancient_words_freq = defaultdict(int) ancient_count = sum([len(sentence) for sentence in sentences_ancient]) for sentence in sentences_ancient: for word in sentence: if word in ancient_chinese_words: ancient_words_freq[word] += 1 # 白話文modern_words_freq = defaultdict(int) modern_count = sum([len(sentence) for sentence in sentences_modern]) for sentence in sentences_modern: for word in sentence: if word in ancient_chinese_words: modern_words_freq[word] += 1 # 讀取測試集with open(~/test.txt) as testdata: sentences_test = pandas.read_csv(testdata) # 預測sentences_type = []def get_prob(word, freq, amcount): #引入拉普拉斯平滑 return (freq[word] + 1)/(len(freq) + amcount) prio_prob_modern = len(sentences_modern)/(len(sentences_ancient)+ len(sentences_modern)) #先驗概率prio_prob_ancient = len(sentences_ancient)/(len(sentences_ancient)+ len(sentences_modern))for sentence in sentences_test[text]: prob_modern = prio_prob_modern prob_ancient = prio_prob_ancient for word in sentence: prob_modern = get_prob(word, modern_words_freq, modern_count) * prob_modern prob_ancient = get_prob(word, ancient_words_freq, ancient_count) * prob_ancient sentences_type.append(prob_ancient/(prob_ancient + prob_modern)) sentences_test[y] = sentences_type # 保存數據sentences_test.to_csv(myresult1.csv, sep=,, columns=[id, y], index=False)

效果圖

二分類可以用準確率召回率來評測,當然還是log-loss指標計算方式,來測評。

log-loss的取值範圍是0到正無窮。越接近0,說明模型預測的結果越佳。log-loss的計算公式為:

其中n為總樣本數,yi為第i個樣本的真實標籤,pi為預測第ii個樣本的標籤是1的概率。

比如說有兩句話:

「少時 一狼徑去 其一犬坐於前」:實際為文言文。模型預測為文言文的概率為0.8。

「一會兒 一隻狼徑直走開了 另一隻狼像狗似的蹲坐在屠夫的前面」:實際為白話文。模型預測其為文言文的概率為0.4。

那麼在這個兩個樣本上的log-loss

指標越接近於0效果越好,這裡在0.3左右。

--------------------------------------------------------------------------------------------------------------

寫在最後:當然這裡的方法是取巧了,正常的話我們還是要分詞,分完詞還可以針對詞計數,對於過小詞數進行刪除,用較多的詞來作為特徵,當然多不一定就好,比如的啊嗎這些,所以可以用停用詞或者td—tdif:利用在單個文本的詞頻乘以所有文本的詞頻,在單個裡多,所以文本出現少,說明是優秀的特徵,如果在所以文檔里都出現很多次,那說明是爛大街的字詞。

原理是很簡單的,第一會了不難,第二也確實簡單,主要難在文本處理上。

這裡是二分類,如果是多分類的話,聽說是利用貝葉斯多項式。包有nltk里的樸素貝葉斯,他進入的形式是字典形式 如[{詞1:1,詞2:0},類1],還有一個sklearn的貝葉斯多項式包MutinomialNB包他的進入形式是對應的特徵[1,0,0,1,1],類別。【10代表有無,nltk只能進入一個參數,所以需要zip,而另一個進入兩個參數】


推薦閱讀:

機器學習評估指標
iPIN網的大數據來源及數據分析處理方式?
「七步走戰略」輕鬆搞定數據分析
如何提取特徵?
通俗易懂說數據挖掘十大經典演算法

TAG:數據分析 | 數據挖掘 | Python |