다음과 같은 그래프를 생성하는 데이터 세트가있는 경우 표시된 피크 (이 경우 3 개)의 x 값을 알고리즘 적으로 결정하는 방법은 무엇입니까?
다음과 같은 그래프를 생성하는 데이터 세트가있는 경우 표시된 피크 (이 경우 3 개)의 x 값을 알고리즘 적으로 결정하는 방법은 무엇입니까?
답변:
일반적인 접근 방식은 데이터 를 평활화 한 다음 로컬 최대 필터를 평활화하여 피크를 찾는 것 입니다. 에서 R
:
argmax <- function(x, y, w=1, ...) {
require(zoo)
n <- length(y)
y.smooth <- loess(y ~ x, ...)$fitted
y.max <- rollapply(zoo(y.smooth), 2*w+1, max, align="center")
delta <- y.max - y.smooth[-c(1:w, n+1-1:w)]
i.max <- which(delta <= 0) + w
list(x=x[i.max], i=i.max, y.hat=y.smooth)
}
반환 값에는 x
질문에 답하는 로컬 최대 값 ( ) 의 인수 와 해당 로컬 최대 값이 발생하는 x 및 y 배열의 인덱스 ( i
)가 포함됩니다.
상황에 따라 조정되는 두 가지 매개 변수가 있습니다 w
. 로컬 최대 값을 계산하는 데 사용되는 창의 절반 너비입니다. (값은 데이터 배열 길이의 절반보다 작아야합니다.) 작은 값은 작은 로컬 범프를 선택하는 반면 큰 값은 그 값을 바로 통과합니다. 이 코드에서 명시 적이 지 않은 다른 span
것이 loess
더 매끄 럽습니다. (일반적으로 0과 1 사이입니다. x 값 범위의 비율로 창 너비를 반영합니다.) 값이 클수록 데이터가보다 적극적으로 스무딩되어 로컬 범프가 완전히 사라집니다.
이 튜닝 효과를 확인하려면 결과를 플롯하는 테스트 기능을 약간 만들어 보겠습니다.
test <- function(w, span) {
peaks <- argmax(x, y, w=w, span=span)
plot(x, y, cex=0.75, col="Gray", main=paste("w = ", w, ", span = ", span, sep=""))
lines(x, peaks$y.hat, lwd=2) #$
y.min <- min(y)
sapply(peaks$i, function(i) lines(c(x[i],x[i]), c(y.min, peaks$y.hat[i]),
col="Red", lty=2))
points(x[peaks$i], peaks$y.hat[peaks$i], col="Red", pch=19, cex=1.25)
}
다음은 약간 시끄러운 합성 데이터에 적용되는 몇 가지 실험입니다.
x <- 1:1000 / 100 - 5
y <- exp(abs(x)/20) * sin(2 * x + (x/5)^2) + cos(10*x) / 5 + rnorm(length(x), sd=0.05)
par(mfrow=c(3,1))
test(2, 0.05)
test(30, 0.05)
test(2, 0.2)
넓은 창 (중간 플롯) 또는보다 적극적인 부드러운 (하단 플롯)은 상단 플롯에서 감지 된 로컬 최대 값을 제거합니다. 공격적인 스무딩이 이러한 피크를 이동시키는 것처럼 보이기 때문에 여기에서 가장 좋은 조합은 넓은 창이고 부드러운 스무딩 일 것입니다. 이 예에서, w=50
그리고 span=0.05
훌륭한 일 (미도시)를 않습니다.
엔드 포인트의 로컬 최대 값이 감지 되지 않습니다 . 이들은 별도로 검사 할 수 있습니다. 이를 지원하기 위해 argmax
스무딩 된 y 값을 반환합니다.
이 접근법은 범용 작업을위한보다 공식적인 모델링에 비해 몇 가지 장점이 있습니다.
데이터의 선입 모델을 채택하지 않습니다.
데이터 특성에 맞출 수 있습니다.
관심있는 피크의 종류를 감지하도록 조정할 수 있습니다.
w
및 span
에 대한 최상의 값을 결정하고 더 높은 값이 span
피크를 이동하고 있음을 발견해야했습니다 . 이 단계조차 자동화 될 수 있다고 생각합니다. 예를 들어 첫 번째 문제에서 발견 된 피크의 품질을 평가할 수 있으면 optimize
매개 변수를 실행할 수 있습니다 ! 두 번째 문제의 경우, 예를 들어 발견 된 피크의 양쪽에서 창을 선택하고 더 높은 값을 찾으십시오.
주석에서 언급했듯이 시계열이 주기적으로 적합하면 고조파 회귀 모델이 함수를 부드럽게하고 1 차 및 2 차 미분 테스트를 적용하여 피크를 식별하는 방법을 제공합니다. Huber는 여러 개의 피크가 있고 기능이 반드시 주기적 일 필요가없는 경우 장점이있는 비모수 테스트를 지적했습니다. 그러나 무료 점심은 없습니다. 그가 언급 한 방법에는 장점이 있지만 파라 메트릭 모델이 적절한 경우 단점이있을 수 있습니다. 그것은 항상 비모수 적 기법을 사용하는 것과 반대입니다. 파라 메트릭 가정을 피하지만 파라 메트릭 가정이 적절할 때 파라 메트릭 접근 방식이 더 좋습니다. 그의 절차는 또한 데이터의 시계열 구조를 최대한 활용하지 않습니다.
제안 된 절차의 장점을 지적하는 것이 적절하지만 잠재적 인 단점을 지적하는 것도 중요하다고 생각합니다. 내 접근 방식과 Huber는 효율적인 방식으로 최고점을 찾습니다. 그러나 로컬 최대 값이 이전에 결정된 최고 피크보다 낮은 경우 그의 절차가 약간 더 많은 작업이 필요하다고 생각합니다.
신호 처리에서 일반적인 피크 검출 방식은 다음과 같습니다.
작동하는 또 다른 방법은 급격하게 고역 통과 필터링 된 신호와 심하게 평활화 (저역 통과 또는 중간 필터링)를 비교하고 3 단계를 적용하는 것입니다.
도움이 되었기를 바랍니다.