はじめに
データサイエンス系のアプリケーションエンジニアとして働いています@mtaguchiです。
エンジニアにも関わらず数学はちょっと苦手な方なので、前回同様、記事を書きながら勉強していきたいと思います。
万人ウケするネタは少なめかもしれませんが、主に備忘録的に書いていきますので応援のLGTMを頂けると嬉しいです。
百聞は一見に如かずでShape Factorについて学びます
今日は、予知保全用のツールであるPredictive Maintenance Toolboxで、試しにとある時系列データの分類問題を解こうとしていた(といいますか生波形の特徴を確認しようとしていた)ときに、Shape Factorの値が2値分類の特徴量としてふさわしそうだったので、Shape Factorの意味について調べてみました。ここではPredictive Maintenance Toolboxの詳細については割愛しますが、詳細は一応こちらからリンクに飛んで頂くことができます。
Shape Factorとは
日本語では波形率ともよばれたりしています。Shape Factorの計算式は下記で
\frac{V_{rms}}{\mu}
時系列の信号が下記の場合、
\newcommand{\vect}[1]{\boldsymbol{#1}}
\vect{X} = \{X_1, X_2, ... , X_N\}
それぞれ以下のように定義されます。
V_{rms} = \sqrt{\frac{1}{N}\sum^N_{n=1}X_{n}^2}\\
\mu = \sum^N_{n=1}|X_{n}|
少しだけ補足
なぜ最初にわざわざPredictive Maintenance Toolboxの名前を出したのかというと、Predictive Maintenance Toolboxでは新しめのバージョンではMATLABコードの自動生成に対応していて、Shape Factorの計算式を見ることができたからです。何のことやらと言う場合は読み飛ばして頂いて結構です。ただ、自動生成されたコードによるとShape Factorの計算スクリプトが下記のようになっていたので、Shape Factorの式はここからもダブルチェックしましたよ、というお話でした。
rwave_ShapeFactor = rms(inputSignal,'omitnan')/mean(abs(inputSignal),'omitnan');
※rwaveは自分でつけた変数名です
実際の波形とShape Factorの値を見比べてみましょう
(注)ここからひたすらFigureが続きます。。。。
値が1で一定の波形の場合
式からもわかるように、当然RMS = Mean = Shape Factor = 1ですね。
波形のタイトルの所に3つの値をさりげなく載せていますのでご確認ください。
0付近を基準に概ね-0.5~0.5の間で値がランダムに上下する場合
RMSとMeanが近い値を取るので、Shape Factorも1に近い値になってますね。
概ね振幅が0.5で、1点だけ外れ値のような大きな値を取る場合
外れ値の2乗が効いているのか、Shape Factorの値がかなり大きくなりました。
外れ値が2点の場合は、1点の場合よりもShape Factorの値が大きくなりました
外れ値が3点の場合は、2点の場合よりもShape Factorの値が大きくなりました
振幅1のサインカーブ
振幅1のサインカーブに1の直流成分が乗っている場合
直流成分が乗っていない場合よりもShape Factorが大きくなりました
振幅1のサインカーブに100の直流成分が乗っている場合
ここまでくるとRMSとMeanの差がほぼなくなり、Shape Factorが1になりましたね。
考察
今回、時系列データの2値分類にShape Factorが良さそうということで検証を始めましたが、直流成分の有無もしくは大きさ、か外れ値的な大きな値の有無が関係しているのかもしれない...という気がしてきました。こういう波形になるという裏付けとなる何かがあれば大発見なのでしょうが、ただの外れ値だったらショックですね。データサイエンスにおける前処理の大切さを再確認しました。
ちなみに、私のこちらの記事よりも、もっと沢山の波形における波形率をまとめてくださっているサイト[1]もありますので、一番最後に参考文献として掲載させて頂きます。
スクリプト
今回使用したスクリプトも一応載せておきます。wav
に任意の時系列データを入れました。
wavrms = rms(wav);
wavabs = abs(wav);
wavmean = mean(wavabs);
wavsf = wavrms/wavmean;
figure;
plot(wav);
str = ['RMS = ' num2str(wavrms) ', Mean = ' num2str(wavmean) ', ShapeFactor = ' num2str(wavsf)];
title(str);
最後に
前回の記事では、脳波系のデータサイエンスを頑張ると宣言しましたが、早々に今回はあまり関係のないネタになってしまいました。
しかしながら、時系列データ解析という点では共通部分がありますので、どこかしらで良き交点が見つかると嬉しいです。引き続き、もろもろ数学的な紐解きも頑張ってみたいと思いますので、応援のLGTMを頂けると嬉しいです。