MENU

作成した学習モデルでスパムの判定

f:id:hanamichi_sukusuku:20210130153748p:plain

実行結果

f:id:hanamichi_sukusuku:20210130153824p:plain

 

hanamichi-sukusuku.hatenablog.com

 

このプログラムでは上記で作成した学習モデルを用いて自身で作成したテキストのスパム判定を行っている。

 

 

三連引用符

test_text1 = """
会社から支給されているiPhoneの調子が悪いのです。
修理に出すので、しばらくはアプリのテストができません。
"""
test_text2 = """
億万長者になる方法を教えます。
すぐに以下のアドレスに返信して。
"""

 

この"""で囲まれているのは三連引用符と言って、この"""や'''で囲まれ定義した文字列は、文字列の中で行われた改行は、文字としての改行として扱われる。

test_text1の場合、

"会社から支給されているiPhoneの調子が悪いのです。\n修理に出すので、しばらくはアプリのテストができません。"

このように記述した場合と同義になる。

 

ファイルやモデルの準備

data_file = "./ok-spam.pickle"
model_file = "./ok-spam-model.pickle"
label_names = ['OK', 'SPAM']
# 単語辞書を読み出す --- (※2)
data = pickle.load(open(data_file, "rb"))
word_dic = data[2]
# MeCabの準備
# 学習済みモデルを読み出す --- (※3)
model = pickle.load(open(model_file, "rb"))

 

変数dataには[ラベルデータ, 単語頻出のデータ, 単語辞書]という形でデータが格納されている。なのでword_dic = data[2]では単語辞書を変数に格納している。

 

各テキストを関数に渡し、スパムか非スパムかの判定を行う

if __name__ == "__main__": # --- (※8)
 check_spam(test_text1)
 check_spam(test_text2)

 

 

check_spam()関数、テキストがスパムかどうか判定する

def check_spam(text):
 # テキストを単語IDのリストに変換し単語の頻出頻度を調べる
  zw = np.zeros(word_dic['__id'])
  count = 0
  s = tagger.parse(text)
 # 単語毎の回数を加算 --- (※5)
  for line in s.split("\n"):
   if line == "EOS": break
   org = line.split("\t")[3]# 単語の原型
   if org in word_dic:
    id = word_dic[org]
    zw[id] += 1
    count += 1
    zw = zw / count # --- (※6)
 # 予測
  pre = model.predict([zw])[0] # --- (※7)
  print("- 結果=", label_names[pre])

 

単語辞書と同じ要素数の配列を用意。これにより受け取ったテキストを辞書からIDに変換し、そのIDの出現回数をカウントすることができる。

tagger.parse()で形態素解析

s.split("\n")で各単語の情報のまとまりで区切られた配列を作成。

line.split("\t")[3]で情報のまとまりを配列に変換し、原型を取得している。

f:id:hanamichi_sukusuku:20210130161032p:plain

上記の画像はs.split("\n") の中身を出力したものである。

 

if org in word_dic:ではその単語の原型が辞書に含まれている時、0で初期化した配列から辞書のIDと同じものの値を1足す。変数countは総回数を数え、最後に作成した配列zwからcountを割ることで単語の出現頻度のデータを作成している。

 

mode.predict([zw])[0]で結果を予測し、配列として取得されるのでインデックス番号を指定することで値のみを取得する。

label_names["OK", "SPAM"]と定義しているので予測結果が0ならスパムではない、1ならスパムということになる。