『Aidemy-AIアプリコース』受講記:14日目(8章添削問題)

プログラミングスクール「Aidemy」を受講し、その体験記をコツコツ書いていこうと思います。
「Aidemy」の受講を検討している方、どんなことをするかイメージを持っていただければ幸いです。

自己紹介:
大卒。ITに関して無知識。
新卒で造船業:現場管理。転職を目指し「Aidemy」を受講。

8/1
<14日目>

8月に入りましたね!
内容が難しくなってきたのでだんだん予定より遅れ気味ですが、気を取り直して頑張っていきます!

<今日の学習内容>
8章添削問題(2.5h)

今回は添削問題です!

手書きの数字の認識・分類をするための学習器をより高い精度で作成したいと思います。
与えられるデータに対して手法を選び、ハイパーパラメーターを調整して学習能力の高い
学習器を作ってください。
また、一番評価の高い手法の名前と、調整したパラメーターとその値を出力してください。
#自作
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.svm import LinearSVC
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import f1_score
from sklearn.model_selection import RandomizedSearchCV
import time
import scipy.stats

data = load_digits()
train_X, test_X, train_y, test_y = train_test_split(data.data, data.target, random_state=42)

#digits_data = pd.DataFrame(data.data)
#digits_data.head(5)


C_list = scipy.stats.uniform(0.00001, 1000)
depth_list = scipy.stats.randint(1, 11)
n_estimators_list = scipy.stats.randint(1, 21)
k_list = scipy.stats.randint(1, 11)
random_state = scipy.stats.randint(0, 100)

models_name = ['ロジスティック回帰', '線形SVM', '非線形SVM', '決定木', 'ランダムフォレスト', 'k-NN']
models = [LogisticRegression(), LinearSVC(), SVC(), DecisionTreeClassifier(), RandomForestClassifier(), KNeighborsClassifier()]
params = [{'C' : C_list, 
         'random_state' : random_state},
        {'C' : C_list, 
         'random_state' : random_state},
        {'C' : C_list, 
        'kernel' :  ["linear", "rbf", "poly", "sigmoid"],
        'decision_function_shape' : ['ovo', 'ovr'],
        'random_state' : random_state},
        {'max_depth' : depth_list,
        'random_state' : random_state},
        {'n_estimators' : n_estimators_list,
        'max_depth' : depth_list,
        'random_state' : random_state},
        {'n_neighbors' : k_list}]
   
max_score = 0
best_model = None
best_param = None
#model_title = ["classification data using LogisticRegression", "classification data using LinearSVC", "classification data using SVC", "classification data using DecisionTreeClassifier", "classification data using RandomForestClassifier", "classification data using KNeighborsClassifier"]
#i = 0

for name, model, param in zip(models_name, models, params):
   start = time.time()
   clf = RandomizedSearchCV(model, param)
   clf.fit(train_X, train_y)
   pred_y = clf.predict(test_X)
   score = f1_score(test_y, pred_y, average="micro")
   end_time = time.time() - start
   accuracy = clf.score(test_X, test_y)
   print('名前 : ', name)
   #print('モデル : ', model)
   print('モデル:{}'.format(model.__class__.__name__))
   print('パラメーター : ', clf.best_params_)
   #print('param : ', param)
   print('score : ', clf.score(test_X, test_y))
   print('実行時間 : ', end_time)
   print()
   if max_score < score:
       max_score = score
       best_model = model.__class__.__name__
       best_param = clf.best_params_
       cal_time = end_time

print('最も評価の高い手法')          
print('モデル:{}'.format(best_model))
print("パラメーター:{}".format(best_param))
print("ベストスコア:", max_score)
print('実行時間:', cal_time)
#解答例
# 必要なモジュールがあれば追記してください
import scipy.stats
from sklearn.datasets import load_digits
from sklearn.linear_model import LogisticRegression
from sklearn.svm import LinearSVC
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import RandomizedSearchCV
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score

data = load_digits()
train_X, test_X, train_y, test_y = train_test_split(
   data.data, data.target, random_state=42)

# 以下にコードを記述してください
# グリッドサーチ用にモデルとパラメーターセットをまとめた辞書を用意
# 辞書のkeyにはオブジェクトのインスタンスを指定することができます
model_param_set_grid = {
   LogisticRegression(): {
       "C": [10 ** i for i in range(-5, 5)],
       "random_state": [42]
   },
   LinearSVC(): {
       "C": [10 ** i for i in range(-5, 5)],
       "multi_class": ["ovr", "crammer_singer"],
       "random_state": [42]
   },
   SVC(): {
       "kernel": ["linear", "poly", "rbf", "sigmoid"],
       "C": [10 ** i for i in range(-5, 5)],
       "decision_function_shape": ["ovr", "ovo"],
       "random_state": [42]
   },
   DecisionTreeClassifier(): {
       "max_depth": [i for i in range(1, 20)],
   },
   RandomForestClassifier(): {
       "n_estimators": [i for i in range(10, 20)],
       "max_depth": [i for i in range(1, 10)],
   },
   KNeighborsClassifier(): {
       "n_neighbors": [i for i in range(1, 10)]
   }
}

# ランダムサーチ用にモデルとパラメーターセットをまとめた辞書を用意
model_param_set_random = {
   LogisticRegression(): {
       "C": scipy.stats.uniform(0.00001, 1000),
       "random_state": scipy.stats.randint(0, 100)
   },
   LinearSVC(): {
       "C": scipy.stats.uniform(0.00001, 1000),
       "multi_class": ["ovr", "crammer_singer"],
       "random_state": scipy.stats.randint(0, 100)
   },
   SVC(): {
       "kernel": ["linear", "poly", "rbf", "sigmoid"],
       "C": scipy.stats.uniform(0.00001, 1000),
       "decision_function_shape": ["ovr", "ovo"],
       "random_state": scipy.stats.randint(0, 100)
   },
   DecisionTreeClassifier(): {
       "max_depth": scipy.stats.randint(1, 20),
   },
   RandomForestClassifier(): {
       "n_estimators": scipy.stats.randint(10, 100),
       "max_depth": scipy.stats.randint(1, 20),
   },
   KNeighborsClassifier(): {
       "n_neighbors": scipy.stats.randint(1, 20)
   }
}

# スコア比較用に変数を用意
max_score = 0
best_model = None
best_param = None

# グリッドサーチでパラメーターサーチ
for model, param in model_param_set_grid.items():
   clf = GridSearchCV(model, param)
   clf.fit(train_X, train_y)
   pred_y = clf.predict(test_X)
   score = f1_score(test_y, pred_y, average="micro")
   # 最高評価更新時にモデルやパラメーターも更新
   if max_score < score:
       max_score = score
       best_model = model.__class__.__name__
       best_param = clf.best_params_

# ランダムサーチでパラメーターサーチ
for model, param in model_param_set_random.items():
   clf = RandomizedSearchCV(model, param)
   clf.fit(train_X, train_y)
   pred_y = clf.predict(test_X)
   score = f1_score(test_y, pred_y, average="micro")
   # 最高評価更新時にモデルやパラメーターも更新
   if max_score < score:
       max_score = score
       best_model = model.__class__.__name__
       best_param = clf.best_params_
       
print("学習モデル:{},\nパラメーター:{}".format(best_model, best_param))
# 最も成績のいいスコアを出力してください。
print("ベストスコア:",max_score)

問題文の通りで手書きの数字の認識・分類するための学習器の制作です。
各モデル、各パラメーターでどれが一番うまく分類することが可能かを調べるためのプログラムです。

僕はランダムサーチのみで調べましたが、解答例はグリッドサーチも含めて調べています。

確かに網羅するには両方調べるべきでしたね!

なかなか難しくなってきました。
2周はやらないと身につきそうもありません。

それではまた明日!

この記事が気に入ったらサポートをしてみませんか?