本ページでは以下のページを要約するとともに、個人的な解説も記載しています。独特な解釈をしている部分があるので、誤りなどの指摘はtwitterまでお願いします。
参考ページ
はじめに — scikit-learn 1.1.2 ドキュメント
https://scikit-learn.org/stable/tutorial/basic/tutorial.html
閲覧日:2022年10月8日
https://www.yosoaidol.com/p/scikit-learnpython.html
よりも少しだけ高度な内容になっています。
ルール
scikit-learnのestimatorはルールに従って設計されています。詳細なルールについてはこちらで定義されています。今後ブログでも扱う予定です。
型
特に指定がない限り、float64
にキャストされます。
以下の例では、10行2000列で生成したnumpy配列を明示的にfloat32
に指定しました。
その後、その配列をRBFSampler
と呼ばれる次元圧縮を行うアルゴリズムを使用し、10行100列のnumpy配列に変換しています。変換後の型を確認するとfloat64
にキャストされています。
import numpy as np
from sklearn import kernel_approximation
rng = np.random.RandomState(0)
#10行,2000列のランダムな数値を生成
X = rng.rand(10, 2000)
#float32に型を設定
X = np.array(X, dtype='float32')
X.dtype
#dtype('float32')
#RBFSamplerは次元拡張、圧縮用のアルゴリズム
#ここでは10行100列の配列に次元圧縮をおこなっている
transformer = kernel_approximation.RBFSampler()
X_new = transformer.fit_transform(X)
X_new.dtype
print(X_new.shape)
#dtype('float64')
分類での予測値は、教師データとして使用した型がそのまま出力されます。
以下の例では、教師データとして整数値を入力した場合は整数値が、文字型として入力した場合は文字型として出力されています。
回帰の予測値はfloat64
として出力されます。
from sklearn import datasets
from sklearn.svm import SVC
#分類用のアヤメのデータセットをロード
iris = datasets.load_iris()
#サポートベクターマシンの分類用アルゴリズムを使用して学習
#教師データとしては、品種を整数値(0,1,2,…)で表したものを使用
clf = SVC()
clf.fit(iris.data, iris.target)
#SVC()
list(clf.predict(iris.data[:3]))
#[0, 0, 0] 整数値で出力
#教師データとしては、品種を文字('setosa'など)で表したものを使用
clf.fit(iris.data, iris.target_names[iris.target])
#SVC()
list(clf.predict(iris.data[:3]))
#['setosa', 'setosa', 'setosa'] 文字型で出力
パラメータの再調整
学習した後でもパラメータの調整を行うことができます。
以前学習したものに上書きされるので、過去のものは残りません。
以下の例では、一度サポートベクターマシンのカーネル関数と呼ばれるハイパーパラメータをlinear
にして学習したのち、rbf
に変更し再学習をおこなっています。clf.set_params(kernel='rbf').fit(X, y)
の部分で再学習をおこなっています。この時、linear
で学習したAIモデルに上書きされます。
import numpy as np
from sklearn.datasets import load_iris
from sklearn.svm import SVC
X, y = load_iris(return_X_y=True)
clf = SVC()
#サポートベクターマシンのカーネル関数(次元拡張のやり方を決める関数)を'linear'に設定
clf.set_params(kernel='linear').fit(X, y)
#SVC(kernel='linear')
clf.predict(X[:5])
#array([0, 0, 0, 0, 0])
#カーネル関数(次元拡張のやり方を決める関数)を'rbf'にして再学習
clf.set_params(kernel='rbf').fit(X, y)
#SVC()
clf.predict(X[:5])
#array([0, 0, 0, 0, 0])
マルチクラスとマルチラベルの学習
サポートベクターマシンなど分類で使用するアルゴリズムの中で、2クラス分類用のアルゴリズムがあります。
2クラス分類用のアルゴリズムを多クラス分類で用いるためには、考え方が3種類あります。詳細はこちら。
・one-vs-the-rest(one-vs-all)
・one-vs-one
・error correcting output codes
scikit-learnでは、全ての分類用モデルに多クラス分類ができるよう設計されていますが、多クラス分類を行うとき指定することによって2クラス分類をどのように使って、多クラス分類を行なうのかを選択することができます。
以下のコードではOneVsRestClassfier
という手法を使用して、2クラス分類モデルを多クラス分類に適応させています。
from sklearn.svm import SVC
from sklearn.multiclass import OneVsRestClassifier
from sklearn.preprocessing import LabelBinarizer
X = [[1, 2], [2, 4], [4, 5], [3, 2], [3, 1]]
y = [0, 0, 1, 1, 2]
#2クラス分類をOneVsRestClassfierという手法を使って多クラス分類をできるようにしている。
classif = OneVsRestClassifier(estimator=SVC(random_state=0))
classif.fit(X, y).predict(X)
#array([0, 0, 1, 1, 2])
また、以下のようなコードにすることで、予測値をワンホットエンコーディング化することができます。
しかし、4つ目と5つ目の結果をみてください。全ての予測ラベルが「0」になっています。これはどのラベルにも当てはまらなかったことを意味しています。出力方法を変えることで、このような違いも出てくることに注意してください。
y = LabelBinarizer().fit_transform(y)
classif.fit(X, y).predict(X)
#array([[1, 0, 0],
# [1, 0, 0],
# [0, 1, 0],
# [0, 0, 0],
# [0, 0, 0]])
このような教師データをワンホットエンコーディングすることで、複数のラベルを持つマルチラベルの予測を行うことができます。
教師データが「0~4」の5つのデータが存在するので、5列の配列に変換されます。
最終的な予測値のとして、それぞれのデータがどのラベルに属するのかを出力します。
from sklearn.preprocessing import MultiLabelBinarizer
y = [[0, 1], [0, 2], [1, 3], [0, 2, 3], [2, 4]]
y = MultiLabelBinarizer().fit_transform(y)
classif.fit(X, y).predict(X)
#array([[1, 1, 0, 0, 0],
# [1, 0, 1, 0, 0],
# [0, 1, 0, 1, 0],
# [1, 0, 1, 0, 0],
# [1, 0, 1, 0, 0]])
これで機械学習チュートリアルが終了です。1~4の内容は固定ページでまとめてあります。