「【機械学習】LinearSVCを使って配列の合計値を判定してみた➀」に続いて処理の実装について細かく説明していこうかと思います。
処理の内容やサンプルソースを理解するうえで読んでおいたほうがいい記事について説明してありますのでまだ読んでいない方は、リンクから前の記事を読んでくれると嬉しいです。
処理の概要
前回も処理の概要を載せましたが、改めて載せておきます。
以下の順番で処理を実装していきます。
- 学習用のデータを用意する
- データに対する答えを用意する
- 学習させる
- テストデータを用意する
- テストデータを使って回答を求める
- テストデータの回答を作成する
- 結果の出力
処理の解説
はじめに
はじめに、必要なモジュールをインポートします。
- LinearSVC⇒学習用のアルゴリズム
- accuracy_score⇒テスト結果を評価するためのパッケージ
- random⇒試験用のデータを作成するために使用
from sklearn.svm import LinearSVCfrom sklearn.metrics import accuracy_scoreimport random
学習データの用意をする
L:25~29 あたり、
ループで回しながら二次元配列を用意します。
# テストデータを作るlearn_data = []for i in range(10): for j in (range(10)): learn_data.append([i, j])
以下のような配列が作られます。こちらのデータを学習用に使います。
[[0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [0, 9], [1, 0], [1, 1], [1, 2], [1, 3], [1, 4], [1, 5], [1, 6], [1, 7], [1, 8], [1, 9], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4], [2, 5], [2, 6], [2, 7], [2, 8], [2, 9], [3, 0], [3, 1], [3, 2], [3, 3], [3, 4], [3, 5], [3, 6], [3, 7], [3, 8], [3, 9], [4, 0], [4, 1], [4, 2], [4, 3], [4, 4], [4, 5], [4, 6], [4, 7], [4, 8], [4, 9], [5, 0], [5, 1], [5, 2], [5, 3], [5, 4], [5, 5], [5, 6], [5, 7], [5, 8], [5, 9], [6, 0], [6, 1], [6, 2], [6, 3], [6, 4], [6, 5], [6, 6], [6, 7], [6, 8], [6, 9], [7, 0], [7, 1], [7, 2], [7, 3], [7, 4], [7, 5], [7, 6], [7, 7], [7, 8], [7, 9], [8, 0], [8, 1], [8, 2], [8, 3], [8, 4], [8, 5], [8, 6], [8, 7], [8, 8], [8, 9], [9, 0], [9, 1], [9, 2], [9, 3], [9, 4], [9, 5], [9, 6], [9, 7], [9, 8], [9, 9]]
データに対する答えを用意する
L:31あたり
ループで作成した2次元配列を「jude」関数(後述)に渡して、答えの配列を取得します。
# ラベルを作成するlearn_label = judge(learn_data)
L:7~14あたり
判定ロジック「2次元配列」から配列を一つ取り出し、
要素同士を足し算し、「10」以上の場合は「1」を、それ以外は「0」を「result」変数に追加してい行き、すべての答えを作り終わったら戻り値に「result」を渡してあげます。
# 判定処理def judge(list_data): result = [] for data in list_data: if (data[0] + data[1]) >= 10:result.append(1) else:result.append(0) return result
学習させる
L:34~36
「clf」変数にインスタンスの生成を行う。
「fit」メソッドに「学習用のデータ」と「ラベル(学習データの回答)」を渡して学習させます。
# 学習させるclf = LinearSVC(max_iter=10000)clf.fit(learn_data, learn_label)
学習の処理
clf.fit("学習用データ","ラベル")
テストデータを用意する
L:38,39
「0~9」の数字が2個含まれた、配列を10個作成します。
# テストデータを作成するtest_data = [[random.randrange(10), random.randrange(10)] for i in range(10)]
以下の出力内容は一例ですがこんな感じでランダムな配列を作成します。
1回目
[[6, 7], [2, 4], [6, 0], [9, 1], [1, 9], [3, 5], [2, 8], [5, 2], [3, 7], [8, 5]]
2回目
[[3, 0], [3, 7], [3, 6], [8, 0], [7, 7], [2, 2], [3, 9], [0, 9], [1, 8], [9, 9]]
3回目
[[9, 2], [0, 4], [1, 1], [4, 8], [8, 2], [7, 4], [4, 4], [8, 4], [8, 4], [1, 2]]
テストデータを使って回答を求める
L:40,41
L:32で学習させたオブジェクトを使ってサンプルデータの回答を求めます。
求めた結果は「test_label」に配列として取得されます。
# テストデータの予測test_label = clf.predict(test_data)
回答を求める
回答の配列 = clf.predict("テストデータ")
テストデータの回答を作成する
L:44
先ほど使った「judge」関数を使って回答を用意します。
# 回答を作成するanswer = judge(test_data)
L:7~14あたり
# 判定処理def judge(list_data): result = [] for data in list_data: if (data[0] + data[1]) >= 10:result.append(1) else:result.append(0) return result
結果の出力
L:46~48
上のprintでは配列の要素同士の足し算と予測結果を出力しています。
下のprintでは、正解率を出力しています。
スポンサーリンク
# 予測結果の評価print(addition(test_data), "の予測結果:", test_label)print("正解率 = ", accuracy_score(answer, test_label))

addition 関数
「addition」関数は自作関数で、二次元配列を受け取り、配列をひとつずつ取り出し、足し算し、配列として返します。
# 足し算def addition(list_data): result = [] for data in list_data: result.append((data[0] + data[1])) return result
accuracy_score
「accuracy_score」は、「回答」と「機械学習で導き出した回答」を引数に渡すことで正当率を求めてくれます。
accuracy_score("回答", "機械学習で導き出した回答")
注意点
実装中に以下のような警告が出たので載せておきます。
base.py:929: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations. "the number of iterations.", ConvergenceWarning)
google翻訳をすると「 base.py:929:ConvergenceWarning:Liblinearは収束に失敗しました。反復回数を増やしてください。 「反復回数」、ConvergenceWarning) 」
テスト回数が少なくて設定値を上げろと言っているっぽい
引用元のライブラリの説明をみてみると「 max_iter 」がデフォルト値だと小さいみたいなので値を上げてみたら警告が解消されました。
max_iter:int, (default=1000)
https://scikit-learn.org/stable/modules/generated/sklearn.svm.LinearSVC.html
The maximum number of iterations to be run.
L:35
警告がでる実装
デフォルトなので「max_iter」が「1000」
clf = LinearSVC()
警告が出ない実装
clf = LinearSVC(max_iter=10000)
おわりに
今回は、機械学習を実装面から触れてみたのですが、ふーんこうやればこうなるんだーととりあえず学習してくれているけど、概念的な部分は自分がいまいち理解できてないのかなーと思いました。
概念が理解できていないと応用は厳しいと思うので、概念が詳しく乗っている本を探してきてまた紹介出来たらなと思います。