[비정형 데이터] 06. 어떤 특징을 추출할 수 있을까? - 주파수

2020. 5. 4. 17:07데이터 분석/비정형데이터분석


주파수 신호 특징

시간에 따라 변하는 신호들은 더 기본적인 신호들로 쪼갤 수 있습니다. 이때 여러 주파수를 가진 신호들로 나타낼 수 있는데 이를 신호의 (주파수) 스펙트럼이라고 합니다. 이 분석은 시간축에 표현했을 때 보이지 않았던 특성들이 주파수 관점에서 보았을 때 파악할 수 있고 다른 신호와 비교 분석 시 유용합니다.

주기 신호는 같은 주기를 갖는 정현파(기본파)와 이 정현파의 정수배 주파수를 갖는 정현파(고주파)들의 합으로 표현할 수 있습니다. 이때, 기본파는 신호의 표현을 바꾸는데 바탕 역할을 하는 신호를 뜻하고 고조파는 기본파가 가지는 주파수의 몇 배에 해당하는 주파수를 가지는 신호를 말합니다.

그렇다면 정현파는 무엇일까요?

정현파는 등속 회전 운동체의 위치를 시간에 대해 그린 파형을 갖는 신호로 T=0에서 한 주기의 파형이 어느 위치에서 출발해서(위상) 얼만큼의 크기로(진폭) 얼마나 빠르게 반복되는가(주파수)로 나타낼 수 있습니다. 즉, 진폭, 위상, 주파수 3가지 요소에 의해 정의되고 사인 또는 코사인 함수로 표현이 가능한 파형입니다.

간단하게 아래 그림을 통해 살펴보겠습니다. 왼쪽 원의 파란점이 움직이는 물체라고 가정했을 때 이 움직이는 물체의 위치를 Y축에 투영하면 오른쪽과 같이 나타낼 수 있습니다. 진폭은 정현파가 진동하면서 발생할 수 있는 값의 범위로 원의 반지름, 위상은 각으로 표시된 정현파의 출발위치로 원점에서 코사 인파 꼭짓점(사인파 영점)까지의 거리를 뜻하고 주파수는 정현파가 1초에 같은 파형을 반복하는 횟수로 연두색 선이 1초 내에 몇 번 반복되는가입니다. 연두색 선은 원을 한 바퀴 도는 데 걸리는 시간. 즉, 정현파가 같은 파형을 반복하는 최소 시간 간격으로 주기를 말합니다.

정현파 그림

주파수는 주기와 역수관계로 신호의 시간적인 변화 속도와 관련되어 있습니다. 주파수가 높을수록 신호 파형이 시간적으로 더 빨리 변하고 이를 고주파 신호라고 합니다.

(주파수) 스펙트럼은 정현파를 주파수의 함수로 취급하여 주파수 축 상에 그 진폭과 위상을 나타낸 것입니다. 파형 데이터로부터 주파수 성분을 파악하기 위하여 정현파를 이용하여 fitting 시켜 계수 값을 알아낼 수 있습니다.

cosin함수와 해당 함수보다 주파수가 더 높은 sin함수를 더하여 주파수가 다른 두 개의 정현파를 합친 신호를 생성하여 실습해보겠습니다.

t = seq(0,200,by=0.1) # 0.1초 단위로 신호 생성
x = cos(2*pi*t/16) + 0.75*sin(2*pi*t/5)
par(mfrow=c(2,1))
plot(t,x,"l")
x.spec = spectrum(x)  

결과

spectrum(x)함수는 frequency(주파수값)를 구한 다음 각 freqency 값에 따라 나올 수 있는 주파수 영역을 확률 밀도 함수에 적용하여 아래 그래프의 y값으로 도출됩니다. 주파수 영역은 진폭에 비례하기 때문에 각각의 주파수가 나타내는 진폭의 크기가 얼마인지를 추정하는 함수라고 생각하시면 됩니다.

spcetrum함수를 적용시킨 x.spec의 구조를 확인해보겠습니다.

str(x.spec)
List of 16
 $ freq     : num [1:1012] 0.000494 0.000988 0.001481 0.001975 0.002469 ...
 $ spec     : num [1:1012] 0.04259 0.00589 0.05144 0.0932 0.08914 ...
 $ coh      : NULL
 $ phase    : NULL
 $ kernel   : NULL
 $ df       : num 1.77
 $ bandwidth: num 0.000143
 $ n.used   : int 2025
 $ orig.n   : int 2001
 $ series   : chr "x"
 $ snames   : NULL
 $ method   : chr "Raw Periodogram"
 $ taper    : num 0.1
 $ pad      : num 0
 $ detrend  : logi TRUE
 $ demean   : logi FALSE
 - attr(*, "class")= chr "spec"

freq는 주파수, spec는 주파수를 통해 추정된 진폭의 크기(주파수 영역의 power)에 대한 확률값입니다. 앞서 0.1초 단위로 시간축을 생성하였음에도 spectrum함수는 y값만 인식하고 시간 t는 인식하지 않기 때문에 시간축을 0,1,2로 가정합니다. freq에 시간축을 곱하여 주파수값을 제대로 나타내 주어야 합니다.

spx = x.spec$freq*1/0.1  # freq: frequency값 (0.1초 단위로 증폭)

spec는 주파수 영역의 양수 값만 나타나는데 신호는 음수 값, 양수 값 모두 가지기 때문에 *2를 통해 주파수 영역을 구해냅니다. 아래 그림과 같은 신호가 있을 때 연두색 부분에 해당하는 주파주 영역을 모두 구하고 싶은데 spec은 분홍색에 해당하는 영역의 값만 도출되기 때문에 *2로 주파수 영역에 해당하는 값을 도출합니다.

spy = 2*x.spec$spec  
par(mfrow=c(1,1))
plot(spy*spx,xlab = "frequency", ylab = "spectral density", type ="l")

결과

2개 파형에 대한 주파수 값을 알 수 있는 그래프가 나왔습니다.

spectrum 분석을 통해 변수 화하는 방법은 다음과 같습니다.

  • 상위 n개를 추출해서 해당 frequency와 spectral density값
    • 현재는 시각화를 통해 2개의 파형이 나오는 것을 알 수 있지만 일일이 모든 변수를 시각화할 수 없기 대문에 상위 5~6개를 추출하여 변수로 사용함
# 상위 2개에 해당하는 주파수값의 위치를 반환하여 spx의 위치값에 적용하여 sepctral density값 도출
spx[which(spy%in%sort(spy,decreasing = TRUE)[1:2])]
  • spectral density의 최솟값을 설정하고 최소값 이상이 되는 frequency의 개수
  • 위 범위에 해당 주파수 power(주파수 영역)에 대한 평균 또는 분산
  • 주파수가 가장 큰 기본파의 frequency값과 나머지 고조파들의 차이
spx[spy>100]
[1] 0.05925926 0.06419753 0.19753086 0.20246914

rlst = spy[spy>100]
a = max(rlst)

mean(rlst)   # 크기가 100 이상이 되는 주파수 영역에 대한 평균
[1] 0.1308642
var(rlst)    # 크기가 100 이상이 되는 주파수 영역에 대한 분산
[1] 0.006381141


# 최대값과 다른 주파수들이 얼마만큼 차이가 나는지 
a-rlst
[1] 0.143209877 0.138271605 0.004938272 0.000000000

해당 글은 순천향대학교 빅데이터공학과 우지영 교수님의 강의를 바탕으로 정리된 내용으로 모든 자료의 출처는 우지영 교수님의 수업자료에 있음을 알려드립니다.

728x90