福岡人データサイエンティストの部屋

データサイエンスを極めるため、日々の学習を綴っています。

【RandomForest】ワインの美味しさ評価【Python】



こんにちは!こーたろーです。


最近CNNばかりでしたので、他のモデルも使おうということで、RandomForestをやってみます。


結構やっている人も多いワインの美味しさ評価です。


ハンズオンの基礎トレーニングではよく使われると思います。


機械学習を始めたばかりの人にもこれはやってほしいですね。


それでは早速始めていきましょう。



必要データのダウンロード



archive.ics.uci.edu
今回は、機械学習を行うためのデータソースが多くオープンとなっている「UCI machine learning repository」からデータを取得して行っていきます。


UCI machine learning repository」

こちらのサイトの中にある、白ワインのデータを使用します。

https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality

上記URLからダウンロードしても大丈夫です。

せっかくですので、Pythonでダウンロードします。

from urllib.request import urlretrieve

url = "https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-white.csv"
savepath = "winequality-white.csv"

urlretrieve(url, savepath)



Pythonのファイルと同じフォルダ内にダウンロードします。


オープンデータ取得の練習にもなるので、urllib.requestも使えるようになりましょう。

ワインデータの確認



データのダウンロードしたら、ファイルをPythonでロードしてデータフレームとして表示してみます。

import pandas as pd
wine = pd.read_csv('winequality-white.csv', encoding="utf-8", sep = ";")
wine






4898個のデータセットがあることが分かります。


12カラムのうち、quality(品質)は、今回の目的変数となります。
それ以外の11カラムが説明変数ということですね。


データの前処理



学習データとテストデータを作成していきます。


scikit-learnの「train_test_split」にてデータを分割します。

from sklearn.model_selection import train_test_split

x = wine.drop("quality", axis = 1)
y = wine["quality"]

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2)

まず、データフレームを説明変数(x)と目的変数(y)に分割します。
その後、x,yそれぞれを80%が学習データ、20%がテストデータとして分割します。
これで前処理は完了です。

モデルの作成(RandomForest)



続いてモデルを作成していきます。


今回はシンプルにランダムフォレスト単体で実行していきます。

from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier()
model.fit(x_train,y_train)



ランダムフォレストのオブジェクトを作成して、fitメソッドで学習データでの学習を行います。

モデルの評価



最後にモデルを評価していきます。


学習済みのモデルに対して、predictメソッドにてテストデータの説明変数を代入することで、目的変数を予測していきます。


今回使用したデータは、品質を10段階評価しているため、出力は0から10の値(11段階)で生成されます。

from sklearn.metrics import accuracy_score, classification_report
import numpy as np

y_pred = model.predict(x_test)
y_test = np.ravel(y_test)

print(classification_report(y_test, y_pred))
print("accuracy = ", accuracy_score(y_test, y_pred))






正答率は67%と少し低めです。この原因を考察してみます。



評価の考察



そもそも、今回のデータは全ての評価(0~10)に対して、どれくらいサンプル数があるのでしょうか。
確認してみます。

import matplotlib.pyplot as plt

plt.figure(figsize = (10,3))

plt.hist(wine["quality"] , bins=11, range = (0,10))
plt.title("y_train histgram")
plt.xlabel("Quality")
plt.ylabel("Number of Count")
plt.grid(True)
plt.tight_layout()






学習データについては正規分布のようなグラフになっています。


つまり、中央の付近の値については学習がよく進むが、中央から離れるほど学習の精度が下がる傾向にあります。


次に、予測結果とテストデータの分布を調べます。

plt.figure(figsize = (10,6))

plt.subplot(2,1,1)
plt.hist(y_pred, bins=11, range = (0,10))
plt.title("y_pred histgram")
plt.xlabel("Quality")
plt.ylabel("Number of Count")
plt.grid(True)

plt.subplot(2,1,2)
plt.hist(y_test, bins=11, range = (0,10))
plt.title('y_test histgram')
plt.xlabel('Quality')
plt.ylabel('Number of Count')
plt.grid(True)

plt.tight_layout()






概ね、分布は同じになることが分かります。
ここで、正答率の計算ですが、11段階の分布について、1段階でもずれていれば間違いと判断するため正答率は下がってしまいます。


今回は、11段階の分類で試しましたが、これを回帰として取り扱うと、誤差の評価となって、また違う評価がでそうです。


実際には、かなりの確率で当たっているような気がします。
気が向いたら、回帰での評価も行っていきたいです。


ではでは。


Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎