python 自然言語処理、英語、日本語、タイ語の言語判定を行うプログラム

 

f:id:hanamichi_sukusuku:20210112192244p:plain

実行結果

f:id:hanamichi_sukusuku:20210112192314p:plain

このプログラムは日本語、英語、タイ語の言語判定を行うプログラム。

 

モジュールインポート

import numpy as np
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score

 

numpyは強力な数値計算ライブラリ。

アルゴリズムチートシートを確認するとLinearSVCアルゴリズムでは上手に分類できない場合でテキストデータを扱う場合、NaiveBayesを利用することが推奨されている。

そして、scikit-learnでは3種類のNaiveBayes分類器が用意されているが今回はシンプルに利用できるGaussianNBを利用する。

 

Unicodeのコードポイント頻度測定

def count_codePoint(str):
 # Unicodeのコードポイントをアドレスとする配列を用意 --- (*2)
 counter = np.zeros(65535)

  for i in range(len(str)):
   # 各文字をUnicodeのコードポイントに変換 --- (*3)
   code_point = ord(str[i])
    if code_point > 65535 :
      continue
    # 対応するアドレスの出現回数をインクリメント --- (*4)
   counter[code_point] += 1

  # 各要素を文字数で割って正規化 --- (*5)
  counter = counter/len(str)
   return counter

 

Unicodeとは符号化文字集合と言われ世界中の文字に対して割り当てられ管理されている番号の集合体。ここで割り当てられている番号をコードポイントという。なぜ世界中の文字を番号に振り分けているかというと人がわかる文字をコンピューターが認識するのに一度数字に変換してから読み取るからである。

例えば

pythonではord()でコードでコードポイントが取得できる。

>>> ord("あ")
12354

この様に取得できる。

 

ord(str[i])で引数で受けとった文字の先頭から末尾までの文字を取得してコードポイントに変換。

if文でコードポイントが65535より大きい数字のものの場合処理を飛ばす。

初期化したcounterに格納されている配列のインデックスがコードポイントの箇所に1を足す。こうすることでどの文字がどのくらいの頻度で使用されているかわかるので文字の出現頻度による言語判定ができる。

counter/len(str) では正規化というより全体の文字数に対しての割合を格納しなおしていると考えた方が良い。

最後に呼び出し元に文字の出現頻度を示した割合の配列を返す。

 

学習用データの作成

x_train = [count_codePoint(ja_str),count_codePoint(en_str),count_codePoint(th_str)]
y_train = ['ja','en','th']

 

x_trainではリスト内で関数を呼び出してデータを格納している。

 

学習

clf = GaussianNB()
clf.fit(x_train, y_train)

 

評価用データの用意

ja_test_str = 'こんにちは'
en_test_str = 'Hello'
th_test_str = 'สวัสดี'

x_test = [count_codePoint(en_test_str),count_codePoint(th_test_str),
      count_codePoint(ja_test_str)]
y_test = ['en', 'th', 'ja']

 

評価

y_pred = clf.predict(x_test)
print(y_pred)
print("正解率 = " , accuracy_score(y_test, y_pred))