tkminfit.py 技術ドキュメント

ライブラリの機能や目的

tkminfit.py は、scipy.optimize.minimize をベースとした最小二乗最適化の共通ランナーを提供するPythonライブラリです。既存の tknlsq.nonlinear_lsqscipy.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.ndarray

  • names: 全てのパラメータ名を含むリスト。List[str]

  • free_names: 最適化された自由パラメータ名を含むリスト。List[str]

  • optimized_names: 最適化対象として指定されたパラメータ名を含むリスト (通常は free_names と同じ)。List[str]

  • linear_names: 線形ブロック最適化で扱われた線形パラメータ名を含むリスト。List[str]

  • residuals: 最適化後の残差ベクトル。np.ndarray

  • jacobian: 最適化されたパラメータ点におけるヤコビアン行列 (オプション)。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: 自由度 (データ数 - 自由パラメータ数)。int

  • N: データ数 (残差ベクトルのサイズ)。int

  • p_free: 自由パラメータの数。int

  • RSS: 残差の二乗和 (Residual Sum of Squares)。float

  • objective: 最適化後の目的関数値 (RSS + penalty)。float

  • success: 最適化が成功したかを示す真偽値。bool

  • message: 最適化結果に関するメッセージ。str

  • nfev: 目的関数評価回数 (オプション)。Optional[int]

  • nit: 反復回数 (オプション)。Optional[int]

  • warning: 警告メッセージ。str

  • raw_result: scipy.optimize.minimize から返された生の最適化結果オブジェクト (reprから除外される)。object

  • linear_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.ndarray

    • cov: 自由パラメータの共分散行列 (推定できない場合は None)。Optional[np.ndarray]

    • stderr_free: 自由パラメータの標準誤差ベクトル (推定できない場合は None)。Optional[np.ndarray]

    • stderr: 全パラメータの標準誤差を格納する辞書。Dict[str, Optional[float]]

    • sigma2: 残差の分散 \(\sigma^2\) (推定できない場合は None)。Optional[float]

    • dof: 自由度。int

    • warning: 警告メッセージ。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スクリプトやアプリケーションからインポートされて利用されることを想定しています。