【C++】スムージングとベースライン推定のためのライブラリ「sablib」を公開しました
はじめに
これまで当ブログでは、ノイズを含むデータの平滑化やバックグラウンド(ベースライン)を推定するための各種アルゴリズムを紹介し、C++やPythonで実装してきました。
- Savitzky-Golay法: スペクトルデータのスムージングに広く使われる定番手法
- Whittaker Smoother: ペナルティ付き最小二乗法を用いた強力なスムージング手法
- 単純移動平均法: 単純移動平均を繰り返すことでベースラインを推定する手法
- AsLS法: Whittaker Smootherを応用したベースライン推定手法
- airPLS法 / arPLS法: AsLS法を改良した、より精度の高いベースライン推定手法
これらの手法は、分析化学のデータ処理(スペクトル解析など)において欠かすことができません。ただ、自分で調べてみた範囲ではC++で使えるものは多くないことから、せっかく公開したのなら、まとめてライブラリにしてしまおうと考えました。そうにして作成したものが今回紹介する「sablib」です。
sablibとは
sablibは、C++で使えるスムージングとベースライン推定のアルゴリズムをまとめたライブラリです。線形代数ライブラリ Eigen を使用しており、疎行列を活用することで大量のデータも高速に処理できます。ブログ記事で紹介したコードをベースにしていますが、コードを見直して書き直したところも多いです。なお、ブログで未紹介のアルゴリズムも一部収録しています。
- リポジトリ:Izadori/sablib
- ドキュメント:sablib – smoothing and baseline library
- ライセンス: MIT
必要環境
- C++17以上に対応したコンパイラ
- Eigen 3.4.0以上
- CMake 3.10以上
主な機能
sablibは大きく分けて「平滑化」と「ベースライン推定」の2つの機能を提供します。
1. 平滑化 (Smoothing)
- Savitzky-Golay法
- Whittaker Smoother
- P-Spline: ペナルティ付きBスプライン
- 移動平均: 単純移動平均(SMA)および加重移動平均(WMA)
2. ベースライン推定 (Baseline Estimation)
- 古典的手法: 直線・多項式フィッティングや3次スプライン
- 単純移動平均法
- AsLS法
- airPLS法
- arPLS法
- BEADS法(Baseline Estimation And Denoising using Sparsity): ノイズ除去とベースライン推定を同時にできるアルゴリズム
使い方
sablibのビルド
リポジトリからクローンします。
git clone https://github.com/Izadori/sablib.gitCMakeを使ってビルドします。
cd sablib
mkdir build
cd build
cmake ..
cmake --build .もしEigen3が見つからない場合は、cmake .. -DCMAKE_PREFIX_PATH="/path/to/Eigen3"としてみてください。
導入方法
CMakeプロジェクトであれば、以下のようにして簡単に追加できます。
find_package(Eigen3 REQUIRED) # Eigen 3.4.0以上が必要です
set(SABLIB_DIR "/path/to/sablib")
include_directories(${SABLIB_DIR})
find_library(SABLIB_LIB NAMES sablib libsablib PATHS "${SABLIB_DIR}/build")
target_link_libraries(my_app PRIVATE ${SABLIB_LIB} Eigen3::Eigen)コード例(arPLS法によるベースライン推定)
#include <vector>
#include "sablib/sablib.h"
int main()
{
std::vector<double> signal = { /* 観測データ */ };
// arPLSアルゴリズムでベースラインを推定
// 引数: 信号, 平滑化パラメータlambda
double lambda = 1e5;
std::vector<double> baseline = sablib::BaselineArPLS(signal, lambda);
// 補正後の信号を取得
std::vector<double> corrected(signal.size());
for(size_t i = 0; i < signal.size(); ++i) {
corrected[i] = signal[i] - baseline[i];
}
return 0;
}おわりに
sablibは、まだまだ発展途上のツールです。今後もアルゴリズムの追加や修正などを行っていきます。また、sablibに搭載したアルゴリズムについても当ブログ上で紹介していく予定です。
バグレポートや機能要望、プルリクエストなどは大歓迎です。もし興味を持っていただけたら、ぜひGitHubでスターを付けていただけると励みになります。



ディスカッション
コメント一覧
まだ、コメントがありません