機械学習練習用のscikit-learnを、付属データセットload_breast_cancerを使って試します。
scikit-learnの使い方
scikit-learnは機械学習の勉強用でよく使われているパッケージです。
読み方は、サイキット・ラーン。
このパッケージでは、実際に学習を試すためのデータが入っているため、整形されたデータを作らなくても試すことができます。
load_iris アヤメの分類
load_diabetes 糖尿病患者の進行状況
load_digits 8×8ピクセルの数字データ
load_linnerud 男性の生理学的特徴と運動能力の関係
load_wine ワインを3種類に分類
load_breast_canser 乳がんの陰性/陽性判定
また予測するためのアルゴリズムが複数はいっているため、いろんなモデルを使用できます。
学習データと訓練データの切り分け、学習、予測、評価もほぼほぼ1関数書けばいいのでプログラムが短く済ますことができます。
このように便利なパッケージですが、触ってみていろいろと苦労したのでそのあたりもまとめていきます。
例えば他の記事でscikit-learnを紹介するときに使われている「ボストンの家賃」のデータ(load_boston)は現在はパッケージから除外されています。
初心者向けに簡素化されていますが、それでもまだまだ理解途中ですので間違いありましたらご容赦ください。
データの確認
「load_iris」はアヤメの分類データです。
まずどんなキーがあるか調べます。
from sklearn.datasets import load_iris
dataset = load_iris()
print(dataset.keys())
最初この用意されているデータセットで、data, targetと区分けされているのがよくわかりませんでした。
いろいろ調べてみると、判定するためのもととなる要因となる数値を「説明変数」、結果となる数値を「目的変数」として区別しているためのようです。
「説明変数」は1種類ではなく複数のパラメータがはいります。このデータセットでは、アヤメのパーツごとの大きさに該当します。
「目的変数」はアヤメの種類となります。このデータセットでは、アヤメの種類名はtargetの配列とtarget_namesの組み合わせで決まります。
任意の「説明変数」を渡すことで、「目的変数」つまりどのアヤメなのかを予想してくれる...ということになります。
まずは本データセットのデータの名前、ターゲットの名前を取得・確認しておきましょう。
from sklearn.datasets import load_iris
dataset = load_iris()
print("feature name", dataset.feature_names)
print("target name", dataset.target_names)
data名の方は「がく片の長さ」「がく片の幅(cm)」「花弁の長さ(cm)」「花弁の幅(cm)」に対応したデータが入っています。
target名では「セトサ」「バージカラー」「ヴァージニカ」という種類が定められています。これはターゲットの配列で各行ごとに割り当てされています。
データは使いやすいようPandasのデータフレームに変換できます。
その際、feature_namesをカラム名にできます。
from sklearn.datasets import load_iris
import pandas as pddataset = load_iris()
df = pd.DataFrame(dataset.data, columns=dataset.feature_names)
df.head
人によってはPandasで使いやすくするために、データフレームをdataにtargetの情報も付け加えて作成していました。
機械学習例
では実際にアルゴリズムを使って学習・予測・評価していきましょう。
まずデータを作成します。「scikit-learn」では「load_iris」という関数を使うだけで、事前に用意されたアヤメのデータをロードすることができます。
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_splitdataset = load_iris()
data, target = dataset.data, dataset.target
次に、「train_test_split」を使います。
これは既存のデータを、訓練用のデータとテスト用のデータにわけます。
data_train, data_test, target_train, target_test = train_test_split(data, target, test_size=0.6, random_state=1)
パラメータtest_size、train_sizeで振り分ける比率が変更できます。
test_sizeが0.6なら60%がテスト用、残りが訓練用となります。
毎回の答えがランダムに変更されないようにするには「random_state」を指定します。「random_state=1」で毎回同じ内容が返ってきます。
RandomForest
アルゴリズムで学習・評価させていきましょう。
まずは「ランダムフォレスト(RandomForestClassifier)」というアルゴリズムで学習させます。
ランダムフォレストは少しずつ異なる決定木をたくさん用意し、多数決や平均で予測をするものだそうです。
ランダムフォレストのオブジェクトを作ったら、「fit」関数を実行するだけで学習します。
from sklearn.ensemble import RandomForestClassifier
model = RandomForestClassifier()
model.fit(data_train, target_train)
評価は「score」で行います。
model.score(data_test, target_test )
結果が1に近いほど予測があっていることがわかります。
出力してみると「0.9555555555555556」でした。
LogisticRegression
LogisticRegressionは、ロジスティック回帰モデルです。
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(data_train, target_train)
model.score(data_test, target_test )
出力は「0.9666666666666667」です。
LinearRegression
LinearRegressionは、線形回帰モデルの一つで、説明変数の値から目的変数の値を予測します。
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(data_train, target_train)
model.score(data_test, target_test )
スコアの出力は「0.9081233488416994」となりました。
SVC
違うアルゴリズム(SVC)で試してみます。
SVCは「サポートベクトルマシン分類」で分類、回帰、外れ値検出などに用いられる教師あり学習法。データセットに対して二値分類や多値分類が行えます。
from sklearn.svm import SVC
model = SVC(kernel='rbf', gamma=0.001, C=1, random_state=1)
model.fit(data_train, target_train)
model.score(data_test, target_test )
出力は「0.3111111111111111」となりました。
パラメータの設定のせいかもしれませんが、あまりはまりませんでした。
引数のパラメータについては「grid search」を使って自動的に塩梅のいいものを選べるようです。
Scikit-learnのGridSearchCVクラスによるグリッドサーチ – Helve Tech Blog (helve-blog.com)
一度に複数のモデルを使う
一度に複数のモデルを使えるので、それぞれのモデルの評価を確認することもできます。
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import LinearRegressionmodels = [RandomForestClassifier(), LogisticRegression(), LinearRegression()]
for model in models:
model.fit(data_train, target_train)
print(model.score(data_test, target_test))
結果は以下。
スケーリング
株価などでは3桁のぼろ株から1万円以上のものまで大きく値幅が違います。
これでは意図した結果にならない可能性もあるので、データ数値を事前に調整したほうがいいです。
正規化(normalizing、MinMaxScaler)では、数値を0-1の間に収めてくれます。
中心化(centering)とでは、平均値が0になるように位置をずらします。
標準化(normalizing、StandardScaler)では、元のデータの平均が0になるように位置をずらし、さらに標準偏差が1になるように変換します。
アルゴリズムの選び方
scikit-learnにはアルゴリズムがたくさんあるので便利ですが、逆に選ぶときに苦労します。
そこで参考になるのがチートシートです。
Choosing the right estimator — scikit-learn 1.2.2 documentation
Yes,Noを答えていき
・classification(教師あり学習)
・regression(回帰:教師あり学習)
・clustering(分類:教師なし学習)
・dimensionality reduction(次元削減:教師なし学習)
の4つのカテゴリで様々なアルゴリズムにたどりつきます。
上記の例では、すでにあやめは分類されているので「classification(教師あり学習)」に該当すると思われます。
サンプル数は多くないのでLinearSVCがよさそうです。
from sklearn.svm import LinearSVC
model = LinearSVC()
model.fit(data_train, target_train)
model.score(data_test, target_test )
これで評価すると「0.9444444444444444」となりました。
試しにサンプル数が多い場合におすすめされているSGD classifierを試してみます。
from sklearn.linear_model import SGDClassifier
model = SGDClassifier()
model.fit(data_train, target_train)
model.score(data_test, target_test )
すると評価は「0.7」ともうひとつでした。
「predict」関数を使えば、予測を行いその予測結果を見ることもできます。
pre=model.predict(data_test)
print(pre)
エラー
Found input variables with inconsistent numbers of samples
「サンプル数が一定でない入力変数」があるというエラー。
データのshapeがあっているかもういち度確認してみましょう。
X.shape
y.shape