---
# System prepended metadata

title: 機械学習

---

# 機械学習


## 1. 線形回帰モデル

### 要約

基本は連続値を扱う。
直線で予測する＝線形回帰
曲線で予測＝非線形回帰


- Vapnikの原理
「本来解くべき問題より難しい問題はやるべきでない」

密度ひ推定？

- 扱うデータ
  - 入力　m次元のベクトル
  - 出力(目的変数)　スカラー値

説明変数 $\boldsymbol x=(x_{1},x_{2},・・・,x_{m})^{T} \in \mathbb R^{m}$

$\mathbb R^{m}$=m次元空間の実数, m次元空間中の１点を取る


- パラメータ

$\boldsymbol w=(w_{1},w_{2},・・・,w_{m})^{T} \in \mathbb R^{m}$

- 線形結合

$\hat y=\boldsymbol w^{T}\boldsymbol x + w_{0}= \displaystyle\sum_{j=1}^{m} w_{j}x_{j} + w_{0}$

(hatは予測値を表すのが慣例)


- 説明変数が１個なら単回帰、２個以上なら重回帰

- 参考文献：機械学習のエッセンス　おすすめ

(特に線形回帰に限らない話↓)
- 汎化性能測定
  - 学習用データと検証用のデータで分ける
  - 汎化性能＝未知のデータに対してどれくらい精度が高いかを見る
 
- 線形回帰モデル
  - パラメータは最小二乗法でもとめる。
  - 予測と実測値のズレの二乗の和が小さくなるように

$\displaystyle　MSE_{train}=\frac{1}{n_{train}} \displaystyle\sum_{i=1}^{ntrain}(\hat y_{i}^{(train)}-y_{i}^{(train)})^{2}$

- MSE(Mean Squared Error)
- 外れ値は予測が引っ張られるの注意

```参考文献：イラストで学ぶ機械学習```

$\frac{\partial }{\partial \boldsymbol w} MSE_{train}$ = 0

凸な二乗関数と考えると微分して０になる所が最小値


### 実装演習結果,考察

**np_regression.ipynb**

- 単回帰予測

![](https://i.imgur.com/zvyEgEf.png)


- 多項式回帰

![](https://i.imgur.com/tHJHkSR.png)


- 重回帰分析

```
w0_true:   1.0   w0_estimated: -0.32
w1_true:   0.5   w1_estimated: 1.2e+01
w2_true:   2.0   w2_estimated: -3.3e+01
w3_true:   1.0   w3_estimated: 2.1e+01
```
**skl_regression.ipynb**

- 線形単回帰分析
```
#　予測
array([-0.26491325,  8.39106825])
```

- 重回帰分析(2変数)

```
model2.coef_
array([-0.26491325,  8.39106825])
```

- モデルの検証
    - 決定係数　$R^{2}$ 0から1までの値を取る。
    1に近いほど、回帰式が実際のデータに当てはまっている
$$
R^{2} = 1 – \displaystyle\frac{\sum_{i=0}^{n-1} (y_i – \hat{y_i})^{2}}{\sum_{i=0}^{n-1} (y_i – \bar{y_i})^{2}}
$$
    - MSE(平均二乗誤差)
    実際の値と予測値の絶対値の2乗を平均したもの。
    $$
MSE = \ \displaystyle\frac{1}{n} \sum_{i=0}^{n-1} (y_i – \hat{y_i})^{2}
$$
```   
MSE Train : 44.983, Test : 40.412
R^2 Train : 0.500, Test : 0.434
```

他の予測
```
model2.predict([[0.3, 4]])
array([4.24007956])
model2.predict([[0.9, 10]])
array([54.42754109])
```

---

元々用意されているsklearnのデータセットを使用、
実際はまずこのデータ構造に持ってくるまでが大変。

- 単回帰
検証として部屋が一つの場合、
部屋の数を１で入れると住宅価格がマイナスのありえない値で出てきてしまう。
直線なのでしょうがないか。以下の**外挿問題**に相当。
- 外挿(extrapolation): 訓練データの範囲外で出力を求める事。一般的には弱い。あまり精度は期待できない
- 内挿(interpolation): 学習データの範囲内で出力を求める事
- 重回帰
説明変数として２つ選んでいるが、どちらが結果（価格）に影響を大きく与えているのか分かる方法はないかと思ったが、おそらく係数がそのまま影響、強さになるだろうと思った。

```
model2.coef_
---
array([-0.26491325,  8.39106825]) 
# 犯罪率　部屋数　→部屋数の方が影響が大きい
```

### その他関連事項

他に追加して行列操作に慣れるために
「ゼロから作るディープラーニング１」のP56の多次元配列あたりを
触ってみた。気づきとしては

- 改めてPythonでは変数名の大文字、小文字を識別する（別変数になる）
- numpyで行列のアダマール積と内積がごっちゃになる。ややこしい。

行列の積(内積)
```
a = np.array([[1,2,3],[4,5,6]])
b = np.array([[1,2],[3,4],[5,6]])
print(np.dot(a, b))
print(a@b)
---
[[22 28]
 [49 64]]
[[22 28]
 [49 64]]
```

同じ要素数の行列なら```*```で要素同士の掛け算(アダマール積)
```
d = np.array([[1,2,3],[4,5,6]])
e = np.array([[1,2,3],[4,5,6]])
d*e　＃アダマール積
---
array([[ 1,  4,  9],
       [16, 25, 36]])
```

- 外れ値に弱いモデル→例えばざっくり外れ値を見つける方法

max, minを見たり、図として箱ひげ図にするなど。

```
df.describe()
---
CRIM	ZN	INDUS	CHAS	NOX	RM	AGE	DIS	RAD	TAX	PTRATIO	B	LSTAT	PRICE
count	506.000000	506.000000	506.000000	506.000000	506.000000	506.000000	506.000000	506.000000	506.000000	506.000000	506.000000	506.000000	506.000000	506.000000
mean	3.613524	11.363636	11.136779	0.069170	0.554695	6.284634	68.574901	3.795043	9.549407	408.237154	18.455534	356.674032	12.653063	22.532806
std	8.601545	23.322453	6.860353	0.253994	0.115878	0.702617	28.148861	2.105710	8.707259	168.537116	2.164946	91.294864	7.141062	9.197104
min	0.006320	0.000000	0.460000	0.000000	0.385000	3.561000	2.900000	1.129600	1.000000	187.000000	12.600000	0.320000	1.730000	5.000000
25%	0.082045	0.000000	5.190000	0.000000	0.449000	5.885500	45.025000	2.100175	4.000000	279.000000	17.400000	375.377500	6.950000	17.025000
50%	0.256510	0.000000	9.690000	0.000000	0.538000	6.208500	77.500000	3.207450	5.000000	330.000000	19.050000	391.440000	11.360000	21.200000
75%	3.677083	12.500000	18.100000	0.000000	0.624000	6.623500	94.075000	5.188425	24.000000	666.000000	20.200000	396.225000	16.955000	25.000000
max	88.976200	100.000000	27.740000	1.000000	0.871000	8.780000	100.000000	12.126500	24.000000	711.000000	22.000000	396.900000	37.970000	50.000000
```

```
参考文献：ゼロからつくるDeepLearning
```


## 2. 非線形回帰モデル

### 要約

データを線形で捉えられない場合

$w$について求めたい。重みについては線形=Liner-in-parameter
線形モデルによる非線形回帰

$y_{i}=w_{0}+\displaystyle \sum_{j=1}^{m} w_{j}\phi_{j}(\boldsymbol x_{i}) + \varepsilon_{i}$


$\phi_{j}(\boldsymbol x_{i})$の部分が線形の時に$x_{i}$だった部分。$x_{i}$を入力として$x_{i}^{2}$や$\log x_{i}$などに変わりえる。
ここを**基底関数**という。
使われる基底関数は
- 多項式関数　$\phi_{j}=x^{j}$
- ガウス型基底関数 $\displaystyle　\phi_{j}(x)=exp\Big( \frac{(x-\mu_{j})^{2}}{2h_{j}}\Big)$
- スプライン関数/Bスプライン関数
がある


#### 未学習、過学習

- 未学習(underfitting)
学習データに対して、十分小さな誤差が得られない

- 過学習(overfitting)
    - 対策1: データ数を増やす
    - 対策2: 不要な基底関数(変数)を削除して表現力を抑止
    - AICによるモデル選択？
    - 対策3: 正則化法を利用して表現力を抑止(イメージとして９次の項まであっても係数(w)が小さければ無視さされる)
- 正則化項
モデルが複雑さに伴ってその値が大きくなる
重みパラメータ(係数)を一定の範囲に押し込める

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

予測と実際の二乗和誤差
$(y-\Phi^{n\times k} \omega)^{T}(y-\Phi\omega)$

$\gamma$ は重みの調整パラメータ（ハイパーパラメータ）

MSEの最小化

- ２種類の正則化
    - Ridge推定
    - Lasso推定

- 手元のモデルが未学習か過学習かの判定
　訓練誤差はやろうと思えば上げられるが未知のデータに対する判定の能力、汎化能力があるかが問題
    - 訓練誤差もテスト誤差も下がらない→汎化ができている可能性(OK)
    - 訓練誤差もテスト誤差も下がらない->未学習(採用している手法の表現力が足りない)
    - 訓練誤差は小さいが、テスト誤差が大きい→過学習
    　手元のモデル

- ホールドアウト法（評価方法）
    - 訓練データとテストデータの分け方
    - 最初の2割データを評価用、あとは訓練用と決め打ちで変更しない
    - 手元に大量のデータがある場合は良いが**一般的に問題あり**
    - 検証データの外れ値があった場合、

- 交差検証法
    - 訓練データとテストデータを分け方を変えながらモデル作成
    　（採用している手法は同じだが、重みが異なるモデルができる）
    - データの偏りを避けられる
    - 全ての精度の平均値をCV値と呼ぶ

CV値の出し方、二乗誤差が一般的。
- 学習誤差
    - $MSE_{train}=\displaystyle\frac{1}{n_{train}} \displaystyle \sum_{i=1}^{n_{train}}(\hat y_{i}^{(train)}-y_{i}^{(train)})^{2}$
- 検証誤差
    - $MSE_{test}=\displaystyle\frac{1}{n_{test}} \displaystyle \sum_{i=1}^{n_{test}}(\hat y_{i}^{(test)}-y_{i}^{(test)})^{2}$

- グリッドサーチ
    - 全てのチューニングパラメータの組み合わせで評価値を算出
    - 最も良い評価値を持つチューニングパラメータを持つ組み合わせを
    　「いいモデルのパラメータ」として採用

　　　ハイパーパラメータの選び方、ニューラルネットで**ベイズ最適化**が出てくる。


### 実装演習結果,考察

**skl_nonlinear_regression.ipynb**

注意) path名を自分のドライブのフォルダ名に変える必要あり

多項式
次数がある程度上がるとほぼ一緒。多分少ない次数で表現できれば
その方がよい。
![](https://i.imgur.com/FCD0ObJ.png)


KerasRegressor

![](https://i.imgur.com/651Pd3x.png)





(線形回帰)
Kernel Ridgeで当てはまりがよくなっている。パラメータαを大きくすると
制約が強くなり汎化能力が増す方向、小さくすると係数への制約が小さくなる
Lasso()はL1正則化。パラメータαの効き方は同様。

「Pythonではじめる機械学習」によると
> リッジとLassoの2つではまずリッジを試してみるとよい
> しかし特徴量がたくさんあって、そのうち重要なものはわずかしかない場合は
> Lassoの方が向いているだろう
> 
とある
Lassoとリッジのペナルティと組み合わせたElasticNetというクラスもあるという。

### その他関連事項

- 俗に言われる訓練データが7,8割、Testデータが2,3割というのは根拠があるのか？疑問を持った。5割で分けると訓練データとしてもっと欲しい気もするし、かといってvalidationが1割だと不安な気もする
https://towardsdatascience.com/finally-why-we-use-an-80-20-split-for-training-and-test-data-plus-an-alternative-method-oh-yes-edc77e96295d
を見るとパレートの法則（経験則による8割2割の法則）と
以下の論文を紹介している
>  A scaling law for the validation-set training-set size ratio (Guyon). Here, they reference “ the best training/validation split for a specific problem: preventing overtraining of neural networks. They find that the fraction of patterns reserved for the validation set should be inversely proportional to the square root of the number of free adjustable parameters. Our result generalizes and confirms their result.” (Guyon, 1997).

データ数のルート分の１で分けると少し良くなったという報告もある

- Kaggleはやった事ないが、コンペ中は順位を決めるテストデータの一部しか公表されていないようだ。この場合のそのテストデータだけで自分のモデルを評価するのは危ない（これがホールドアウト法に該当する）。その為、自らTestデータの一部をValidationデータとして交差検証を行う。

- 少し勘違いしていたが、クロスバリデーションはiterationの中で一番良いモデルを採用するものを決める為のものではなく、今採用している手法(線形回帰、重回帰、非線形回帰など)とパラメータでの汎化性能を知る為のもの、結果他の手法と(CV値を)比べて採用、不採用を決められる。
検証の結果ハイパーパラメータが決まったら、訓練、検証含めて学習できる。


- Leave-one-out 交差検証
　データを一つ抜き出して検証データとし、それ以外を訓練データとして学習する。
 全てのデータが一回ずつ検証対象になる。
 k-分割交差における、kが標本サイズと同じになったもの。
 一つ抜き法、ジャックナイフ法とも呼ばれる
 **精度は高いが、時間がかかる**
 
```参考文献: 「Pythonではじめる機械学習」```
 
 
## 3.  ロジスティック回帰モデル

### 要約

分類タスク

あえてDeepではなく、ロジスティック回帰を使う場合もあるので使えるとよい
説明変数は回帰の時と変わらないが目的変数が０か１
> 説明変数 $\boldsymbol x=(x_{1},x_{2},・・・,x_{m})^{T} \in \mathbb R^{m}$
> 目的変数 $\boldsymbol y \in \big\{0, 1 \big\}$

確率で出力されるので0,1の確度が分かるのでうれしい

**分類問題へのアプローチ**
- 識別的アプローチ　$p(C_{k} |x)$を直接モデル化
    - 条件確率。xが決まった上で(割り当てられた上)でクラスC_{k}に割り当てられる確率 -> 
    **ロジスティック回帰**
- 生成的アプローチ $p(C_{k})$と$p(x|C_{k})$をmodel化し、その後Bayesの定理を用いて$p(C_{k}|x)$を求める
- 識別関数　f(x) > 0 -> C=1,  f(x)<0 C=0  $C_{k}$に割り当てられる確率は出せない。　例としてSVM

ベイズの定理復習
$p(C_{k}|x)=\displaystyle \frac{p(C_{k}, x)}{p(x)}=\frac{p(x|C_{k})p(C_{k})}{p(x)}$

線形回帰
$x^{T}w\in \mathbb{R}$　ほしい目的変数は0か1 $\boldsymbol y \in \big\{0, 1 \big\}$
実数全体に含まれる$x^{T}w$を[0, 1]に押し込める＝sigmoid関数の使用
$sigmoid= \displaystyle\frac{1}{1-e^{-z}}=\frac{e^{z}}{1+e^{z}}$
だが
$\sigma(x)= \displaystyle \frac{1}{1+exp(-ax)}$
で表すと$a$がパラメータとなって曲線の形を変えられる。
$a$を大きくしていくとステップ関数に近くなる

→合成関数の求め方は確認しておく

ロジット変換


---
もとめたい値=左辺Xが与えられた時にY＝１となる確率を知りたい

$\displaystyle P(Y=1|\boldsymbol x)=\sigma(w_{0}+w_{1}x_{1})$
(説明変数を１個として)
求められた確率がある値以上なら１、以下なら０とする。この値は自分で判断、決める。

---

#### 最尤推定

ベルヌーイ分布のパラメータの推定
データから元の分布を推定する

$\displaystyle P(y)=p^{y}(1-p)^{1-y}$
$\displaystyle P(y_{1},y_{2},・・・,y_{n};p)=\prod^{n}_{i=1} p^{y_{i}}(1-p)^{1-y_{i}}$
同時確率: n回の試行でy1～ynが同時に起こる確率(pが固定)
尤度関数: $y_{1}～y_{n}$のデータが得られた際の尤度関数

ここで確率部分はシグモイド関数で置き換えるのだったから

$P(y_{1},y_{2},・・・,y_{n}|w_{0},w_{1},・・・,w_{m})=\prod^{n}_{i=1} p^{y_{i}}(1-p)^{1-y_{i}}$
$\displaystyle=\prod^{n}_{i=1} \sigma(\boldsymbol w^{T}\boldsymbol x_{i})^{y_{i}}(1-(\boldsymbol w^{T}\boldsymbol x_{i}))^{1-y_{i}}$
$\displaystyle=L(\boldsymbol w)$
$w$が未知　尤度関数Lを最大とするパラメータを探索


勾配法の最小化問題に持っていきたいのでマイナスをつけて、桁落ちしないようにlogをつける
$\displaystyle E(w_{0}, w_{1}, ・・・, w_{m})=-\log L(w_{0}, w_{1},,,w_{m})$
最小二乗法の最小化に近い形

パラメータは勾配降下法で$w$を更新していく
$\displaystyle w(k+1)=w^{k}-\eta\frac{\partial E(w)}{\partial w}$

$\eta$:学習率

誤差関数の微分(傾き)に学習率を掛けたものを引いて次の$w$とする。

$\displaystyle w^{(k+1)}=w^{(k)}-\eta \sum_{i=1}^{n}(y_{i}-p_{i})\boldsymbol x_{i}$

- 確率的勾配降下法(SGD)

データの数が多い場合は1回の更新で時間がかかる。
1回の更新ですべてのデータを使うのでは無く、ランダムにデータを一つ選んで更新

---

### 実装演習結果,考察:

**np_logistic_regression.ipynb**

![](https://i.imgur.com/WCqRBbR.png)

**skl_logistic_regression.ipynb**

(前処理)
Titanicデータ, AgeでNan(抜け)あり。DataframeのFilter機能便利。
欠損値補完はfillna()で平均値補完、中央値補完など。
前後関係で保管したい時はinterpolate()使用。

- 幾つか変数、関数についてLogistic regression
  - **predict_proba()** それぞれのクラスに属する確率を返す
  - **decision_function()** 確信度を返す。値が大きいほど確信度が高い？ (skleanサイトより　> Confidence scores per (sample, class) combination. In the binary case, confidence score for self.classes_[1] where >0 means this class would be predicted.)
  - model.intercept 切片にあたる
  - model.coef 係数
 
 チケットクラス＋性別と年齢より
![](https://i.imgur.com/ZG56fVS.png)

例の中にある```titanic_df['Pclass_Gender'] = titanic_df['Pclass'] + titanic_df['Gender']```の
足し算で混ぜてしまう分け方は意図がよく分からなかった。
チケットクラス２の男性(1)とチケットクラス３の女性(0)を混ぜてもいいのだろうか。

- データを２つに分けてそれぞれで結果の混同行列の出力

![](https://i.imgur.com/1zlirBy.png)

![](https://i.imgur.com/dFyyzo2.png)


- 講義内で出てきた```Using ML to Predict Parking Difficulty[Google AI Blog:2017 Feb.]```より
Logistic回帰を選んだ理由
  - Logistic回帰は理解しやすい。
  - トレーニングデータのNoiseに強い
  - 確率で出るのは助かる
  - 各特長量の影響が理解しやすく、モデルの振る舞いがreaosonableか判断しやすい


- SGDに関してもう少し。
> 確率的勾配降下法とは、大雑把に言うと、
「勾配法」＋「確率を使って勾配の計算を高速に行う」
ような最適化手法です。

通常の勾配法は
パラメータは勾配降下法で$w$を更新していく
$\displaystyle w(k+1)=w^{k}-\eta\frac{\partial E(w)}{\partial w}$
最急降下法・・・今いる点の勾配情報を参考にする
デメリットとしては曲線の谷が複数ある場合などで局所解に陥る事

確率的勾配降下法＝オンライン勾配降下法
「普通の」勾配降下法のことをバッチ勾配降下法＝データを全部使う

#### モーメンタム：　

過去の勾配の変化を使って振動しないようにする。今までの移動平均を使う
$\boldsymbol w_{t+1}=\boldsymbol w_{t}-\alpha\nabla_{w}\mathcal{L}(\boldsymbol w)$
$\nabla_{w}$: モーメンタム
$\alpha$:　学習率
$\mathcal{L}(\boldsymbol w)$: 損失関数


- Momentum SGD
$v_{t+1}\leftarrow\gamma v_{t}-\alpha g_{t}$
$\theta_{t+1}\leftarrow \theta_{t}+v_{t+1}$

$\gamma$: 慣性の減衰率
$t$: 現在のエポック
$g_{t}$: そのエポックにおけるコスト関数の勾配
$\alpha$: 学習率

これら勾配降下、モーメンタムなどは後のニューラルネットでも出てくる

### 課題

> 設定 タイタニックの乗客データを利用しロジスティック回帰モデルを作成 特徴量抽出をしてみる
> 課題 年齢が30歳で男の乗客は生き残れるか？

### その他関連事項

- オッズ比　ある事象が発生する確率としない確率の比
 $\displaystyle \frac{p}{1-p}$
 ゼロよりマイナスにならない。大きい方は無限大を取り得る。

- ロジット変換　オッズで対数を取る
 $\log(\displaystyle \frac{p}{1-p})$
 対数を取ると上記のアンバランスさがなくなる。

- 最尤推定量
> パラメータ$\theta$に従う分布の密度関数$f(x;\theta)$とする。尤度関数を$L(θ;x)=f(x;θ)$とすると、$L(θ;x)$を最大にするような推定量$θ=\hatθ$の最尤推定量という。

- 混同行列

```
                      Predict
      ┌────────┬───────────┬─────────────┐
      │        │Positive   │   Negative  │
      ├────────┼───────────┼─────────────┤
      │positive│  TP       │    FN       │
      │        │           │             │
Actual├────────┼───────────┼─────────────┤
      │        │           │             │
      │Negative│  FP       │    TN       │
      │        │           │             │
      └────────┴───────────┴─────────────┘
```
- 真陽性(True Positive)
判別したいものを正しく判別できた数を「真陽性」
  - 真陽性率（True Positive Rate） $TP/(TP+FN)$
- 真陰性(True Negative)
判別対象外のものを正しく判別できなかった数を「真陰性」
- 偽陽性(False Positive)
判別対象外のものを誤って判別してしまった数を「偽陽性」
  - 偽陽性率(False Positive Rate) $FP/(FP+TN)$
- 偽陰性(False Negative)
判別したいものを誤って判別できなかった数を「偽陰性」

- 正解率(Accuracy)
  - $(TP+TN)/(TP+FN+FP+TN)$
  
- 適合率、精度(Precision)
  - $TP/(TP+FP)$
  
- 再現率(Recall)
  - $TP/(TP+FN)$
  
- F値（F-measure）
  - $\displaystyle \frac{2}{(1/precision+1/recall)}$

ROC曲線は真陽性率と偽陽性率の関係をグラフにしたもの

考察：最近も会社であったケースだがそもそも異常検出のような
正例データが少ない場合は混同行列による評価は妥当なのだろうか？
→異常検知でも使われるようでRecall重視という記述はネット上ではあったが
それ以上の事は分からなかった。取りこぼしが許されないケースを想定すればRecall重視というは分かる。

```
参考文献：　はじめてのパターン認識
```

## 4. 主成分分析

### 要約

PCA（principal component analysis）
次元を圧縮する、特徴量を減らす
- 可視化できる
- 冗長な特徴量をまとめられる
　(一般的には少ない特徴量で多く説明できると好ましい)

- 分散が最大になるように軸を探索する。
  分散が最大の場合、情報が多く残っている。
→ある軸に射影したデータがばらついている＝元のデータの情報を多く含んでいる
分散が少ない＝データの区別がつかなくなる


例えばある特徴量a,bの間は
a=2bのようなほぼ線形の関係がある場合、実質1次元のデータとして取り扱える。
元の冗長な特徴量を特徴空間に含まれる情報を要約した特徴量に置き換える。

軸を探す＝分散の最適化。


---

PCAの実装中身

1. データ行列の中心化

$C=X-1\mu^{T}$
１は全ての要素が１である列ベクトル
$\mu$は$\boldsymbol X$の各行の平均値を要素とする列ベクトル
(平均を引いて中心に寄せる)

2. SVDの実行

$C=U\Sigma V^{T}$

3. 主成分を特定する
最初のk個の主成分はVの最初のk個の列。k個の右特異ベクトル。

4. データの変換

変換されたデータは$U$の最初のk列

- 寄与率
軸一つでデータの何割を説明できているか。
主成分のいくつまで使うかなど参考になる

```
参考文献：「機械学習のための特徴量エンジニアリング」
参考リンク：統計科学研究所:
https://statistics.co.jp/reference/software_R/statR_9_principal.pdf
```

---

### 実装演習結果,考察:

**np_pca.ipynb**

固有値、固有ベクトルの計算
![](https://i.imgur.com/t1sw6aD.png)

変換
![](https://i.imgur.com/9zkjrcI.png)

逆変換(元に戻す)
![](https://i.imgur.com/8jdGHXW.png)

**skl_pca.ipynb**

Cancerデータを元に次元数３０でPCAの実行

![](https://i.imgur.com/sOZjbMO.png)

次元数を２として視覚化している。

![](https://i.imgur.com/3nKPFSx.png)


```pca.explained_variance_ratio_```＝各主成分が持つ分散の比率、寄与率

試しに３次元でPCAを行うと
```
explained variance ratio: [0.43315126 0.19586506 0.09570611]
```
3番目はあまり説明に寄与していない


## 5. アルゴリズム

#### K近傍法(kNN)

分類の手法の一つ。教師あり学習。

最近傍のデータをK個取ってきて、それらがもっとも多く所属するクラスに識別
k=1なら最も近いところ1点で見る。

#### k-means

クラスタリング。手元のデータの分類を行う。
1. 各クラスの中心をとりあえず作る
2. 各データ点に対して、各クラスタ中心との距離を計算し、最も距離が近いクラスタを割り当てる
3. 各クラスタで平均ベクトル(中心)を計算する（中心の更新）
4. クラスタの再割り当てと中心の更新を繰り返す

注意：初期値のおかれ方でクラスタの別れ方が違ってくる

### 実装演習結果,考察:

**np_kmeans.ipynb**

![](https://i.imgur.com/Z5MmtAM.png)

**skl_kmeans.ipynb**

```
species	class_0	class_1	class_2
labels			
0	0	50	19
1	46	1	0
2	13	20	29
```
KNeighborsClassifier
![](https://i.imgur.com/AV3SgWc.png)

**np_knn.ipynb**




sklearnに入っているWineの典型的なデータセット。3つの品種に分かれている。
うまく分かれていないクラスもあった

```
species	class_0	class_1	class_2
labels			
0	     0	    50	    19
1	    46	    1	    0
2	    13	    20	    29

```

初期値によって適切にクラスタリングされない場合があるという事だったので
KMeans()の乱数に関連がありそうな所を変えてみたが特に変化は無かった。

実際のケースではあらかじめ分かれているクラス数が分かっている場合、
そうでない場合もあると思うが、結果に関しては自分で解釈する必要がある

**np_knn.ipynb**

![](https://i.imgur.com/kbaZEmn.png)


### その他関連事項

**K近傍**

参考文献より行ったコード実行

```python
from sklearn.model_selection import train_test_split 
from sklearn.datasets import load_breast_cancer
from sklearn.neighbors import KNeighborsClassifier

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

 
c = load_breast_cancer() 
X_train,X_test,y_train,y_test=train_test_split(c.data, c.target,stratify=c.target, random_state=66)
 
training_accuracy = []
test_accuracy = []

# roll the k neighbors
neighbors_settings = range(1, 11)

for neighbor in neighbors_settings:
  clf = KNeighborsClassifier(n_neighbors=neighbor)
  clf.fit(X_train, y_train)
  training_accuracy.append(clf.score(X_train, y_train))
  test_accuracy.append(clf.score(X_test, y_test))

plt.plot(neighbors_settings, training_accuracy, label="training accuracy")
plt.plot(neighbors_settings, test_accuracy, label="test accuracy")
plt.ylabel("Accuracy")
plt.xlabel("n_neighbors")
plt.legend()
```

![](https://i.imgur.com/fnxQcMW.png)

K近傍ではFitは訓練データをセットするのみ。
１つの近傍点のみを用いるとクラスの決定境界は訓練データ配置に近い。
近傍点を増やす、(より多くの点を考慮)すると境界はなだらかで汎化性能が上がる。
過剰適合に相当するのは**考慮する近傍点が少ない方**
なぜテストデータの性能が近傍点が少ない所で落ちるかは腑に落ちる


```
参考文献:Pythonではじめる機械学習
``` 


## 6. サポートベクターマシーン

### 要約

基本的には2クラス分類。線形モデルの正負で２値分類。
(多クラス問題は(K-1)の一対他SVMで実現する事が多い)
線形判別関数と最も近いデータ点（サポートベクター）との距離をマージン。
このマージンが最大となる線形判別関数をもとめる。

線形判別関数(超平面)を
$\boldsymbol w^{T}x+b=0$

全てのデータ点で

$|\boldsymbol w^{T}\boldsymbol x + b|$

目的関数
$\displaystyle \max_{w,b}[\min_{i}\frac{t_{i}(\boldsymbol w^{t}\boldsymbol x_{i}+b)}{\| \boldsymbol w\|}]$

各点と決定境界との距離は点と直線との距離の公式から
$\displaystyle \frac{t_{i}(\boldsymbol w^{t}\boldsymbol x_{i}+b)}{\| \boldsymbol w\|}$
$t_{i}$:　教師データ {-1, 1}
$x_{i}$:　学習データ

$\displaystyle t_{i}(\boldsymbol w^{t}\boldsymbol x_{i}+b)$

結果として目的関数は以下になる

$\displaystyle \max_{w,b}\frac{1}{\| \boldsymbol w\|}$
$\displaystyle \min_{w,b}\frac{1}{2}\| \boldsymbol w\|$





線形分離可能でない問題の場合、**スラック変数の導入**
このような手法を**ソフトマージン識別器**

$\left\{
\begin{array}{ll}
\xi_{i}=0 & (マージン内で正しく識別できる場合) \\
0 < \xi_{i} \leq 1& (マージン境界を越えるが正しく識別できる場合) \\
\xi_{i} > 1 & (識別境界を超えて誤識別される場合)
\end{array}
\right.$


訓練データ$D=\{(x_{1},y_{1}),,,(x_{l},y_{l})\}\in \mathfrak R \times\{-1, 1\}$
$\displaystyle \frac{\|w\|}{2}+C\sum_{i=1}^{l}\xi_{i}$

右が誤差項。$C$はhハイパーパラメータでペナルティの強さを表す。
大きければ大きいほど誤差を優先する解が得られる。(誤差を許容しすぎない)
「モデルの複雑さ」と「誤分類」のトレードオフ

制約条件
$t_{i}(\boldsymbol w^{T}\boldsymbol x_{i}+b) - 1 + \xi_{i} \geq 0$
$\xi_{i} \geq 0$


- マージンの外側のデータは予測に影響を与えない

- カーネルトリック
  - データを別の空間に写像。その空間で線形に分離。


```
参考文献：
はじめてのパターン認識
http://www-erato.ist.hokudai.ac.jp/lecture2011/material/lecture-1.pdf
http://sudillap.hatenablog.com/entry/2013/04/08/235610
```


### 実装演習結果,考察:

**np_svm.ipynb**

線形分離可能のケース

![](https://i.imgur.com/KgFfuQ2.png)

線形分離不可能のケース

![](https://i.imgur.com/KL2eUPV.png)




![](https://i.imgur.com/koYvMfi.png)


- サンプルの個数が大きいとうまく機能しない
- 全ての特徴量が同じスケールになるように変換した方がよい
- 予測がされた理由の説明が難しい
- 特徴量が似た測定器の測定結果(画像)のような同じスケールの場合は試す価値あり


```
参考文献:Pythonではじめる機械学習
```


### その他関連事項

カーネルの種類について

正規化線形カーネルを用いた場合、

$\displaystyle k(x,y)=\frac{x^{T}y}{\|x\|\|y\|}$

は$x$と$y$の相関係数を表している

参考に相関係数は
$\displaystyle r_{xy}=\frac{\sum_{i=1}^{n}(x_{i}-\bar x)(y_{i}-\bar y)}{\sqrt{\sum_{i=1}^{n}(x_{i}-\bar x)^{2} \sqrt{\sum_{i=1}^{n}(y_{i}-\bar y)^{2}}}}$


https://zenn.dev/wsuzume/books/66b6fe7bb537b3e2b4bb/viewer/4d8835

- RBF(動径基底関数カーネル)

SVMの文脈ではガウスカーネルとも呼ばれる
https://mathwords.net/doukeikitei

> ある点 c→ からの距離のみに基づいて値が決まる関数のことを動径関数（Radial Function）と言います。
例えば、
・$\vec{f_{\vec c}}(\vec x)=\|\vec x−\vec c\|^{2}$
・$\vec f_{\vec c}(\vec x)=exp(−γ\|\vec x−\vec c\|^{2})$
などは動径関数です。
（このページでは、添字の $\vec c$ は動径関数の中心を表します）
$\vec x$ が $\vec c$ から遠くなると、この関数の値は急激に 0 に近づいていきます。

$\vec x$ と $\vec c$が近いと１に近づく。

- 多項式カーネル

$k(x, y)=(1+x^{T}y)^{d}$ dは正の整数
$k(x, y)=(x^{T}y + c)^{2}$


- カーネルと特徴ベクトルの対応
カーネル関数$k(x,y)$が$k(x,y)=\phi (x)^{T}\phi (y)$
と表現できる時、$k(x,y)$は特徴ベクトル$\phi$に対応する
