Pythonでいろいろやってみる

Pythonを使った画像処理や機械学習などの簡単なプログラムを載せています。

Linear SVCによる言語判定 - 頻出単語を特徴量に使う

scikit-learnは機械学習用ライブラリで以下のアルゴリズムが使用できます。

classificationアルゴリズムの一つ、Linear Support Vector Classificationを用いた言語判定器を作ります。線形の境界を引いて識別する手法です。
英語では'the'が最も使用頻度が高いのですが、登場頻度の高い単語(頻出単語)が言語によって違うだろうと考え、その出現頻度を特徴量として機械学習させ言語判定します。手順は

  • 学習用データとして6つの言語のテキストファイルを作り、それぞれの頻出単語(ベスト5)を調べる
  • 全言語の頻出単語リストを特徴量リストとする
  • 学習用データを4分割して特徴量リストの出現頻度を調べ特徴量とする
  • 分類器(Linear SVC)による言語判定
環境
  • windows10 home
  • Anaconda 3/ jupyter notebook 5.6.0
  • Python 3.7.0
  • scikit-learn 0.19.2
準備

ドイツ語、英語、フランス語、インドネシア語、イタリア語、マレーシア語のニュースサイトなどから複数の記事をコピーペーストして4000語程度のテキストファイルを作り、フォルダlanguage内に保存します(例、Deutsch.txt)。また、テスト用データとして数100語程度のテキストファイルを作り、同様にフォルダlanguage内に保存します(例、Deutsch_test.txt)。

コード
#モジュールのインポート
import collections
from sklearn import svm, metrics

#各言語のテキストファイルから頻出単語を抽出
words_n = 5
feature_words =[] 
language_list=['Deutsch','English','French','Indonesian','Italian','Malay']

print('■■各言語の頻出単語■■')
for language in language_list:
    file_name = 'languages/'+language+'.txt'

    with open(file_name,mode='r',encoding = 'utf-8-sig') as f:
        read_text = f.read()
    word_list=read_text.split()
    c = collections.Counter(word_list)

    for i in range(words_n):
        feature_words.append(c.most_common(words_n)[i][0])

for language,i in zip(language_list,range(len(language_list))):        
    print(language,feature_words[i*words_n:(i+1)*words_n])

feature_words_unique = list(set(feature_words))    
print('■■重複する単語を除いたリスト■■')
print(feature_words_unique)

#学習用データ作成
label=[]
data_set_matrix=[]

for language in language_list:
    file_name = 'languages/'+language+'.txt'

    with open(file_name,mode='r',encoding = 'utf-8-sig') as f:
        read_text = f.read()
    word_list=read_text.split()
    data_size=int(len(word_list)/4)
    
    for i in range(4):
        label.append(language)
        data_set = []
        
        for feature_word in feature_words_unique:
            counter = word_list[i*data_size:(i+1)*data_size].count(feature_word)/data_size
            data_set.append(counter)
        data_set_matrix.append(data_set)
        
#機械学習
clf = svm.SVC()
clf.fit(data_set_matrix,label)

print('■■学習データを使って検証■■')

predict = clf.predict(data_set_matrix)
score = metrics.accuracy_score(label,predict)

print('<正解>')
print(label)
print('<予測>')
print(predict)
print('<正解率>')
print(score)

print('■■テスト用データを使って検証■■')

label_test=[]
test_data_set=[]

for language in language_list:
    file_name = 'languages/'+language+'_test.txt'

    with open(file_name,mode='r',encoding = 'utf-8-sig') as f:
        read_text = f.read()
    word_list=read_text.split()
    label_test.append(language)
    data_set=[]
    for feature_word in feature_words_unique:
        counter = word_list.count(feature_word)/len(word_list)
        data_set.append(counter)
    test_data_set.append(data_set)

predict = clf.predict(test_data_set)
score = metrics.accuracy_score(label_test,predict)

print('<正解>')
print(label_test)
print('<予測>')
print(predict)
print('<正解率>')
print(score)
実行結果

6言語から各5個、計30個の頻出単語が抽出され、そこから重複する単語(la,yang,dan,di)をそれぞれ重複分に減らし、24個の頻出単語リストができました。(これを特徴量に使います)
24個の学習用データを使った場合、1個不正解で正解率は0.958となりました。マレーシア語をインドネシア語に間違えています。
また、テスト用データを用いた場合にもマレーシア語をインドネシア語に間違えて正解率は0.833となりました。

■■各言語の頻出単語■■
Deutsch ['die', 'der', 'und', 'in', 'zu']
English ['the', 'to', 'and', 'of', 'a']
French ['de', 'la', 'à', 'le', 'les']
Indonesian ['yang', 'dan', 'di', 'untuk', 'dengan']
Italian ['di', 'e', 'la', 'a', 'il']
Malay ['dan', 'yang', 'di', 'kepada', 'ini']
■■重複する単語を除いたリスト■■
['zu', 'a', 'e', 'yang', 'the', 'les', 'le', 'la', 'dan', 'di', 'of', 'dengan', 'ini', 'die', 'untuk', 'and', 'de', 'der', 'il', 'à', 'to', 'in', 'kepada', 'und']
■■学習データを使って検証■■
<正解>
['Deutsch', 'Deutsch', 'Deutsch', 'Deutsch', 'English', 'English', 'English', 'English', 'French', 'French', 'French', 'French', 'Indonesian', 'Indonesian', 'Indonesian', 'Indonesian', 'Italian', 'Italian', 'Italian', 'Italian', 'Malay', 'Malay', 'Malay', 'Malay']
<予測>
['Deutsch' 'Deutsch' 'Deutsch' 'Deutsch' 'English' 'English' 'English' 'English' 'French' 'French' 'French' 'French' 'Indonesian' 'Indonesian' 'Indonesian' 'Indonesian' 'Italian' 'Italian' 'Italian' 'Italian' 'Indonesian' 'Malay' 'Malay' 'Malay']
<正解率>
0.9583333333333334
■■テスト用データを使って検証■■
<正解>
['Deutsch', 'English', 'French', 'Indonesian', 'Italian', 'Malay']
<予測>
['Deutsch' 'English' 'French' 'Indonesian' 'Italian' 'Indonesian']
<正解率>
0.8333333333333334

以下のサイトを参考にさせていただきました

scikit-learn >> Choosing the right estimator
scikit-learn >> 1.4. Support Vector Machines
scikit-learn >> sklearn.svm.LinearSVC
ウエディングパーク Tech Blog >> 【機械学習入門|Python|scikit-learn】結局何ができる?cheat-sheetから解説してみる篇

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村