俺人〜OREGIN〜俺、バカだから人工知能に代わりに頑張ってもらうまでのお話

俺って、おバカさんなので、とっても優秀な人工知能を作って代わりに頑張ってもらうことにしました。世界の端っこでおバカな俺が夢の達成に向けてチマチマ頑張る、そんな小さなお話です。現在はG検定、E資格に合格し、KaggleやProbSpaceのコンペに参画しながら、Pythonや機械学習、統計学、Dockerなどの勉強中です。学習したことをブログにアウトプットすることで、自分の身に着けていきたいと思います。まだまだ道半ばですが、お時間がありましたら見て行ってください。

ランダムフォレストでキノコを分類する(Pythonによるスクレイピング&機械学習テクニック)

今回は、Webからキノコに関するデータをダウンロードして、ランダムフォレストで分類を行いました。

これまでは、数学的に境界を決定して分類するSVMサポートベクターマシン)という学習モデルを使ってきましたが、今回は、「ランダムフォレスト」という多数決で予測するクラスを決定する学習モデルを使っていきます。

今回も Pythonによるスクレイピング&機械学習開発テクニック増補改訂 Scrapy、BeautifulSoup、scik [ クジラ飛行机 ]の第4章を参考にさせていただきながら、取り組んでいます。 

では、振り返っていきたいと思います。

ランダムフォレストでキノコを分類する

1.準備(キノコのデータをダウンロードする)

まずは、キノコのデータをダウンロードします。

UCI機械学習リポジトリで公開されている毒キノコに関するデータを使って機械学習します。

https://archive.ics.uci.edu/ml/datasets/Mushroom/

コードは以下の通りで、「kinoko-download.py」に保存しました。 

import urllib.request as req
local= "kinoko.csv"
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/mushroom/agaricus-lepiota.data"
req.urlretrieve(url, local)
print("ok")

今回は、Jupyter notebookを使って実行を行いました。

Jupyter notebookについては、以下もご参照ください。

oregin-ai.hatenablog.com

Jupyter notebookで、Pythonのコードを書いた「.py」ファイルを実行するには、以下のように、「%run -i 」のあとにファイル名を指定して実行します。

%run -i kinoko-download.py

f:id:kanriyou_h004:20200613142807p:plain

図1.kinoko-download.py実行結果

ダウンロードした「kinoko.csv」ファイルの中身は以下の通りとなっています。

f:id:kanriyou_h004:20200613143005p:plain

図2.kinoko.csv

このCSVファイルの内容は、1行が一つのキノコを表しており、カンマで区切られた23個の特徴量がアルファベットで表されています。

左から1列目のアルファベットは、有毒かどうかの特徴を表しています。[p]はpoisonous(毒), [e]はeddible(食用)を表しています。

詳細は、以下のサイトの「Attribute Information:」をご参照ください。

https://archive.ics.uci.edu/ml/datasets/Mushroom

2.全体像

では、本題のランダムフォレストでキノコを分類するコードに入ります。

コード全体は以下の通りで、「kinoko-train.py」に保存しました。

import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics 
from sklearn.model_selection import train_test_split 

# データの読み込み
mr = pd.read_csv("kinoko.csv", header=None)

# データ中の記号を数値に変換する
label = []
data = []
for row_index, row in mr.iterrows():
    label.append(row.loc[0])
    row_data = []
    for v in row.loc[1:]:
        row_data.append(ord(v))
    data.append(row_data)

# 学習用とテスト用データに分ける
data_train, data_test, label_train, label_test = train_test_split(data, label)

# 学習と予測
clf = RandomForestClassifier()
clf.fit(data_train, label_train)
predict = clf.predict(data_test)

# 精度を確認
ac_score = metrics.accuracy_score(label_test, predict)
cl_report = metrics.classification_report(label_test, predict)
print("正解率=", ac_score)
print("レポート=\n", cl_report)

では、コードを順番に見ていきます。

3.データの読込

今回は、データの読込にpandasモジュールのread_csv()メソッド利用します。

一つ目の引数の"kinoko.csv"は、読み込むCSVファイル名です。

二つ目の引数の'header=None'は、カラム名を記載したヘッダ行がないことを表します。CSVファイルの1行目にカラム名が記載されている場合は、'header=0'とします。(1ではなく0なのでご注意を)

mr = pd.read_csv("kinoko.csv", header=None)

4.データの中の記号を数値に変換する

続いて、読み込んだデータがアルファベットで表された記号となっているので、機械学習ができるように、数値に変換します。 

まずは、正解ラベルデータを格納する[label]と、特徴データを格納する[data]を初期化します。

label = []
data = []

pandasのiterrows()メソッドをつかって、CSVファイルを読み込んだ[mr]から、1行ずつ行のインデックス[row_index]とその行のデータ[row]を処理していきます。 

for row_index, row in mr.iterrows():

各行の先頭の要素(row.loc[0])を正解ラベルデータ[label]に追加していきます。

    label.append(row.loc[0])

記号を数値に変換したデータを格納する一時的なリスト型の変数[row_data]を初期化します。

     row_data = []

 各行の2番目の要素から最後の要素まで(row.loc[1:])について、ord()関数を使って、アルファベットを文字コード(数値)に変換して一時的な変数[row_data]に格納します。

     for v in row.loc[1:]:
  row_data.append(ord(v))

 数値に変換したrow_dataを特徴データ[data]に追加していきます。

     data.append(row_data)

 上記を全ての行に実施することで、正解ラベルデータと特徴データができました。

5.学習用とテスト用データに分ける

sklearn.model_selectionモジュールの、train_test_split()メソッドを使って、正解ラベルデータと特徴データを学習用とテスト用に分けます。

引数に、特徴データと正解ラベルデータを渡すことで、学習用の特徴データ[data_train]、テスト用の特徴データ[data_test]、学習用の正解ラベルデータ[labe_train]、テスト用の正解ラベルデータ[labe_test]の4つリストが出力されます。

data_train, data_test, label_train, label_test = train_test_split(data, label)

6.学習と予測

 今回は、sklearn.ensembleからインポートしたRandomForestClassifier(ランダムフォレスト分類)を利用していきます。 

使い方は、SVMサポートベクターマシン)のときと同様にRandomForestClassifierのクラスを呼び出して、ランダムフォレストを使った分類ができるモデルの実体を作ります。

clf = RandomForestClassifier() 

モデルの実体ができたら、学習時もSVMと同様、fit()メソッドを使って、学習用特徴データ(data_train)と学習用正解ラベル(label_train)を引数に渡して実行するだけで、学習は完了です。

clf.fit(data_train, label_train) 

 続いて、学習したモデル(clf)を使って、予測を行います。

予測についてもSVMと同様に、predict()メソッドにテスト用特徴データ(data_test)を渡すことで、予測した結果を出力してくれます。

predict = clf.predict(data_test)  

7.精度を確認

予測した結果(predict)の精度を算出します。

まず、scikit-learnからmetricsモジュールをimportして、accuracy_score()メソッドを使って全体の精度を求めます。

accuracy_score()は、テスト用の正解ラベル(label_test)と予測した結果(predict)を引数に渡す事で、予測した結果が正解ラベルと同じだった割合を算出してくれます。

ac_score = metrics.accuracy_score(label_test, predict) 

また、scikit-learnからmetricsモジュールの、classification_report()メソッドを使ってラベル毎の精度を求めます。

cl_report = metrics.classification_report(label_test, predict) 

 最後に、求めた全体の精度と、ラベル毎の精度を出力します。

print("正解率=", ac_score)
print("レポート=\n", cl_report)

8.Jupyter Notebook上で実行してみる

先ほど作成したファイルをJupyter Notebook上で実行してみます。

以下の通り、うまく分類することができました。

f:id:kanriyou_h004:20200613160213p:plain

図3.kinoko-train.py実行結果

正解率と1となり、手元に用意したデータでは100%分類することができました。

このデータは、毒キノコか、食べられるキノコかの判定なので、100%の精度で分類できてよかったです。(笑)

 

今回は、新たな学習モデルとして、ランダムフォレストを使ってみました。

キノコの傘の形など、大小関係がない特徴(カテゴリカル変数)を使って分類できる点が、とても良いと感じました。

ランダムフォレストについても、改めて解説記事を投稿したいと思います。

様々な学習モデルがありますが、一つずつ活用できるよう身に着けていきたいです。

 

今後も、Pythonによるスクレイピング&機械学習開発テクニック増補改訂 Scrapy、BeautifulSoup、scik [ クジラ飛行机 ]で、スクレイピング機械学習開発に取り組んでいきたいと思います。

 

 

 【過去記事】

2019年8月31日(土)にE資格を受験して、合格しました!

E資格対策として勉強の進め方や、参考書などをまとめました。

これから受験される方がいらっしゃいましたらご参考まで。

oregin-ai.hatenablog.com 

 

 2019年3月9日(土)にG検定を受験し、見事合格できました!

受験の体験記や勉強法などを別のブログにまとめました。

これから受験される方がいらっしゃいましたらご参考まで。

g-kentei.hatenablog.com

 【E資格対策に使った参考書】