
【機械学習】単純なアルゴリズムで迷惑メールを分類してみた
2021.12.20
迷惑メールを分類してみた
今回は、「単純なアルゴリズムで迷惑メールを分類する」というテーマで、紹介していきます。
具体的には、
- ナイーブベイズ
- ロジスティック回帰
- パーセプトロン
を使って、それぞれでどのぐらいの精度が出るのかを、調査してみたいと思います。
わかりやすくまとめていきますので、ぜひチャレンジしてみてくださいね!
ナイーブベイズ
このナイーブベイズについて説明するには、「ベイズの定理」について知る必要があります。
「ベイズの定理」とは、以下で表される、条件付き確率に関する式です。
$$P(B|A)=\frac{P(A|B)P(B)}{P(A)}$$
「\(P(B)\) 」は、事象 A が起きるかどうかに関わらず、事象 B が起こる確率です。
「\(P(B|A)\) 」は、事象 A が起きた場合に、事象 B が起きる確率です。
基本的には、事象 A が実際に起こったことやデータ、事象 B が求めたい情報や分類したいものになります。
たとえば、ある土地では、雨が降る確率が「 \(P(rain)=0.1\)」になりますね!
ナイーブベイズとは
「ナイーブベイズアルゴリズム」とは、ベイズの定理を元に与えられたデータから、最も確からしいものはどれかを検証するアルゴリズムです。
わかりやすく、文書の分類で考えてみましょう。
与えられた文書を、「経済・スポーツ・芸能」などのカテゴリに分けるとします。
これら各カテゴリの文書に、あらかじめ、出現する単語の頻度を学習させておくのです。
たとえば経済カテゴリなら、「金融・日経平均・ビジネス」などの単語が、出現しやすくなります。
スポーツカテゴリなら、「野球・応援・監督」などの単語が、文書に出現しやすくなりますね。
与えられた文書に出現する単語を解析し、このデータを元に、どのカテゴリの文書に最もふさわしいかを出力していくわけです。
ナイーブベイズアルゴリズムには課題も
ただし、ナイーブベイズアルゴリズムは、現実世界の問題へは応用しにくいです…。
というのも、「それぞれのデータは独立である」という、仮定に基づいているため。
しかし、比較的簡単なアルゴリズムで、計算リソースも少なく済むので、条件を満たすようなデータに対しては十分に使えます。
迷惑メール分類
では実際に、迷惑メールの分類を行います。
今回学習させるデータは、kaggle の「sms-spam-collection-dataset.zip」。
【 kaggle:学習データ】
https://www.kaggle.com/uciml/sms-spam-collection-dataset
以下にコードを載せます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | import random import matplotlib.pyplot as plt import numpy as np import pandas as pd from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import CountVectorizer from sklearn.naive_bayes import BernoulliNB # CSV読み込み・データ整理 df = pd.read_csv('/spam.csv', encoding='latin-1') df.drop(['Unnamed: 2', 'Unnamed: 3', 'Unnamed: 4'], axis=1, inplace=True) df.rename(columns={"v1":"label", "v2":"text"}, inplace=True) n = random.randint(0,5567) cut_data = df.loc[n:n+4] df.drop([n,n+1,n+2,n+3,n+4], axis=0, inplace=True) # トレーニング・評価データ分割 X = pd.DataFrame(df['text']) Y = pd.DataFrame(df['label']) X_train, X_test, Y_train, Y_test = train_test_split(X, Y, train_size=0.7, test_size=0.3, random_state=1) # 単語の出現回数取得 vec_count = CountVectorizer(min_df=3) vec_count.fit(X_train['text']) # トレーニング・評価データをベクトル化 X_train_vec = vec_count.transform(X_train['text']) X_text_vec = vec_count.transform(X_test['text']) # ベルヌーイモデルを利用(2値分類) model = BernoulliNB() model.fit(X_train_vec, Y_train['label']) # 予測テキストデータ作成 check_data_text = np.array(cut_data["text"]) check_data_label = np.array(cut_data["label"]) df_data = pd.DataFrame(check_data_text, columns=['text']) # 予測テキストデータをベクトル化 input_vec = vec_count.transform(df_data['text']) # 予測結果の表示 print(model.predict(input_vec)) print(cut_data['label']) |
まずは与えられたデータで、「スパムメール」と「通常メール」に含まれる、単語の頻度を数えます。
それを元に、単語のベクトル化を行います。
単語の出現頻度に関するデータをベクトル化させることで、実際に学習をして、分類器を作成していくのです。
作成した分類器に、あらかじめ分離しておいた、予測用のデータを渡します。
結果は、「5/5」で正解となりました。
パーセプトロン
「パーセプトロン」とは、現在のディープラーニング分野の大元となるアルゴリズムです。
このアルゴリズムでは、複数の入力に対し、重みをつけて学習させておいたバイアスを加算します。
「0」か「1」を出力する、単層ニューラルネットワークです。
式で表すと、以下のようになります。
$$(出力)=b+x_1w_1+x_1w_1+x_1w_1+……$$
それぞれの意味は、次の通り。
- b:バイアス
- x_n:入力
- w_n:x_nにかかる重み
迷惑メール分類
では、パーセプトロンを使って、迷惑メールの分類をしていきましょう!
以下にコードを載せます。
1 2 3 4 5 6 7 8 9 10 | # X_train_vecやY_trainはナイーブベイズで整えたデータを再利用 from sklearn.linear_model import Perceptron as Pec # パーセプトロン model = Pec(eta0 = 0.1,random_state=1,shuffle=True) model.fit(X_train_vec,Y_train['label']) # 予測結果の表示 print(model.predict(input_vec)) print(cut_data['label']) |
今回は、ナイーブベイズの時に整えたデータを、そのまま流用しました。
上で説明した通り、ベクトル化した単語を入力として重みを学習し、分類器を作成します。
こちらも、「5/5」で正解でした。
ロジスティック回帰
ロジスティック回帰は、一般化線形モデルのひとつです。
基本的には、パーセプトロンと同じモデルを利用します。
入力に対して、重みをつけバイアスを加えて、出力を決定するのです。
具体的に、パーセプトロンとの違いは、次のとおり。
- パーセプトロン:「確率的勾配降下法」を利用
- ロジスティック回帰:「座標降下法」や「準ニュートン法」を利用
迷惑メール分類
では、ロジスティック回帰を使って、迷惑メール分類をしていきましょう!
1 2 3 4 5 6 7 8 | # X_train_vecやY_trainはナイーブベイズで整えたデータを再利用 from sklearn.linear_model import LogisticRegression as LogR model = LogR(random_state=1) model.fit(X_train_vec,Y_train['label']) # 予測結果の表示 print(model.predict(input_vec)) print(cut_data['label']) |
データは、上2つと同じものを使っています。
やってることもほとんど同じで、
- 単語をベクトル化
- それを学習させて重みを決定
- 予測テスト
という流れです。
こちらは正解率が「4/5」で、1問だけスパムメールを、通常のメールと間違えていました…。
さいごに
今回は、「ナイーブベイズ」「パーセプトロン」「ロジスティック回帰」という3つの単純なアルゴリズムで、迷惑メールの分類(文書分類)を行いました!
どれも簡単で扱いやすく、理解もしやすいアルゴリズムだったかと思います。
精度も良かったので、2種類の文書分類程度なら、このぐらい簡単なものを使ってもいいかもしれませんね。
ぜひ、皆さんもお試しあれ!
こちらの記事もオススメ!
書いた人はこんな人

- 「好きを仕事にするエンジニア集団」の(株)ライトコードです!
ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。
システム開発依頼・お見積もり大歓迎!
また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です!
インターンや新卒採用も行っております。
以下よりご応募をお待ちしております!
https://rightcode.co.jp/recruit
ITエンタメ10月 13, 2023Netflixの成功はレコメンドエンジン?
ライトコードの日常8月 30, 2023退職者の最終出社日に密着してみた!
ITエンタメ8月 3, 2023世界初の量産型ポータブルコンピュータを開発したのに倒産!?アダム・オズボーン
ITエンタメ7月 14, 2023【クリス・ワンストラス】GitHubが出来るまでとソフトウェアの未来