1. 程式人生 > >自然語言處理一:基於樸素貝葉斯的語種檢測

自然語言處理一:基於樸素貝葉斯的語種檢測

本文來自是對七月線上寒小陽自然語言處理課程的總結。

本文使用樸素貝葉斯完成一個語種檢測的分類器,準確度經過簡單的引數調優可以達到99.1%。



機器學習的演算法要取得好效果,離不開資料,咱們先拉點資料(twitter資料,包含English, French, German, Spanish, Italian 和 Dutch 6種語言)瞅瞅。

# 讀取資料
in_f = open('data.csv')
lines = in_f.readlines()
in_f.close()
# 把資料和標籤以list形式存入到dataset中
dataset = [(line.strip()[:-3], line.strip()[-2:]) for line in lines]

檢視資料的樣子

print(dataset[:5])
[('1 december wereld aids dag voorlichting in zuidafrika over bieten taboes en optimisme',
  'nl'),
 ('1 mill\xc3\xb3n de afectados ante las inundaciones en sri lanka unicef est\xc3\xa1 distribuyendo ayuda de emergencia srilanka',
  'es'),
 ('1 mill\xc3\xb3n de fans en facebook antes del 14 de febrero y paty miki dani y berta se tiran en paraca\xc3\xaddas qu\xc3\xa9 har\xc3\xadas t\xc3\xba porunmillondefans',
  'es'),
 ('1 satellite galileo sottoposto ai test presso lesaestec nl galileo navigation space in inglese',
  'it'),
 ('10 der welt sind bei', 'de')]

為了一會兒檢測一下咱們的分類器效果怎麼樣,我們需要一份測試集。

所以把原資料集分成訓練集的測試集,咱們用sklearn自帶的分割函式。

from sklearn.model_selection import train_test_split
x, y = zip(*dataset)
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1)

模型要有好效果,資料質量要保證

我們用正則表示式,去掉噪聲資料

import re

def remove_noise(document):
    noise_pattern = re.compile("|".join(["http\S+", "\@\w+", "\#\w+"]))
    clean_text = re.sub(noise_pattern, "", document)
    return clean_text.strip()

remove_noise("Trump images are now more popular than cat gifs. @trump #trends http://www.trumptrends.html")

輸出為:
'Trump images are now more popular than cat gifs.'
下一步要做的就是抽取特徵,構建模型
from sklearn.feature_extraction.text import CountVectorizer
N = range(1, 10, 1)
test_score_list = []
for n in N:
    vec = CountVectorizer(
        lowercase=True,     # lowercase the text
        analyzer='char_wb', # tokenise by character ngrams
        ngram_range=(1, n),  # use ngrams of size 1 and 2
        max_features=1000,  # keep the most common 1000 ngrams
        preprocessor=remove_noise
    )
    vec.fit(x_train)

    # 把分類器import進來並且訓練
    from sklearn.naive_bayes import MultinomialNB
    classifier = MultinomialNB()

    classifier.fit(vec.transform(x_train), y_train)
    # 看看我們的準確率如何
    s = classifier.score(vec.transform(x_test), y_test)
    print('n-gram 的取值為',n,'所對應的精度取值',s)
    test_score_list.append(s)

由下圖可以看出當ngram的取值為4是精度最高:


畫出不同gram的不同取值對最後結果的影響

import matplotlib.pyplot as plt
plt.plot(N, test_score_list)
plt.title('Relationship of N and test_score')
plt.xlabel('N-gram')
plt.ylabel('test_score')
plt.show()

圖如下: