tkminfit.py 技術ドキュメント
ライブラリの機能や目的
tkminfit.py は、scipy.optimize.minimize をベースとした最小二乗最適化の共通ランナーを提供するPythonライブラリです。既存の tknlsq.nonlinear_lsq が scipy.optimize.least_squares を利用するのに対し、このモジュールはNelder-Meadなどの minimize 系メソッドを使用したいアプリケーション向けに、薄い共通層を提供します。
主な用途は以下の通りです。
非線形パラメータ最適化:
optid=1とマークされた非線形パラメータを最適化します。線形ブロック最適化:
optid_lin=1とマークされた線形パラメータブロックを最適化します。Variable Projection (変数射影): 非線形パラメータごとに線形パラメータを内部で線形最小二乗法により解く手法を実装しています。
共分散と標準誤差の推定: 数値ヤコビアンを計算し、そこから最適化されたパラメータの共分散行列と標準誤差を推定します。
このライブラリは、複雑なモデルのパラメータフィッティングにおいて、柔軟な最適化手法の選択と、結果の統計的評価を支援することを目的としています。
importする方法
このライブラリをPythonプログラムから利用するには、次のようにインポートします。
import tkminfit
特定の関数やクラスのみをインポートする場合は、以下のように記述します。
from tkminfit import minimize_lsq, variable_projection_lsq, MinimizeLSQResult
必要な非標準ライブラリとインストール方法
tkminfit.py は、以下の非標準ライブラリに依存しています。
NumPy: 数値計算(配列操作、線形代数など)に広く使用されます。
SciPy: 科学技術計算ライブラリ。特に
scipy.optimize.minimizeが必要です。tklsq: このライブラリは
tklsqモジュールのサブモジュールとして開発されており、tklsq.tklsq,tklsq.tkparamio,tklsq.tknlsqの各モジュールに依存します。
NumPyとSciPyは、Pythonのパッケージマネージャーである pip を使ってインストールできます。
pip install numpy scipy
tklsq モジュール群は、通常、tkminfit.py と同じプロジェクト内で提供されるか、別途インストールが必要です。もし tklsq が独立したパッケージとして提供されている場合は、同様に pip でインストールします。
pip install tklsq # 必要に応じて
importできる変数と関数
型エイリアス
ArrayLike説明:
Sequence[float]またはnp.ndarrayを許容する型エイリアス。浮動小数点数のシーケンスまたはNumPy配列を受け入れることを示します。
ParamValues説明:
Dict[str, float]を許容する型エイリアス。パラメータ名をキー、浮動小数点数値を値とする辞書を示します。
クラス
MinimizeLSQResult
minimize ベースの最小二乗最適化の結果を格納するデータクラスです。
フィールド:
params: 最適化後の全パラメータと値を含む辞書。Dict[str, float]params_free: 最適化された自由パラメータの値のみを含むNumPy配列。np.ndarraynames: 全てのパラメータ名を含むリスト。List[str]free_names: 最適化された自由パラメータ名を含むリスト。List[str]optimized_names: 最適化対象として指定されたパラメータ名を含むリスト (通常はfree_namesと同じ)。List[str]linear_names: 線形ブロック最適化で扱われた線形パラメータ名を含むリスト。List[str]residuals: 最適化後の残差ベクトル。np.ndarrayjacobian: 最適化されたパラメータ点におけるヤコビアン行列 (オプション)。Optional[np.ndarray]cov_free: 自由パラメータの共分散行列 (オプション)。Optional[np.ndarray]stderr_free: 自由パラメータの標準誤差ベクトル (オプション)。Optional[np.ndarray]stderr: 全パラメータの標準誤差を格納する辞書 (自由パラメータのみ値が入る)。Dict[str, Optional[float]]sigma2_resid: 残差の分散 \(\sigma^2\) (オプション)。Optional[float]dof: 自由度 (データ数 - 自由パラメータ数)。intN: データ数 (残差ベクトルのサイズ)。intp_free: 自由パラメータの数。intRSS: 残差の二乗和 (Residual Sum of Squares)。floatobjective: 最適化後の目的関数値 (RSS + penalty)。floatsuccess: 最適化が成功したかを示す真偽値。boolmessage: 最適化結果に関するメッセージ。strnfev: 目的関数評価回数 (オプション)。Optional[int]nit: 反復回数 (オプション)。Optional[int]warning: 警告メッセージ。strraw_result:scipy.optimize.minimizeから返された生の最適化結果オブジェクト (reprから除外される)。objectlinear_result:solve_linear_blockから返された線形最適化結果オブジェクト (Variable Projection時のみ、reprから除外される)。object
プロパティ:
sigma_resid: 残差の標準偏差 \(\sigma\) (オプション)。sigma2_residが None でない場合、\(\sqrt{\max(\text{sigma2\_resid}, 0.0)}\) を返します。Optional[float]
関数
pack_values(values: Mapping[str, float], names: Sequence[str]) -> np.ndarray
動作: 指定された名前のリストに従って、辞書形式のパラメータ値をNumPy配列に変換します。これにより、最適化ルーチンに渡すためのベクトル形式にパックされます。
引数:
values: パラメータ名とその値を含む辞書。names: NumPy配列にパックするパラメータ名の順序付けられたシーケンス。
戻り値: 指定された名前の順序で値が格納された
np.ndarray。
unpack_values(p_free: ArrayLike, base_values: Mapping[str, float], free_names: Sequence[str]) -> Dict[str, float]
動作: 自由パラメータのベクトル
p_freeと、元の全パラメータのベース値base_valuesを使用して、更新された全パラメータ値の辞書を再構築します。p_freeの値がfree_namesに対応するパラメータに適用されます。引数:
p_free: 自由パラメータの値を格納したNumPy配列またはシーケンス。base_values: 全てのパラメータの初期値または固定値を含む辞書。free_names:p_freeの値が対応する自由パラメータ名のシーケンス。
戻り値: 更新された全パラメータ名とその値を含む辞書。
Dict[str, float]
residuals_to_objective(residuals: ArrayLike, *, penalty: float = 0.0) -> float
動作: 残差ベクトルから目的関数値(残差の二乗和 RSS とオプションのペナルティの合計)を計算します。残差が非有限値(NaN, Inf)の場合、その要素は大きな値 (\(1.0 \times 10^{100}\)) に置き換えられます。
引数:
residuals: 残差を含むNumPy配列またはシーケンス。penalty: 目的関数に加算するペナルティ値。デフォルトは \(0.0\)。
戻り値: 計算された目的関数値 (\(RSS + \text{penalty}\))。
float
solve_linear_block(y: ArrayLike, params: Mapping[str, Mapping[str, object]], p_current: Mapping[str, float], design_matrix_func: Callable[[Mapping[str, float], Sequence[str]], np.ndarray], *, lin_names: Optional[Sequence[str]] = None, weights: Optional[ArrayLike] = None) -> Tuple[Dict[str, float], object]
動作: 現在の非線形パラメータのもとで、線形パラメータを線形最小二乗法で解きます。これはVariable Projection法の一部として使用されます。
design_matrix_funcは、現在のパラメータと線形パラメータ名に基づいて計画行列Xを生成する関数です。引数:
y: 観測データ (従属変数)。params: パラメータ情報を含む辞書 (例:tkparamio.read_param_csv()の戻り値)。p_current: 現在の全パラメータ値を含む辞書。design_matrix_func: 現在のパラメータと線形パラメータ名を受け取り、計画行列Xを返す関数。シグネチャ例:
def design_matrix_func(p: Dict[str, float], lin_names: Sequence[str]) -> np.ndarray:
lin_names: 線形ブロックのパラメータ名のシーケンス (オプション)。指定しない場合、tkparamio.linear_param_names()から取得されます。weights: 重み付き最小二乗に使用する重みベクトル (オプション)。
戻り値:
p_new: 線形パラメータが更新された全パラメータ値の辞書。Dict[str, float]linear_result: 線形最小二乗の結果オブジェクト (例:tklsq.tklsq.LinearLSQResult)。object
estimate_covariance_for_params(residual_func: Callable[[Mapping[str, float]], ArrayLike], params_fit: Mapping[str, float], free_names: Sequence[str], *, rel_step: float = 1.0e-6, abs_step: float = 1.0e-12) -> Tuple[np.ndarray, Optional[np.ndarray], Optional[np.ndarray], Dict[str, Optional[float]], Optional[float], int, str]
動作: 任意の残差関数
residual_funcと適合済みパラメータparams_fitに基づいて、指定された自由パラメータfree_namesの共分散、標準誤差、残差分散を推定します。これには数値ヤコビアンの計算が含まれます。引数:
residual_func: パラメータ辞書を受け取り、残差ベクトルを返す関数。シグネチャ例:
def residual_func(params_dict: Dict[str, float]) -> ArrayLike:
params_fit: 適合済みパラメータ値を含む辞書。free_names: 共分散を推定する自由パラメータ名のシーケンス。rel_step: 数値ヤコビアン計算の相対ステップサイズ。デフォルトは \(1.0 \times 10^{-6}\)。abs_step: 数値ヤコビアン計算の絶対ステップサイズ。デフォルトは \(1.0 \times 10^{-12}\)。
戻り値:
J: 数値ヤコビアン行列。np.ndarraycov: 自由パラメータの共分散行列 (推定できない場合はNone)。Optional[np.ndarray]stderr_free: 自由パラメータの標準誤差ベクトル (推定できない場合はNone)。Optional[np.ndarray]stderr: 全パラメータの標準誤差を格納する辞書。Dict[str, Optional[float]]sigma2: 残差の分散 \(\sigma^2\) (推定できない場合はNone)。Optional[float]dof: 自由度。intwarning: 警告メッセージ。str
minimize_lsq(residual_func: Callable[[Mapping[str, float]], ArrayLike], params: Mapping[str, Mapping[str, object]], *, free_names: Optional[Sequence[str]] = None, method: str = "Nelder-Mead", use_penalty: bool = True, maxiter: Optional[int] = None, options: Optional[dict] = None, callback: Optional[Callable[[int, Dict[str, float], float], None]] = None, print_interval: int = 0, rel_step: float = 1.0e-6, abs_step: float = 1.0e-12) -> MinimizeLSQResult
動作:
scipy.optimize.minimizeを使用して、残差の二乗和にペナルティを加えた目的関数を最小化します。これは主に非線形パラメータの最適化に使用されます。引数:
residual_func: パラメータ辞書を受け取り、残差ベクトルを返す関数。シグネチャ例:
def residual_func(params_dict: Dict[str, float]) -> ArrayLike:
params: パラメータ情報を含む辞書 (例:tkparamio.read_param_csv()の戻り値)。free_names: 最適化する自由パラメータ名のシーケンス (オプション)。指定しない場合、tkparamio.nonlinear_param_names()から取得されます。method:scipy.optimize.minimizeに渡す最適化メソッド名 (例: "Nelder-Mead", "L-BFGS-B" など)。デフォルトは "Nelder-Mead"。use_penalty: 境界制約ペナルティを目的関数に含めるかどうかの真偽値。デフォルトはTrue。maxiter: 最大反復回数 (オプション)。options引数で指定することもできます。options:scipy.optimize.minimizeに渡すオプション辞書。callback: 各反復後に呼び出されるコールバック関数。シグネチャ例:
def callback(iteration: int, current_params: Dict[str, float], objective_value: float) -> None:
print_interval: 進行状況をコンソールに出力する頻度。\(0\) の場合、出力しません。rel_step: 共分散推定のための数値ヤコビアン計算の相対ステップサイズ。abs_step: 共分散推定のための数値ヤコビアン計算の絶対ステップサイズ。
戻り値: 最適化結果を格納した
MinimizeLSQResultオブジェクト。依存: この関数は
scipyに依存するため、未インストールの場合ImportErrorを発生させます。
variable_projection_lsq(y: ArrayLike, params: Mapping[str, Mapping[str, object]], model_func: Callable[[Mapping[str, float]], ArrayLike], design_matrix_func: Callable[[Mapping[str, float], Sequence[str]], np.ndarray], *, nonlin_names: Optional[Sequence[str]] = None, lin_names: Optional[Sequence[str]] = None, method: str = "Nelder-Mead", use_penalty: bool = True, weights: Optional[ArrayLike] = None, maxiter: Optional[int] = None, options: Optional[dict] = None, callback: Optional[Callable[[int, Dict[str, float], float], None]] = None, print_interval: int = 0, rel_step: float = 1.0e-6, abs_step: float = 1.0e-12) -> MinimizeLSQResult
動作: Variable Projection (変数射影) 法を用いて最小二乗最適化を行います。非線形パラメータの探索中に、線形パラメータを線形最小二乗法で毎回解き、目的関数を評価します。
model_funcは完全なモデルのフィッティング結果を生成し、design_matrix_funcは線形パラメータのための計画行列を生成します。引数:
y: 観測データ (従属変数)。params: パラメータ情報を含む辞書。model_func: パラメータ辞書を受け取り、モデルの予測値ベクトルを返す関数。シグネチャ例:
def model_func(params_dict: Dict[str, float]) -> ArrayLike:
design_matrix_func: 現在のパラメータと線形パラメータ名を受け取り、計画行列Xを返す関数。シグネチャ例:
def design_matrix_func(p: Dict[str, float], lin_names: Sequence[str]) -> np.ndarray:
nonlin_names: 最適化する非線形パラメータ名のシーケンス (オプション)。指定しない場合、tkparamio.nonlinear_param_names()から取得されます。lin_names: 線形ブロックのパラメータ名のシーケンス (オプション)。指定しない場合、tkparamio.linear_param_names()から取得されます。method:scipy.optimize.minimizeに渡す最適化メソッド名。デフォルトは "Nelder-Mead"。use_penalty: 境界制約ペナルティを目的関数に含めるかどうかの真偽値。デフォルトはTrue。weights: 重み付き最小二乗に使用する重みベクトル (オプション)。maxiter: 最大反復回数 (オプション)。options:scipy.optimize.minimizeに渡すオプション辞書。callback: 各反復後に呼び出されるコールバック関数。シグネチャ例:
def callback(iteration: int, current_params: Dict[str, float], objective_value: float) -> None:
print_interval: 進行状況をコンソールに出力する頻度。\(0\) の場合、出力しません。rel_step: 共分散推定のための数値ヤコビアン計算の相対ステップサイズ。abs_step: 共分散推定のための数値ヤコビアン計算の絶対ステップサイズ。
戻り値: 最適化結果を格納した
MinimizeLSQResultオブジェクト。依存: この関数は
scipyに依存するため、未インストールの場合ImportErrorを発生させます。
main scriptとして実行したときの動作
tkminfit.py のソースコードには、if __name__ == "__main__": ブロックが存在しません。
したがって、このライブラリファイルをPythonインタプリタで直接実行しても、特別な動作は定義されていません。
このファイルは他のPythonスクリプトやアプリケーションからインポートされて利用されることを想定しています。