"""
ridge_kernel_gaussian.py
概要:
ガウスカーネルを用いたリッジ回帰を実行し、結果をプロットするスクリプト。
詳細説明:
このスクリプトは、与えられたExcelファイルからデータを読み込み、
ガウスカーネルベースのリッジ回帰モデルを構築します。
カーネルリッジ回帰により係数を計算し、元のデータとフィッティング結果、
および計算された係数をグラフとして表示します。
コマンドライン引数で入力ファイル名、ガウス幅、リッジパラメータを設定できます。
関連リンク:
:doc:`ridge_kernel_gaussian_usage`
"""
import sys
import numpy as np
from numpy import exp
import openpyxl
import pandas as pd
import matplotlib.pyplot as plt
infile = 'random-poly-Gauss.xlsx'
wG = 0.1
lmda = 0.0
xcal0 = None
xcal1 = None
ncal = 101
fontsize = 16
if __name__ == "__main__":
argv = sys.argv
narg = len(argv)
if narg >= 2:
infile = argv[1]
if narg >= 3:
wG = float(argv[2])
if narg >= 4:
lmda = float(argv[3])
[ドキュメント]
def kernel(xi, xj):
"""
概要:
ガウスカーネル関数を計算します。
詳細説明:
2つの入力値 `xi` と `xj` の間のガウスカーネル値を計算します。
ガウス幅 `wG` はグローバル変数として定義されています。
:param xi: float または array-like: カーネル計算のための1つ目のデータ点。
:param xj: float または array-like: カーネル計算のための2つ目のデータ点。
:returns: float または array-like: 計算されたガウスカーネル値。
"""
a = (xi - xj) / wG
return exp(-a**2)
[ドキュメント]
def KernelRidge(x, y, lmda = 0.0):
"""
概要:
カーネルリッジ回帰の係数を計算します。
詳細説明:
与えられたデータ `x` と `y`、およびリッジ正則化パラメータ `lmda` を用いて、
カーネルリッジ回帰モデルの係数 `ci` を計算します。
カーネル行列 `Sij` を構築し、逆行列を計算して係数を導出します。
:param x: numpy.ndarray または pandas.Series: 独立変数(特徴量)のデータ配列。
:param y: numpy.ndarray または pandas.Series: 従属変数(ターゲット)のデータ配列。
:param lmda: float, optional: リッジ正則化の強さを制御するパラメータ (デフォルトは0.0)。
:returns: list[float]: 計算されたモデルの係数 `c_i` のリスト。
"""
n = len(x)
Si = np.empty([n, 1])
Sij = np.empty([n, n])
for i in range(0, n):
Si[i, 0] = y[i]
for j in range(0, n):
for l in range(j, n):
Sij[j, l] = Sij[l, j] = kernel(x[j], x[l])
Sij[j, j] += lmda
print("Vector and Matrix:")
print("Si=")
print(Si)
print("Sij=")
print(Sij)
print("")
ci = np.linalg.inv(Sij) @ Si
ci = ci.transpose().tolist()
return ci[0]
[ドキュメント]
def main():
"""
概要:
カーネルリッジ回帰のメイン処理を実行し、結果をプロットします。
詳細説明:
入力ファイルからデータを読み込み、グローバル変数 `wG` と `lmda` を使用して
カーネルリッジ回帰モデルを構築します。
計算された係数 `ci` を用いて予測値を生成し、元のデータ、
フィッティング曲線、および係数をグラフとして表示します。
ユーザーがEnterキーを押すまでプログラムは待機します。
:returns: None
"""
global wG
print("Ridge Gaussian regression")
print(f"infile={infile}")
print(f"Gaussian width={wG}")
print(f"Ridge lambda={lmda}")
print("")
print(f"Read [{infile}]")
df = pd.read_excel(infile, engine = 'openpyxl')
labels = df.columns.to_list()
x = df[labels[0]]
y = df[labels[1]]
ndata = len(x)
xcal0 = min(x)
xcal1 = max(x)
xcalstep = (xcal1 - xcal0) / (ncal - 1)
print("")
print(f"Execute linear least-squares method")
ci = KernelRidge(x, y, lmda)
for i in range(ndata):
print(f" x0[{i}={x[i]:6.3g}: c[{i}]={ci[i]:6.3g}")
xcal = [xcal0 + i * xcalstep for i in range(ncal)]
ycal = []
for i in range(ncal):
_x = xcal[i]
yl = 0.0
for k in range(ndata):
yl += ci[k] * kernel(_x, x[k])
ycal.append(yl)
#================================================================
# Plot
#================================================================
fig, axes = plt.subplots(1, 2, figsize = (8, 6))
axes[0].plot(x, y, label = 'input', linestyle = '', marker = 'o')
axes[0].plot(xcal, ycal, label = 'fit', linestyle = '-')
axes[0].tick_params(labelsize = fontsize)
axes[0].set_xlabel('$x$', fontsize = fontsize)
axes[0].set_ylabel('$y$', fontsize = fontsize)
axes[0].legend(fontsize = fontsize)
axes[1].plot(x, ci, label = 'coeff', linestyle = '-', linewidth = 0.5, marker = 'o')
axes[1].tick_params(labelsize = fontsize)
axes[1].set_xlabel('$i$', fontsize = fontsize)
axes[1].set_ylabel('$c_i$', fontsize = fontsize)
# axes[1].legend(fontsize = fontsize)
plt.tight_layout()
plt.pause(0.1)
print("")
print("Press ENTER to terminate")
input()
if __name__ == "__main__":
main()