노이즈 필터
센서 측정과 노이즈
IoT 환경에서 수집되는 값은 모두 센서를 통해 측정된 데이터입니다. 모든 센서는 필연적으로 일정 수준의 노이즈(잡음)를 포함하며, 이론적으로 완전히 깨끗한 데이터는 수학적으로 생성한 가상 데이터일 뿐입니다. 아래 예제는 노이즈가 없는 순수한 신호를 표현합니다.

SCRIPT({
$.result = { columns: ["val", "sig"], types: ["double", "double"] }
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 );
$.yield( val, 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)) )
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 },
})
)
일반적으로 우리가 제거하고 싶은 노이즈는 관측 대상 신호보다 더 높은 주파수를 갖습니다.

SCRIPT({
$.result = { columns: ["val", "sig", "noise"], types: ["double", "double", "double"] }
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);
$.yield( val, 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" },
{ type: "line", data: column(2), name:"noise" },
],
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({
$.result = { columns: ["val", "sig"], types: ["double", "double"] }
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);
$.yield( val, 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 },
})
)
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)처럼 연속된 값을 평균하면 노이즈가 줄어드는 효과가 있습니다. 아래 예시는 단순 평균을 적용한 결과입니다.

SCRIPT({
const filter = require("@jsh/filter")
const avg = new filter.Avg();
const { arrange } = require("@jsh/generator");
}, {
for( val of arrange(1, 5, 0.03)) {
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);
avg.push(sig + noise);
$.yield(val, sig + noise, avg.value());
}
})
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 },
})
)
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)))
MOVAVG( value(1), window(10) )
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 }
})
)
누적 평균, 이동 평균, 지수 평균
Machbase TQL은 누적 평균, 이동 평균, 지수 평균 등을 쉽게 적용할 수 있는 필터 함수를 제공합니다. 각 필터에 관한 상세 예제는 하위 문서에서 확인할 수 있습니다.
시계열 필터 요약
- AVG / MOVAVG : 저주파 신호에서 고주파 노이즈를 제거할 때 사용합니다.
- EWMA : 최근 데이터에 더 많은 가중치를 주어 추이를 부드럽게 관찰할 수 있습니다.
- Median Filter : 순간적인 이상치에 민감할 때 유용합니다.
최근 업데이트