LoginSignup
0

More than 1 year has passed since last update.

posted at

updated at

ラビットチャレンジ 機械学習

0章 機械学習のイメージ

機械学習は、問題設定もしくは学習シナリオ(教師あり学習、教師なし学習、半教師あり学習、強化学習)をコンピュータに与え、それが解けるようするために訓練させるイメージです。

教師あり学習

入力データと出力データから、そのデータを説明できる評価関数を作成する手法
分類と回帰がある。

分類:SVM(サポートベクターマシーン)、ランダムフォレスト
回帰:線形回帰、ランダムフォレスト

長所 短所
特徴量を自動作成 入力データにノウハウが必要
ビックデータに生かせる 大量のデータが必要
一部に限定することで人間の能力を凌駕 学習した以上の結果は得られない
結果の理由がブラックボックス

教師なし学習

入力データのみから、そのデータを説明できる評価関数を作成する手法
クラスタリングと次元削減がある

クラスタリング:$k$平均法、階層クラスタリング、自己組織化写像
次元削減:主成分分析(PCA)、因子分析

強化学習

ある環境下で、目的とする報酬を最大化するために、どのような行動をとるべきかを確立する手法

0.1 機械学習の定義

トム・ミッチェルによる機械学習の定義(1997)は次の通り

コンピュータプログラムは、タスクTを性能評価Pで測定し、その性能が経験Eにより改善される場合、タスクTおよび性能指標Pに関して経験Eから学習すると言われている

タスクT:アプリケーションにさせたいこと
性能評価P:予想と実際の差
経験E:データ

0.2 機械学習の前に

機械学習や深層学習を積極的に利用したい気持ちは分かるが、問題の解決に必ずしも機械学習や深層学習を使う必要はない。機械学習や深層学習にもデメリットがあり、使わない方が効率が良い場合も往々にしてある。

0.2.1 機械学習・深層学習のデメリット

機械学習や深層学習には、応用数学(線形代数、微分積分、確率統計及び情報理論)の知識が必要である。
そのため開発ができたとしても、機械学習・深層学習の知識がない人がトラブルを起こした場合、解決することができない。

0.2.2 機械学習・深層学習に必要なデータの前処理

集めたデータ(ローデータ)はそのまま使えるとことは少なく、欠損値や異常値に対する適切なクレンジング処理が必要である。

第1章 線形回帰モデル

まずは、機械学習モデルの中で代表的な線形回帰モデルを考察する。
線形回帰は教師あり学習の1つであり、目的変数が説明変数の係数に対して線形なモデルを学習するものである。
線形回帰では訓練データに適合する回帰係数を学習する際、2乗誤差の最小化を行う

1.1 回帰問題

教師あり学習の1つであり、ざっくり言うと関数近似問題。
ある入力値(離散値または連続値)から、連続値の出力を予測する問題。

  • 直線(1次関数)で予想する場合:線形回帰(Linear regression)
  • 曲線(1次関数以外)で予想する場合:非線形回帰(Nonlinear regression)

回帰は予測のみならず、ランキング問題も解くことができるが、おススメしない。
回帰問題を解くことと、ランキング問題を解くことを比較すると回帰問題を解く方が難しい。
難しい問題(回帰問題)を解くことで、簡単な問題(ランキング問題)を解くべきではない。
参考:Vapnik(バプニック)の原理
VapnikはSVM(サポートベクターマシーン)を提唱した人

1.2 回帰問題で扱うデータ

  • 入力データ

 各要素の説明変数または特徴量と呼ぶ
 $m$次元のベクトル($m=1$の場合は、スカラー)

$$x=(x_1,x_2,x_3,\cdots,x_m)^T\in\mathbb{R^m}$$

 $m=1$の場合
$$x\in\mathbb{R}$$

$\mathbb{R}$;実数全体
慣例としてベクトルは太字で書く。$T$は転値

  • 出力データ (出力を複数にすることはできる。マルチタスク学習が近い。)  目的変数と呼ぶ(スカラー値である)

$$y\in\mathbb{R}$$

説明変数($x\in\mathbb{R^m}$)を使って、目的変数($y\in\mathbb{R}$)を予測できるようする。
教師データ { $(x_i,y_i);i=1,2,3,\cdots,n $ }
回帰問題の具体例には、住宅価格の予測や来場者の予測などがある。

ボストンの住宅価格データ(Boston Housingデータセット:The Boston house-price data)の予測を例に挙げた場合
説明変数($x\in\mathbb{R^m}$):13変数(犯罪率、敷地面積、産業、川の隣、環境、部屋数、築年数、距離、道路、税金、生徒と先生、黒人、低所得)
目的変数($y\in\mathbb{R})$:住宅価格

注:ボストンの住宅価格データ(Boston Housingデータセット
1970年代後半における(米国マサチューセッツ州にある)ボストンの住宅価格の表形式データセット(=構造化データセット)のこと。(家賃の予想をする。)

1.3 線形回帰モデルのパラメータ

線形回帰のモデルの推定するべき未知のパラメータ$w$は
$$w=(w_1,w_2,w_3,\cdots,w_m)^T\in\mathbb{R^m}$$

切片を$w_0$とする。(切片をバイアス項ともいう)

なお、回帰問題のゴールは、{ $(x_i,y_i);i=1,2,3,\cdots,n $ } を用いて、
うまいパラメータ $w=(w_1,w_2,w_3,\cdots,w_n)$ を求めること。
最終的には、教師データにはない $x$ を持ってきて、その入力を線形回帰モデルに入力することで、出力を得る。

1.4 線形結合

予測値を $\hat{y}\in\mathbb{R}$ とすると、(慣例として予測値にはハット^を付ける)
(目的変数 $y\in\mathbb{R}$ と混同しないため、予測値を $\hat{y}\in\mathbb{R}$ とする)

\begin{eqnarray}
\hat{y}&=&w^Tx+w_0=(w_1,w_2,w_3,\cdots,w_m)
\begin{pmatrix}
x_1\\
x_2\\
x_3\\
\vdots \\
x_m
\end{pmatrix}+w_0\\
&=& w_1x_1+w_2x_2+w_3x_3+\cdots+w_mx_m+w_0\\
&=& \sum_{k=1}^m x_k w_k+w_0
\end{eqnarray}

と表すことができる。

1.5 単回帰モデル

単回帰 ⇒ 直線 ⇒ 1次元のイメージ
説明変数が1次元 ($w=w_1$)の場合を単回帰といい、直線の式で表される
データについては、回帰直線に誤差 $\epsilon$ を考慮すると

$$y=w_0+w_1x_1+\epsilon$$
$y$:目的変数、 $w_0$:切片、 $w_1$:回帰係数、 $x_1$:説明変数、 $\epsilon$:誤差

$x_1$と$y$が既知のため、$\epsilon$ が最小になるように、パラメータ $w_0$と$w_1$ を設定すればよい。

1.6 重回帰モデル

単回帰 ⇒ 局面・超平面 ⇒ $m$次元のイメージ
説明変数が多次元($m$次元($1\leqq m\in\mathbb{N}$))の場合を重回帰という。
データについては、回帰直線に誤差 $\epsilon$ を考慮すると
$$y=w_0+w_1x_1+w_2x_2+w_3x_3+\cdots+w_mx_m+\epsilon=w_0+\sum_{k=1}^m w_kx_k+\epsilon$$

$y$:目的変数、 $w_0$:切片、 $\epsilon$:誤差、
$w_1,w_2,w_3\cdots ,w_m$:回帰係数、
$x_1,x_2,x_3\cdots ,x_m$:説明変数

1.7 パラメータの推定

1.7.1 平均二乗誤差(残差平方和)(Mean Squared Error)

データとモデル出力の誤差を二乗した後、平均を取ったもの
小さいほど直線とデータの距離が近い
頭文字をとってMSEで表す。
データは既知のもので、パラメータは未知である。

$$MSE_{\rm train}=\frac{1}{n_{\rm train}}\sum_{k=1}^{n_{\rm train}}\Big(\hat{y_k}-y_k\Big)^2$$

1.7.2 最小二乗法

学習データの平均二乗誤差を最小とするパラメータを探索する方法
学習データの平均二乗誤差の最小化は、その勾配が0になる点を求めれば良い

MSEを最小にするような $w\in\mathbb{R^m}$
$$\hat{w}=\arg \min_{w\in\mathbb{R^{m+1}}}MSE_{\rm train}$$

$w$に対して微分したものが0となる$w$の点を求める。つまり勾配が0になる点を求める。
$$\frac{\partial}{\partial w}MSE_{\rm train}=0$$

第1章 線形回帰のハンズオン

ボストンの住宅データセットを線形回帰モデルで分析(適切な査定結果が必要)

課題:部屋数が4で犯罪率が0.3の物件はいくらになるか?

必要なモジュールとデータのインポート

# from モジュール名 import クラス名(もしくは関数名や変数名)
from sklearn.datasets import load_boston
from pandas import DataFrame
import numpy as np

# ボストンデータを"boston"というインスタンスにインポート
boston = load_boston()

# インポートしたボストンデータを確認(data / target / feature_names / DESCR)
print(boston)

{'data': array([[6.3200e-03, 1.8000e+01, 2.3100e+00, ..., 1.5300e+01, 3.9690e+02,
4.9800e+00],
[2.7310e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9690e+02,
9.1400e+00],
[2.7290e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9283e+02,
4.0300e+00],
...,
[6.0760e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,
5.6400e+00],
[1.0959e-01, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9345e+02,
6.4800e+00],
[4.7410e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,
7.8800e+00]]), 'target': array([24. , 21.6, 34.7, 33.4, 36.2, 28.7, 22.9, 27.1, 16.5, 18.9, 15. ,
18.9, 21.7, 20.4, 18.2, 19.9, 23.1, 17.5, 20.2, 18.2, 13.6, 19.6,
15.2, 14.5, 15.6, 13.9, 16.6, 14.8, 18.4, 21. , 12.7, 14.5, 13.2,
13.1, 13.5, 18.9, 20. , 21. , 24.7, 30.8, 34.9, 26.6, 25.3, 24.7,
21.2, 19.3, 20. , 16.6, 14.4, 19.4, 19.7, 20.5, 25. , 23.4, 18.9,
35.4, 24.7, 31.6, 23.3, 19.6, 18.7, 16. , 22.2, 25. , 33. , 23.5,
19.4, 22. , 17.4, 20.9, 24.2, 21.7, 22.8, 23.4, 24.1, 21.4, 20. ,
20.8, 21.2, 20.3, 28. , 23.9, 24.8, 22.9, 23.9, 26.6, 22.5, 22.2,
23.6, 28.7, 22.6, 22. , 22.9, 25. , 20.6, 28.4, 21.4, 38.7, 43.8,
33.2, 27.5, 26.5, 18.6, 19.3, 20.1, 19.5, 19.5, 20.4, 19.8, 19.4,
21.7, 22.8, 18.8, 18.7, 18.5, 18.3, 21.2, 19.2, 20.4, 19.3, 22. ,
20.3, 20.5, 17.3, 18.8, 21.4, 15.7, 16.2, 18. , 14.3, 19.2, 19.6,
23. , 18.4, 15.6, 18.1, 17.4, 17.1, 13.3, 17.8, 14. , 14.4, 13.4,
15.6, 11.8, 13.8, 15.6, 14.6, 17.8, 15.4, 21.5, 19.6, 15.3, 19.4,
17. , 15.6, 13.1, 41.3, 24.3, 23.3, 27. , 50. , 50. , 50. , 22.7,
25. , 50. , 23.8, 23.8, 22.3, 17.4, 19.1, 23.1, 23.6, 22.6, 29.4,
23.2, 24.6, 29.9, 37.2, 39.8, 36.2, 37.9, 32.5, 26.4, 29.6, 50. ,
32. , 29.8, 34.9, 37. , 30.5, 36.4, 31.1, 29.1, 50. , 33.3, 30.3,
34.6, 34.9, 32.9, 24.1, 42.3, 48.5, 50. , 22.6, 24.4, 22.5, 24.4,
20. , 21.7, 19.3, 22.4, 28.1, 23.7, 25. , 23.3, 28.7, 21.5, 23. ,
26.7, 21.7, 27.5, 30.1, 44.8, 50. , 37.6, 31.6, 46.7, 31.5, 24.3,
31.7, 41.7, 48.3, 29. , 24. , 25.1, 31.5, 23.7, 23.3, 22. , 20.1,
22.2, 23.7, 17.6, 18.5, 24.3, 20.5, 24.5, 26.2, 24.4, 24.8, 29.6,
42.8, 21.9, 20.9, 44. , 50. , 36. , 30.1, 33.8, 43.1, 48.8, 31. ,
36.5, 22.8, 30.7, 50. , 43.5, 20.7, 21.1, 25.2, 24.4, 35.2, 32.4,
32. , 33.2, 33.1, 29.1, 35.1, 45.4, 35.4, 46. , 50. , 32.2, 22. ,
20.1, 23.2, 22.3, 24.8, 28.5, 37.3, 27.9, 23.9, 21.7, 28.6, 27.1,
20.3, 22.5, 29. , 24.8, 22. , 26.4, 33.1, 36.1, 28.4, 33.4, 28.2,
22.8, 20.3, 16.1, 22.1, 19.4, 21.6, 23.8, 16.2, 17.8, 19.8, 23.1,
21. , 23.8, 23.1, 20.4, 18.5, 25. , 24.6, 23. , 22.2, 19.3, 22.6,
19.8, 17.1, 19.4, 22.2, 20.7, 21.1, 19.5, 18.5, 20.6, 19. , 18.7,
32.7, 16.5, 23.9, 31.2, 17.5, 17.2, 23.1, 24.5, 26.6, 22.9, 24.1,
18.6, 30.1, 18.2, 20.6, 17.8, 21.7, 22.7, 22.6, 25. , 19.9, 20.8,
16.8, 21.9, 27.5, 21.9, 23.1, 50. , 50. , 50. , 50. , 50. , 13.8,
13.8, 15. , 13.9, 13.3, 13.1, 10.2, 10.4, 10.9, 11.3, 12.3, 8.8,
7.2, 10.5, 7.4, 10.2, 11.5, 15.1, 23.2, 9.7, 13.8, 12.7, 13.1,
12.5, 8.5, 5. , 6.3, 5.6, 7.2, 12.1, 8.3, 8.5, 5. , 11.9,
27.9, 17.2, 27.5, 15. , 17.2, 17.9, 16.3, 7. , 7.2, 7.5, 10.4,
8.8, 8.4, 16.7, 14.2, 20.8, 13.4, 11.7, 8.3, 10.2, 10.9, 11. ,
9.5, 14.5, 14.1, 16.1, 14.3, 11.7, 13.4, 9.6, 8.7, 8.4, 12.8,
10.5, 17.1, 18.4, 15.4, 10.8, 11.8, 14.9, 12.6, 14.1, 13. , 13.4,
15.2, 16.1, 17.8, 14.9, 14.1, 12.7, 13.5, 14.9, 20. , 16.4, 17.7,
19.5, 20.2, 21.4, 19.9, 19. , 19.1, 19.1, 20.1, 19.9, 19.6, 23.2,
29.8, 13.8, 13.3, 16.7, 12. , 14.6, 21.4, 23. , 23.7, 25. , 21.8,
20.6, 21.2, 19.1, 20.6, 15.2, 7. , 8.1, 13.6, 20.1, 21.8, 24.5,
23.1, 19.7, 18.3, 21.2, 17.5, 16.8, 22.4, 20.6, 23.9, 22. , 11.9]), 'feature_names': array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7'), 'DESCR': ".. _boston_dataset:\n\nBoston house prices dataset\n---------------------------\n\n*Data Set Characteristics:* \n\n :Number of Instances: 506 \n\n :Number of Attributes: 13 numeric/categorical predictive. Median Value (attribute 14) is usually the target.\n\n :Attribute Information (in order):\n - CRIM per capita crime rate by town\n - ZN proportion of residential land zoned for lots over 25,000 sq.ft.\n - INDUS proportion of non-retail business acres per town\n - CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)\n - NOX nitric oxides concentration (parts per 10 million)\n - RM average number of rooms per dwelling\n - AGE proportion of owner-occupied units built prior to 1940\n - DIS weighted distances to five Boston employment centres\n - RAD index of accessibility to radial highways\n - TAX full-value property-tax rate per $10,000\n - PTRATIO pupil-teacher ratio by town\n - B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town\n - LSTAT % lower status of the population\n - MEDV Median value of owner-occupied homes in $1000's\n\n :Missing Attribute Values: None\n\n :Creator: Harrison, D. and Rubinfeld, D.L.\n\nThis is a copy of UCI ML housing dataset.\nhttps://archive.ics.uci.edu/ml/machine-learning-databases/housing/\n\n\nThis dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.\n\nThe Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic\nprices and the demand for clean air', J. Environ. Economics & Management,\nvol.5, 81-102, 1978. Used in Belsley, Kuh & Welsch, 'Regression diagnostics\n...', Wiley, 1980. N.B. Various transformations are used in the table on\npages 244-261 of the latter.\n\nThe Boston house-price data has been used in many machine learning papers that address regression\nproblems. \n \n.. topic:: References\n\n - Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.\n - Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243, University of Massachusetts, Amherst. Morgan Kaufmann.\n", 'filename': 'D:\Anaconda3\lib\site-packages\sklearn\datasets\data\boston_house_prices.csv'}

# DESCR変数の中身を確認
print(boston['DESCR'])

出力結果は次の通り

.. _boston_dataset:

Boston house prices dataset

Data Set Characteristics:

:Number of Instances: 506

:Number of Attributes: 13 numeric/categorical predictive. Median Value (attribute 14) is usually the target.

:Attribute Information (in order):
- CRIM per capita crime rate by town
- ZN proportion of residential land zoned for lots over 25,000 sq.ft.
- INDUS proportion of non-retail business acres per town
- CHAS Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)
- NOX nitric oxides concentration (parts per 10 million)
- RM average number of rooms per dwelling
- AGE proportion of owner-occupied units built prior to 1940
- DIS weighted distances to five Boston employment centres
- RAD index of accessibility to radial highways
- TAX full-value property-tax rate per $10,000
- PTRATIO pupil-teacher ratio by town
- B 1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town
- LSTAT % lower status of the population
- MEDV Median value of owner-occupied homes in $1000's

:Missing Attribute Values: None

:Creator: Harrison, D. and Rubinfeld, D.L.

This is a copy of UCI ML housing dataset.
https://archive.ics.uci.edu/ml/machine-learning-databases/housing/

This dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.

The Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic
prices and the demand for clean air', J. Environ. Economics & Management,
vol.5, 81-102, 1978. Used in Belsley, Kuh & Welsch, 'Regression diagnostics
...', Wiley, 1980. N.B. Various transformations are used in the table on
pages 244-261 of the latter.

The Boston house-price data has been used in many machine learning papers that address regression
problems.

.. topic:: References

  • Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.
    • Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243, University of Massachusetts, Amherst. Morgan Kaufmann.
# feature_names変数の中身を確認
# カラム名
print(boston['feature_names'])

出力結果(feature_names変数の中身)は次の通り

['CRIM' 'ZN' 'INDUS' 'CHAS' 'NOX' 'RM' 'AGE' 'DIS' 'RAD' 'TAX' 'PTRATIO'
'B' 'LSTAT']

それぞれの変数と日本語訳
CRIM:町別の犯罪率
ZN:敷地面積(25,000平方フィートを超える区画に分類される住宅地の割合)
INDUS:非小売業の土地面積の割合
CHAS:川の隣(チャールズ川沿いかどうか[区画が川に接している場合は1、そうでない場合は0])
NOX:環境(NOx濃度:窒素感化物の濃度)
RM:部屋数(1戸当たりの平均部屋数)
AGE:築年数(1940年より前に建てられた持ち家の割合)
DIS:距離(5つあるボストン雇用センターまでの加重距離)
RAD:道路(主要高速道路へのアクセス性の指数)
TAX:税金(10,000ドル当たりの固定資産税率)
PTRATIO:生徒と先生(教師あたりの生徒の数)
B:黒人(町ごとの黒人の割合-0.63を1000倍した値)
LSTAT:低所得(低所得者人口の割合)

PRICE:住宅価格

# data変数(説明変数)の中身を確認
print(boston['data'][:5])

出力結果(data変数の中身)は次の通り

[[6.3200e-03 1.8000e+01 2.3100e+00 0.0000e+00 5.3800e-01 6.5750e+00
6.5200e+01 4.0900e+00 1.0000e+00 2.9600e+02 1.5300e+01 3.9690e+02
4.9800e+00]
[2.7310e-02 0.0000e+00 7.0700e+00 0.0000e+00 4.6900e-01 6.4210e+00
7.8900e+01 4.9671e+00 2.0000e+00 2.4200e+02 1.7800e+01 3.9690e+02
9.1400e+00]
[2.7290e-02 0.0000e+00 7.0700e+00 0.0000e+00 4.6900e-01 7.1850e+00
6.1100e+01 4.9671e+00 2.0000e+00 2.4200e+02 1.7800e+01 3.9283e+02
4.0300e+00]
[3.2370e-02 0.0000e+00 2.1800e+00 0.0000e+00 4.5800e-01 6.9980e+00
4.5800e+01 6.0622e+00 3.0000e+00 2.2200e+02 1.8700e+01 3.9463e+02
2.9400e+00]
[6.9050e-02 0.0000e+00 2.1800e+00 0.0000e+00 4.5800e-01 7.1470e+00
5.4200e+01 6.0622e+00 3.0000e+00 2.2200e+02 1.8700e+01 3.9690e+02
5.3300e+00]]

# target変数(目的変数)の中身を確認
print(boston['target'][:5])

出力結果(target変数の中身)は次の通り

[24. 21.6 34.7 33.4 36.2 28.7 22.9 27.1 16.5 18.9 15. 18.9 21.7 20.4
18.2 19.9 23.1 17.5 20.2 18.2 13.6 19.6 15.2 14.5 15.6 13.9 16.6 14.8
18.4 21. 12.7 14.5 13.2 13.1 13.5 18.9 20. 21. 24.7 30.8 34.9 26.6
25.3 24.7 21.2 19.3 20. 16.6 14.4 19.4 19.7 20.5 25. 23.4 18.9 35.4
24.7 31.6 23.3 19.6 18.7 16. 22.2 25. 33. 23.5 19.4 22. 17.4 20.9
24.2 21.7 22.8 23.4 24.1 21.4 20. 20.8 21.2 20.3 28. 23.9 24.8 22.9
23.9 26.6 22.5 22.2 23.6 28.7 22.6 22. 22.9 25. 20.6 28.4 21.4 38.7
43.8 33.2 27.5 26.5 18.6 19.3 20.1 19.5 19.5 20.4 19.8 19.4 21.7 22.8
18.8 18.7 18.5 18.3 21.2 19.2 20.4 19.3 22. 20.3 20.5 17.3 18.8 21.4
15.7 16.2 18. 14.3 19.2 19.6 23. 18.4 15.6 18.1 17.4 17.1 13.3 17.8
14. 14.4 13.4 15.6 11.8 13.8 15.6 14.6 17.8 15.4 21.5 19.6 15.3 19.4
17. 15.6 13.1 41.3 24.3 23.3 27. 50. 50. 50. 22.7 25. 50. 23.8
23.8 22.3 17.4 19.1 23.1 23.6 22.6 29.4 23.2 24.6 29.9 37.2 39.8 36.2
37.9 32.5 26.4 29.6 50. 32. 29.8 34.9 37. 30.5 36.4 31.1 29.1 50.
33.3 30.3 34.6 34.9 32.9 24.1 42.3 48.5 50. 22.6 24.4 22.5 24.4 20.
21.7 19.3 22.4 28.1 23.7 25. 23.3 28.7 21.5 23. 26.7 21.7 27.5 30.1
44.8 50. 37.6 31.6 46.7 31.5 24.3 31.7 41.7 48.3 29. 24. 25.1 31.5
23.7 23.3 22. 20.1 22.2 23.7 17.6 18.5 24.3 20.5 24.5 26.2 24.4 24.8
29.6 42.8 21.9 20.9 44. 50. 36. 30.1 33.8 43.1 48.8 31. 36.5 22.8
30.7 50. 43.5 20.7 21.1 25.2 24.4 35.2 32.4 32. 33.2 33.1 29.1 35.1
45.4 35.4 46. 50. 32.2 22. 20.1 23.2 22.3 24.8 28.5 37.3 27.9 23.9
21.7 28.6 27.1 20.3 22.5 29. 24.8 22. 26.4 33.1 36.1 28.4 33.4 28.2
22.8 20.3 16.1 22.1 19.4 21.6 23.8 16.2 17.8 19.8 23.1 21. 23.8 23.1
20.4 18.5 25. 24.6 23. 22.2 19.3 22.6 19.8 17.1 19.4 22.2 20.7 21.1
19.5 18.5 20.6 19. 18.7 32.7 16.5 23.9 31.2 17.5 17.2 23.1 24.5 26.6
22.9 24.1 18.6 30.1 18.2 20.6 17.8 21.7 22.7 22.6 25. 19.9 20.8 16.8
21.9 27.5 21.9 23.1 50. 50. 50. 50. 50. 13.8 13.8 15. 13.9 13.3
13.1 10.2 10.4 10.9 11.3 12.3 8.8 7.2 10.5 7.4 10.2 11.5 15.1 23.2
9.7 13.8 12.7 13.1 12.5 8.5 5. 6.3 5.6 7.2 12.1 8.3 8.5 5.
11.9 27.9 17.2 27.5 15. 17.2 17.9 16.3 7. 7.2 7.5 10.4 8.8 8.4
16.7 14.2 20.8 13.4 11.7 8.3 10.2 10.9 11. 9.5 14.5 14.1 16.1 14.3
11.7 13.4 9.6 8.7 8.4 12.8 10.5 17.1 18.4 15.4 10.8 11.8 14.9 12.6
14.1 13. 13.4 15.2 16.1 17.8 14.9 14.1 12.7 13.5 14.9 20. 16.4 17.7
19.5 20.2 21.4 19.9 19. 19.1 19.1 20.1 19.9 19.6 23.2 29.8 13.8 13.3
16.7 12. 14.6 21.4 23. 23.7 25. 21.8 20.6 21.2 19.1 20.6 15.2 7.
8.1 13.6 20.1 21.8 24.5 23.1 19.7 18.3 21.2 17.5 16.8 22.4 20.6 23.9
22. 11.9]

データフレームの作成

# 説明変数らをDataFrameへ変換
df = DataFrame(data=boston.data, columns = boston.feature_names)

# 目的変数をDataFrameへ追加
df['PRICE'] = np.array(boston.target)

# 最初の5行を表示
df.head(5)

出力結果は次の通り

CRIM ZN INDUS CHAS NOX RM AGE DIS RAD TAX PTRATIO B LSTAT PRICE
0 0.00632 18.0 2.31 0.0 0.538 6.575 65.2 4.0900 1.0 296.0 15.3 396.90 4.98 24.0
1 0.02731 0.0 7.07 0.0 0.469 6.421 78.9 4.9671 2.0 242.0 17.8 396.90 9.14 21.6
2 0.02729 0.0 7.07 0.0 0.469 7.185 61.1 4.9671 2.0 242.0 17.8 392.83 4.03 34.7
3 0.03237 0.0 2.18 0.0 0.458 6.998 45.8 6.0622 3.0 222.0 18.7 394.63 2.94 33.4
4 0.06905 0.0 2.18 0.0 0.458 7.147 54.2 6.0622 3.0 222.0 18.7 396.90 5.33 36.2

df.head()で上から指定した行数分を出力します。
データフレーム形式で見るとわかりやすく、
列ごとの値や各行が1個分のデータであることなどがわかります。

線形単回帰分析

# カラムを指定してデータを表示:RM(部屋数)
df[['RM']].head()

出力結果は次の通り

RM
0 6.575
1 6.421
2 7.185
3 6.998
4 7.147
# 説明変数
data = df.loc[:, ['RM']].values

# dataリストの表示(1-5)
print(data[0:5])

出力結果は次の通り

[[6.575]
[6.421]
[7.185]
[6.998]
[7.147]]

単回帰で使用する説明変数を取り出してみる。
単回帰のためRM(部屋数)だけを使用する。

なお、仮に単回帰で使用する変数がDIS(距離)だけの場合は次

# カラムを指定してデータを表示:DIS(距離)
df[['DIS']].head()

# 説明変数
data = df.loc[:, ['DIS']].values

# dataリストの表示(1-5)
print(data[0:5])

出力結果は次の通り

DIS
0 4.09
1 4.9671
2 4.9671
3 6.0622
4 6.0622

[[4.09 ]
[4.9671]
[4.9671]
[6.0622]
[6.0622]]

# 目的変数
target = df.loc[:, 'PRICE'].values

print(target[0:5])

出力結果は次の通り

[24. 21.6 34.7 33.4 36.2]

目的変数を取り出す

学習

# sklearnモジュールからLinearRegressionをインポート
from sklearn.linear_model import LinearRegression

# オブジェクト生成
model = LinearRegression()

# fit関数でパラメータ推定
model.fit(data, target)

出力結果は次の通り

LinearRegression()

#予測
model.predict([[1]])

出力結果は次の通り

[-25.5685118]

部屋数1の住宅の価格が -25.5685118

ボストン住宅データセットの線形回帰モデルでの分析
  適切な査定結果が必要
  高すぎても安すぎても会社に損害がある

課題の再掲:部屋数が4で犯罪率が0.3の物件はいくらになるか?
(結果は、物価の価格が 4.24007956)

# カラムを指定してデータを表示
df[['RM', 'CRIM']].head()

出力結果は次の通り

RM CRIM
0 6.575 0.00632
1 6.421 0.02731
2 7.185 0.02729
3 6.998 0.03237
4 7.147 0.06905

# 説明変数
data2 = df.loc[:, ['RM', 'CRIM']].values

# 目的変数
target2 = df.loc[:, 'PRICE'].values

# オブジェクト生成
model2 = LinearRegression()

# fit関数でパラメータ推定
model2.fit(data2, target2)

出力結果は次の通り

LinearRegression()

print(model2.predict([[4, 0.3]]))

出力結果は次の通り

[4.24007956]

回帰係数と切片の値を確認

# 単回帰の回帰係数と切片を出力
print('推定された回帰係数: %.3f, 推定された切片 : %.3f' % (model.coef_, model.intercept_))

出力結果は次の通り

推定された回帰係数: 9.102, 推定された切片 : -34.671

# 重回帰の回帰係数と切片を出力
print(model.coef_)
print(model.intercept_)

出力結果は次の通り

[9.10210898]
-34.67062077643857

決定係数

# train_test_splitをインポート
from sklearn.model_selection import train_test_split

# 70%を学習用、30%を検証用データにするよう分割
X_train, X_test, y_train, y_test = train_test_split(data, target, 
test_size = 0.3, random_state = 666)
# 学習用データでパラメータ推定
model.fit(X_train, y_train)
# 作成したモデルから予測(学習用、検証用モデル使用)
y_train_pred = model.predict(X_train)
y_test_pred = model.predict(X_test)

# matplotlibをインポート
import matplotlib.pyplot as plt
# Jupyterを利用していたら、以下のおまじないを書くとnotebook上に図が表示
%matplotlib inline
# 学習用、検証用それぞれで残差をプロット
plt.scatter(y_train_pred, y_train_pred - y_train, c = 'blue', marker = 'o', label = 'Train Data')
plt.scatter(y_test_pred, y_test_pred - y_test, c = 'lightgreen', marker = 's', label = 'Test Data')
plt.xlabel('Predicted Values')
plt.ylabel('Residuals')
# 凡例を左上に表示
plt.legend(loc = 'upper left')
# y = 0に直線を引く
plt.hlines(y = 0, xmin = -10, xmax = 50, lw = 2, color = 'red')
plt.xlim([10, 50])
plt.show()

出力結果は次の通り
sc1.png


# 平均二乗誤差を評価するためのメソッドを呼び出し
from sklearn.metrics import mean_squared_error
# 学習用、検証用データに関して平均二乗誤差を出力
print('MSE Train : %.3f, Test : %.3f' % (mean_squared_error(y_train, y_train_pred), mean_squared_error(y_test, y_test_pred)))
# 学習用、検証用データに関してR^2を出力
print('R^2 Train : %.3f, Test : %.3f' % (model.score(X_train, y_train), model.score(X_test, y_test)))

出力結果は次の通り

MSE Train : 44.983, Test : 40.412
R^2 Train : 0.500, Test : 0.434

第2章 非線形回帰モデル

2.1 基底展開法

非線形の場合は、基底展開法を使ってモデリングする
 回帰関数として、基底関数と呼ばれる既知の非線形関数とパラメータベクトルの線形結合を利用する
 未知パラメータについては、最小二乗法もしくは最尤法により推定する
 基底展開法も線形回帰と同じ枠組みで推定可能である

$$y_k=f(x_k)+\epsilon_k \qquad y_i=w_0+\sum_{k=1}^m w_k\phi_k(x_k)+\epsilon_k$$

基底関数の例
多項式関数
$$\phi_k(x)=x^k$$

ガウス型基底関数

$$\phi_k(x)=\exp \Bigg(\frac{(x-\mu_k)^2}{2h_k}\Bigg)$$

スプライン関数

2.2 モデルの式

基底展開法も線形回帰と同じ考え方で推定が可能である。

説明変数($x\in\mathbb{R^m}$)

$$x_k=(x_{k1},x_{k2},x_{k3},\cdots,x_{km})\in\mathbb{R^m}$$

非線形ベクトル
$$\phi(x_i)=\Big(\phi_1(x_i),\phi_2(x_i),\phi_3(x_i),\cdots ,\phi_k(x_i) \Big)^T\in\mathbb{R^k}$$

非線形関数の計画行列
$$\Phi^{(train)}=\Big(\phi(x_1),\phi(x_2),\phi(x_3),\cdots ,\phi(x_n) \Big)^T\in\mathbb{R^{n\times k}}$$

最尤法による予測
最小二乗法と同様に $\hat{y}$ を求めることができる。
$$\hat{y}=\Phi\Big(\Phi^{(train)T}\Phi^{(train)}\Big)^{-1}\Phi^{(train)T}\Phi^{(train)}$$

2.2 未学習・過学習

機械学習では、データを

1.学習データ
2.検証データ

に分けるのが一般的です。学習データと訓練データに分ける理由は、次に紹介する過学習(Overfitting)を起こさないことが主です。

2.2.1 未学習(Underfitting)

学習データに対して、十分小さな誤差が得られないモデル。つまり、うまく学習できていない
対策 モデルの表現力が低いため、表現力の高いモデルを使用する。特徴量を増やす。

2.2.2 過学習(Overfitting)

学習データに対して誤差は小さくなったものの、検証データに対する誤差が大きいモデル。
つまり、学習データの影響を受けすぎている場合です。

対策
1.学習データを増やす
2.不要な基底関数(説明変数)を削除して、表現力を抑える
3.正則化を使用して表現力を抑える

2.3 正則化(罰則化法)

モデルの複雑さに伴って値が大きくなる正則化項を課した関数を最小化
ただしMSE()等が最小となる点を探そうとすると過学習を起こす可能性がある。
そのため、原点近辺に制約を与えた上で最小となる点を探す。

$$S_{\gamma}=(y-\Phi^{n \times k}w)^T(y-\Phi w)+\gamma R(w)$$

2.4 L1ノルム、L2ノルム

$L^1$ノルムを利用した時の推定量をラッソ(Lasso)推定量という

$$ R(w)=\sum_{k=1}^m|w_k|=|w_1|+|w_2|+|w_3|+\cdots +|w_m|$$

$L^2$ノルムを利用した時の推定量をリッジ(Ridge)推定量もしくはスパース推定という

$$R(w)=\sqrt{\sum_{k=1}^m w_k^2}=\sqrt{w_1^2+w_2^2+w_3^2+\cdots +w_m^2}$$

2.5 モデルの検証(ホールドアウト法・交差検証)

2.5.1 ホールドアウト法

データを学習用とテスト用の2つに分割する。(学習用データ:テスト用データ=7:3で分けるなど)
予測精度および誤り率を推定するために使用
デメリットは、手元に大量にデータがない場合、良い性能評価を与えない
基底展開法に基づく非線形回帰モデルでは、基底関数の数、位置、チューニングをホールドアウト値を小さくするモデルで決定する

2.5.2 交差検証(クロスバリデーション)

データをブロックに分割し、1つのブロックを検証用データ、他を学習データとする。
これをイテレーターという。分割した数だけイテレータを繰り返してモデルをそれぞれ作成
できたモデルに対してそれぞれテストデータを与え、得られた精度の平均(CV値)をそれぞれ算出する。
各モデルのうち、最もCV値が小さいものが一番性能が良い

第2章 非線形回帰のハンズオン

モジュールのインポートとseabornの設定


import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

%matplotlib inline

#seaborn設定
sns.set()
#背景変更
sns.set_style("darkgrid", {'grid.linestyle': '--'})
#大きさ(スケール変更)
sns.set_context("paper")

n=100

def true_func(x):
    z = 1-48*x+218*x**2-315*x**3+145*x**4
    return z 

def linear_func(x):
    z = x
    return z

# 真の関数表示

x = np.arange(0, 1, 0.01)
y = true_func(x)

plt.plot(x, y)
plt.show()

download.png

# 真の関数からデータ生成
data = np.random.rand(n).astype(np.float32)
data = np.sort(data)
target = true_func(data)

# ノイズを加える
noise = 0.5 * np.random.randn(n)
target = target + noise

# ノイズ付きデータを描画
plt.scatter(data, target)

plt.title('NonLinear Regression')
plt.legend(loc=2)

d2.png

nonl1.png

from sklearn.linear_model import LinearRegression

clf = LinearRegression()
data = data.reshape(-1, 1)
target = target.reshape(-1, 1)
clf.fit(data, target)

p_lin = clf.predict(data)

plt.scatter(data, target, label='data')
plt.plot(data, p_lin, color='darkorange', marker='', linestyle='-', linewidth=1, markersize=6, label='linear regression')
plt.legend()
print(clf.score(data, target))

0.37878360977970466

d3.png

約0.38 と線形回帰ではうまく予測できていないことが分かります。

再度挑戦したところ、

0.19402766475720878

nonl2.png

約0.19 と線形回帰ではうまく予測できていないことが分かります。

非線形回帰による分析

from sklearn.kernel_ridge import KernelRidge

clf = KernelRidge(alpha=0.0002, kernel='rbf')
clf.fit(data, target)

p_kridge = clf.predict(data)

plt.scatter(data, target, color='blue', label='data')

plt.plot(data, p_kridge, color='orange', linestyle='-', linewidth=3, markersize=6, label='kernel ridge')
plt.legend()

print(clf.score(data, target))

0.8546032766354164

d4.png

精度が1に近づいている。線形回帰(0.37878360977970466)よりも精度がかなり向上していることがわかります。再度チャレンジしたところ

0.83065477947335

nonl3.png

やはり精度が1に近づいています。

ラッソ回帰の場合は

from sklearn.metrics.pairwise import rbf_kernel
from sklearn.linear_model import Lasso

kx = rbf_kernel(X=data, Y=data, gamma=4)

lasso_clf = Lasso(alpha=0.0001, max_iter=1000)
lasso_clf.fit(kx, target)

p_lasso = lasso_clf.predict(kx)

plt.scatter(data, target, color='blue', label='data')

plt.plot(data, p_lasso, color='orange', linestyle='-', linewidth=3, markersize=3,label='lasso')
plt.legend()

print(lasso_clf.score(kx, target))

0.8494137416910993

d5.png

リッジ回帰の過学習

#リッジ過学習
from sklearn.kernel_ridge import KernelRidge

#正規化を行わない
clf = KernelRidge(alpha=0.0000,kernel='rbf')
clf.fit(data, target)

p_kridge = clf.predict(data)

plt.scatter(data, target, color='blue', label='data')

plt.plot(data, p_kridge, color='orange', linestyle='-', linewidth=3, markersize=6, label='kernel ridge')
plt.legend()
print(clf.score(data, target))

0.9999999999999979

d6.png

数字は「だけ」いい

scikit-learnのKernelRidgeを利用しない

rbf_kernel:RBFカーネル関数
Ridge:リッジ回帰モデル

#Ridge
from sklearn.metrics.pairwise import rbf_kernel
from sklearn.linear_model import Ridge

kx = rbf_kernel(X=data, Y=data, gamma=50)

clf = Ridge(alpha=30)
clf.fit(kx, target)

p_ridge = clf.predict(kx)

plt.scatter(data, target,label='data')
for i in range(len(kx)):
    plt.plot(data, kx[i], color='black', linestyle='-', linewidth=1, markersize=3, label='rbf', alpha=0.2)

plt.plot(data, p_ridge, color='green', linestyle='-', linewidth=1, markersize=3,label='ridge regression')

print(clf.score(kx, target))

0.8355822156212662

d7.png

2度目

0.8182710804590342

nonl4.png

多項式を基底関数とした非線形回帰モデル

1次式から10次式までの多項式をそれぞれ基底関数にした非線形回帰モデル

from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline

deg = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

for d in deg:
    regr = Pipeline([
        ('poly', PolynomialFeatures(degree=d)),
        ('linear', LinearRegression())
    ])
    regr.fit(data, target)

    # make predictions
    p_poly = regr.predict(data)

    # plot regression result
    plt.scatter(data, target, label='data')
    plt.plot(data, p_poly, label='polynomial of degree %d' % (d))
    print(regr.score(data, target))

出力結果は次の通り

0.37878361384149006
0.5247287010587878
0.6566958180318789
0.857521201080545
0.8596743380417626
0.8598373812208518
0.8602155674528944
0.8615757809921557
0.8616076647596161
0.861566726847494

d8.png

2度目

0.19402767615562078
0.5517231588121143
0.6211594578122404
0.8339868076733876
0.8372181758831069
0.8377105753616771
0.841044264532349
0.846253471732493
0.846578547945985
0.8462776660848432

nonl5.png

カーネル回帰にラッソ推定量を適用したモデル

rbf_kernel:RBFカーネル関数
Lasso:ラッソ回帰モデル

from sklearn.metrics.pairwise import rbf_kernel
from sklearn.linear_model import Lasso

kx = rbf_kernel(X=data, Y=data, gamma=5)

lasso_clf = Lasso(alpha=10000, max_iter=1000)
lasso_clf.fit(kx, target)

p_lasso = lasso_clf.predict(kx)

plt.scatter(data, target)

plt.plot(data, p_lasso, color='green', linestyle='-', linewidth=3, markersize=3)

print(lasso_clf.score(kx, target))

出力結果は次の通り

-2.220446049250313e-16

d9.png

nonl6.png

サポートベクター回帰モデル(SVR)

from sklearn import model_selection, preprocessing, linear_model, svm

# SVR-rbf
clf_svr = svm.SVR(kernel='rbf', C=1e3, gamma=0.1, epsilon=0.1)
clf_svr.fit(data, target)
y_rbf = clf_svr.fit(data, target).predict(data)

print(clf_svr.score(data, target))

# plot
plt.scatter(data, target, color='blue', label='data')
plt.plot(data, y_rbf, color='orange', label='Support Vector Regression (RBF)')
plt.legend()
plt.show()

0.5049601396308219

d10.png

2度目

0.5539489247604701

nonl7.png

Kerasによる深層学習実装

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.1, random_state=0)

from keras.callbacks import EarlyStopping, TensorBoard, ModelCheckpoint

cb_cp = ModelCheckpoint('/content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.{epoch:02d}-{val_loss:.2f}.hdf5', verbose=1, save_weights_only=True)
cb_tf  = TensorBoard(log_dir='/content/drive/My Drive/study_ai_ml/skl_ml/out/tensorBoard', histogram_freq=0)
def relu_reg_model():
    model = Sequential()
    model.add(Dense(10, input_dim=1, activation='relu'))
    model.add(Dense(1000, activation='relu'))
    model.add(Dense(1000, activation='relu'))
    model.add(Dense(1000, activation='relu'))
    model.add(Dense(1000, activation='relu'))
    model.add(Dense(1000, activation='relu'))
    model.add(Dense(1000, activation='relu'))
    model.add(Dense(1000, activation='relu'))
    model.add(Dense(1000, activation='linear'))
#     model.add(Dense(100, activation='relu'))
#     model.add(Dense(100, activation='relu'))
#     model.add(Dense(100, activation='relu'))
#     model.add(Dense(100, activation='relu'))
    model.add(Dense(1))

    model.compile(loss='mean_squared_error', optimizer='adam')
    return model

from keras.models import Sequential
from keras.layers import Input, Dense, Dropout, BatchNormalization
from keras.wrappers.scikit_learn import KerasRegressor

# use data split and fit to run the model
estimator = KerasRegressor(build_fn=relu_reg_model, epochs=100, batch_size=5, verbose=1)

history = estimator.fit(x_train, y_train, callbacks=[cb_cp, cb_tf], validation_data=(x_test, y_test))

Epoch 1/100
18/18 [==============================] - 3s 39ms/step - loss: 2.3687 - val_loss: 1.3184

Epoch 00001: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.01-1.32.hdf5
Epoch 2/100
18/18 [==============================] - 0s 5ms/step - loss: 1.2527 - val_loss: 0.8765

Epoch 00002: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.02-0.88.hdf5
Epoch 3/100
18/18 [==============================] - 0s 5ms/step - loss: 1.3513 - val_loss: 1.1190

Epoch 00003: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.03-1.12.hdf5
Epoch 4/100
18/18 [==============================] - 0s 5ms/step - loss: 1.4372 - val_loss: 0.9950

Epoch 00004: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.04-1.00.hdf5
Epoch 5/100
18/18 [==============================] - 0s 8ms/step - loss: 1.1755 - val_loss: 0.6253

Epoch 00005: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.05-0.63.hdf5
Epoch 6/100
18/18 [==============================] - 0s 6ms/step - loss: 1.0516 - val_loss: 1.0208

Epoch 00006: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.06-1.02.hdf5
Epoch 7/100
18/18 [==============================] - 0s 6ms/step - loss: 1.2518 - val_loss: 0.6161

Epoch 00007: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.07-0.62.hdf5
Epoch 8/100
18/18 [==============================] - 0s 5ms/step - loss: 1.0415 - val_loss: 0.8969

Epoch 00008: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.08-0.90.hdf5
Epoch 9/100
18/18 [==============================] - 0s 5ms/step - loss: 1.0551 - val_loss: 0.6596

Epoch 00009: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.09-0.66.hdf5
Epoch 10/100
18/18 [==============================] - 0s 5ms/step - loss: 0.8400 - val_loss: 1.0283

Epoch 00010: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.10-1.03.hdf5
Epoch 11/100
18/18 [==============================] - 0s 5ms/step - loss: 1.2764 - val_loss: 0.5673

Epoch 00011: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.11-0.57.hdf5
Epoch 12/100
18/18 [==============================] - 0s 7ms/step - loss: 0.7415 - val_loss: 0.6156

Epoch 00012: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.12-0.62.hdf5
Epoch 13/100
18/18 [==============================] - 0s 6ms/step - loss: 0.6729 - val_loss: 0.5275

Epoch 00013: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.13-0.53.hdf5
Epoch 14/100
18/18 [==============================] - 0s 11ms/step - loss: 0.8777 - val_loss: 0.5321

Epoch 00014: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.14-0.53.hdf5
Epoch 15/100
18/18 [==============================] - 0s 5ms/step - loss: 0.8296 - val_loss: 0.6560

Epoch 00015: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.15-0.66.hdf5
Epoch 16/100
18/18 [==============================] - 0s 8ms/step - loss: 0.6910 - val_loss: 0.2104

Epoch 00016: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.16-0.21.hdf5
Epoch 17/100
18/18 [==============================] - 0s 5ms/step - loss: 0.4999 - val_loss: 0.1959

Epoch 00017: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.17-0.20.hdf5
Epoch 18/100
18/18 [==============================] - 0s 5ms/step - loss: 0.4434 - val_loss: 0.1674

Epoch 00018: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.18-0.17.hdf5
Epoch 19/100
18/18 [==============================] - 0s 5ms/step - loss: 0.5439 - val_loss: 0.2865

Epoch 00019: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.19-0.29.hdf5
Epoch 20/100
18/18 [==============================] - 0s 6ms/step - loss: 0.3424 - val_loss: 0.1589

Epoch 00020: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.20-0.16.hdf5
Epoch 21/100
18/18 [==============================] - 0s 6ms/step - loss: 0.4706 - val_loss: 0.1520

Epoch 00021: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.21-0.15.hdf5
Epoch 22/100
18/18 [==============================] - 0s 6ms/step - loss: 0.3670 - val_loss: 0.2082

Epoch 00022: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.22-0.21.hdf5
Epoch 23/100
18/18 [==============================] - 0s 5ms/step - loss: 0.3142 - val_loss: 0.1180

Epoch 00023: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.23-0.12.hdf5
Epoch 24/100
18/18 [==============================] - 0s 5ms/step - loss: 0.3173 - val_loss: 0.2538

Epoch 00024: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.24-0.25.hdf5
Epoch 25/100
18/18 [==============================] - 0s 5ms/step - loss: 0.3298 - val_loss: 0.4576

Epoch 00025: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.25-0.46.hdf5
Epoch 26/100
18/18 [==============================] - 0s 7ms/step - loss: 0.4976 - val_loss: 0.2659

Epoch 00026: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.26-0.27.hdf5
Epoch 27/100
18/18 [==============================] - 0s 5ms/step - loss: 0.4850 - val_loss: 0.3054

Epoch 00027: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.27-0.31.hdf5
Epoch 28/100
18/18 [==============================] - 0s 6ms/step - loss: 0.4312 - val_loss: 0.1528

Epoch 00028: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.28-0.15.hdf5
Epoch 29/100
18/18 [==============================] - 0s 12ms/step - loss: 0.3060 - val_loss: 0.2119

Epoch 00029: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.29-0.21.hdf5
Epoch 30/100
18/18 [==============================] - 0s 11ms/step - loss: 0.3605 - val_loss: 0.2328

Epoch 00030: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.30-0.23.hdf5
Epoch 31/100
18/18 [==============================] - 0s 9ms/step - loss: 0.3202 - val_loss: 0.1851

Epoch 00031: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.31-0.19.hdf5
Epoch 32/100
18/18 [==============================] - 0s 8ms/step - loss: 0.3274 - val_loss: 0.3435

Epoch 00032: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.32-0.34.hdf5
Epoch 33/100
18/18 [==============================] - 0s 6ms/step - loss: 0.3498 - val_loss: 0.3050

Epoch 00033: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.33-0.31.hdf5
Epoch 34/100
18/18 [==============================] - 0s 7ms/step - loss: 0.4392 - val_loss: 0.1888

Epoch 00034: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.34-0.19.hdf5
Epoch 35/100
18/18 [==============================] - 0s 12ms/step - loss: 0.2745 - val_loss: 0.2376

Epoch 00035: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.35-0.24.hdf5
Epoch 36/100
18/18 [==============================] - 0s 11ms/step - loss: 0.3910 - val_loss: 0.1773

Epoch 00036: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.36-0.18.hdf5
Epoch 37/100
18/18 [==============================] - 0s 14ms/step - loss: 0.2674 - val_loss: 0.2316

Epoch 00037: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.37-0.23.hdf5
Epoch 38/100
18/18 [==============================] - 0s 12ms/step - loss: 0.4182 - val_loss: 0.1392

Epoch 00038: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.38-0.14.hdf5
Epoch 39/100
18/18 [==============================] - 0s 13ms/step - loss: 0.2366 - val_loss: 0.1962

Epoch 00039: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.39-0.20.hdf5
Epoch 40/100
18/18 [==============================] - 0s 11ms/step - loss: 0.3074 - val_loss: 0.2793

Epoch 00040: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.40-0.28.hdf5
Epoch 41/100
18/18 [==============================] - 0s 10ms/step - loss: 0.4282 - val_loss: 0.2520

Epoch 00041: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.41-0.25.hdf5
Epoch 42/100
18/18 [==============================] - 0s 9ms/step - loss: 0.3577 - val_loss: 0.2010

Epoch 00042: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.42-0.20.hdf5
Epoch 43/100
18/18 [==============================] - 0s 6ms/step - loss: 0.3206 - val_loss: 0.1439

Epoch 00043: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.43-0.14.hdf5
Epoch 44/100
18/18 [==============================] - 0s 10ms/step - loss: 0.2555 - val_loss: 0.1906

Epoch 00044: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.44-0.19.hdf5
Epoch 45/100
18/18 [==============================] - 0s 11ms/step - loss: 0.3127 - val_loss: 0.2133

Epoch 00045: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.45-0.21.hdf5
Epoch 46/100
18/18 [==============================] - 0s 13ms/step - loss: 0.2234 - val_loss: 0.2968

Epoch 00046: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.46-0.30.hdf5
Epoch 47/100
18/18 [==============================] - 0s 7ms/step - loss: 0.3244 - val_loss: 0.1655

Epoch 00047: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.47-0.17.hdf5
Epoch 48/100
18/18 [==============================] - 0s 8ms/step - loss: 0.3943 - val_loss: 0.1154

Epoch 00048: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.48-0.12.hdf5
Epoch 49/100
18/18 [==============================] - 0s 10ms/step - loss: 0.3033 - val_loss: 0.1479

Epoch 00049: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.49-0.15.hdf5
Epoch 50/100
18/18 [==============================] - 0s 11ms/step - loss: 0.2892 - val_loss: 0.1643

Epoch 00050: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.50-0.16.hdf5
Epoch 51/100
18/18 [==============================] - 0s 11ms/step - loss: 0.3575 - val_loss: 0.1322

Epoch 00051: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.51-0.13.hdf5
Epoch 52/100
18/18 [==============================] - 0s 11ms/step - loss: 0.1997 - val_loss: 0.1382

Epoch 00052: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.52-0.14.hdf5
Epoch 53/100
18/18 [==============================] - 0s 8ms/step - loss: 0.2448 - val_loss: 0.1006

Epoch 00053: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.53-0.10.hdf5
Epoch 54/100
18/18 [==============================] - 0s 7ms/step - loss: 0.3163 - val_loss: 0.2483

Epoch 00054: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.54-0.25.hdf5
Epoch 55/100
18/18 [==============================] - 0s 5ms/step - loss: 0.2589 - val_loss: 0.2009

Epoch 00055: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.55-0.20.hdf5
Epoch 56/100
18/18 [==============================] - 0s 9ms/step - loss: 0.2954 - val_loss: 0.1127

Epoch 00056: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.56-0.11.hdf5
Epoch 57/100
18/18 [==============================] - 0s 9ms/step - loss: 0.2948 - val_loss: 0.2259

Epoch 00057: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.57-0.23.hdf5
Epoch 58/100
18/18 [==============================] - 0s 6ms/step - loss: 0.2602 - val_loss: 0.1211

Epoch 00058: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.58-0.12.hdf5
Epoch 59/100
18/18 [==============================] - 0s 6ms/step - loss: 0.2215 - val_loss: 0.2863

Epoch 00059: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.59-0.29.hdf5
Epoch 60/100
18/18 [==============================] - 0s 5ms/step - loss: 0.1998 - val_loss: 0.1559

Epoch 00060: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.60-0.16.hdf5
Epoch 61/100
18/18 [==============================] - 0s 8ms/step - loss: 0.2701 - val_loss: 0.1486

Epoch 00061: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.61-0.15.hdf5
Epoch 62/100
18/18 [==============================] - 0s 10ms/step - loss: 0.3268 - val_loss: 0.2724

Epoch 00062: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.62-0.27.hdf5
Epoch 63/100
18/18 [==============================] - 0s 7ms/step - loss: 0.3950 - val_loss: 0.2788

Epoch 00063: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.63-0.28.hdf5
Epoch 64/100
18/18 [==============================] - 0s 5ms/step - loss: 0.4328 - val_loss: 0.1337

Epoch 00064: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.64-0.13.hdf5
Epoch 65/100
18/18 [==============================] - 0s 6ms/step - loss: 0.3054 - val_loss: 0.1788

Epoch 00065: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.65-0.18.hdf5
Epoch 66/100
18/18 [==============================] - 0s 5ms/step - loss: 0.2838 - val_loss: 0.1487

Epoch 00066: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.66-0.15.hdf5
Epoch 67/100
18/18 [==============================] - 0s 9ms/step - loss: 0.2816 - val_loss: 0.2568

Epoch 00067: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.67-0.26.hdf5
Epoch 68/100
18/18 [==============================] - 0s 10ms/step - loss: 0.3562 - val_loss: 0.2701

Epoch 00068: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.68-0.27.hdf5
Epoch 69/100
18/18 [==============================] - 0s 5ms/step - loss: 0.4052 - val_loss: 0.1701

Epoch 00069: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.69-0.17.hdf5
Epoch 70/100
18/18 [==============================] - 0s 14ms/step - loss: 0.2667 - val_loss: 0.2477

Epoch 00070: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.70-0.25.hdf5
Epoch 71/100
18/18 [==============================] - 0s 11ms/step - loss: 0.2383 - val_loss: 0.1706

Epoch 00071: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.71-0.17.hdf5
Epoch 72/100
18/18 [==============================] - 0s 10ms/step - loss: 0.3184 - val_loss: 0.1495

Epoch 00072: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.72-0.15.hdf5
Epoch 73/100
18/18 [==============================] - 0s 8ms/step - loss: 0.3163 - val_loss: 0.3475

Epoch 00073: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.73-0.35.hdf5
Epoch 74/100
18/18 [==============================] - 0s 8ms/step - loss: 0.3339 - val_loss: 0.1130

Epoch 00074: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.74-0.11.hdf5
Epoch 75/100
18/18 [==============================] - 0s 6ms/step - loss: 0.2950 - val_loss: 0.1577

Epoch 00075: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.75-0.16.hdf5
Epoch 76/100
18/18 [==============================] - 0s 6ms/step - loss: 0.2316 - val_loss: 0.1398

Epoch 00076: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.76-0.14.hdf5
Epoch 77/100
18/18 [==============================] - 0s 5ms/step - loss: 0.2111 - val_loss: 0.1690

Epoch 00077: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.77-0.17.hdf5
Epoch 78/100
18/18 [==============================] - 0s 6ms/step - loss: 0.3059 - val_loss: 0.2156

Epoch 00078: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.78-0.22.hdf5
Epoch 79/100
18/18 [==============================] - 0s 6ms/step - loss: 0.2102 - val_loss: 0.1805

Epoch 00079: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.79-0.18.hdf5
Epoch 80/100
18/18 [==============================] - 0s 6ms/step - loss: 0.3325 - val_loss: 0.1725

Epoch 00080: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.80-0.17.hdf5
Epoch 81/100
18/18 [==============================] - 0s 6ms/step - loss: 0.2600 - val_loss: 0.2401

Epoch 00081: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.81-0.24.hdf5
Epoch 82/100
18/18 [==============================] - 0s 11ms/step - loss: 0.2752 - val_loss: 0.1804

Epoch 00082: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.82-0.18.hdf5
Epoch 83/100
18/18 [==============================] - 0s 5ms/step - loss: 0.2183 - val_loss: 0.1633

Epoch 00083: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.83-0.16.hdf5
Epoch 84/100
18/18 [==============================] - 0s 6ms/step - loss: 0.3495 - val_loss: 0.1369

Epoch 00084: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.84-0.14.hdf5
Epoch 85/100
18/18 [==============================] - 0s 5ms/step - loss: 0.2212 - val_loss: 0.1626

Epoch 00085: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.85-0.16.hdf5
Epoch 86/100
18/18 [==============================] - 0s 5ms/step - loss: 0.1862 - val_loss: 0.1461

Epoch 00086: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.86-0.15.hdf5
Epoch 87/100
18/18 [==============================] - 0s 5ms/step - loss: 0.1649 - val_loss: 0.1199

Epoch 00087: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.87-0.12.hdf5
Epoch 88/100
18/18 [==============================] - 0s 5ms/step - loss: 0.2830 - val_loss: 0.1360

Epoch 00088: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.88-0.14.hdf5
Epoch 89/100
18/18 [==============================] - 0s 11ms/step - loss: 0.2637 - val_loss: 0.1703

Epoch 00089: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.89-0.17.hdf5
Epoch 90/100
18/18 [==============================] - 0s 16ms/step - loss: 0.2872 - val_loss: 0.1716

Epoch 00090: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.90-0.17.hdf5
Epoch 91/100
18/18 [==============================] - 0s 16ms/step - loss: 0.2421 - val_loss: 0.1363

Epoch 00091: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.91-0.14.hdf5
Epoch 92/100
18/18 [==============================] - 0s 11ms/step - loss: 0.3171 - val_loss: 0.1216

Epoch 00092: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.92-0.12.hdf5
Epoch 93/100
18/18 [==============================] - 0s 10ms/step - loss: 0.3229 - val_loss: 0.1370

Epoch 00093: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.93-0.14.hdf5
Epoch 94/100
18/18 [==============================] - 0s 6ms/step - loss: 0.2654 - val_loss: 0.1550

Epoch 00094: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.94-0.16.hdf5
Epoch 95/100
18/18 [==============================] - 0s 5ms/step - loss: 0.2720 - val_loss: 0.1576

Epoch 00095: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.95-0.16.hdf5
Epoch 96/100
18/18 [==============================] - 0s 5ms/step - loss: 0.2874 - val_loss: 0.1960

Epoch 00096: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.96-0.20.hdf5
Epoch 97/100
18/18 [==============================] - 0s 6ms/step - loss: 0.3330 - val_loss: 0.2022

Epoch 00097: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.97-0.20.hdf5
Epoch 98/100
18/18 [==============================] - 0s 5ms/step - loss: 0.2197 - val_loss: 0.1240

Epoch 00098: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.98-0.12.hdf5
Epoch 99/100
18/18 [==============================] - 0s 5ms/step - loss: 0.2322 - val_loss: 0.1977

Epoch 00099: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.99-0.20.hdf5
Epoch 100/100
18/18 [==============================] - 0s 5ms/step - loss: 0.2265 - val_loss: 0.1991

Epoch 00100: saving model to /content/drive/My Drive/study_ai_ml/skl_ml/out/checkpoints/weights.100-0.20.hdf5


y_pred = estimator.predict(x_train)

18/18 [==============================] - 0s 2ms/step

plt.title('NonLiner Regressions via DL by ReLU')
plt.plot(data, target, 'o')
plt.plot(data, true_func(data), '.')
plt.plot(x_train, y_pred, "o", label='predicted: deep learning')
#plt.legend(loc=2)

nonli1.png

print(lasso_clf.coef_)

[-0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0.
-0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0. -0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]

第3章 ロジスティック回帰モデル

ロジスティック回帰は回帰問題を扱うモデルではなく、分類問題を扱うモデルである。

3.1 分類問題

教師あり学習の1つで、ある入力値からどのクラスに分類するか予測する

3.2 分類で扱うデータ

入力:説明変数
$m$次元のベクトル

$$x=(x_1,x_2,x_3,\cdots,x_m)^T\in\mathbb{R^m}$$
出力:目的変数
離散値$y\in${0,1}

3.3 シグモイド関数

シグモイド関数 $\sigma(x)$ は、入力が実数のとき必ず出力が0と1に収まる単調増加関数

$$\sigma(x)=\frac{1}{1+\exp(-ax)}=\frac{1}{1+e^{-ax}}$$

sigmoid.png

シグモイド関数の微分はシグモイド関数自身で表現できる。
$$\sigma^{\prime}(x)=a\sigma(x)\big(1-\sigma(x) \big)$$

sigmoidd.png

証明


\begin{eqnarray}
\sigma^{\prime}(x)&=&\bigg(\frac{1}{1+e^{-ax}}\bigg)^{\prime}\\
&=&\frac{-\big(-ae^{-ax}\big)}{(1+e^{-ax})^2}\\
&=&a\times\frac{1}{1+e^{-ax}}\times \frac{e^{-ax}}{1+e^{-ax}}\\
&=&a\times\frac{1}{1+e^{-ax}}\times \bigg(1-\frac{1}{1+e^{-ax}} \bigg)\\
&=&a\sigma (x)\Big(1- \sigma (x)\Big)
\end{eqnarray}

線形結合した値をシグモイド関数に与えることで$y=1$となる確率が出力
$$P(Y=1|x)=\sigma(w_0+w_1x_1+w_2x_2+w_3x_3+\cdots+w_mx_m)$$
出力された確率が0.5以上なら1、未満なら0とする

この数式を考察する際に最尤推定を使用する

3.4 最尤推定

元のデータである$x$、$y$を生成するに至る尤もらしいパラメータを探す推定方法
尤度関数を最大化させる未知のパラメータを探す
ロジスティック回帰モデルではベルヌーイ分布を利用する

3.5 尤度関数

データを固定し、パラメータを変化させる
1回の試行で$y=y_1$となる確率
$$p(y)=p^y(1-p)^{1-y}$$

$n$回の試行で同時に、$y_1,y_2,y_3,\cdots,y_n$が起こる確率

\begin{eqnarray}
P(y_1,y_2,y_3,\cdots,y_n ;p)&=&\prod_{k=1}^np^{y_k}(1-p)^{1-y_k} \\
&=&\prod_{k=1}^n \Big(\sigma(w^Tx_k) \Big)^{y_k}\Big(1-\sigma(w^Tx_k)\Big)^{1-y_k} \\
&=& L(w)
\end{eqnarray}

3.6 対数尤度関数

尤度関数は式が積の形になっているので、対数を取り和の形に直すと計算が楽になる
対数尤度関数が最大になる点と尤度関数が最大になる点は同じとなる。

\begin{eqnarray}
-\log L(w)&=&-\log L(w_1,w_2,w_3,\cdots,w_m)\\
&=&-\Big(y_1\log y_1+\cdots+y_m\log y_m+(1-y_1)\log (1-y_1)+\cdots+ (1-y_m)\log (1-y_m)+\Big)\\
&=&-\sum_{k=1}^m\Big(y_k\log y_k+(1-y_k)\log(1-y_k) \Big)
\end{eqnarray}

対数尤度関数を微分して0になる点を求めることができないため、勾配降下法を使って逐次求める。

3.7 勾配降下法

反復学習でパラメータを逐次更新する方法
パラメータ$k$が更新されなくなったとき、最適解が見つかったことになる。

$$w^{k+1}=w^k-\eta\sum_{i=1}^n(y_i-p_i)x_i$$

データを全て使うため大量のメモリが必要になる。
計算時間が多くなる問題がある。
最適解ではなく局所最適解に収束する可能性がある。

3.8 確率的勾配降下法

データを1件ずつランダムに選び、パラメータを更新する勾配降下法

$$w^{k+1}=w^k-\eta(y_i-p_i)x_i$$

3.9 モデルの評価

3.10 混合行列

tnp3.JPG

1.真陽性:TP(True Positive) ⇒ 正しくPositiveと判別した数
2.偽陽性:FP(False Positive) ⇒ 間違えてPositiveと判別した数
3.真陰性:TN(True Negative) ⇒ 正しくNegativeと判別した数
4.偽陰性;FN(False Negative) ⇒ 間違えてNegativeと判別した数

3.10.1 正解率(Accuracy)

全データ($TP+FN+FP+TN$)のうち、正しく判別した($TP+TN$)確率
$$\frac{TP+TN}{TP+FN+FP+TN}$$

3.10.2 再現率(Recall)

Positiveなデータ($TP+FN$)から、Positiveと予想($TP$)できる確率
$$\frac{TP}{TP+FN}$$

3.10.3 適合率(Precision)

モデルがPositiveと予想したデータ$TP+FP$から、Positiveと予想($TP$)できる確率
$$\frac{TP}{TP+FP}=P$$

3.10.4 F値(F score)

再現率(Recall)と適合率(Precision)の調和平均
$$\frac{2}{\frac{1}{Recall}+\frac{1}{Precision}}=\frac{2(Precision)(Recall)}{Recall+Precision}$$

第3章 ロジスティック回帰のハンズオン

モジュールの読み込み・データ表示

#from モジュール名 import クラス名(もしくは関数名や変数名)
import pandas as pd
from pandas import DataFrame
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

#matplotlibをinlineで表示するためのおまじない (plt.show()しなくていい)
%matplotlib inline

データの読み込み

# titanic data csvファイルの読み込み
titanic_df = pd.read_csv('../data/titanic_train.csv')

データセットの確認

# ファイルの先頭部を表示し、データセットを確認する
titanic_df.head(5)

tit1.JPG

不要なデータの削除する

#予測に不要と考えるからうをドロップ (本当はここの情報もしっかり使うべきだと思っています)
titanic_df.drop(['PassengerId', 'Name', 'Ticket', 'Cabin'], axis=1, inplace=True)

#一部カラムをドロップしたデータを表示
titanic_df.head()

logi1.JPG

欠損値の補完をする

#nullを含んでいる行を表示
titanic_df[titanic_df.isnull().any(1)].head(10)

tit3.JPG

#Ageカラムのnullを中央値で補完

titanic_df['AgeFill'] = titanic_df['Age'].fillna(titanic_df['Age'].mean())

#再度nullを含んでいる行を表示 (Ageのnullは補完されている)
titanic_df[titanic_df.isnull().any(1)]

#titanic_df.dtypes

tit5.JPG

ロジスティック回帰の実装(チケット価格から生死を判別)

# 運賃だけのリストを作成(説明変数)
data1 = titanic_df.loc[:, ["Fare"]].values

# 生死フラグのみのリストを作成(目的変数)
label1 = titanic_df.loc[:, ["Survived"]].values

from sklearn.linear_model import LogisticRegression

# ロジスティック回帰モデルのインスタンスを生成して学習
model = LogisticRegression()
model.fit(data1, label1)

LogisticRegression()

結果の確認


# model.predict(61)
print(model.predict([[61]]))

#model.predict_proba(62)
print(model.predict([[62]]))


[0]
[1]

X_test_value = model.decision_function(data1) 
print(model.predict([[62]]))
print(model.predict_proba([[62]]))

[[0.50358033 0.49641967]]
[[0.49978123 0.50021877]]

print (model.intercept_)

print (model.coef_)

[-0.94131796]
[[0.01519666]]

w_0 = model.intercept_[0]
w_1 = model.coef_[0,0]

# def normal_sigmoid(x):
#     return 1 / (1+np.exp(-x))

def sigmoid(x):
    return 1 / (1+np.exp(-(w_1*x+w_0)))

x_range = np.linspace(-1, 500, 3000)

plt.figure(figsize=(9,5))
#plt.xkcd()
plt.legend(loc=2)


# plt.ylim(-0.1, 1.1)
# plt.xlim(-10, 10)

# plt.plot([-10,10],[0,0], "k", lw=1)
# plt.plot([0,0],[-1,1.5], "k", lw=1)
plt.plot(data1,np.zeros(len(data1)), 'o')
plt.plot(data1, model.predict_proba(data1), 'o')
plt.plot(x_range, sigmoid(x_range), '-')
#plt.plot(x_range, normal_sigmoid(x_range), '-')
#

log3.png

ロジスティック回帰の実装(2変数から生死を判別)

titanic_df['Gender'] = titanic_df['Sex'].map({'female': 0, 'male': 1}).astype(int)
titanic_df.head(3)

性別(sex)が
男性︓male 、 女性︓female
のため、計算ができない。
そこで、男性︓male=1 、 女性︓female=0とした
変数「Gender」を作成する。

logi4.JPG

titanic_df['Pclass_Gender'] = titanic_df['Pclass'] + titanic_df['Gender']
titanic_df.head()

Pclass_Gender を Pclass(乗客の社会階級)+Gender(乗客の性別)で定義する。
Pclassは、1 が High class / 2 が Middle class / 3 がLow class
Genderは、1 が男性 / 0 が女性

Pclass = 1 ⇒ High classの女性
Pclass = 2 ⇒ High classの男性 or Middle classの女性
Pclass = 3 ⇒ Middle classの男性 or Low classの女性
Pclass = 4 ⇒ Low classの男性 or

logi6.JPG

titanic_df = titanic_df.drop(['Pclass', 'Sex', 'Gender','Age'], axis=1)
titanic_df.head()

logi7.JPG

np.random.seed = 0

xmin, xmax = -5, 85
ymin, ymax = 0.5, 4.5

index_survived = titanic_df[titanic_df["Survived"]==0].index
index_notsurvived = titanic_df[titanic_df["Survived"]==1].index

from matplotlib.colors import ListedColormap
fig, ax = plt.subplots()
cm = plt.cm.RdBu
cm_bright = ListedColormap(['#FF0000', '#0000FF'])
sc = ax.scatter(titanic_df.loc[index_survived, 'AgeFill'],
                titanic_df.loc[index_survived, 'Pclass_Gender']+(np.random.rand(len(index_survived))-0.5)*0.1,
                color='r', label='Not Survived', alpha=0.3)
sc = ax.scatter(titanic_df.loc[index_notsurvived, 'AgeFill'],
                titanic_df.loc[index_notsurvived, 'Pclass_Gender']+(np.random.rand(len(index_notsurvived))-0.5)*0.1,
                color='b', label='Survived', alpha=0.3)
ax.set_xlabel('AgeFill')
ax.set_ylabel('Pclass_Gender')
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
ax.legend(bbox_to_anchor=(1.4, 1.03))

matplotlib.legend.Legend at 0x1e9027ba730

logi9.png

#運賃だけのリストを作成(説明変数)
data2 = titanic_df.loc[:, ["AgeFill", "Pclass_Gender"]].values
data2

array([[22. , 4. ],
[38. , 1. ],
[26. , 3. ],
...,
[29.69911765, 3. ],
[26. , 2. ],
[32. , 4. ]])

#生死フラグのみのリストを作成(目的変数)
label2 =  titanic_df.loc[:,["Survived"]].values

model2 = LogisticRegression()

model2.fit(data2, label2)

LogisticRegression()

model2.predict([[10,1]])

array([1], dtype=int64)

model2.predict_proba([[10,1]])

array([[0.03754749, 0.96245251]])

10歳でHigh classの女性(Pclass = 1)は96%で生存すると予測

課題:年齢が30歳で男の乗客は生き残れるか
を男性の社会的地位によって場合分けする。

print(model2.predict([[30,2]]))
print(model2.predict_proba([[30, 2]]))

High class ⇒ Pclass = 2  ⇒ model2.predict_proba([[30, 2]])
結果:生存者と予想、生存率69.1%

[1]
[[0.30829809 0.69170191]]

print(model2.predict([[30,3]]))
print(model2.predict_proba([[30, 3]]))

Middle class ⇒ Pclass = 3 ⇒ model2.predict_proba([[30, 3]])
結果:死者と予想、生存率33.1%

[0]
[[0.66890121 0.33109879]]

print(model2.predict([[30,4]]))
print(model2.predict_proba([[30, 4]]))

Low class ⇒ Pclass = 4 ⇒ model2.predict_proba([[30, 4]])
結果:死者と予想、生存率9.8%

[0]
[[0.90154649 0.09845351]]

h = 0.02
xmin, xmax = -5, 85
ymin, ymax = 0.5, 4.5
xx, yy = np.meshgrid(np.arange(xmin, xmax, h), np.arange(ymin, ymax, h))
Z = model2.predict_proba(np.c_[xx.ravel(), yy.ravel()])[:, 1]
Z = Z.reshape(xx.shape)

fig, ax = plt.subplots()
levels = np.linspace(0, 1.0)
cm = plt.cm.RdBu
cm_bright = ListedColormap(['#FF0000', '#0000FF'])
#contour = ax.contourf(xx, yy, Z, cmap=cm, levels=levels, alpha=0.5)

sc = ax.scatter(titanic_df.loc[index_survived, 'AgeFill'],
                titanic_df.loc[index_survived, 'Pclass_Gender']+(np.random.rand(len(index_survived))-0.5)*0.1,
                color='r', label='Not Survived', alpha=0.3)
sc = ax.scatter(titanic_df.loc[index_notsurvived, 'AgeFill'],
                titanic_df.loc[index_notsurvived, 'Pclass_Gender']+(np.random.rand(len(index_notsurvived))-0.5)*0.1,
                color='b', label='Survived', alpha=0.3)

ax.set_xlabel('AgeFill')
ax.set_ylabel('Pclass_Gender')
ax.set_xlim(xmin, xmax)
ax.set_ylim(ymin, ymax)
#fig.colorbar(contour)

x1 = xmin
x2 = xmax
y1 = -1*(model2.intercept_[0]+model2.coef_[0][0]*xmin)/model2.coef_[0][1]
y2 = -1*(model2.intercept_[0]+model2.coef_[0][0]*xmax)/model2.coef_[0][1]
ax.plot([x1, x2] ,[y1, y2], 'k--')

logi11.png

モデル評価(混同行列とクロスバリデーション)

from sklearn.model_selection import train_test_split

# 1つの説明変数(Fare)のデータ
traindata1, testdata1, trainlabel1, testlabel1 = train_test_split(data1, label1, test_size=0.2)
traindata1.shape
trainlabel1.shape

# 2つの説明変数(AgeFill, Pclass_Gender)のデータ
traindata2, testdata2, trainlabel2, testlabel2 = train_test_split(data2, label2, test_size=0.2)
traindata2.shape
trainlabel2.shape
# 本来は同じデータセットを分割しなければいけない。(簡易的に別々に分割している。)

eval_model1=LogisticRegression()
eval_model2=LogisticRegression()

predictor_eval1=eval_model1.fit(traindata1, trainlabel1).predict(testdata1)
predictor_eval2=eval_model2.fit(traindata2, trainlabel2).predict(testdata2)
#predictor_eval=eval_model.fit(traindata, trainlabel).predict(testdata)

(712, 1)

eval_model1.score(traindata1, trainlabel1)

説明変数が1:学習データの決定係数

0.6685393258426966

eval_model1.score(testdata1,testlabel1)

説明変数が1:検証データの決定係数

0.6703910614525139

eval_model2.score(traindata2, trainlabel2)

説明変数が2:学習データの決定係数

0.7668539325842697

eval_model1.score(testdata1,testlabel1)

説明変数が2:検証データの決定係数

0.8100558659217877

説明変数が2のモデルのほうが、やはり精度が良い。

from sklearn import metrics
print(metrics.classification_report(testlabel1, predictor_eval1))
print(metrics.classification_report(testlabel2, predictor_eval2))

説明変数が1

precision recall f1-score support
0 0.65 0.99 0.78 107
1 0.93 0.19 0.32 72
accuracy 0.67 179
macro avg 0.79 0.59 0.55 179
weighted avg 0.76 0.67 0.60 179

説明変数が2

precision recall f1-score support
0 0.85 0.87 0.86 119
1 0.73 0.68 0.71 60
accuracy 0.81 179
macro avg 0.79 0.78 0.78 179
weighted avg 0.81 0.81 0.81 179

混合行列

from sklearn.metrics import confusion_matrix
confusion_matrix1=confusion_matrix(testlabel1, predictor_eval1)
confusion_matrix2=confusion_matrix(testlabel2, predictor_eval2)

confusion_matrix1

array([[106, 1],
[ 58, 14]], dtype=int64)

confusion_matrix2

array([[104, 15],
[ 19, 41]], dtype=int64)

fig = plt.figure(figsize = (7,7))
#plt.title(title)
sns.heatmap(
    confusion_matrix1,
    vmin=None,
    vmax=None,
    cmap="Blues",
    center=None,
    robust=False,
    annot=True, fmt='.2g',
    annot_kws=None,
    linewidths=0,
    linecolor='white',
    cbar=True,
    cbar_kws=None,
    cbar_ax=None,
    square=True, ax=None, 
    #xticklabels=columns,
    #yticklabels=columns,
    mask=None)

logi12.png

fig = plt.figure(figsize = (7,7))
#plt.title(title)
sns.heatmap(
    confusion_matrix2,
    vmin=None,
    vmax=None,
    cmap="Blues",
    center=None,
    robust=False,
    annot=True, fmt='.2g',
    annot_kws=None,
    linewidths=0,
    linecolor='white',
    cbar=True,
    cbar_kws=None,
    cbar_ax=None,
    square=True, ax=None, 
    #xticklabels=columns,
    #yticklabels=columns,
    mask=None)

logi13.png

#Paired categorical plots

import seaborn as sns
sns.set(style="whitegrid")

# Load the example Titanic dataset
titanic = sns.load_dataset("titanic")

# Set up a grid to plot survival probability against several variables
g = sns.PairGrid(titanic, y_vars="survived",
                 x_vars=["class", "sex", "who", "alone"],
                 size=5, aspect=.5)

# Draw a seaborn pointplot onto each Axes
g.map(sns.pointplot, color=sns.xkcd_rgb["plum"])
g.set(ylim=(0, 1))
sns.despine(fig=g.fig, left=True)

plt.show()

logi14.png

#Faceted logistic regression

import seaborn as sns
sns.set(style="darkgrid")

# Load the example titanic dataset
df = sns.load_dataset("titanic")

# Make a custom palette with gendered colors
pal = dict(male="#6495ED", female="#F08080")

# Show the survival proability as a function of age and sex
g = sns.lmplot(x="age", y="survived", col="sex", hue="sex", data=df,
               palette=pal, y_jitter=.02, logistic=True)
g.set(xlim=(0, 80), ylim=(-.05, 1.05))
plt.show()

logi15.png

第4章 主成分分析

線形変換後の変数の分散が最大となる射影軸を探索することにより、多変量データの持つ構造をより少数個の指標に圧縮する。

学習データ
$$x_i=(x_{i1},x_{i2},x_{i3},\cdots,x_{im})\in\mathbb{R^m}$$

平均(ベクトル)
$$\bar{x}=\frac{1}{n}\sum_{i=1}^n x_i$$

データ行列
$$\bar{X}=\Big(x_1-\bar{x},x_2-\bar{x},x_3-\bar{x},\cdots x_n-\bar{x}, \big)^T$$

分散共分散行列
$$Var(\bar{X})=\frac{1}{n}\bar{X}^T\bar{X} $$

線形変換後のベクトル
$$s_j=(s_{1j},s_{2j},s_{3j},\cdots,s_{nj})^{T}=\bar{X}a_j\qquad a_j\in\mathbb{R^m}$$
$j$ は射影軸のインデックス

4.1 ラグランジュ関数(目的関数・制約条件)

目的関数
$$\arg\max_{a\in\mathbb{R^m}} a_j^T Var(\bar{X}) a_j$$

制約条件は
$$a_j^Ta_j=1$$

制約条件付の最適化問題
⇒ ラグランジュ関数を最大にする係数ベクトル(微分して0になる点)を探索

4.2 ラグランジュ関数

$$E(a_j)=a_j^T Var(\bar{X}) a_j -\lambda \left(a_j^Ta_j-1\right)$$

ラグランジュ関数の両辺を微分して、係数ベクトル(微分して0になる点)を探す
$$\frac{\partial E(a_j)}{\partial a_j}=2Var (\bar{X})a_j-2\lambda a_j \quad (=0)$$
両辺2で割って、移行すると
$$Var (\bar{X})a_j=\lambda a_j$$
射影先の分散は固有値と一致する
$$Var (s_1)=a_1^TVar (\bar{X})a_1 =\lambda_1 a_1^Ta_1=\lambda_1$$

4.3 寄与率

第$k$主成分の分散の全分散に対する割合(第$k$主成分が持つ情報量の割合)のことを寄与率$c_k$という
$$c_k=\frac{\lambda_k}{\displaystyle\sum_{i=1}^m\lambda_i}=\frac{\lambda_k}{\lambda_1+\lambda_2+\lambda_3+\cdots+\lambda_k +\cdots+\lambda_m}$$

4.4 累積寄与率

第1から第$k$主成分まで圧縮した際の情報損失量の割合のことを累積寄与率$r_k$という。
$$c_k=\frac{\displaystyle\sum_{j=1}^k\lambda_j}{\displaystyle\sum_{i=1}^m\lambda_i}=\frac{\lambda_1+\lambda_2+\lambda_3+\cdots+\lambda_k }{\lambda_1+\lambda_2+\lambda_3+\cdots+\lambda_k +\cdots+\lambda_m}$$

乳がん検査データを利用しロジスティック回帰モデルを作成
主成分を利用し2次元空間上に次元圧縮

第4章 PCAのハンズオン

必要なモジュールのインポート

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegressionCV
from sklearn.metrics import confusion_matrix
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
%matplotlib inline

csvファイルから読み込む。

cancer_df = pd.read_csv('data/cancer.csv')

print('cancer df shape: {}'.format(cancer_df.shape))

cn1.JPG

cancer df shape: (569, 33)

569レコード、33カラム(次元)
最後にある名前のなしのカラム「Unnamed: 32」が不要なカラム

cancer_df['Unnamed: 32'].isnull().all()

削除する

cancer_df.drop('Unnamed: 32', axis=1, inplace=True)
print('cancer df shape: {}'.format(cancer_df.shape))

cancer df shape: (569, 32)

# 目的変数の抽出
y = cancer_df.diagnosis.apply(lambda d: 1 if d == 'M' else 0)

# 説明変数の抽出
X = cancer_df.loc[:, 'radius_mean':]

# 学習用とテスト用でデータを分離
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

# 標準化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# ロジスティック回帰で学習
logistic = LogisticRegressionCV(cv=10, random_state=0)
logistic.fit(X_train_scaled, y_train)

# 検証
print('Train score: {:.3f}'.format(logistic.score(X_train_scaled, y_train)))
print('Test score: {:.3f}'.format(logistic.score(X_test_scaled, y_test)))
print('Confustion matrix:\n{}'.format(confusion_matrix(y_true=y_test, y_pred=logistic.predict(X_test_scaled))))

データを可視化する

pca = PCA(n_components=30)
pca.fit(X_train_scaled)
plt.bar([n for n in range(1, len(pca.explained_variance_ratio_)+1)], pca.explained_variance_ratio_)

cn2.png

次元数2まで圧縮

# PCA
# 次元数2まで圧縮
pca = PCA(n_components=2)
X_train_pca = pca.fit_transform(X_train_scaled)
print('X_train_pca shape: {}'.format(X_train_pca.shape))
# X_train_pca shape: (426, 2)

# 寄与率
print('explained variance ratio: {}'.format(pca.explained_variance_ratio_))
print('cumulative contribution ratio: {}'.format(pca.explained_variance_ratio_.sum()))
# explained variance ratio: [ 0.43315126  0.19586506]
# cumulative contribution ratio: 0.6290163245532956

# 散布図にプロット
temp = pd.DataFrame(X_train_pca)
temp['Outcome'] = y_train.values
b = temp[temp['Outcome'] == 0]
m = temp[temp['Outcome'] == 1]
plt.scatter(x=b[0], y=b[1], marker='o') # 良性は○でマーク
plt.scatter(x=m[0], y=m[1], marker='^') # 悪性は△でマーク
plt.xlabel('PC 1') # 第1主成分をx軸
plt.ylabel('PC 2') # 第2主成分をy軸

X_train_pca shape: (426, 2)
explained variance ratio: [0.43315126 0.19586506]
cumulative contribution ratio: 0.6290163245532956
Text(0, 0.5, 'PC 2')

cn3.png

形状より2次元が確認できる
また、第1成分の寄与率が0.433、第2成分の寄与率が0.195である。

次元数3まで圧縮

pca2 = PCA(n_components=3)
X_train_pca2 = pca2.fit_transform(X_train_scaled)
print('X_train_pca2 shape: {}'.format(X_train_pca2.shape))

# 寄与率
print('explained variance ratio: {}'.format(pca2.explained_variance_ratio_))
print('cumulative contribution ratio: {}'.format(pca2.explained_variance_ratio_.sum()))

from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = Axes3D(fig)

# 散布図にプロット
temp = pd.DataFrame(X_train_pca2)
temp['Outcome'] = y_train.values
b = temp[temp['Outcome'] == 0]
m = temp[temp['Outcome'] == 1]
ax.scatter(xs=b[0], ys=b[1], marker='o') 
ax.scatter(xs=m[0], ys=m[1], marker='^') 
ax.set_xlabel('PC 1')
ax.set_ylabel('PC 2')
ax.set_zlabel('PC 3')

X_train_pca2 shape: (426, 3)
explained variance ratio: [0.43315126 0.19586506 0.09570611]
cumulative contribution ratio: 0.7247224331320569

cn4.png

第5章 アルゴリズム

5.1 k近傍法

教師あり学習の1つ。分類問題のための機械学習手法
最近傍のデータを$k$個取り、それらが最も多く属するクラスに識別する。
$k$を変化させると結果も変わる
$k$を大きくすると決定境界は滑らかになる

第5章 k近傍法のハンズオン

課題:人口データと分類結果をプロット
モジュールのインポート

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

訓練データの生成

def gen_data():
    x0 = np.random.normal(size=50).reshape(-1, 2) - 1
    x1 = np.random.normal(size=50).reshape(-1, 2) + 1.
    x_train = np.concatenate([x0, x1])
    y_train = np.concatenate([np.zeros(25), np.ones(25)]).astype(np.int)
    return x_train, y_train

X_train, ys_train = gen_data()
plt.scatter(X_train[:, 0], X_train[:, 1], c=ys_train)

matplotlib.collections.PathCollection at 0x7f9ed90f2b38

knn1.png

# 距離の計算
def distance(x1, x2):
    return np.sum((x1 - x2)**2, axis=1)

def knc_predict(n_neighbors, x_train, y_train, X_test):
    y_pred = np.empty(len(X_test), dtype=y_train.dtype)
    for i, x in enumerate(X_test):
        distances = distance(x, X_train)
        nearest_index = distances.argsort()[:n_neighbors]
        mode, _ = stats.mode(y_train[nearest_index])
        y_pred[i] = mode
    return y_pred

# 図
def plt_resut(x_train, y_train, y_pred):
    xx0, xx1 = np.meshgrid(np.linspace(-5, 5, 100), np.linspace(-5, 5, 100))
    xx = np.array([xx0, xx1]).reshape(2, -1).T
    plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train)
    plt.contourf(xx0, xx1, y_pred.reshape(100, 100).astype(dtype=np.float), alpha=0.2, levels=np.linspace(0, 1, 3))

# ハイパーパラメータk=3
n_neighbors = 3

xx0, xx1 = np.meshgrid(np.linspace(-5, 5, 100), np.linspace(-5, 5, 100))
X_test = np.array([xx0, xx1]).reshape(2, -1).T

# k近傍法
y_pred = knc_predict(n_neighbors, X_train, ys_train, X_test)
plt_resut(X_train, ys_train, y_pred)

download.png

numpyによる実装

xx0, xx1 = np.meshgrid(np.linspace(-5, 5, 100), np.linspace(-5, 5, 100))
xx = np.array([xx0, xx1]).reshape(2, -1).T

from sklearn.neighbors import KNeighborsClassifier
knc = KNeighborsClassifier(n_neighbors=n_neighbors).fit(X_train, ys_train)
plt_resut(X_train, ys_train, knc.predict(xx))

knn3.png

5.2 k-平均法(k-means)

$k$-平均法は教師なし学習の1つで、トップダウンでクラスタリングする機械学習の手法
$k$-平均法は教師なし学習、つまりラベルのないデータの分類方法です
与えられたデータを$k$個のクラスタリング(特徴が似ているグループ化)する。
クラスタリングのゴールは、同じクラスタ内のデータ点同士の距離が短くなるように、データを与えられた数のクラスタに分類していきます。具体的には、

$k$-平均法のアルゴリズム
1.各クラスタ中心の初期値を設定する
2.各データ点に対して、各クラスタ中心との距離を計算し、最も距離が近いクラスタを割り当てる
3.各クラスタの平均ベクトル(中心)を計算する
4.収束するまで2~3の処理を繰り返す

第5章 k-平均法のハンズオン

課題:人口データと分類結果をプロット
モジュールのインポート


%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

データ生成


def gen_data():
    x1 = np.random.normal(size=(100, 2)) + np.array([-5, -5])
    x2 = np.random.normal(size=(100, 2)) + np.array([5, -5])
    x3 = np.random.normal(size=(100, 2)) + np.array([0, 5])
    return np.vstack((x1, x2, x3))

#データ作成
X_train = gen_data()
#データ描画
plt.scatter(X_train[:, 0], X_train[:, 1])

matplotlib.collections.PathCollection at 0x7f91d7c80208

kmeans1.png

学習

def distance(x1, x2):
    return np.sum((x1 - x2)**2, axis=1)

n_clusters = 3
iter_max = 100

# 各クラスタ中心をランダムに初期化
centers = X_train[np.random.choice(len(X_train), n_clusters, replace=False)]

for _ in range(iter_max):
    prev_centers = np.copy(centers)
    D = np.zeros((len(X_train), n_clusters))
    # 各データ点に対して、各クラスタ中心との距離を計算
    for i, x in enumerate(X_train):
        D[i] = distance(x, centers)
    # 各データ点に、最も距離が近いクラスタを割り当
    cluster_index = np.argmin(D, axis=1)
    # 各クラスタの中心を計算
    for k in range(n_clusters):
        index_k = cluster_index == k
        centers[k] = np.mean(X_train[index_k], axis=0)
    # 収束判定
    if np.allclose(prev_centers, centers):
        break

クラスタリングの結果


def plt_result(X_train, centers, xx):
    # データを可視化
    plt.scatter(X_train[:, 0], X_train[:, 1], c=y_pred, cmap='spring')
    # 中心を可視化
    plt.scatter(centers[:, 0], centers[:, 1], s=200, marker='X', lw=2, c='black', edgecolor="white")
    # 領域の可視化
    pred = np.empty(len(xx), dtype=int)
    for i, x in enumerate(xx):
        d = distance(x, centers)
        pred[i] = np.argmin(d)
    plt.contourf(xx0, xx1, pred.reshape(100, 100), alpha=0.2, cmap='spring')

y_pred = np.empty(len(X_train), dtype=int)
for i, x in enumerate(X_train):
    d = distance(x, centers)
    y_pred[i] = np.argmin(d)

xx0, xx1 = np.meshgrid(np.linspace(-10, 10, 100), np.linspace(-10, 10, 100))
xx = np.array([xx0, xx1]).reshape(2, -1).T

plt_result(X_train, centers, xx)

kmeans2.png

numpy実装

from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=3, random_state=0).fit(X_train)

print("labels: {}".format(kmeans.labels_))
print("cluster_centers: {}".format(kmeans.cluster_centers_))
kmeans.cluster_centers_

labels: [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0]
cluster_centers: [[ 0.1008684 5.03166593]
[-5.11083576 -4.94058639]
[ 4.70054324 -5.00574056]]
array([[ 0.1008684 , 5.03166593],
[-5.11083576, -4.94058639],
[ 4.70054324, -5.00574056]])

plt_result(X_train, kmeans.cluster_centers_, xx)

knn4.png

第6章 サポートベクターマシーン(SVM)

教師あり学習の1つで、2クラス分類のための機械学習手法
線形モデルの正負で2値分類

6.1 目的関数の導出

各点と決定境界との距離は、点と直線との距離の公式から

$$\frac{| w^{\rm T}x_i+b| }{ | | x | |}=\frac{t_i( w^{\rm T}x_i+b) }{ | | x | |}$$

$w$:パラメータ、$x$:説明変数、$b$:切片、$t_i$:分類

点$(\alpha ,\beta )$ と直線:$ax+by+c=0$の距離の公式は
$$\frac{|a\alpha+b\beta+c |}{\sqrt{a^2+b^2}}$$

マージンとは決定境界と最も距離の近いデータ点との距離をいい
$$\min_{i}\frac{t_i( w^{\rm T}x_i+b) }{ | | w | |}$$

サポートベクターマシーンは、マージンを最大化することを目標なので目的関数は

$$\max_{w,b}\bigg(\min_{i}\frac{t_i( w^{\rm T}x_i+b) }{ | | w | |}\bigg)$$

マージン上の点において、$t_i\left(w^{\rm T}x_i+b\right)=1$ が成り立つため、すべての点に対して、$t_i( w^{\rm T}x_i+b\geqq 1$が成り立ち、目的関数は次の式となる。
$$\max_{w.b}\frac{1}{| | w | |}$$

6.2 サポートベクターマシーンの主目的

目的関数
$$\min_{w.b}\frac12 | | w | |^2$$
制約条件
$$t_i( w^{\rm T}x_i+b\geqq 1\qquad (i=1,2,3,\cdots,n)$$

6.3 Lagrangeの未定乗数法

制約付き最適化問題を解く手法のこと。

制約条件
$$g_i(x)\geqq 0 \qquad (i=1,2,3,\cdots,n)$$
のもとで、$f(x)$ が最小となる $x$ は、変数
$\lambda_i\geqq 0\quad (i=1,2,...,n)$ を用いて新たに定義したLagrange関数
$$L(x,λ)=f(x)−\sum_{i=1}^n=\lambda_i g(x)$$
において
$$\frac{\partial L}{\partial x_j}=0\qquad (j=1,2,3,\cdots,m)$$
を満たす。

6.3.1 カルーシュ・クーン・タッカー条件

制約付き最適化問題において最適解が満たす条件のこと。

制約 $gi(x)\geqq 0\quad (i=1,2,3,\cdots,n)$ のもとで、$f(x)$ が最小となる$x^{∗}は以下を満たす。

\begin{eqnarray}
&\frac{\partial L}{\partial x_j}|_{x^*}=0\qquad (j=1,2,3,\cdots,m)\\
&g_i(x^*)\leqq 0,\quad \lambda_i \geqq 0,\quad \lambda_ig_i(x^*)\quad (i=1,2,3,\cdots,n)
\end{eqnarray}

$L$はLagrange関数、$\lambda $はLagrange乗数である

6.3.2 Lagrange関数

$$L(w,b,a)=\frac{1}{2}| | w | |^2 -\sum_{i=1}^n a_i \Big(t_i( w^{\rm T}x_i+b)-1\Big) $$
Lagrange乗数:$a_i\geqq 0\quad (i=1,2,3,\cdots,n)$

最小となる$w$、$b$ は次の式を満たす。

\begin{eqnarray}
\frac{\partial L}{\partial w}&=&w-\sum_{i=1}^na_it_ix_i=0\\
\frac{\partial L}{\partial b}&=&-\sum_{i=1} a_it_i=0
\end{eqnarray}

式変形すると

\begin{eqnarray}
w&=&\sum_{i=1}^na_it_ix_i\\
\sum_{i=1} a_it_i&=&0
\end{eqnarray}

第6章サポートベクターマシーンのハンズオン

モジュールのインポート

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

訓練データ生成① (線形分離可能)

def gen_data():
    x0 = np.random.normal(size=50).reshape(-1, 2) - 2.
    x1 = np.random.normal(size=50).reshape(-1, 2) + 2.
    X_train = np.concatenate([x0, x1])
    ys_train = np.concatenate([np.zeros(25), np.ones(25)]).astype(np.int)
    return X_train, ys_train

X_train, ys_train = gen_data()
plt.scatter(X_train[:, 0], X_train[:, 1], c=ys_train)

svm1.png

学習

t = np.where(ys_train == 1.0, 1.0, -1.0)

n_samples = len(X_train)
# 線形カーネル
K = X_train.dot(X_train.T)

eta1 = 0.01
eta2 = 0.001
n_iter = 500

H = np.outer(t, t) * K

a = np.ones(n_samples)
for _ in range(n_iter):
    grad = 1 - H.dot(a)
    a += eta1 * grad
    a -= eta2 * a.dot(t) * t
    a = np.where(a > 0, a, 0)

予測


index = a > 1e-6
support_vectors = X_train[index]
support_vector_t = t[index]
support_vector_a = a[index]

term2 = K[index][:, index].dot(support_vector_a * support_vector_t)
b = (support_vector_t - term2).mean()

xx0, xx1 = np.meshgrid(np.linspace(-5, 5, 100), np.linspace(-5, 5, 100))
xx = np.array([xx0, xx1]).reshape(2, -1).T

X_test = xx
y_project = np.ones(len(X_test)) * b
for i in range(len(X_test)):
    for a, sv_t, sv in zip(support_vector_a, support_vector_t, support_vectors):
        y_project[i] += a * sv_t * sv.dot(X_test[i])
y_pred = np.sign(y_project)

# 訓練データを可視化
plt.scatter(X_train[:, 0], X_train[:, 1], c=ys_train)
# サポートベクトルを可視化
plt.scatter(support_vectors[:, 0], support_vectors[:, 1],
                    s=100, facecolors='none', edgecolors='k')
# 領域を可視化
#plt.contourf(xx0, xx1, y_pred.reshape(100, 100), alpha=0.2, levels=np.linspace(0, 1, 3))
# マージンと決定境界を可視化
plt.contour(xx0, xx1, y_project.reshape(100, 100), colors='k',
                     levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--'])


# マージンと決定境界を可視化
plt.quiver(0, 0, 0.1, 0.35, width=0.01, scale=1, color='pink')

svm2.png

丸が付いているデータがサポートベクトル

訓練データ生成② (線形分離不可能)


factor = .2
n_samples = 50
linspace = np.linspace(0, 2 * np.pi, n_samples // 2 + 1)[:-1]
outer_circ_x = np.cos(linspace)
outer_circ_y = np.sin(linspace)
inner_circ_x = outer_circ_x * factor
inner_circ_y = outer_circ_y * factor

X = np.vstack((np.append(outer_circ_x, inner_circ_x),
               np.append(outer_circ_y, inner_circ_y))).T
y = np.hstack([np.zeros(n_samples // 2, dtype=np.intp),
               np.ones(n_samples // 2, dtype=np.intp)])
X += np.random.normal(scale=0.15, size=X.shape)
x_train = X
y_train = y

plt.scatter(x_train[:,0], x_train[:,1], c=y_train)

svm3.png

元のデータ空間では線形分離はできない(直線による分離が不可能)ため、
特徴空間上で線形分離することを考える。
今回はカーネルとしてRBFカーネル(ガウシアンカーネル)を利用する。

def rbf(u, v):
        sigma = 0.8
        return np.exp(-0.5 * ((u - v)**2).sum() / sigma**2)

X_train = x_train
t = np.where(y_train == 1.0, 1.0, -1.0)

n_samples = len(X_train)
# RBFカーネル
K = np.zeros((n_samples, n_samples))
for i in range(n_samples):
    for j in range(n_samples):
        K[i, j] = rbf(X_train[i], X_train[j])

eta1 = 0.01
eta2 = 0.001
n_iter = 5000

H = np.outer(t, t) * K

a = np.ones(n_samples)
for _ in range(n_iter):
    grad = 1 - H.dot(a)
    a += eta1 * grad
    a -= eta2 * a.dot(t) * t
    a = np.where(a > 0, a, 0)

予測

index = a > 1e-6
support_vectors = X_train[index]
support_vector_t = t[index]
support_vector_a = a[index]

term2 = K[index][:, index].dot(support_vector_a * support_vector_t)
b = (support_vector_t - term2).mean()

xx0, xx1 = np.meshgrid(np.linspace(-1.5, 1.5, 100), np.linspace(-1.5, 1.5, 100))
xx = np.array([xx0, xx1]).reshape(2, -1).T

X_test = xx
y_project = np.ones(len(X_test)) * b
for i in range(len(X_test)):
    for a, sv_t, sv in zip(support_vector_a, support_vector_t, support_vectors):
        y_project[i] += a * sv_t * rbf(X_test[i], sv)
y_pred = np.sign(y_project)

# 訓練データを可視化
plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train)
# サポートベクトルを可視化
plt.scatter(support_vectors[:, 0], support_vectors[:, 1],
                    s=100, facecolors='none', edgecolors='k')
# 領域を可視化
plt.contourf(xx0, xx1, y_pred.reshape(100, 100), alpha=0.2, levels=np.linspace(0, 1, 3))
# マージンと決定境界を可視化
plt.contour(xx0, xx1, y_project.reshape(100, 100), colors='k',
                     levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--'])

svm4.png

ソフトマージンSVM

訓練データ生成③(重なりあり)


x0 = np.random.normal(size=50).reshape(-1, 2) - 1.
x1 = np.random.normal(size=50).reshape(-1, 2) + 1.
x_train = np.concatenate([x0, x1])
y_train = np.concatenate([np.zeros(25), np.ones(25)]).astype(np.int)

plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train)

svm5.png

学習


X_train = x_train
t = np.where(y_train == 1.0, 1.0, -1.0)

n_samples = len(X_train)
# 線形カーネル
K = X_train.dot(X_train.T)

C = 1
eta1 = 0.01
eta2 = 0.001
n_iter = 1000

H = np.outer(t, t) * K

a = np.ones(n_samples)
for _ in range(n_iter):
    grad = 1 - H.dot(a)
    a += eta1 * grad
    a -= eta2 * a.dot(t) * t
    a = np.clip(a, 0, C)

予測


index = a > 1e-8
support_vectors = X_train[index]
support_vector_t = t[index]
support_vector_a = a[index]

term2 = K[index][:, index].dot(support_vector_a * support_vector_t)
b = (support_vector_t - term2).mean()

xx0, xx1 = np.meshgrid(np.linspace(-4, 4, 100), np.linspace(-4, 4, 100))
xx = np.array([xx0, xx1]).reshape(2, -1).T

X_test = xx
y_project = np.ones(len(X_test)) * b
for i in range(len(X_test)):
    for a, sv_t, sv in zip(support_vector_a, support_vector_t, support_vectors):
        y_project[i] += a * sv_t * sv.dot(X_test[i])
y_pred = np.sign(y_project)

# 訓練データを可視化
plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train)
# サポートベクトルを可視化
plt.scatter(support_vectors[:, 0], support_vectors[:, 1],
                    s=100, facecolors='none', edgecolors='k')
# 領域を可視化
plt.contourf(xx0, xx1, y_pred.reshape(100, 100), alpha=0.2, levels=np.linspace(0, 1, 3))
# マージンと決定境界を可視化
plt.contour(xx0, xx1, y_project.reshape(100, 100), colors='k',
                     levels=[-1, 0, 1], alpha=0.5, linestyles=['--', '-', '--'])

svm7.png

マージン内にデータが入ることを少しだけ許容して決定境界が引かれている。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0