Ridge-Gauusian.py 技術ドキュメント

プログラムの動作

Ridge-Gauusian.py は、与えられた2次元の数値データ (\(x\), \(y\)) に対して、ガウス関数を基底としたリッジ回帰(Ridge Regression)フィッティングを行うPythonプログラムです。

このプログラムの主な機能は以下の通りです。

  1. データ読み込み: Excelファイルから\(x\)軸と\(y\)軸のデータを読み込みます。

  2. リッジ回帰計算: 指定された数のガウス基底関数を用いて、読み込んだデータにリッジ回帰モデルを適合させます。リッジ回帰は、正則化項を導入することで、特に基底関数の数が多い場合に発生しがちな過学習(overfitting)を抑制する効果があります。

  3. 結果の可視化: フィッティングされた曲線と元のデータ点を比較するプロット、および各ガウス基底関数の係数を示すプロットを生成し、グラフウィンドウに表示します。

  4. 係数の表示: フィッティングによって求められた各ガウス基底関数の係数をコンソールに出力します。

このプログラムは、物理実験データや工学的な測定データなど、ノイズを含む可能性のあるデータに対して、ロバストな曲線フィッティングを行うのに役立ちます。

原理

Ridge-Gauusian.py は、線形最小二乗法に基づくリッジ回帰の原理を利用してデータをフィッティングします。

1. モデル関数

データ点 \((x_i, y_i)\) を、\(M\)個のガウス基底関数 \(f_k(x)\) の線形結合で近似します。モデル関数 \(y(x)\) は次の形で表されます。

\[ y(x) = \sum_{k=0}^{M-1} c_k f_k(x) \]

ここで、\(c_k\) はフィッティングによって求められる係数です。 本プログラムでは、基底関数 \(f_k(x)\) としてガウス関数を使用します。

\[ f_k(x) = \exp\left(-\left(\frac{x - x_{0k}}{w_G}\right)^2\right) \]

\(x_{0k}\)\(k\)番目のガウス関数の中心、\(w_G\) はガウス関数の幅です。プログラムでは、\(x_{0k}\) は入力データの\(x\)の最小値から最大値までの範囲で等間隔にnG個配置され、wG はコマンドライン引数で指定またはデフォルト値が使用されます。

2. リッジ回帰

通常の最小二乗法では、残差二乗和 \(\sum_{i=1}^{N} (y_i - y(x_i))^2\) を最小化します。リッジ回帰では、この目的関数に係数の二乗和に比例する正則化項(Ridge penalty)を追加します。これにより、係数が極端に大きな値をとることを防ぎ、モデルの複雑さを抑制し、過学習を軽減します。

最小化する目的関数 \(E(\mathbf{c})\) は次のようになります。

\[ E(\mathbf{c}) = \sum_{i=1}^{N} \left(y_i - \sum_{k=0}^{M-1} c_k f_k(x_i)\right)^2 + \lambda \sum_{k=0}^{M-1} c_k^2 \]

ここで、\(N\) はデータ点の総数、\(M\) はガウス基底関数の数 (nG)、\(\lambda\) はリッジパラメータ (lmda) です。\(\lambda \ge 0\) であり、\(\lambda = 0\) の場合は通常の最小二乗法に帰着します。

3. 正規方程式と解法

目的関数 \(E(\mathbf{c})\) を各係数 \(c_k\) で偏微分し、0 と置くことで、係数ベクトル \(\mathbf{c}\) を求めるための正規方程式が得られます。この正規方程式は行列形式で次のように表すことができます。

\[ (\mathbf{F}^T \mathbf{F} + \lambda \mathbf{I}) \mathbf{c} = \mathbf{F}^T \mathbf{y} \]

ここで、

  • \(\mathbf{c}\) は係数ベクトル \((c_0, c_1, \ldots, c_{M-1})^T\)

  • \(\mathbf{y}\) は観測値ベクトル \((y_0, y_1, \ldots, y_{N-1})^T\)

  • \(\mathbf{F}\)\(N \times M\) のデザイン行列で、その要素は \(\mathbf{F}_{ik} = f_k(x_i)\)

  • \(\mathbf{I}\)\(M \times M\) の単位行列。

  • \(\mathbf{F}^T\)\(\mathbf{F}\) の転置行列。

プログラムでは、Sij 行列が \((\mathbf{F}^T \mathbf{F} + \lambda \mathbf{I})\) に対応し、Si ベクトルが \(\mathbf{F}^T \mathbf{y}\) に対応します。係数 \(\mathbf{c}\) は、この正規方程式を解くことで得られます。

\[ \mathbf{c} = (\mathbf{F}^T \mathbf{F} + \lambda \mathbf{I})^{-1} \mathbf{F}^T \mathbf{y} \]

これは np.linalg.inv(Sij) @ Si というNumPyの行列演算によって計算されます。

必要な非標準ライブラリとインストール方法

Ridge-Gauusian.py の実行には、以下のPython非標準ライブラリが必要です。

  • numpy: 数値計算、特に配列操作や線形代数計算(行列の逆行列計算など)に使用されます。

  • openpyxl: Excelファイル (.xlsx) の読み書きに使用されます。pandas がExcelファイルを読み込む際に内部的に利用します。

  • pandas: データ構造(DataFrame)を提供し、Excelファイルからのデータ読み込みを容易にします。

  • matplotlib: データのプロットおよびフィッティング結果の可視化に使用されます。

これらのライブラリは、Pythonのパッケージインストーラ pip を使ってインストールできます。コマンドプロンプトやターミナルで以下のコマンドを実行してください。

pip install numpy openpyxl pandas matplotlib

必要な入力ファイル

プログラムはExcelファイル (.xlsx) を入力として期待します。

  • ファイル名: デフォルトでは random-poly-Gauss.xlsx ですが、コマンドライン引数で別のファイル名を指定できます。

  • ファイル形式: .xlsx 拡張子のExcelファイル。

  • データ構造:

    • データはシートの最初の2列に配置されている必要があります。

    • 1列目が独立変数 \(x\) のデータ、2列目が従属変数 \(y\) のデータです。

    • Excelシートにはヘッダー行(列のラベル)が存在する必要があります。プログラムはこれらのラベルを df.columns.to_list() で取得し、df[labels[0]]df[labels[1]] を使ってデータを参照します。

入力ファイルの例:

x_data

y_data

0.0

1.0

0.1

1.1

0.2

1.3

...

...

生成される出力ファイル

Ridge-Gauusian.py は、実行によって明示的な出力ファイルを生成しません

しかし、プログラムの実行中に以下の情報が標準出力(コンソール)に表示され、またグラフウィンドウが表示されます。

  1. コンソール出力:

    • 使用される入力ファイル名、ガウス基底関数の数 (nG)、ガウス関数の幅 (wG)、リッジパラメータ (lmda)。

    • リッジ回帰の計算に使用された「Vector and Matrix」として、正規方程式の Si ベクトルと Sij 行列が表示されます。

    • フィッティングによって求められた各ガウス関数の中心 x0[i] と、対応する係数 c[i] のリスト。

    • プログラム終了時に「Press ENTER to terminate」と表示され、Enterキーが押されるまでグラフウィンドウは閉じません。

  2. グラフウィンドウ:

    • matplotlibによって生成されるグラフィカルなウィンドウが表示されます。このウィンドウには、以下の2つのサブプロットが含まれます。

      • 左側のプロット: 入力データ点(マーカー 'o')と、リッジ回帰によってフィッティングされた曲線(実線)が表示されます。これにより、モデルがデータにどの程度適合しているかを視覚的に確認できます。

      • 右側のプロット: 各ガウス基底関数のインデックス i と、それに対応するフィッティング係数 \(c_i\) の値がプロットされます。これにより、どの基底関数がモデルに大きく寄与しているか、またリッジ正則化が係数にどのような影響を与えているかを評価できます。

コマンドラインでの使用例 (Usage)

Ridge-Gauusian.py は、以下の形式でコマンドラインから実行できます。いくつかのパラメータはオプションであり、指定しない場合はデフォルト値が使用されます。

python Ridge-Gauusian.py [infile] [nG] [wG] [lmda]
  • [infile]: (オプション) 入力Excelファイルの名前(例: my_data.xlsx)。.xlsx 形式である必要があります。省略された場合、デフォルトの random-poly-Gauss.xlsx が使用されます。

  • [nG]: (オプション) 使用するガウス基底関数の数。整数値で指定します。省略された場合、デフォルトの 51 が使用されます。

  • [wG]: (オプション) 各ガウス基底関数の幅。浮動小数点数で指定します。省略された場合、デフォルトの 0.3 が使用されます。

  • [lmda]: (オプション) リッジ正則化パラメータ \(\lambda\)。浮動小数点数で指定します。省略された場合、デフォルトの 0.0(通常の最小二乗法に相当)が使用されます。

コマンドラインでの具体的な使用例

例1: デフォルト引数を使用して実行

入力ファイルとして random-poly-Gauss.xlsx がカレントディレクトリにあると仮定し、他のパラメータもデフォルト値を使用する場合。

python Ridge-Gauusian.py

実行結果の説明: プログラムは、デフォルトの入力ファイル random-poly-Gauss.xlsx からデータを読み込みます。ガウス基底関数は51個、各ガウス関数の幅は0.3、リッジ正則化パラメータは0.0(つまり通常の最小二乗法)としてフィッティングが実行されます。 コンソールには、次のような情報が出力されます。

Ridge Gaussian regression
infile=random-poly-Gauss.xlsx
nGauss=51
  width=0.3
Ridge lambda=0.0

Read [random-poly-Gauss.xlsx]

Execute linear least-squares method
Vector and Matrix:
Si=
[[...]]  # 計算されたSiベクトル
Sij=
[[...]]  # 計算されたSij行列

 x0[0]=  ...: c[0]=  ...
 ...
 x0[50]=  ...: c[50]=  ...

Press ENTER to terminate

同時に、matplotlibによるグラフウィンドウが表示され、左側に元のデータ点とフィッティング曲線、右側に各係数\(c_i\)の値がプロットされます。

例2: カスタム引数を使用して実行

my_data.xlsx という独自の入力ファイルを使い、ガウス基底関数の数を20個、幅を0.1、リッジ正則化パラメータを0.001に設定して実行する場合。

python Ridge-Gauusian.py my_data.xlsx 20 0.1 0.001

実行結果の説明: プログラムは、指定された my_data.xlsx ファイルからデータを読み込みます。ガウス基底関数を20個使用し、その幅は0.1と設定されます。リッジ正則化パラメータは0.001に設定されるため、係数が極端に大きな値になることが抑制され、より滑らかなフィッティング結果が期待されます。 コンソールには、指定された引数の値が反映された上で、例1と同様の計算詳細(Si ベクトルと Sij 行列)および各ガウス関数の中心とフィッティング係数が出力されます。

Ridge Gaussian regression
infile=my_data.xlsx
nGauss=20
  width=0.1
Ridge lambda=0.001

Read [my_data.xlsx]

Execute linear least-squares method
Vector and Matrix:
Si=
[[...]]  # 計算されたSiベクトル
Sij=
[[...]]  # 計算されたSij行列

 x0[0]=  ...: c[0]=  ...
 ...
 x0[19]=  ...: c[19]=  ...

Press ENTER to terminate

その後、matplotlibによるグラフウィンドウが表示され、my_data.xlsx のデータと、設定されたパラメータでフィッティングされた曲線および係数がプロットされます。リッジパラメータが非ゼロであるため、右側の係数プロットでは、係数の変動が0.0の場合に比べて抑えられていることが確認できます。