機械学習のPython実現ガイド
【概要】機械学習の用語(46項目)とPython実装を示す。用語は教師あり学習手法、教師なし学習手法(クラスタリング)、次元削減・特徴抽出手法、行列分解手法、評価指標、実装支援技術、実装結果の検証・評価に分類され、対応するPython関数を明示する。実装例として、ロジスティック回帰、SVM、k-NN、決定木・ランダムフォレスト、k-means、階層的クラスタリング、DBSCAN、PCA、t-SNE、因子分析、線形判別分析(LDA)、特異値分解(SVD)、QR分解の13のプログラムを提供する。
【サイト内のPython関連主要ページ】
- Windows AI支援Python開発環境構築ガイド: 別ページ »で説明
- AIエディタ Windsurf の活用: 別ページ »で説明
- AIエディタCursorガイド: 別ページ »で説明
- Google Colaboratory: 別ページ »で説明
- Python(Google Colaboratoryを含む)のまとめ: 別ページ »で説明
- 機械学習の Python 実現ガイド: 別ページ »で説明
- 行列計算の Python 実現ガイド: 別ページ »で説明
- 統計分析のPython での実現ガイド: 別ページ »で説明
- 音声信号処理の Python 実現ガイド: 別ページ »で説明
- カラー画像処理の Python 実現ガイド: 別ページ »で説明
- Python 言語によるとても簡単なアドベンチャーゲーム(変数,式,if,while,関数,print,time.sleep, def, global を使用): 別ページ »で説明
- Pythonプログラミング講座:基礎から応用まで(授業資料,全15回): 別ページ »で説明
- Pythonプログラミングの例と実践ガイド: 別ページ »で説明
【外部リソース】
- Pythonの公式サイト: https://www.python.org
- 東京大学の「Pythonプログラミング入門」: https://utokyo-ipp.github.io/IPP_textbook.pdf
- ITmedia社の「Pythonチートシート」の記事: https://atmarkit.itmedia.co.jp/ait/articles/2004/20/news015.html
機械学習の基本
-
教師あり学習・教師なし学習:正解データ(教師信号、ラベル)の有無による学習方法の違い。教師あり学習では入力と正解のペアからパターンを学習し、教師なし学習ではデータの構造やパターンを正解データを用いずに発見する
-
分類・回帰:予測問題の種類の違い。分類は離散的なカテゴリ(クラス)への割り当てであり、回帰は連続的な数値の予測である
-
訓練データ:モデルのパラメータを学習するために使用するデータセット。通常、入力(特徴量)と出力のペアで構成される
-
特徴量:データの特性や属性を数値化した変数。画像認識ではピクセル値や色情報、テキスト分析では単語の出現頻度などが特徴量として用いられる。PCAなどの手法により元の特徴量から新たな特徴量を生成する(特徴抽出する)こともある
-
距離:データポイント間の隔たりを定量化した尺度。ユークリッド距離、マンハッタン距離など様々な定義がある。距離が小さいほどデータポイントは類似している
-
確率分布:確率変数がとりうる値とその確率の関係を表す数学的モデル。正規分布、ベルヌーイ分布、ポアソン分布などがある
-
分散:データが平均値からどれだけ散らばっているかを表す統計量。分散の値が大きいほどデータのばらつきが大きい
-
相関:2つの変数間の関連性の強さと方向を示す統計量。相関係数で定量化され、-1から1の値をとる。正の相関では、一方が増えると他方も増える傾向を示す
-
次元:データを表現するために必要な特徴量(変数)の数。次元はデータの複雑さを表す
-
最適化:モデルの性能を表す目的関数(損失関数や評価関数)を最小化または最大化するパラメータの値を探索する手法。勾配降下法などのアルゴリズムが用いられる
-
陽性・陰性(または正例・負例、ポジティブクラス・ネガティブクラス):二値分類における2つのクラスの呼称。検出したい事象を陽性とすることが多いが、定義は問題設定による
用語リスト
教師あり学習手法
ロジスティック回帰:線形モデルとシグモイド関数を組み合わせた分類手法。多クラス分類にはソフトマックス関数を適用し、最尤推定により重みパラメータを最適化する。
サポートベクターマシン(SVM):データを高次元空間に写像し、マージン最大化により最適な分離超平面を探索する機械学習アルゴリズム。カーネルトリック(低次元空間での計算により高次元空間での内積を効率的に求める手法)を用いた非線形分類を実現する。
k近傍法(k-NN):新規データポイントに対し、訓練データセットからk個の最近傍点を距離計算により特定し、その近傍点の値に基づいて予測を行うインスタンスベース学習手法。
決定木:特徴量に基づく階層的な木構造により、データを再帰的に分割して判断ルールを生成する手法。
ランダムフォレスト:複数の決定木を組み合わせたアンサンブル学習手法。各決定木の予測結果を統合することで、高い精度と汎化性能を実現する。
線形判別分析(LDA):教師あり学習における次元削減手法。クラス間の分散を最大化し、クラス内の分散を最小化する軸を見つけることで、特徴抽出を実現する。k個のクラスではk-1個の判別軸が得られる。
教師なし学習手法(クラスタリング)
k-meansクラスタリング:クラスタ中心の初期配置、データポイントの割り当て、中心の再計算を反復する教師なし学習アルゴリズム。
階層的クラスタリング:データの階層構造を抽出する手法。ボトムアップ(凝集型)は個別データ点から開始して近接クラスタを段階的に統合し、トップダウン(分割型)は単一クラスタから開始して段階的に分割する。
DBSCAN:密度ベースでクラスタリングを行うアルゴリズム。データ点を、十分に密な領域にあるコアポイント、コアポイントの近傍にある境界ポイント、どのクラスタにも属さないノイズポイントの3種類に分類する。クラスタ数の事前指定が不要で、外れ値の自動識別が可能。
次元削減・特徴抽出手法
PCA(主成分分析):データの分散が最大となる軸を算出し、次元削減を実現する統計的手法。直交する主成分を順次抽出することで次元削減と特徴抽出を行う。各主成分の寄与率により重要度を定量的に評価できる。主成分負荷量により、各主成分と元の変数との関係を把握できる。
因子分析:観測変数の背後にある潜在的な共通因子を抽出する統計的手法。PCAがデータの分散を最大化する軸を探索するのに対し、因子分析は観測変数間の相関構造を説明する潜在因子を仮定する。心理学や社会科学の分野で活用されている。
t-SNE:確率分布の一致度を最適化する非線形次元削減手法。近傍点間の関係(局所構造)を保持しながら、反復的な最適化プロセスによりクラスタ構造の可視化に優れた低次元表現を生成する。
行列分解手法
特異値分解(SVD):行列を3つの行列(U、Σ、V^T)の積に分解する手法。特異値の大きさは各成分の重要度を示す指標である。データ圧縮や潜在的意味解析などの分析が可能となる。
QR分解:行列を直交行列Q(Q^T Q = I)と上三角行列Rの積に分解する手法。最小二乗法や固有値計算において重要な役割を持つ。Gram-Schmidt直交化法の実装として解釈できる。
評価指標
精度(Accuracy):全予測における正解の割合を示す指標。
適合率(Precision):陽性予測の正確性を示す指標。
再現率(Recall):陽性サンプルの検出率を示す指標。
F1スコア:適合率と再現率のバランスを評価する指標。両者の調和平均により算出される。
コフェネティック相関係数:階層的クラスタリングの結果を評価する指標。元の距離とデンドログラム上の距離の相関を測定する。
KL-divergence(Kullback-Leibler情報量):2つの確率分布間の差異を測定する指標。t-SNEの最適化において、高次元空間と低次元空間における点間の類似度を表す確率分布の一致度を評価するために使用される。
寄与率:各主成分が全体の分散をどの程度説明するかを示す割合。PCAにおける主成分の重要度を表す。
累積寄与率:複数の主成分による累積的な分散説明率を示す指標。次元削減における情報保持率を評価する。
固有値:各主成分が持つ分散の大きさを表す値。PCAにおいて主成分の重要度を示す。
主成分負荷量:各主成分と元の変数との相関を示す値。主成分の解釈に用いられる。
共通性:因子分析において、観測変数が共通因子によって説明される分散の割合。
判別係数:線形判別分析(LDA)における各判別関数の係数。
実装のための技術
-
標準化:各特徴量の平均を0、標準偏差を1に変換する前処理手法。特徴量間のスケールを統一し、距離や内積を用いるアルゴリズム(k-NNやSVM)において特定の特徴量の影響が過大になることを防ぐ。
-
次元削減:高次元データを低次元空間に変換する手法。計算コストの削減、可視化、過学習の抑制を目的とする。
-
k分割交差検証:データセットをk個に分割し、1つをテストデータ、残りを訓練データとして使用する処理をk回繰り返す手法。各分割で得られた評価指標の平均と標準偏差によりモデルの汎化性能を評価する。
-
グリッドサーチ:指定したハイパーパラメータの候補値の全組み合わせを試行し、交差検証により最適なパラメータセットを決定する最適化手法。
-
データの可視化:データの分布、パターン、クラスタ構造、モデルの予測結果を視覚的に表現する手法。
-
エルボー法:k-meansクラスタリングにおいて、クラスタ数kとクラスタ内分散の関係をプロットし、クラスタ内分散の減少が急激から緩やかに変わる転換点から最適なクラスタ数を決定する手法。
-
デンドログラム:階層的クラスタリングの結果を樹形図として可視化する手法。データポイント間の距離関係と各段階での統合距離を示す。
-
最尤推定:観測データが得られる確率を最大化するパラメータを推定する統計的手法。ロジスティック回帰や因子分析で用いられる。
実装結果の検証,評価
-
汎化性能:モデルが訓練データ以外の未知データに対して正確な予測を行う能力。交差検証により評価する。
-
ハイパーパラメータ:学習アルゴリズムの動作を制御する、学習前に設定するパラメータ。k-NNのk値、SVMのカーネル種類、決定木の最大深度等が該当する。
-
混同行列(Confusion Matrix):分類モデルの予測結果を真陽性、偽陽性、真陰性、偽陰性に分類して表形式で示す評価ツール。精度、適合率、再現率、F1スコアの算出基礎となる。
-
シルエット係数(Silhouette Coefficient):クラスタリング結果の品質を評価する指標。各データポイントについて、同一クラスタ内の他点との平均距離と最近隣クラスタの点との平均距離から算出し、-1から1の範囲で評価する。値が1に近いほどクラスタが明確に分離されていることを示す。
Python での実現
| 用語 | 対応関数・クラス・属性 |
|---|---|
| ロジスティック回帰 |
主要: 関連: |
| サポートベクターマシン(SVM) |
主要: 関連: |
| k近傍法(k-NN) |
主要: 関連: |
| 決定木 |
主要: 関連: |
| ランダムフォレスト |
主要: 関連: 属性: |
| 線形判別分析(LDA) |
主要: 属性: 属性: |
| 用語 | 対応関数・クラス・属性 |
|---|---|
| k-meansクラスタリング |
主要: 属性: |
| 階層的クラスタリング |
主要: 関連: |
| DBSCAN |
主要: |
| 用語 | 対応関数・クラス・属性 |
|---|---|
| PCA(主成分分析) |
主要: 属性: 属性: 属性: |
| 因子分析 |
主要: 属性: |
| t-SNE |
主要: |
| 用語 | 対応関数・クラス・属性 |
|---|---|
| 特異値分解(SVD) |
主要: 関連: |
| QR分解 |
主要: |
| 用語 | 対応関数・クラス・属性 |
|---|---|
| 精度(Accuracy) |
主要: 関連: |
| 適合率(Precision) |
主要: 関連: |
| 再現率(Recall) |
主要: 関連: |
| F1スコア |
主要: 関連: |
| コフェネティック相関係数 |
主要: |
| KL-divergence(Kullback-Leibler情報量) |
主要: |
| 寄与率 |
主要: |
| 累積寄与率 |
主要: |
| 固有値 |
主要: |
| 主成分負荷量 |
主要: |
| 共通性 |
主要: |
| 判別係数 |
主要: |
| 用語 | 対応関数・クラス・属性 |
|---|---|
| 標準化 |
主要: 関連: |
| 次元削減 |
主要: 関連: |
| k分割交差検証 |
主要: 関連: |
| グリッドサーチ |
主要: 関連: |
| データの可視化 |
主要: 関連: 関連: |
| エルボー法 |
主要: 関連: |
| デンドログラム |
主要: 関連: |
| 最尤推定 |
主要: 関連: |
| 用語 | 対応関数・クラス・属性 |
|---|---|
| 汎化性能 |
主要: |
| ハイパーパラメータ |
主要: 関連: |
| 混同行列(Confusion Matrix) |
主要: 関連: 関連: |
| シルエット係数(Silhouette Coefficient) |
主要: 関連: |
| 用語 | 対応関数・クラス・属性 |
|---|---|
| データ分割 |
主要: |
| データフレーム操作 |
主要: |
補足:classification_reportについて
classification_report (scikit-learn)は、精度(Accuracy)、適合率(Precision)、再現率(Recall)、F1スコアの4つの評価指標を一括で計算・出力する関数である。個別の指標を計算する場合は各関数(accuracy_score等)を使用し、まとめて結果を確認したい場合はclassification_reportを使用する。
Pythonプログラム例
1. ロジスティック回帰
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix
# データ準備
iris = load_iris()
X = iris.data
y = iris.target
# 学習データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# ロジスティック回帰モデルの構築と学習
model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)
# テストデータでの予測と性能評価
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred))
# 混同行列の表示
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))
# 5分割交差検証による性能評価
cv_scores = cross_val_score(model, X, y, cv=5)
print(f"Cross-validation scores: {cv_scores}")
print(f"Average CV score: {cv_scores.mean():.3f} (+/- {cv_scores.std() * 2:.3f})")
線形モデルとシグモイド関数を組み合わせた分類手法を実装する。データセットを訓練データとテストデータに分割し、ロジスティック回帰モデルを構築する。最尤推定により重みパラメータを最適化し、テストデータで予測を行う。分類レポートにより精度、適合率、再現率、F1スコアを算出する。混同行列により予測結果を真陽性、偽陽性、真陰性、偽陰性の4つに分類し、表形式で示す。k分割交差検証により汎化性能を評価し、各分割での評価指標の平均と標準偏差からモデルの安定性を確認する。多クラス分類にはソフトマックス関数が内部で適用される。
2. SVM
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.metrics import classification_report
# Irisデータセットの読み込み
iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target
# データの分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# モデル構築
svm = SVC(kernel='rbf', random_state=42)
# パラメータグリッド
param_grid = {
'C': [0.1, 1, 10],
'gamma': ['scale', 'auto', 0.1, 1],
}
# グリッドサーチ
grid_search = GridSearchCV(
svm,
param_grid,
cv=5,
scoring='accuracy',
n_jobs=-1
)
# モデル学習
grid_search.fit(X_train, y_train)
# 最適パラメータと評価
print(f"Best parameters: {grid_search.best_params_}")
y_pred = grid_search.predict(X_test)
print(classification_report(y_test, y_pred))
データを高次元空間に写像し、マージン最大化により最適な分離超平面を探索する。RBFカーネルを使用し、カーネルトリックにより非線形分類を実現する。グリッドサーチによりハイパーパラメータ(正則化係数Cとカーネルパラメータgamma)の全組み合わせを探索し、k分割交差検証により最適値を決定する。並列処理により計算を高速化し、最適パラメータでモデルを構築する。テストデータで予測を行い、分類レポートにより精度、適合率、再現率、F1スコアを算出する。距離や内積を用いるため、特徴量の標準化が推奨される。
3. k-NN
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score, train_test_split
from sklearn.metrics import classification_report
# Irisデータセットの読み込み
iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target
# データの分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# k値の範囲でモデル評価
k_range = range(1, 31)
k_scores = []
for k in k_range:
knn = KNeighborsClassifier(n_neighbors=k)
scores = cross_val_score(knn, X, y, cv=5)
k_scores.append(scores.mean())
# 最適なkの選択
best_k = k_range[np.argmax(k_scores)]
print(f"Best k: {best_k}")
# 最適モデルの構築と評価
knn = KNeighborsClassifier(n_neighbors=best_k)
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
print(classification_report(y_test, y_pred))
新規データポイントに対し、訓練データセットからk個の最近傍点を距離計算により特定し、その近傍点の値に基づいて予測を行うインスタンスベース学習手法を実装する。k値を1から30の範囲で変化させ、各k値についてk分割交差検証により汎化性能を評価する。評価指標の平均が最大となるk値を最適値として選択する。最適なk値でモデルを構築し、テストデータで予測を行う。分類レポートにより精度、適合率、再現率、F1スコアを算出する。距離ベースのアルゴリズムであるため、特徴量の標準化が推奨される。
4. 決定木・ランダムフォレスト
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import classification_report
# Irisデータセットの読み込み
iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target
# 学習用とテスト用にデータを分割
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.3, random_state=42
)
# 決定木による学習と予測
dt = DecisionTreeClassifier(random_state=42)
dt.fit(X_train, y_train)
dt_pred = dt.predict(X_test)
print("Decision Tree:")
print(classification_report(y_test, dt_pred))
# ランダムフォレストによる学習と予測
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)
rf_pred = rf.predict(X_test)
print("\nRandom Forest:")
print(classification_report(y_test, rf_pred))
# 特徴量重要度の算出と表示
feature_importance = pd.DataFrame({
'feature': iris.feature_names,
'importance': rf.feature_importances_
})
print("\nFeature importance:")
print(feature_importance.sort_values('importance', ascending=False))
決定木は特徴量に基づく階層的な木構造により、データを再帰的に分割して判断ルールを生成する手法である。ランダムフォレストは複数の決定木を組み合わせたアンサンブル学習手法であり、各決定木の予測結果を統合することで高い精度と汎化性能を実現する。データセットを訓練データとテストデータに分割し、両手法でモデルを構築する。分類レポートにより各手法の性能を評価する。特徴量重要度により各特徴量がモデルの予測に寄与する程度を定量的に評価する。スケーリングや前処理の要件が最小限である。
5. k-means
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from sklearn.datasets import load_iris
# Irisデータセットの読み込み
iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target
# エルボー法とシルエット分析による最適クラスタ数の決定
inertias = []
silhouette_scores = []
K = range(2, 10)
# 各クラスタ数での評価指標を計算
for k in K:
kmeans = KMeans(n_clusters=k, random_state=42)
kmeans.fit(X)
inertias.append(kmeans.inertia_)
silhouette_scores.append(silhouette_score(X, kmeans.labels_))
# エルボー法のプロット
plt.figure(figsize=(8, 6))
plt.plot(K, inertias, 'bo-')
plt.xlabel('Number of clusters (k)')
plt.ylabel('Inertia')
plt.title('Elbow Method')
plt.grid(True)
plt.show()
# シルエットスコアが最大となるクラスタ数を選択
best_k = K[np.argmax(silhouette_scores)]
# 最適なクラスタ数でモデルを再学習
kmeans = KMeans(n_clusters=best_k, random_state=42)
clusters = kmeans.fit_predict(X)
# 結果の出力
print(f"Best number of clusters: {best_k}")
print(f"Silhouette score: {silhouette_score(X, clusters):.3f}")
# クラスタリング結果の基本統計量
cluster_stats = pd.DataFrame(X)
cluster_stats['Cluster'] = clusters
print("\nCluster statistics:")
print(cluster_stats.groupby('Cluster').mean())
クラスタ中心の初期配置、データポイントの割り当て、中心の再計算を反復する教師なし学習アルゴリズムを実装する。クラスタ数を2から9の範囲で変化させ、各クラスタ数についてクラスタ内分散とシルエット係数を計算する。エルボー法によりクラスタ数kとクラスタ内分散の関係をプロットし、クラスタ内分散の減少が急激から緩やかに変わる転換点から最適なクラスタ数を決定する。シルエット係数により同一クラスタ内の凝集度と他クラスタとの分離度を評価する。シルエット係数が最大となるクラスタ数でモデルを再学習し、クラスタごとの基本統計量を算出する。
6. 階層的クラスタリング
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
from sklearn.cluster import AgglomerativeClustering
from scipy.cluster.hierarchy import dendrogram, linkage, cophenet
from scipy.spatial.distance import pdist
import matplotlib.pyplot as plt
# Irisデータセットの読み込み
iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target
# 階層的クラスタリング実行
hierarchical = AgglomerativeClustering(n_clusters=3)
clusters = hierarchical.fit_predict(X)
# 結果の表示
print("階層的クラスタリング結果:")
print("各クラスタのサンプル数:", np.bincount(clusters))
# クラスタごとの基本統計量
cluster_stats = pd.DataFrame(X)
cluster_stats['Cluster'] = clusters
print("\nクラスタごとの平均値:")
print(cluster_stats.groupby('Cluster').mean())
# デンドログラム作成
linkage_matrix = linkage(X, method='ward')
plt.figure(figsize=(10, 7))
dendrogram(linkage_matrix)
plt.title('Hierarchical Clustering Dendrogram')
plt.xlabel('Sample index')
plt.ylabel('Distance')
plt.show()
# コフェネティック相関係数の計算
c, coph_dists = cophenet(linkage_matrix, pdist(X))
print(f"\nCophenetic correlation coefficient: {c:.3f}")
データの階層構造を抽出する手法を実装する。ボトムアップ(凝集型)アプローチにより、個別データ点から開始して近接クラスタを段階的に統合する。ウォード法による距離計算により、クラスタ内分散を最小化する方向で統合を進める。クラスタ数を3に設定し、階層的クラスタリングを実行する。各クラスタのサンプル数とクラスタごとの平均値を表示し、クラスタの特性を把握する。デンドログラムにより階層構造を樹形図として可視化し、データポイント間の距離関係と各段階での統合距離を表現する。コフェネティック相関係数により元の距離とデンドログラム上の距離の相関を測定し、階層的クラスタリングの結果を評価する。
7. DBSCAN
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score
# Irisデータセットの読み込み
iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target
# データの標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# DBSCANによるクラスタリング
dbscan = DBSCAN(eps=0.3, min_samples=5)
clusters = dbscan.fit_predict(X_scaled)
# クラスタ評価
n_clusters = len(set(clusters)) - (1 if -1 in clusters else 0)
# シルエットスコアの計算
if n_clusters >= 2 and len(clusters[clusters != -1]) >= 2:
mask = clusters != -1
silhouette_avg = silhouette_score(X_scaled[mask], clusters[mask])
print(f"Number of clusters: {n_clusters}")
print(f"Silhouette score: {silhouette_avg:.3f}")
else:
print(f"Number of clusters: {n_clusters}")
print("Silhouette score cannot be calculated.")
密度ベースでクラスタリングを行うアルゴリズムを実装する。データを標準化により前処理し、特徴量間のスケールを統一する。データ点を、十分に密な領域にあるコアポイント、コアポイントの近傍にある境界ポイント、どのクラスタにも属さないノイズポイントの3種類に分類する。パラメータepsにより近傍を定義する距離閾値を、min_samplesによりコアポイント判定の最小サンプル数を設定する。クラスタ数の事前指定が不要で、外れ値の自動識別が可能である。ノイズポイントを除外してクラスタ数を計算し、シルエット係数によりクラスタリング結果の品質を評価する。
8. PCA
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
# Irisデータセットの読み込み
iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target
# データの標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# PCAの実行
pca = PCA()
X_pca = pca.fit_transform(X_scaled)
# 寄与率、累積寄与率、固有値の表示
explained_variance_ratio = pca.explained_variance_ratio_
cumulative_variance_ratio = np.cumsum(explained_variance_ratio)
eigenvalues = pca.explained_variance_
print("Explained variance ratio:", explained_variance_ratio)
print("Cumulative explained variance ratio:", cumulative_variance_ratio)
print("Eigenvalues:", eigenvalues)
# 主成分負荷量の表示
print("\n主成分負荷量:")
for i, loadings in enumerate(pca.components_, 1):
print(f"\n第{i}主成分:")
for j, loading in enumerate(loadings):
print(f" {iris.feature_names[j]}: {loading:.4f}")
# 可視化
plt.figure(figsize=(12, 4))
# スクリープロット
plt.subplot(131)
plt.plot(range(1, len(explained_variance_ratio) + 1), explained_variance_ratio, 'bo-')
plt.xlabel('Principal Component')
plt.ylabel('Explained Variance Ratio')
plt.title('Scree Plot')
plt.grid(True)
# 累積寄与率のプロット
plt.subplot(132)
plt.plot(range(1, len(cumulative_variance_ratio) + 1), cumulative_variance_ratio, 'ro-')
plt.xlabel('Number of Components')
plt.ylabel('Cumulative Explained Variance Ratio')
plt.title('Cumulative Variance')
plt.grid(True)
# 第1・第2主成分でのデータ分布
plt.subplot(133)
scatter = plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap='viridis')
plt.xlabel('First Principal Component')
plt.ylabel('Second Principal Component')
plt.title('Data Distribution in PC Space')
plt.colorbar(scatter)
plt.tight_layout()
plt.show()
データの分散が最大となる軸を算出し、次元削減を実現する統計的手法を実装する。データを標準化により前処理し、特徴量間のスケールを統一する。PCAを実行し、元のデータを主成分空間に変換する。寄与率により各主成分が全体の分散を説明する割合を算出する。累積寄与率により複数の主成分による累積的な分散説明率を計算し、次元削減における情報保持率を評価する。固有値により各主成分が持つ分散の大きさを表し、主成分の重要度を示す。主成分負荷量により各主成分と元の変数との相関を示し、主成分の解釈を可能にする。スクリープロットにより主成分の重要度を可視化し、寄与率の減少傾向を確認する。第1・第2主成分空間でのデータ分布を散布図により可視化し、クラスタ構造を把握する。
9. t-SNE
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.manifold import TSNE
import matplotlib.pyplot as plt
# Irisデータセットの読み込み
iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target
# t-SNEの実行
tsne = TSNE(n_components=2, perplexity=30, random_state=42)
X_tsne = tsne.fit_transform(X)
# 結果の可視化
plt.figure(figsize=(10, 6))
scatter = plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=y, cmap='viridis')
plt.colorbar(scatter)
plt.title('t-SNE visualization of Iris dataset')
plt.xlabel('First t-SNE component')
plt.ylabel('Second t-SNE component')
plt.show()
確率分布の一致度を最適化する非線形次元削減手法を実装する。近傍点間の関係(局所構造)を保持しながら、反復的な最適化プロセスによりクラスタ構造の可視化に優れた低次元表現を生成する。高次元空間と低次元空間における点間の類似度を表す確率分布を定義し、KL-divergenceによりその一致度を評価しながら最適化を行う。パラメータperplexityにより近傍点の数を制御し、データの局所構造と大域構造のバランスを調整する。2次元に次元削減し、散布図により可視化する。色分けによりクラスタ構造を視覚的に確認できる。
10. 因子分析
import numpy as np
from sklearn.decomposition import FactorAnalysis
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
import pandas as pd
# Irisデータセットの読み込み
iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris.feature_names)
y = iris.target
# データの標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 因子分析の実行
fa = FactorAnalysis(n_components=2, random_state=42)
X_fa = fa.fit_transform(X_scaled)
# 因子負荷量の表示
print("因子負荷量:")
for i, feature_name in enumerate(iris.feature_names):
print(f"\n{feature_name}:")
for j, loading in enumerate(fa.components_[:, i], 1):
print(f" 因子{j}: {loading:.4f}")
# 共通性の計算
communalities = np.sum(fa.components_**2, axis=0)
print("\n共通性:")
for i, (feature_name, comm) in enumerate(zip(iris.feature_names, communalities)):
print(f"{feature_name}: {comm:.4f}")
# 因子間相関の計算
factor_corr = np.corrcoef(X_fa.T)
print("\n因子間相関:")
print(factor_corr)
# 可視化
plt.figure(figsize=(12, 4))
# 因子負荷量のプロット
plt.subplot(131)
plt.scatter(fa.components_[0], fa.components_[1])
for i, feature_name in enumerate(iris.feature_names):
plt.annotate(feature_name, (fa.components_[0, i], fa.components_[1, i]))
plt.xlabel('第1因子')
plt.ylabel('第2因子')
plt.title('因子負荷量プロット')
plt.grid(True)
plt.axhline(y=0, color='k', linestyle='--', alpha=0.3)
plt.axvline(x=0, color='k', linestyle='--', alpha=0.3)
# 因子得点の分布
plt.subplot(132)
scatter = plt.scatter(X_fa[:, 0], X_fa[:, 1], c=y, cmap='viridis', alpha=0.6)
plt.xlabel('第1因子得点')
plt.ylabel('第2因子得点')
plt.title('因子得点の分布')
plt.colorbar(scatter)
# 共通性の棒グラフ
plt.subplot(133)
plt.bar(range(len(communalities)), communalities)
plt.xticks(range(len(iris.feature_names)), iris.feature_names, rotation=45, ha='right')
plt.ylabel('共通性')
plt.title('各変数の共通性')
plt.grid(True, axis='y')
plt.tight_layout()
plt.show()
観測変数の背後にある潜在的な共通因子を抽出する統計的手法を実装する。データを標準化により前処理し、特徴量間のスケールを統一する。因子分析を実行し、2つの潜在因子を抽出する。因子負荷量により各観測変数と潜在因子との関係を定量化する。共通性により各観測変数が共通因子によって説明される分散の割合を算出する。因子間相関により抽出された因子間の関係を評価する。因子負荷量プロットにより各変数がどの因子に強く関連するかを視覚的に把握する。因子得点の分布により、データが因子空間でどのように配置されるかを確認する。PCAがデータの分散を最大化する軸を探索するのに対し、因子分析は観測変数間の相関構造を説明する潜在因子を仮定する点で異なる。
11. 線形判別分析(LDA)
import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import matplotlib.pyplot as plt
# Irisデータセットの読み込み
iris = load_iris()
X = iris.data
y = iris.target
# データの標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# データの分割
X_train, X_test, y_train, y_test = train_test_split(
X_scaled, y, test_size=0.3, random_state=42
)
# LDAの実行
lda = LinearDiscriminantAnalysis()
X_lda = lda.fit_transform(X_scaled, y)
# 判別係数の表示
print("判別係数:")
for i, coef in enumerate(lda.coef_, 1):
print(f"\n判別関数{i}:")
for j, (feature_name, c) in enumerate(zip(iris.feature_names, coef)):
print(f" {feature_name}: {c:.4f}")
# 分類性能の評価
y_pred = lda.predict(X_test)
print("\n分類性能:")
print(f"正答率: {lda.score(X_test, y_test):.4f}")
print("\n分類レポート:")
print(classification_report(y_test, y_pred, target_names=iris.target_names))
# 各判別関数の寄与率
print("\n各判別関数の寄与率:")
explained_ratios = lda.explained_variance_ratio_
for i, ratio in enumerate(explained_ratios, 1):
print(f"判別関数{i}: {ratio:.4f}")
# 可視化
plt.figure(figsize=(12, 4))
# 第1・第2判別関数でのデータ分布
plt.subplot(131)
scatter = plt.scatter(X_lda[:, 0], X_lda[:, 1], c=y, cmap='viridis')
plt.xlabel('第1判別関数')
plt.ylabel('第2判別関数')
plt.title('判別空間でのデータ分布')
plt.colorbar(scatter, ticks=[0, 1, 2], label='Class')
# 判別関数の寄与率
plt.subplot(132)
plt.bar(range(1, len(explained_ratios) + 1), explained_ratios)
plt.xlabel('判別関数')
plt.ylabel('寄与率')
plt.title('判別関数の寄与率')
plt.grid(True, axis='y')
# 第1判別関数のヒストグラム
plt.subplot(133)
for class_label in np.unique(y):
plt.hist(X_lda[y == class_label, 0], alpha=0.5,
label=iris.target_names[class_label], bins=20)
plt.xlabel('第1判別関数')
plt.ylabel('頻度')
plt.title('第1判別関数によるクラス分離')
plt.legend()
plt.grid(True, axis='y')
plt.tight_layout()
plt.show()
教師あり学習における次元削減手法を実装する。クラス間の分散を最大化し、クラス内の分散を最小化する軸を見つけることで、特徴抽出を実現する。データを標準化により前処理し、特徴量間のスケールを統一する。LDAを実行し、3クラス問題に対して2つの判別軸を抽出する。判別係数により各判別関数における特徴量の寄与を定量化する。分類性能を評価し、正答率と分類レポートを表示する。各判別関数の寄与率により、クラス分離への寄与度を把握する。判別空間でのデータ分布を可視化し、クラス分離の状況を確認する。第1判別関数のヒストグラムにより、各クラスがどの程度分離されているかを視覚的に把握する。PCAが教師なし次元削減であるのに対し、LDAはクラスラベル情報を活用する教師あり次元削減である点で異なる。
12. 特異値分解(SVD)
import numpy as np
import matplotlib.pyplot as plt
# サンプルデータの生成
np.random.seed(42)
n_rows, n_cols = 100, 50
# ランク3の行列を生成
U_true = np.random.normal(0, 1, (n_rows, 3))
V_true = np.random.normal(0, 1, (n_cols, 3))
singular_values_true = np.array([10, 5, 2])
X = U_true @ np.diag(singular_values_true) @ V_true.T
# ノイズを追加
X_noisy = X + np.random.normal(0, 0.1, (n_rows, n_cols))
# SVDの実行
U, s, Vt = np.linalg.svd(X_noisy, full_matrices=False)
# 特異値の表示
print("特異値(上位10個):")
for i, value in enumerate(s[:10], 1):
print(f"σ_{i}: {value:.4f}")
# 累積寄与率の計算
cumulative_variance = np.cumsum(s**2) / np.sum(s**2)
print(f"\n上位3成分の累積寄与率: {cumulative_variance[2]:.4f}")
# 低ランク近似の誤差を計算
errors = []
ranks = range(1, min(n_rows, n_cols) + 1)
for r in ranks:
X_approx = U[:, :r] @ np.diag(s[:r]) @ Vt[:r, :]
error = np.linalg.norm(X_noisy - X_approx, 'fro')
errors.append(error)
# 可視化
plt.figure(figsize=(15, 4))
# 特異値のプロット
plt.subplot(141)
plt.plot(range(1, len(s) + 1), s, 'o-')
plt.yscale('log')
plt.xlabel('成分番号')
plt.ylabel('特異値')
plt.title('特異値のスケープロット')
plt.grid(True)
# 累積寄与率
plt.subplot(142)
plt.plot(range(1, len(s) + 1), cumulative_variance, 'o-')
plt.xlabel('成分数')
plt.ylabel('累積寄与率')
plt.title('累積寄与率')
plt.grid(True)
# 近似誤差
plt.subplot(143)
plt.plot(ranks[:20], errors[:20], 'o-')
plt.xlabel('使用する特異値の数')
plt.ylabel('近似誤差')
plt.title('低ランク近似の誤差')
plt.grid(True)
# オリジナルデータの可視化
plt.subplot(144)
plt.imshow(X_noisy[:20, :20], cmap='coolwarm', aspect='auto')
plt.title('オリジナルデータ(部分)')
plt.colorbar()
plt.tight_layout()
plt.show()
# 低ランク近似の比較
plt.figure(figsize=(15, 4))
ranks_demo = [1, 3, 10]
for i, r in enumerate(ranks_demo):
X_approx = U[:, :r] @ np.diag(s[:r]) @ Vt[:r, :]
plt.subplot(1, len(ranks_demo), i+1)
plt.imshow(X_approx[:20, :20], cmap='coolwarm', aspect='auto')
plt.title(f'ランク{r}での近似')
plt.colorbar()
plt.tight_layout()
plt.show()
行列を3つの行列(U、Σ、V^T)の積に分解する手法を実装する。ランク3の行列にノイズを加えたデータを生成し、SVDを実行する。特異値により各成分の重要度を定量化する。累積寄与率により、上位成分がデータの分散をどの程度説明するかを評価する。低ランク近似により、小さい特異値を無視してデータを圧縮する。近似誤差をプロットし、使用する特異値の数と再構成精度の関係を可視化する。特異値のスケープロットにより、重要な成分の数を判断する。異なるランクでの近似結果を比較し、データ圧縮の効果を視覚的に確認する。SVDはPCAの基礎となる手法であり、データ圧縮や潜在的意味解析などの応用が可能である。
13. QR分解
import numpy as np
import matplotlib.pyplot as plt
# サンプルデータの生成
np.random.seed(42)
n_rows, n_cols = 5, 3
A = np.random.randn(n_rows, n_cols)
# QR分解の実行
Q, R = np.linalg.qr(A)
# 結果の表示
print("元の行列 A:")
print(A)
print("\nQ行列(直交行列):")
print(Q)
print("\nR行列(上三角行列):")
print(R)
# 検証
print("\n検証結果:")
print("Q^T Q(単位行列に近いことを確認):")
print(np.round(Q.T @ Q, decimals=10))
print("\nQR(元の行列Aに近いことを確認):")
reconstruction_error = np.linalg.norm(A - Q @ R)
print(f"再構成誤差: {reconstruction_error:.10f}")
# 可視化
plt.figure(figsize=(15, 4))
# 元の行列の可視化
plt.subplot(141)
plt.imshow(A, cmap='coolwarm', aspect='auto')
plt.title('元の行列 A')
plt.colorbar()
# Q行列の可視化
plt.subplot(142)
plt.imshow(Q, cmap='coolwarm', aspect='auto')
plt.title('直交行列 Q')
plt.colorbar()
# R行列の可視化
plt.subplot(143)
plt.imshow(R, cmap='coolwarm', aspect='auto')
plt.title('上三角行列 R')
plt.colorbar()
# Q^T Q の可視化
plt.subplot(144)
plt.imshow(Q.T @ Q, cmap='coolwarm', aspect='auto')
plt.title('Q^T Q(単位行列)')
plt.colorbar()
plt.tight_layout()
plt.show()
# QR分解の応用:最小二乗法による線形回帰
print("\n\nQR分解の応用:最小二乗法による線形回帰")
# サンプルデータの生成
n_samples = 100
X_data = np.random.uniform(0, 10, n_samples)
y_data = 2 * X_data + 1 + np.random.normal(0, 1, n_samples)
# 設計行列の作成
A_reg = np.vstack([X_data, np.ones(n_samples)]).T
# QR分解を使用した最小二乗法
Q_reg, R_reg = np.linalg.qr(A_reg)
beta = np.linalg.solve(R_reg, Q_reg.T @ y_data)
print(f"\n推定された傾き: {beta[0]:.4f}")
print(f"推定された切片: {beta[1]:.4f}")
# 結果の可視化
plt.figure(figsize=(8, 6))
plt.scatter(X_data, y_data, alpha=0.5, label='データ点')
X_sort = np.sort(X_data)
plt.plot(X_sort, beta[0] * X_sort + beta[1], 'r-', linewidth=2,
label='QR分解による回帰直線')
plt.plot(X_sort, 2 * X_sort + 1, 'g--', linewidth=2,
label='真の関係')
plt.xlabel('X')
plt.ylabel('y')
plt.title('QR分解を用いた線形回帰')
plt.legend()
plt.grid(True)
plt.show()
行列を直交行列Q(Q^T Q = I)と上三角行列Rの積に分解する手法を実装する。ランダムに生成した行列に対してQR分解を実行する。Q行列が直交行列であることを、Q^T Qが単位行列に近いことで検証する。QRの積が元の行列Aを再構成できることを、フロベニウスノルムにより確認する。各行列を可視化し、QR分解の構造を視覚的に把握する。QR分解の応用として、最小二乗法による線形回帰問題を実装する。設計行列を作成し、QR分解を用いて回帰係数を安定的に求める。推定された回帰直線と真の関係を比較し、QR分解による解法の有効性を確認する。QR分解はGram-Schmidt直交化法の実装として解釈でき、最小二乗法や固有値計算において重要な役割を持つ。