ノイズフィルター
センサーの測定値とノイズ
IoT環境で収集する値は、いずれもセンサーで測定したデータです。すべてのセンサーには一定のノイズが不可避的に含まれます。理論上、完全にノイズのないデータは数学的に生成した仮想データだけです。以下の例は、ノイズのない純粋な信号を表します。

| |
FAKE(arrange(1,5,0.03))
MAPVALUE(0, round(value(0)*100)/100)
SET(sig, sin(1.2 * 2 * PI * value(0)) )
MAPVALUE(1, $sig)
CHART(
size("600px", "400px"),
chartOption({
xAxis:{ type: "category", data: column(0)},
yAxis:{ max:1.5, min:-1.5 },
series:[
{ type: "line", data: column(1), name:"value" },
],
legend: { bottom: 10 },
})
)一般に、除去したいノイズは観測対象の信号より高い周波数を持ちます。

| |
FAKE(arrange(1,5,0.03))
MAPVALUE(0, round(value(0)*100)/100)
SET(sig, sin(1.2*2*PI*value(0)) )
SET(noise, 0.09*cos(9*2*PI*value(0)) + 0.15*sin(12*2*PI*value(0)))
MAPVALUE(1, $sig)
MAPVALUE(2, $noise)
CHART(
size("600px", "400px"),
chartOption({
xAxis:{ type: "category", data: column(0)},
yAxis:{ max:1.5, min:-1.5 },
series:[
{ type: "line", data: column(1), name:"value" },
{ type: "line", data: column(2), name:"noise" },
],
legend: { bottom: 10 }
})
)実際のセンサーの測定値には、上記のようにノイズが混ざります。分析では、このノイズを除去して信号を観察します。

SCRIPT({
x = []; y = [];
for (i = 1.0; i <= 5.0; i+=0.03) {
val = Math.round(i*100)/100;
sig = Math.sin( 1.2*2*Math.PI*val );
noise = 0.09 * Math.cos(9*2*Math.PI*val) +
0.15 * Math.sin(12*2*Math.PI*val);
x.push( val );
y.push( sig+noise );
}
$.yield({
xAxis:{ type: "category", data: x},
yAxis:{ max:1.5, min:-1.5 },
series:[
{ type: "line", data: y, name:"value+noise" },
],
legend: { bottom: 10 },
});
})
CHART(size("600px", "400px"))FAKE(arrange(1,5,0.03))
MAPVALUE(0, round(value(0)*100)/100)
SET(sig, sin(1.2*2*PI*value(0)) )
SET(noise, 0.09*cos(9*2*PI*value(0)) + 0.15*sin(12*2*PI*value(0)))
MAPVALUE(1, $sig + $noise)
CHART(
size("600px", "400px"),
chartOption({
xAxis:{ type: "category", data: column(0)},
yAxis:{ max:1.5, min:-1.5 },
series:[
{ type: "line", data: column(1), name:"value+noise" },
],
legend: { bottom: 10 }
})
)平均フィルター
センサーのゼロ点校正(zero-point calibration)のように、連続する値の平均を取るとノイズを低減できます。以下は単純平均を適用した例です。

| |
FAKE(arrange(1,5,0.03))
MAPVALUE(0, round(value(0)*100)/100)
SET(sig, sin(1.2*2*PI*value(0)) )
SET(noise, 0.09*cos(9*2*PI*value(0)) + 0.15*sin(12*2*PI*value(0)))
MAPVALUE(1, $sig + $noise)
MAP_AVG(2, value(1))
CHART(
size("600px", "400px"),
chartOption({
xAxis:{ type: "category", data: column(0)},
yAxis:{ max:1.5, min:-1.5 },
series:[
{ type: "line", data: column(1), name:"value+noise" },
{ type: "line", data: column(2), name:"AVG" },
],
legend: { bottom: 10 }
})
)移動平均
蓄積した全サンプルの平均を計算する代わりに、固定サイズのサンプル区間(ウィンドウ)内で平均を計算します。株価チャートでよく使うn日移動平均と同じ考え方です。

| |
| |
ローパスフィルター
移動平均は扱いやすく理解も容易ですが、いくつかの制約があります。
ウィンドウ内のすべてのサンプルに同じ重みを適用するため、最新の傾向を反映するまでに時間がかかる場合があります。 また、値が大きく変化する区間への応答が比較的鈍くなります。 これを補うため、平均の計算時にウィンドウ内の新しい値と古い値に異なる重みを付ける方法がよく使われます。

| |
| |
カルマンフィルター
MAP_KALMAN() 関数の model() 引数は、数学的なシステム変数を表す入力値を受け取ります。最適なシステム値の決定方法は、この文書の対象外です。
ただし、TQLで簡単なカルマンフィルターモデルを適用し、試行を繰り返して経験的に最適なパラメーターを探すことは容易です。
以下の例は、model の値の変化がグラフに与える影響を示します。
さまざまな model 値を適用し、グラフの変化を確認してください。

| |
| |
最終更新日