
「スモールデータ解析と機械学習」を寄り道写経 ~ 書籍のご紹介、第2章「相関関係と主成分分析」
第2章「相関関係と主成分分析」
書籍の著者 藤原幸一 先生
この記事は、テキスト「スモールデータ解析と機械学習」のご紹介、および、第2章「相関関係と主成分分析」の通称「寄り道写経」を取り扱います。
テキストを開いてスモールデータの旅に出発です🚀
はじめに
テキスト「スモールデータ解析と機械学習」
このシリーズは書籍「スモールデータ解析と機械学習」(オーム社、「テキスト」と呼びます)の機械学習の理論・数式とPythonプログラムを参考にしながら、テキストにはプログラムの紹介が無いけれども気になったテーマ、または、テキストのプログラム以外の方法を試したいテーマを「実験的」にPythonコード化する寄り道写経ドキュメンタリーです。
テキストは、2022年2月に発売され、スモールデータと呼ばれる小さなサンプルサイズのデータを用いた機械学習の取り組み方について、理論(数式)とPythonサンプルプログラムを提案する素晴らしい実用書です。
Pythonサンプルプログラムはなんと!機械学習ライブラリをあまり利用していません。
著者の藤原先生自らnumpy等でアルゴリズムを実装する「手作り」機械学習なのです!しかもコードが短い!
機械学習のアルゴリズムをプログラミングを通じて理解したい方にはちょうど良いボリュームだと思います。

寄り道写経は、テキストの実践を通じて「scikit-learnで動かしたらどうだろう?」とか「プログラムは紹介されていないけど、この数式をPythonで実装したらどうなる?」などと感じたことを、私個人の興味でテーマにすくいあげて、Pythonのサンプルコードを書く活動です。

引用表記
この記事は、出典に記載の書籍に掲載された文章及びコードを引用し、適宜、掲載文章とコードを改変して書いています。
【出典】
「スモールデータ解析と機械学習」第1版第1刷、著者 藤原幸一、オーム社
記事中のイラストは、「かわいいフリー素材集いらすとや」さんのイラストをお借りしています。
ありがとうございます!
テキストの主観的ご紹介
章立てを追って、テキストを紹介させてください。
第1章 スモールデータとは
章タイトル通り、スモールデータの概要の説明があります。

第2章 相関関係と主成分分析
■ あらすじ
主役は「主成分分析」です。
分散共分散行列を用いた行列表現、ラグランジュの未定乗数法、固有値問題の流れで、数式を用いた主成分の導出が多くの紙面を使って説明されています。
また、NumPyで主成分分析のテキストオリジナルコードが書かれています。
■ 推しポイント
個人的に押さえておきたいポイントです。
データの変数間の相関関係を用いて主成分分析が行われている。
主成分分析の結果、次元削減されて得た主成分得点は変数間が無相関になる(主成分回帰につながる)。
■ 寄り道写経
以下のテキストオリジナルのPythonコードをscikit-learnで再現してみます。
・データの標準化
・PCA
■ 重要テーマのタグ
#データの標準化 #散布図 #共分散 #相関係数 #主成分分析 #主成分得点の分散の最大化 #直交 #ローディングベクトル #負荷量ベクトル #ノルム #共分散行列 #ラグランジュの未定乗数法 #固有値問題 #固有値 #固有ベクトル #寄与率 #累積寄与率 #行列のランク #特異値分解 #SVD

第3章 回帰分析と最小二乗法
■ あらすじ
スモールデータの回帰問題に適した回帰アルゴリズムを数式とPythonプログラムで理解する章です。
主役は、主成分回帰(PCR)・リッジ回帰・部分的最小二乗法(PLS)です。
回帰アルゴリズムをNumPy等で実装します。
これらの回帰アルゴリズムを用いる理由は、多重共線性の回避、および、サンプルサイズ(行数)が説明変数の数(列数)よりも少ない場合の対応可能性です。
そして章の最後に、オープンデータ「ディーゼル燃料のNIRスペクトルデータ」を回帰アルゴリズムで分析する一大イベントが待っています!
■ 推しポイント
個人的なツボは次の点です。
回帰係数ベクトル$${\boldsymbol{\beta} = (\boldsymbol{X}^{\top} \boldsymbol{X})^{-1} \boldsymbol{X}^{\top} \boldsymbol{y}}$$
行列のランクと条件数
もしもscikit-learnで実装したら・・・シリーズ
■ 寄り道写経
① 重回帰
最小二乗法による回帰係数の算出と未知データの予測を様々なPythonパッケージで試します。
② 多重共線性
オリジナルコードが無いテキストの行列計算をPythonで実装します。
③ 主成分回帰(PCR)、リッジ回帰、部分的最小二乗法(PLS)
テキストオリジナルコードをscikit-learnで再現してみます。
④ 分光分析による物性推定
テキストオリジナルコードをscikit-learnで再現してみます。
■ 重要テーマのタグ
#回帰分析 #最小二乗法 #残差二乗和の最小化 #正規方程式 #回帰係数ベクトル #回帰係数と相関係数 #ガウス-マルコフの定理 #BLUE #最尤法 #多重共線性 #フルランク #行列の条件数 #悪条件 #サンプルサイズが入力変数より少ない #擬似逆行列 #主成分回帰(PCR) #リッジ回帰 #パラメータ$${\mu}$$ #行列の条件数の改善 #部分的最小二乗法(PLS) #潜在変数 #PLS1 #NIPALSアルゴリズム #PLS2 #SIMPLSアルゴリズム #ハイパーパラメータの調整 #クロスバリデーション #K分割交差確認 #leave-one-out法 #PRESS #RMSE #真値と予測値のプロット #分光法 #ディーゼル燃料のNIRスペクトルデータ

第4章 線形回帰モデルにおける入力変数選択
■ あらすじ
オッカムの剃刀の話題から始まる「シンプルなモデル」の大切さ。
この章では変数選択(説明変数を減らす)に取り組みます。
一般的な変数選択の基準や手法にいくつか触れて、スモールデータに適した部分的最小二乗法:PLS用の変数選択と相関関係に基づいた変数クラスタリングによる変数選択に深く入り込みます。
そして章の最後に、オープンデータ「ディーゼル燃料のNIRスペクトルデータ」を用いて複数の変数選択手法を実装する一大イベントが待っています!
■ 推しポイント
もちろん、Pythonで実装する「NCSC」「NCSC-VS」「PLS-beta」「VIP法」のロジックやアルゴリズムです!
個人的には、ロジックやアルゴリズムが難しく感じて、「???」な状態が続いています(汗)
■ 寄り道写経
4.7節「NIRスペクトルの検量線入力波長選択」の次の内容について、テキストオリジナルコードを改造します。
テキストオリジナルコードの実行時に発生するエラーの回避策
図4.17「入力波長選択結果」の4つのアルゴリズムのグラフ描画を一括表示するコード
■ 重要テーマのタグ
#オッカムの剃刀 #過学習 #赤池情報量基準(AIC) #ステップワイズ法 #Lasso回帰 #最小角回帰(LARS) #PLS-beta #VIP法 #クラスタリング #k-平均法 #NCスペクトラルクラスタリング(NCSC) #NC法 #NCSC-VS #NIRスペクトルの検量線入力波長選択

第5章 分類問題と不均衡データ問題
■ あらすじ
この章は「分類タスク」に取り組みます。
目的変数のラベル(たとえば陽性/陰性)の割合が不均衡なケースに焦点を当てています。
分類タスクの一般論として線形判別分析と性能評価を解説した後に、多数クラスを間引くアンダーサンプリング、少数クラスを割増しするオーバーサンプリング、アンサンブル学習に取り組んで、不均衡データの分析手法を学びます。
そして章の最後には「ケーススタディ」と称して、4つの不均衡なオープンデータを用いて複数のアルゴリズムの性能評価を実装する一大イベントが待っています!
■ 推しポイント
ケーススタディを通じたアルゴリズムの理解です!
以下のアルゴリズムに取り組みます。
①ランダムフォレスト
②AdaBoost
③SMOTEでオーバーサンプリング後の決定木
④ADASYNでオーバーサンプリング後の決定木
⑤RUSBoost
個人的な思い出は、ケーススタディのうち1つのアルゴリズムの結果が芳しくなくて、悔しい思いをしたことです(泣)
■ 寄り道写経
5.18節「ケーススタディ」の次の内容について、手動処理の補足とテキストオリジナルコードの改造を実視します。
4つのデータを読み込み可能にするための手動ファイル整形
表5.1「データセットのプロフィール」の表作成
5.18.2項「モデルの学習」のテキストオリジナルコードの実行時に発生するエラーの回避策
5.18.2項「モデルの学習」の全データ・全モデルの実行自動化
表5.2「モデル学習結果」の表作成
■ 重要テーマのタグ
#分類問題 #線形判別分析(LDA) #レイリー商 #カットオフ(閾値) #最小二乗法 #混合行列 #感度(再現率) #特異度 #PPV #F値 #ROC曲線 #AUC #不均衡度 #サンプリング手法 #アンダーサンプリング #ランダムアンダーサンプリング(RUS) #クラスタ基準アンダーサンプリング #トメクリンク #サンプル生成型アンダーサンプリング #オーバーサンプリング #SMOTE #ADASYN #ボーダーラインSMOTE #アンサンブル学習 #判別木 #CART #ジニ不純度 #バギング #ランダムフォレスト #ブースティング #AdaBoost #RUSBoost #SMOTEBoost #不均衡データの性能評価 #G-mean #ケーススタディ #UCI不均衡データ #Covertype #Abalone #CTG #Pageblocks

第6章 異常検知問題
■ あらすじ
異常検知では異常データが無い場合が多くて、正常データだけでモデルの学習を行い、正常/異常の判別を行う、という問題提起から始まる章です。
異常検知に用いるアルゴリズムの中から、テキストは「局所外れ値因子法(LOF)」「アイソレーションフォレスト」「多変量統計的プロセス管理(MSPC)」「オートエンコーダ(AE)」を紹介しています。
そして章の最後にはTennessee Eastmanプロセスにかかる総合的な異常検知に取り組みます。
■ 推しポイント
なんといっても、「Tennessee Eastmanプロセスの異常検知」のPython実践を通じて得られる「異常を検知できたりできなかったりして、データとアルゴリズムの相性があるんだなぁ」という感覚的な知見です!
個人的にはまたまた、最後の一大イベントで、ある1つのアルゴリズムが異常なデータを生成してしまい、悔しい思いをしました。
■ 寄り道写経
6.1~6.6節は「座学」中心のパートとなっています。
文章・数式・グラフ描画の理解を補助する目的で、サンプルデータとサンプルコードを作成します。
6.1節「局所外れ値因子法(LOF)」(scikit-learn使用)
6.2節「アイソレーションフォレスト」(scikit-learn使用)
6.3節「多変量統計的プロセス管理(MSPC)」および6.5節「管理限界の調整」(テキストのMSPC関数使用)
6.6節「時系列データの取り扱い」(テキストのMSPC関数使用)
総まとめの6.8節「Tennessee Eastmanプロセスの異常検知」については、異常データ IDV1 を対象にして、以下の点に関するテキストオリジナルコードの改造を行います。
テキストオリジナルコードの誤植および実行時に発生するエラーの回避策
異常検知結果プロットの関数化
寄与プロットをトップ5表示に改造
■ 重要テーマのタグ
#局所外れ値因子法(LOF) #局所密度 #到達可能性距離 #管理限界 #アイソレーション・フォレスト #異常スコア #多変量統計的プロセス管理(MSPC) #USPC #T²統計量 #Q統計量 #寄与プロット #オートエンコーダ(AE) #再構築誤差(RE) #管理限界の決定方法 #時系列データの取り扱い #自己相関関数 #特異スペクトル分析(SSA) #ダイナミックモデリング #砂山のパラドックス #TEプロセス #パラメータチューニング

第7章 データ収集や解析の心構え
座学です。Pythonコードはありません。
この章はテキストを読んでいただくのが一番かと思います。
重要テーマのタグ風表記は省略いたします。

第2章 相関関係と主成分分析
主に Jupyter Notebook 形式(拡張子 .ipynb)でPythonコードを書きます。
今回は軽いウォーミングアップ・準備体操のつもりで、データ標準化と主成分分析(PCA)の scikit-learn 実装に取り組みます。
プログラム 2.2 データを標準化する
テキストはデータ標準化のオリジナルコードを「scale.py」に実装しています。
この記事では、テキストに類似するNumPyでのデータ標準化と、scikit-learnの標準化関数を実行して比べます。
インポート
### インポート
import numpy as np
データの作成
テキストのデータを引用いたします。
### 既存データXと未知サンプルxの定義 ※テキストのデータを引用
X = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
x = np.array([[10, 11, 12]])
データ標準化の実行(NumPy)
NumPyでデータの平均値と不偏標準偏差を算出して、データを標準化します。
さらに未知データの標準化/再スケール化を実行します。
### numpyで実装
# 既存データの平均と不偏標準偏差の算出
X_mean = X.mean(axis=0)
X_std = X.std(ddof=1, axis=0)
# 既存データの標準化
X_ss = (X - X_mean) / X_std
print('既存データ(標準化後):')
print(X_ss)
print('既存データの平均値:')
print(X_mean)
print('既存データの不偏標準偏差:')
print(X_std)
# 未知データの標準化
x_ss = (x - X_mean) / X_std
print('未知データ(標準化後):')
print(x_ss)
# 標準化した未知データを元のスケールに再変換
re_x_ss = x_ss * X_std + X_mean
print('標準化後未知データを元のスケールに変換:')
print(re_x_ss)
【実行結果】
テキスト15ページの実行結果と同じ値です。

データ標準化の実行(scikit-learn)
scikit-learn の StandardScaler でデータの平均値と標準偏差を算出して、データを標準化します。
さらに未知データの標準化/再スケール化を実行します。
### scikit-learnで実装 ★個人的な趣味 ※不偏分散の標準偏差ではない
# 追加インポート
from sklearn.preprocessing import StandardScaler
# 標準化器の設定
ss = StandardScaler()
# 既存データの標準化
X_ss = ss.fit_transform(X)
print('既存データ(標準化後):')
print(X_ss)
print('既存データの平均値:')
print(ss.mean_)
print('X_std:')
print('既存データの標本標準偏差:')
print(np.sqrt(ss.var_))
# 未知データの標準化
x_ss = ss.transform(x)
print('未知データ(標準化後):')
print(x_ss)
# 標準化した未知データを元のスケールに再変換
re_x_ss = ss.inverse_transform(x_ss)
print('標準化後未知データを元のスケールに変換:')
print(re_x_ss)
【実行結果】
標準化後のデータと標準偏差がテキストと異なります!

実は、scikit-learn の StandardScaler が用いる標準偏差は不偏標準偏差(ddof=1)ではありません。
ddof=0の標本標準偏差なのです。
という事は・・・、スモールデータの場合、データの行数(サンプルサイズ)が小さいので、不偏標準偏差か標本標準偏差かで標準化の値に大きな違いが生じる可能性があります。
scikit-learnを利用する際、および、スモールデータの標準化の際には、くれぐれも気をつけなきゃ、ですね!

プログラム 2.4 PCAの数値例
テキストはPCAのオリジナルコードを「pca.py」に実装しています。
この記事では、scikit-learnのPCAを実行してテキストの結果と比べます。
まずテキストのプログラム2.4の実行結果を見ておきます。

ではブログ用の実装に移ります。
データの作成
テキストのデータを引用いたします。
### データの作成 テキストのデータを引用
x = np.array([[2, 2], [1, -1], [-1, 1], [-2, -2]])
PCAの実行(scikit-learn)
scikit-learn の PCA を実行します。
### scikit-learnのPCA
# 追加インポート
from sklearn.decomposition import PCA
# PCAのインスタンス作成とPCAのの実行
pca_sk = PCA()
result = pca_sk.fit_transform(x)
# ローディング行列の表示
print('ローディング行列:')
print(pca_sk.components_)
# 主成分得点の表示
print('主成分得点行列:')
print(result.round(8))
【実行結果】
正負の記号が若干異なりますが、テキストのPCAの結果とほぼほぼ一致しました。
今後も安心して、scikit-learn の PCA を活用してまいりましょう!!!

なお、テキストの「プログラム 2.5 SVD を用いた PCA」を scikit-learn で実装する場合も、この実装内容となります。
第2章の寄り道写経は以上です。
シリーズの記事
次の記事
前の記事

目次
ブログの紹介
note で7つのシリーズ記事を書いています。
ぜひ覗いていってくださいね!
1.のんびり統計
統計検定2級の問題集を手がかりにして、確率・統計をざっくり掘り下げるブログです。
雑談感覚で大丈夫です。ぜひ覗いていってくださいね。
統計検定2級公式問題集CBT対応版に対応しています。
Python、EXCELのサンプルコードの配布もあります。
2.実験!たのしいベイズモデリング1&2をPyMC Ver.5で
書籍「たのしいベイズモデリング」・「たのしいベイズモデリング2」の心理学研究に用いられたベイズモデルを PyMC Ver.5で描いて分析します。
この書籍をはじめ、多くのベイズモデルは R言語+Stanで書かれています。
PyMCの可能性を探り出し、手軽にベイズモデリングを実践できるように努めます。
身近なテーマ、イメージしやすいテーマですので、ぜひぜひPyMCで動かして、一緒に楽しみましょう!
3.実験!岩波データサイエンス1のベイズモデリングをPyMC Ver.5で
書籍「実験!岩波データサイエンスvol.1」の4人のベイジアンによるベイズモデルを PyMC Ver.5で描いて分析します。
この書籍はベイズプログラミングのイロハをざっくりと学ぶことができる良書です。
楽しくPyMCモデルを動かして、ベイズと仲良しになれた気がします。
みなさんもぜひぜひPyMCで動かして、一緒に遊んで学びましょう!
4.楽しい写経 ベイズ・Python等
ベイズ、Python、その他の「書籍の写経活動」の成果をブログにします。
主にPythonへの翻訳に取り組んでいます。
写経に取り組むお仲間さんのサンプルコードになれば幸いです🍀
5.RとStanではじめる心理学のための時系列分析入門 を PythonとPyMC Ver.5 で
書籍「RとStanではじめる心理学のための時系列分析入門」の時系列分析をPythonとPyMC Ver.5 で実践します。
この書籍には時系列分析のテーマが盛りだくさん!
時系列分析の懐の深さを実感いたしました。
大好きなPythonで楽しく時系列分析を学びます。
6.データサイエンスっぽいことを綴る
統計、データ分析、AI、機械学習、Pythonのコラムを不定期に綴っています。
統計・データサイエンス書籍にまつわる記事が多いです。
「統計」「Python」「数学とPython」「R」のシリーズが生まれています。
7.Python機械学習プログラミング実践記
書籍「Python機械学習プログラミング PyTorch & scikit-learn編」を学んだときのさまざまな思いを記事にしました。
この書籍は、scikit-learnとPyTorchの教科書です。
よかったらぜひ、お試しくださいませ。
最後までお読みいただきまして、ありがとうございました。