アルゴリズム画像

ゆうき( @BASEBALLY15 )です^^

機械学習で「テストデータを20(30)%,学習データを80(70)%に分ける」 って言うけど,なぜ,こんな分け方をするの・・・?

テストデータと学習データの分割
(画像をクリックすると,引用元を確認することが出来ます.)

その悩みを解決するために,今回は,テストデータが何%の時に精度が最も良いのか,ということについて検証します^^

よろしくお願いします・・・

(Jupiter notebookを使用)

検証する際に使ったアルゴリズム

以下の4つのアルゴリズムを使い,それぞれのテストデータの精度を検証しました.

  • LinearSVC(サポートベクタークラシファー)
  • LogisticRegression(ロジスティック回帰)
  • RandomForestClassifier(ランダムフォレスト)
  • KNeighborsClassifier(k近傍法)

それでは,検証結果を見ていきましょう^^

テストデータを何%にするのがベストなのか?

ライブラリ

import numpy as np

import pandas as pd

from pandas import Series, DataFrame

import matplotlib.pyplot as plt

import seaborn as sns

sns.set_style("whitegrid")

%matplotlib inline

そして,以下のコードを記述し,今回の検証で使うアルゴリズムをインポートしたいと思います.

あと,データを分割するライブラリと精度を求めるためのライブラリも追加しておきます.

#LinearSVCを使うためのライブラリ
from sklearn.svm import LinearSVC

#ランダムフォレスターを使うためのライブラリ
from sklearn.ensemble import RandomForestClassifier

#ロジスティック回帰を使うためのライブラリ
from sklearn.linear_model import LogisticRegression

#k近傍法を使うためのライブラリを用意
from sklearn.neighbors import KNeighborsClassifier

#学習用とテスト用に分けるためのライブラリ
from sklearn.model_selection import train_test_split

#精度を求めるためのライブラリ
from sklearn.metrics import accuracy_score

コード

今回の検証では,seabornのアイリスのデータを使いたいと思います.

irisのデータを解析する

まずは,データを読み込みたいと思います.

#seabornのirisのデータを読み込む
iris = sns.load_dataset("iris")

#実行
iris

すると,以下のデータフレームが表示されます.

sepal_lengthsepal_widthpetal_lengthpetal_widthspecies
05.13.51.40.2setosa
14.93.01.40.2setosa
24.73.21.30.2setosa
34.63.11.50.2setosa
45.03.61.40.2setosa
1456.73.05.22.3virginica
1466.32.55.01.9virginica
1476.53.05.22.0virginica
1486.23.45.42.3virginica
1495.93.05.11.8virginica

次に,予測に使うデータX(説明変数)と予測したいデータY(目的変数)に分けます.

#予測に使うデータX(説明変数)
X = iris.drop("species", axis=1)

#予測したいデータY(目的変数)
Y = iris["species"]

dropを使うことで,”species”以外のデータを使うことが出来ます.

また,“species”, axis=1は,” species “の列方向を指定しています.

テストデータ20%から80%までの精度を検証

次に,テストデータの精度を20%から80%の間で検証したいので, for文を使います.

そのために,繰り返す範囲を指定します.

#繰り返し範囲を指定(20%から80%を1%ずつ繰り返す)
all_range = range(20,81,1)


#精度を表示させるためにリストを用意
###LinearSVC###
linear_accuracy = []

###ロジスティック回帰###
log_accuracy = []

###ランダムフォレスター###
random_accuracy = []

###k近傍法###
kn_accuracy = []

そして,4つのアルゴリズムごとに機械学習を行っていきます.

for i in all_range:    
    #学習用とテスト用に分ける
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=i/100)
    
    ###LinearSVC###
    #学習
    linearmodel = LinearSVC()
    linearmodel.fit(X_train, Y_train)
    
    #予測
    Y_pred1 = linearmodel.predict(X_test)
    linear_accuracy.append(accuracy_score(Y_pred1, Y_test))
    
    
    ###ロジスティック回帰###
    #学習
    logmodel = LogisticRegression()
    logmodel.fit(X_train, Y_train)
    
    #予測
    Y_pred2 = logmodel.predict(X_test)
    log_accuracy.append(accuracy_score(Y_pred2, Y_test))
    
    
    ###ランダムフォレスター###
    #学習
    ranmodel = RandomForestClassifier()
    ranmodel.fit(X_train, Y_train)
    
    #予測
    Y_pred3 = ranmodel.predict(X_test)
    random_accuracy.append(accuracy_score(Y_pred3, Y_test))
    
    
    ###k近傍法###
    #学習
    knmodel = KNeighborsClassifier(n_neighbors=1)
    knmodel.fit(X_train, Y_train)
    
    #予測
    Y_pred4 = knmodel.predict(X_test)
    kn_accuracy.append(accuracy_score(Y_pred4, Y_test))

データフレーム化して,それぞれのアルゴリズムの精度を見てみましょう^^

#データフレーム化
df = pd.DataFrame([linear_accuracy, log_accuracy, random_accuracy, kn_accuracy],
                 index=["LinearSVC", "LogisticRegression", "RandomForestClassifier", "KNeighborsClassifier"],
                 columns=[i for i in all_range])
#行と列を入れ替えて表示(Tと記述すると,入れ替えることが出来る)
df.T

すると,以下のように,それぞれの精度が表示されます.

LinearSVCLogisticRegressionRandomForestClassifierKNeighborsClassifier
200.9666670.9333330.9333330.966667
210.9375000.9687500.9687500.968750
220.9696971.0000000.9696970.969697
230.9428571.0000000.9714290.942857
240.9722221.0000000.9722220.972222
760.8859650.9473680.9473680.956140
770.8965520.9137930.9137930.887931
780.8632480.9401710.9316240.948718
790.9663870.9411760.9243700.949580
800.8916670.9333330.9500000.925000

このままでは,どのアルゴリズムと何%のアルゴリズムがベストなのかが分からないので,

精度が98%以上のデータのみを表示させます.

#精度が98%以上のデータのみを表示
all_max = df.T[df.T>=0.98].dropna(how="all", axis=0)

#実行
all_max

すると,このように精度が98%以上のデータだけが表示されます.(NaNは精度が98%よりも低い値です.)

LinearSVCLogisticRegressionRandomForestClassifierKNeighborsClassifier
22NaN1.000000NaNNaN
23NaN1.000000NaNNaN
24NaN1.000000NaNNaN
26NaN1.0000001.0000001.000000
281.0000001.0000001.0000001.000000
29NaN1.000000NaNNaN
34NaN1.000000NaNNaN
360.9814810.981481NaNNaN
371.0000000.9821430.982143NaN
40NaN0.983333NaN0.983333
421.000000NaNNaNNaN
470.9859151.0000001.0000001.000000
50NaNNaN0.986667NaN
510.9870130.987013NaNNaN
53NaN0.987500NaNNaN
56NaN0.988235NaNNaN
73NaN0.981818NaNNaN

これを見ると,テストデータが28%の時,どのアルゴリズムでも精度が100%になっています!

(※実行するたびに精度は変わります.)

最後に,今回の検証結果を可視化したいと思います.

#subplot()の間隔の調整
plt.subplots_adjust(wspace=0.4, hspace=0.6)


###LinearSVCをプロット###
plt.subplot(2,2,1)

plt.plot(all_range, linear_accuracy, color="red")

plt.title("LinearSVC")

plt.ylabel("accuracy")

plt.xlabel("range")
#軸の範囲を指定

plt.xlim(20,80)

plt.ylim(0.85,1.0)


###ロジスティック回帰をプロット###
plt.subplot(2,2,2)

plt.plot(all_range, log_accuracy, color="blue")

plt.title("LogisticRegression")

plt.ylabel("accuracy")

plt.xlabel("range")

plt.xlim(20,80)

plt.ylim(0.85,1.0)


###ランダムフォレスターをプロット###
plt.subplot(2,2,3)

plt.plot(all_range,random_accuracy, color="green")

plt.title("RandomForestClassifier")

plt.ylabel("accuracy")

plt.xlabel("range")

plt.xlim(20,80)

plt.ylim(0.85,1.0)


###k近傍法をプロット###
plt.subplot(2,2,4)

plt.plot(all_range, kn_accuracy, color="purple")

plt.title("KNeighborsClassifier")

plt.ylabel("accuracy")

plt.xlabel("range")

plt.xlim(20,80)

plt.ylim(0.85,1.0)

すると,このように,それぞれのアルゴリズムの精度が表示されます.

アルゴリズムごとの精度

この結果を見ると,テストデータが30%周辺で,精度が良いことが分かります.

使うデータによって,テストデータを何%にするのかを考えないといけないですね^^

終わりに

今回は,テストデータが何%の時に最も精度が良いのかということについて検証してみました.

今後も,Pythonを勉強していて疑問に感じたことは,どんどん解決していこうと思います^^

それでは・・・

Q &A

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA