smoothing.py 技術ドキュメント
プログラムの動作
smoothing.py は、測定データに含まれるノイズを除去し、データのトレンドを抽出、あるいはその微分を計算するためのPythonプログラムです。主にExcelファイルからデータセットを読み込み、指定されたX-Yデータに対して様々な平滑化手法を適用します。
主な機能:
データ入力: Excelファイル(.xlsxまたは.xlsm)から複数の列を持つデータを読み込みます。
データ選択とフィルタリング: ユーザーがX軸とY軸に対応する列を指定し、さらにX軸の範囲(最小値、最大値)でデータをフィルタリングできます。
平滑化手法:
単純移動平均: 指定されたウィンドウサイズ内のデータの平均値で平滑化します。
Savitzky-Golayフィルター: 指定されたウィンドウサイズと多項式次数に基づいてデータを平滑化します。これは、データの形状を比較的保ちながらノイズを除去するのに優れています。
微分計算: Savitzky-Golayフィルターを使用する場合、データの1次、2次、またはそれ以上の高次微分を計算できます。これにより、データの変化率や曲率を分析することが可能です。
リサンプリング: 平滑化後のデータを、指定されたステップでリサンプリングし、均一な間隔のデータセットを生成できます。
結果の可視化: 平滑化されたデータおよび元のデータをグラフとして表示します。
データ出力: 処理されたデータを新しいExcelファイル(.xlsm)に保存します。
テストモード: 複数の平滑化条件を一度に適用し、結果を比較するテストモードを備えています。
解決する課題:
科学実験や工学的測定で得られる生データには、多くの場合ノイズが含まれています。このノイズは、データの解釈を困難にし、正確な分析を妨げます。smoothing.py は、これらのノイズを効果的に除去し、データの根底にあるトレンドや構造を明らかにすることで、より信頼性の高いデータ分析を可能にします。また、データの微分を計算することで、ピーク位置の検出や変化点の特定など、データの詳細な特性を評価する手助けをします。
原理
smoothing.py で使用される主な平滑化および微分アルゴリズムは以下の通りです。
単純移動平均 (Simple Moving Average)
この方法は、各データポイントを、その前後を含む指定されたウィンドウ内のデータポイントの算術平均に置き換えることで平滑化を行います。ウィンドウサイズ
nsmoothが大きいほど、より強力な平滑化効果が得られますが、データの局所的な詳細が失われる可能性もあります。 プログラムではnumpy.convolve関数を用いて実装されています。平滑化された点 \(y_s[i]\) は以下の式で計算されます。
\[ y_s[i] = \frac{1}{N} \sum_{k=i-m}^{i+m} y[k] \]ここで、\(N\) はウィンドウサイズ (
nsmooth) で、\(m = \lfloor N/2 \rfloor\) です。注意: 本プログラムでは、単純移動平均による微分は実装されていません。
Savitzky-Golayフィルター (Polynomial Fit)
Savitzky-Golayフィルターは、指定されたウィンドウサイズ
nsmooth内のデータポイントを、指定された多項式次数norderで最小二乗フィッティングし、フィッティングされた多項式の中央の値(またはその微分値)を新しいデータポイントとして採用する平滑化手法です。このフィルターは、データの形状、特にピークの高さや幅を比較的よく保ちながらノイズを除去できるという利点があります。プログラムでは
scipy.signal.savgol_filter関数を用いて実装されています。 このフィルターは、平滑化だけでなく、データの微分も同時に計算できます。ndifferentialパラメータで微分の次数を指定します。微分値のスケーリング:
scipy.signal.savgol_filterが返す微分値は、サンプリング間隔が1であると仮定して計算されます。したがって、実際のX軸のサンプリング間隔が1でない場合、適切なスケーリングが必要です。本プログラムでは、以下の式で微分値を補正しています。\[ y_{diff}[i] = \frac{y_{savgol\_diff}[i]}{(\Delta x)^{\text{ndifferential}}} \]ここで、\(y_{diff}[i]\) は補正後の微分値、\(y_{savgol\_diff}[i]\) は
savgol_filterが返した微分値、\(\Delta x = x[1] - x[0]\) はX軸のサンプリング間隔、\(\text{ndifferential}\) は微分の次数です。リサンプリング (Resampling)
平滑化されたデータは、
numpy.interp関数を使用して線形補間によりリサンプリングされます。これは、平滑化後のデータを均一なX軸間隔 (sampling_step) で再生成したい場合に有用です。
必要な非標準ライブラリとインストール方法
smoothing.py の実行には、以下の非標準ライブラリが必要です。pip コマンドを使用してインストールできます。
numpy: 数値計算を効率的に行うためのライブラリ。
pip install numpy
pandas: データ構造とデータ分析ツールを提供するライブラリ。
pip install pandas
scipy: 科学技術計算のためのライブラリ。特に
scipy.signal.savgol_filterを使用します。pip install scipy
matplotlib: データの可視化(グラフ描画)を行うためのライブラリ。
pip install matplotlib
tklib:
smoothing.pyの基盤となるユーティリティ関数やアプリケーションフレームワークを提供するカスタムライブラリです。pip install tklib
注記:
tklibは一般的なPythonパッケージリポジトリ(PyPI)に公開されていない可能性があります。もし上記のpip installコマンドでエラーが発生する場合は、tklibが別途提供されるカスタムライブラリであるため、その入手元からインストールまたはパスの設定が必要になります。
必要な入力ファイル
プログラムは、平滑化するデータを含むExcelファイル(.xlsx または .xlsm)を必要とします。
ファイル形式:
.xlsxまたは.xlsmデータ構造:
データは複数の列で構成されている必要があります。
X軸データとY軸データに対応する列が存在しなければなりません。これらの列は、ヘッダー名または0から始まる列インデックスで指定されます。
Excelファイルにシートが複数ある場合、
tklib.tkVariousDataは最初のシートを読み込むと想定されます。
デフォルトファイル名: コマンドライン引数で指定されない場合、デフォルトで
xrd.xlsxというファイル名が期待されます。
例:
以下のようなデータを含むExcelファイル xrd.xlsx を想定します。
Angle (deg) |
Intensity (counts) |
Temp (C) |
|---|---|---|
10.0 |
100 |
25 |
10.1 |
105 |
25 |
10.2 |
102 |
25 |
... |
... |
... |
この場合、xlabel には 'Angle (deg)' または 0 を、ylabel には 'Intensity (counts)' または 1 を指定することになります。
生成される出力ファイル
プログラムは、処理結果を以下の形式で出力します。
出力データファイル (Excel)
ファイル名: 入力ファイル名に基づき、平滑化方法、ウィンドウサイズ、多項式次数、微分の次数を示す情報が追加された
.xlsm形式のファイルが生成されます。平滑化のみの場合 (微分なし、
ndifferential=0):例:
inputfile-simple-11p-order2-smoothed.xlsm例:
inputfile-polynomial-11p-smoothed.xlsm
微分を含む場合 (
ndifferential > 0):例:
inputfile-simple-11p-order2-smoothed-1-diff.xlsm例:
inputfile-polynomial-11p-smoothed-1-diff.xlsm
{dirname}は元のファイルのディレクトリ名。{filebody}は元のファイル名から拡張子を除いた部分。methodはsimpleまたはpolynomial。nsmoothは平滑化に使用する点数。norderは多項式フィットの次数(simpleの場合は固定値として表現される)。ndifferentialは微分の次数。
内容: 生成されるExcelファイルには、以下の列が含まれます。
x: 入力Xデータy(input): 入力Yデータy(smoothen): 平滑化されたYデータ(または微分値)x(resampled): リサンプリングが有効な場合に生成されるXデータy(resampled): リサンプリングが有効な場合に生成されるYデータ
ログファイル (テキスト)
ファイル名: 入力ファイル名と同じベース名で、拡張子が
.logに置き換えられたテキストファイルが生成されます。例:
xrd.xlsxを入力とした場合、xrd.logが生成されます。
内容: プログラムの標準出力(処理開始メッセージ、パラメータ、処理中のメッセージ、処理結果のテーブル表示など)がこのファイルにリダイレクトされて保存されます。
コマンドラインでの使用例 (Usage)
smoothing.py は、コマンドライン引数で動作モードや平滑化パラメータを指定して実行します。
python smoothing.py <mode> <infile> [xmin] [xmax] [xlabel] [ylabel] [method] [norder] [nsmooth] [nincrement] [ndifferential] [do_resampling] [sampling_step]
引数の説明:
<mode>(必須): プログラムの動作モード。test: 複数の異なる平滑化条件(単純移動平均とSavitzky-Golayフィルター)を一度に適用し、結果をグラフで比較表示します。データファイルは保存されません。plot: 指定された単一の平滑化条件を適用し、結果をグラフ表示するとともに、新しいExcelファイルに保存します。
<infile>(必須): 入力Excelファイルへのパス(例:xrd.xlsx)。[xmin](オプション): X軸データの最小値。この値より小さいXデータは無視されます。デフォルトはすべてのデータ。[xmax](オプション): X軸データの最大値。この値より大きいXデータは無視されます。デフォルトはすべてのデータ。[xlabel](オプション): X軸データが含まれる列のヘッダー名または0から始まる列インデックス。デフォルトは0。[ylabel](オプション): Y軸データが含まれる列のヘッダー名または0から始まる列インデックス。デフォルトは1。[method](オプション): 平滑化の方法。simple(単純移動平均) またはpolynomial(Savitzky-Golayフィルター)。testモードでは内部で複数の方法が試されるため、この引数はplotモードでのみ有効です。[norder](オプション):methodがpolynomialの場合の多項式次数。デフォルトは2。nsmoothより小さくなければなりません。[nsmooth](オプション): 平滑化に使用するウィンドウサイズ(点数)。奇数を指定する必要があります。デフォルトは11。[nincrement](オプション):testモードでnsmoothを増やす際の増分値。デフォルトは10。[ndifferential](オプション): 微分の次数。0で平滑化のみ、1で1次微分、2で2次微分など。methodがpolynomialの場合のみ有効です。デフォルトは0。[do_resampling](オプション): リサンプリングを行うかどうかのフラグ。0で行わない、1で行う。デフォルトは0。[sampling_step](オプション): リサンプリングを行う場合のX軸のステップサイズ。デフォルトは0.02。
コマンドラインでの具体的な使用例
ここでは、xrd.xlsx という入力ファイルが存在し、その中に Angle (deg) と Intensity (counts) というヘッダーの列があることを仮定します。
例1: デフォルトパラメータでテストモードを実行
python smoothing.py test xrd.xlsx
説明:
xrd.xlsxを入力ファイルとして、testモードでプログラムを実行します。X軸は最初の列、Y軸は2番目の列として読み込まれます。このモードでは、異なるnsmooth値(11, 21, 31)とnorder値(2, 4)の組み合わせで、単純移動平均とSavitzky-Golayフィルターによる計9種類の平滑化が適用され、その結果が1つのmatplotlibウィンドウに9つのサブプロットとして表示されます。データファイルは保存されません。また、標準出力の内容がxrd.logファイルに保存されます。実行結果:
xrd.logファイルが生成され、実行時の詳細なパラメータと処理結果のテキストが記録されます。Matplotlibのグラフウィンドウが開かれ、9つのサブプロットに元のデータ(プロットはマーカーのみ)と平滑化されたデータ(プロットはライン)が表示されます。各サブプロットのタイトルには、適用された平滑化のパラメータ(点数、方法、多項式次数)が示されます。
例2: 特定の範囲のデータに対してSavitzky-Golayフィルターを適用し、結果を保存
python smoothing.py plot xrd.xlsx 20 50 "Angle (deg)" "Intensity (counts)" polynomial 3 21 0 0
説明:
plotモードでxrd.xlsxを処理します。X軸の範囲を
20から50までに制限します。X軸は
'Angle (deg)'列、Y軸は'Intensity (counts)'列を使用します。平滑化方法として
polynomial(Savitzky-Golayフィルター) を選択します。多項式次数は
3、ウィンドウサイズは21点です。微分は行いません (
ndifferential=0)。リサンプリングも行いません (
do_resampling=0、これはデフォルト値なので省略可能ですが、明示的に含めています)。
実行結果:
xrd.logファイルに実行ログが出力されます。xrd-polynomial-21p-smoothed.xlsmという名前のExcelファイルが生成されます。このファイルには、元のX/Yデータ、および平滑化されたYデータが含まれます。Matplotlibのグラフウィンドウが開かれ、指定された範囲の元のデータと、Savitzky-Golayフィルターで平滑化されたデータが表示されます。
例3: Savitzky-Golayフィルターで1次微分を計算し、リサンプリングして保存
python smoothing.py plot xrd.xlsx * * "Angle (deg)" "Intensity (counts)" polynomial 3 21 0 1 1 0.1
説明:
plotモードでxrd.xlsxを処理します。X軸範囲は全体 (
*) を使用します。X軸は
'Angle (deg)'列、Y軸は'Intensity (counts)'列を使用します。平滑化方法は
polynomialで、多項式次数は3、ウィンドウサイズは21点です。ndifferentialを1に設定し、1次微分を計算します。do_resamplingを1に設定し、リサンプリングを行います。sampling_stepを0.1に設定し、0.1間隔でリサンプリングされたデータを出力します。
実行結果:
xrd.logファイルに実行ログが出力されます。xrd-polynomial-21p-smoothed-1-diff.xlsmという名前のExcelファイルが生成されます。このファイルには、元のX/Yデータ、1次微分されたYデータ、そしてリサンプリングされたX/Yデータが含まれます。Matplotlibのグラフウィンドウが開かれ、元のデータと、1次微分されたデータが表示されます。1次微分データは右Y軸(赤色)で表示され、そのラベルには "First differential" と表示されます。