アイリスのデータセットで試す

作成日: 2021/08/04 更新日: 2023/03/25 サイトの紹介と使い方

初めに

sklearnで用意されているdatasetの一覧はここです。
② アイリスのデータセットはその一部です。
③ この記事の内容は、筆者の知識の範囲内で、かつ筆者の処理スタイルを一貫した形で、記述されます。
④ 一貫した内容でなく、多くの可能性を記述すると、複雑になって学習し辛いと思うからです。

目的

① 説明(入力)変数である特徴量データ(iris.data)からあやめの花を種類別に分類します。
② 目的(出力)変数 iris.taget (あやめの花の種類)を求めます。
③ 分類問題に属します。

データセットの情報を得る

# 宣言部
from sklearn.datasets import load_iris
# コード部
iris = load_iris()
print( “次元数:”,iris.data.ndim )
print( “特徴量:”,iris.data.shape[1] )
print( “データ数:”,iris.data.shape[0] )
print( “花の種類(クラス):”,iris.target_names )
for data, target in zip(iris.data[:5], iris.target[:5]):  print( data, target )
print( iris.DESCR )
<上のコードの実行結果>
次元数: 2
特徴量: 4
データ数: 150
花の種類(クラス): ['setosa' 'versicolor' 'virginica']
[5.1 3.5 1.4 0.2] 0
[4.9 3.  1.4 0.2] 0
[4.7 3.2 1.3 0.2] 0
[4.6 3.1 1.5 0.2] 0
[5.  3.6 1.4 0.2] 0

データのロード

iris = load_iris()
load_iris()関数は、変数irisにbunchオブジェクト型を代入します。

情報

次元数

print( “次元数:”,iris.data.ndim )

ndarrayオブジェクトdataメンバー変数の次元数です。

irisのデータは2次元なので、
iris.data.shape[0]にデータ数
iris.data.shape[1]に特徴量
が設定されています。

特徴量

print( “特徴量:”,iris.data.shape[1] )
print( iris.DESCR )
iris.DESCRの内容は英文なのですが、日本語に訳すと、
iris.data[*][0] はがく片の長さ(cm)
iris.data[*][1] は がく片の幅(cm)
iris.data[*][2] は 花びらの長さ(cm)
iris.data[*][3] は 花びらの幅(cm)
となります。

データ数

print( “データ数:”,iris.data.shape[0] )
データ数が設定されています。
特徴量とデータ数から、iris.dataは、(150,4)の配列変数であることが、分かります。
そして、これは説明(入力)変数です。

クラス

print( “花の種類(=クラス):”,iris.target_names )
花の種類(=クラス): ['setosa' 'versicolor' 'virginica']
iris.dataを処理してiris.targetにクラス(分類)コードを出力します。
iris.target の値は、
'setosa' =0
'versicolor' =1
'virginica'=2

特徴量データ(説明変数)とクラスデータ(目的変数)

for data, target in zip(iris.data[:5], iris.target[:5]): print( data, target )
それぞれ、5個の花のデータをプリントしました。
左側の[ ]内に特徴量4つのデータが、右側にクラスデータが表示されています。

説明(入力)変数の分割

分割

① 説明変数を次の3つに分類します。
・a 学習用:学習用の説明変数
・b 内部評価:学習した説明変数の内部評価用の変数
・c 外部評価:外部評価用の変数
② ①によって、学習する説明変数は・aだけに減ります。
③ ・bは学習した内容の確からしさを確認します。
④ ・a・bだけでは、「過学習」「学習不足」という現象を防げないことが知られています。
・bで、確からしさが99%で会っても、「過学習」が起こっているか確かめることはできません。
⑤ ・cは、基本的にirisdataset以外のデータを用意しますが、とりあえず変数を用意しておきます。

分割コード

# 宣言部
from sklearn.model_selection import train_test_split
# コード
X_train, X_test, y_train, y_test = train_test_split( iris.data, iris.target, test_size=0.3 )
X_internal_test, X_external_test, y_internal_test, y_external_test = train_test_split( X_test, y_test, test_size=0.2 )
分割①

① 説明変数iris.dataと目的変数iris.targetをこの前の項目「分割」の・a学習用と・b・c評価用の2つに分割します。
② X_train, X_test, y_train, y_test = train_test_split( iris.data, iris.target, test_size=0.3 )
は、説明変数iris.data、目的変数iris.targetをtrain_test_split()関数に渡しています。
③ X_trainとy_trainは学習用の戻り値です。
X_trainは説明変数、y_trainは目的変数です。
④ X_testとy_testは評価用の戻り値です。
X_testは説明変数、y_testは目的変数です。
⑤ test_size=0.3は、iris.dataとiris.targetの30%を評価用に、残りを学習用に分割するという指定です。


分割②

① 「分割①」の評価用データを「分割」の・b内部評価と・c外部評価の2つに分割します。
② X_internal_test, X_external_test, y_internal_test, y_external_test = train_test_split( X_test, y_test, test_size=0.2 )は、「分割①」の戻り値X_testとy_testをtrain_test_split()関数に渡しています。
③ X_internal_testとy_internal_testは内部評価用の戻り値です。
X_internal_testは説明変数、y_internal_testは目的変数です。
④ X_external_testとy_external_testは外部評価用の戻り値です。
X_external_testは説明変数、y_external_testは目的変数です。
⑤ test_size=0.2は、X_testとy_testの20%を外部評価用に、残りを内部評価用に分割するという指定です。

3つに分割した変数の情報を取得
# コード部>上のコードに続けてください。
print( "a-1 ",X_train.ndim," 次元 ",X_train.shape[1]," 特徴量 ",X_train.shape[0]," データ数 " )
print( "a-2 ",X_internal_test.ndim," 次元 ",X_internal_test.shape[1]," 特徴量 ",X_internal_test.shape[0]," データ数 " )
print( "a-3 ",X_external_test.ndim," 次元 ",X_external_test.shape[1]," 特徴量 ",X_external_test.shape[0]," データ数 " )   

print( "b-1 ",y_train.ndim," 次元 ",y_train.shape[0]," データ数 " )
print( "b-2 ",y_internal_test.ndim," 次元 ",y_internal_test.shape[0]," データ数 " )
print( "b-3 ",y_external_test.ndim," 次元 ",y_external_test.shape[0]," データ数 " )  
<上のコードの実行結果>
a-1  2  次元  4  特徴量  105  データ数 
a-2  2  次元  4  特徴量  36  データ数 
a-3  2  次元  4  特徴量  9  データ数 
b-1  1  次元  105  データ数 
b-2  1  次元  36  データ数 
b-3  1  次元  9  データ数

①a-1,2,3は学習用と評価用に分割しましたが、説明変数です。
実行結果から同じ次元数、特徴量であることが分かります。
②b-1,2,3は学習用と評価用に分割しましたが、目的変数です。
実行結果から1次元で、データ数が説明変数と同じことが分かります。

sklearnの最近傍分類のサンプル

# 宣言部
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np

# コード部
iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split( iris.data, iris.target, test_size=0.3 )
X_internal_test, X_external_test, y_internal_test, y_external_test = train_test_split( X_test, y_test, test_size=0.2 )

knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(X_train, y_train)
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=1, n_neighbors=1, p=2,
           weights='uniform')

y_pred          = knn.predict(X_test)
y_internal_pred = knn.predict(X_internal_test)
y_external_pred = knn.predict(X_external_test)

p1 = np.mean(y_pred          == y_test)
p2 = np.mean(y_internal_pred == y_internal_test)
p3 = np.mean(y_external_pred == y_external_test)

print( "正答率",p1,p2,p3 )
<実行結果>
正答率 0.9555555555555556 0.9722222222222222 0.8888888888888888

①p1は、学習したデータそのものです。95%の正答率は、5%の誤差を持っていることを意味します。
②p2は、内部評価用のデータです。97%の正答率と①より高いのは、偶然の産物です。
③p3は、外部評価用のデータです。89%の正答率ですが、これはサンプル(お試し)なので気にする必要はありません。
④興味のある方は、p3のデータを変更してもっとお試しを繰り返してください。
⑤p1、p2は後々コードとデータの再現性の維持のために変更しないことをお勧めします。
⑥KNeighborsClassifierを変更すれば、最近傍分類以外も試すことができます。
詳しくは、PYTHONでsklearnを使うを参照してください。

メールアドレス:

お問合せ・御要望

お問合せ

Verified by MonsterInsights
タイトルとURLをコピーしました