- ロジスティック回帰とは
- iris データとは
- 事前準備
- データセット確認
- ペアプロット
- 二値分類のため単純化して検証
- sepal length(ガクの長さ)と sepal width(ガクの幅)
- scikit-learn のロジスティック回帰を用いた予測
- petal length(花弁の長さ)と petal width(花弁の幅)
- scikit-learn のロジスティック回帰を用いた予測
- ロジスティック回帰について簡単に考察
- 機械学習における関数について
- シグモイド関数と交差エントロピー誤差の実装例
- シグモイド関数
- 交差エントロピー誤差
- 参考
- 記事
- 書籍
よくある scikit-learn のデータセットである iris データを利用して分類するタスクを自分なりに整理しながら解いてみました。
ロジスティック回帰とは
ロジスティック回帰とは,回帰という名前とは裏腹に分類のためのアルゴリズムです。線形回帰モデルの出力をロジスティック関数で変換し,2クラスの確率値を出力してクラス識別を行います。
インプットされたデータを 0.0 ~ 1.0 範囲の数値に変換して出力するジグモイド関数を一般化したもので、線形回帰を求める式と連結しているためロジスティック回帰と呼ばれます。
ここでいう一般化とは、1つのインプットデータに対し1つのアウトプットを出力する関数を、ある程度まとまった量のデータをインプットして、そのデータからアウトプットを出せるように拡張した関数のことを指します。
iris データとは
- 花の一種であるアヤメの品種のデータ
左から setosa, versicolor, virginica
引用元
事前準備
venv で環境を作り必要なライブラリをインストールします。
$ mkdir iris
$ cd iris
$ python3 -m venv venv
$ source venv/bin/activate
$ pip install scikit-learn jupyterlab numpy matplotlib pandas seaborn
データセット確認
scikit-learn にある iris のデータセットを読み込み出力してみます。
from sklearn.datasets import load_iris
iris = load_iris()
print(iris.DESCR)
irisのデータセットにはアヤメの下記情報があります。
- sepal length(がくの長さ)
- sepal width(がくの幅)
- petal length(花弁の長さ)
- petal width(花弁の幅)
- それぞれの品種(setosa、versicolor、virginica)
Output exceeds the size limit. Open the full output data in a text editor
.. _iris_dataset:
Iris plants dataset
--------------------
**Data Set Characteristics:**
:Number of Instances: 150 (50 in each of three classes)
:Number of Attributes: 4 numeric, predictive attributes and the class
:Attribute Information:
- sepal length in cm
- sepal width in cm
- petal length in cm
- petal width in cm
- class:
- Iris-Setosa
- Iris-Versicolour
- Iris-Virginica
:Summary Statistics:
============== ==== ==== ======= ===== ====================
Min Max Mean SD Class Correlation
============== ==== ==== ======= ===== ====================
sepal length: 4.3 7.9 5.84 0.83 0.7826
...
on Information Theory, May 1972, 431-433.
- See also: 1988 MLC Proceedings, 54-64. Cheeseman et al"s AUTOCLASS II
conceptual clustering system finds 3 classes in the data.
- Many, many more ...
pandas を使って iris のデータセットをテーブル形式で出力してみます。
import pandas as pd
from sklearn.datasets import load_iris
data = load_iris()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = pd.DataFrame(data.target, columns=['Species'])
df = pd.concat([X, y], axis=1)
df.head()
それぞれ 50行のデータがあり全部で150行のデータがあります。
Species(アヤメの品種)のマッピング
- 0:Setosa
- 1:Versicolour
- 2:Virginica
ペアプロット
ペアプロットして、各特徴量の全組み合わせの散布図を確認してみます。
import seaborn as sns
sns.pairplot(df, hue='Species', hue_order=['Setosa', 'Veriscolour', 'Virginica'], size=2)
二値分類のため単純化して検証
sepal length(ガクの長さ)と sepal width(ガクの幅)
より単純な二値分類タスクとして扱うために、sepal length(ガクの長さ)と sepal width(ガクの幅)の2つの特徴量に限定し、さらに品種(ラベル)を2つに限定します。
今回扱う Species(種類)のマッピング
- 0:Setosa
- 1:Versicolour / Virginica
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
iris = load_iris()
# sepal length と sepal width に限定
X = iris.data[:, :2]
# Iris-Setosa を 0 とし Iris-Versicolour / Iris-Virginica を 1とする
y = np.where(iris.target == 0, 0, 1)
plt.figure(figsize=(10, 6))
plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], color='navy', label='0')
plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], color='brown', label='1')
plt.legend()
navy が Setosa で brown が Versicolour / Virginica としてプロットされます。
scikit-learn のロジスティック回帰を用いた予測
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn import metrics
logreg = LogisticRegression()
# テストデータは全体のうち3割を用いる
x_train, x_test, y_train, y_test =train_test_split(X, y, test_size=0.3, random_state=2)
logreg.fit(x_train, y_train)
# 正解率(accuracy_score)を出す
y_pred = logreg.predict(x_test)
metrics.accuracy_score(y_test, y_pred)
>>> 0.7777777777777778
sepal length(ガクの長さ)と sepal width(ガクの幅)で学習させた結果、0.7777777777777778 の正解率となりました。
petal length(花弁の長さ)と petal width(花弁の幅)
今度は明らかに違いのある petal length(花弁の長さ)と petal width(花弁の幅)の2つの特徴量にし、品種(ラベル)を2つに限定してみます。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data[:, 2:4]
y = np.where(iris.target == 0, 0, 1)
plt.figure(figsize=(10, 6))
plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], color='navy', label='0')
plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], color='brown', label='1')
plt.legend()
scikit-learn のロジスティック回帰を用いた予測
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn import metrics
logreg = LogisticRegression()
# テストデータは全体のうち3割を用いる
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=3)
logreg.fit(x_train, y_train)
# 正解率(accuracy_score)を出す
y_pred = logreg.predict(x_test)
metrics.accuracy_score(y_test, y_pred)
>>> 1.0
明らかに違いのある petal length(花弁の長さ)と petal width(花弁の幅)で学習させた場合のの正解率は 1.0 となりました。
ロジスティック回帰について簡単に考察
scikit-learn を利用すると特に意識することなくできますが、ロジスティック回帰のタスクを解くためには下記2つの関数を実装する必要があります。
- 仮説関数(活性化関数)
- シグモイド関数
- 目的関数(損失関数、誤差関数)
- 交差エントロピー誤差が最小になるような重みを勾配降下法を利用して求める関数
機械学習における関数について
モデル/アルゴリズム、AI/機械を具体的に表現する関数は仮説関数と目的関数の2つに分類されます。
- 仮説関数
- データからどんなタスクを解決できるかの仮説を立て、その仮説をもとに選ばれた仮置きしたモデルを表現した関数。この仮説関数は、活性化関数とも言われますが、仮説関数が活性化関数を内包する用語。
- 目的関数
- 仮説関数がデータにどれぐらい誤差なくフィットするかを計算する関数。また、目的関数が内包する形で、意味合いの似ている、損失関数、誤差関数、コスト関数があります。
シグモイド関数と交差エントロピー誤差の実装例
シグモイド関数
import numpy as np
def sigmoid(x):
'''シグモイド関数'''
return 1 / (1 + np.exp(-x))
sigmoid(np.array([-1, 0, 1]))
>>> array([0.26894142, 0.5 ,0.73105858])
交差エントロピー誤差
import numpy as np
def cross_entropy(h, y):
'''交差エントロピー誤差'''
return (-y * np.log(h) - (1 - y) * np.log(1 - h)).mean()
h = sigmoid(np.array([-1, 0, 1]))
y = np.array([0, 0, 1])
# 交差エントロピー誤差を計算
cross_entropy(h, y)
>>> 0.4398901851987969