데이터에는 두 가지 추세가 있습니다. 독립적 인 추세선을 추출하는 방법?


34

특정 방식으로 정렬되지 않은 데이터 세트가 있지만 명확하게 표시되면 두 가지 뚜렷한 경향이 있습니다. 간단한 선형 회귀 분석은 두 계열 사이의 명확한 구분 때문에 실제로는 적합하지 않습니다. 두 개의 독립적 인 선형 추세선을 얻는 간단한 방법이 있습니까?

레코드를 위해 파이썬을 사용하고 있으며 기계 학습을 포함하여 프로그래밍 및 데이터 분석에 상당히 익숙하지만 절대적으로 필요한 경우 R로 건너 뛸 수 있습니다.

여기에 이미지 설명을 입력하십시오


6
내가 지금까지 가장 좋은 답변은 그래프 용지에 이것을 인쇄하고 연필과 통치자와 계산기를 사용하는 것입니다 ...
jbbiomed

페어 별 슬로프를 계산하여 두 개의 "슬로프 클러스터"로 그룹화 할 수 있습니다. 그러나 두 개의 병렬 추세가 있으면 실패합니다.
Thomas Jungblut

1
나는 그것에 대한 개인적인 경험이 없지만 statsmodels 가 체크 아웃 가치가 있다고 생각 합니다. 통계적으로, 그룹에 대한 상호 작용이있는 선형 회귀가 적합합니다 (그룹화되지 않은 데이터가 있다고 말하는 경우가 아니라면 약간 더 무겁습니다 ...)
Matt Parker

1
불행히도 이것은 데이터가 아닌 사용 데이터에 영향을 미치며 두 개의 개별 시스템에서의 사용이 동일한 데이터 세트로 명확하게 혼합되어 있습니다. 두 가지 사용 패턴을 설명하고 싶지만 클라이언트가 수집 한 약 6 년 분량의 정보를 나타내므로 데이터를 다시 수집 할 수 없습니다.
jbbiomed

2
확인하기 위해 : 고객에게 어떤 측정치가 어느 측정 항목에서 제공되는지를 나타내는 추가 데이터가 없습니까? 이것은 귀하 또는 귀하의 고객이 가지고 있거나 찾을 수있는 데이터의 100 %입니다. 또한 2012 년은 데이터 수집이 무너 지거나 시스템 중 하나 또는 둘 모두가 바닥에 떨어진 것처럼 보입니다. 트렌드가 그 시점에 얼마나 중요한지 궁금해합니다.
Wayne

답변:


30

문제를 해결하려면 데이터 세트에 대한 가정과 일치하는 확률 모델을 정의하는 것이 좋습니다. 귀하의 경우에는 선형 회귀 모델이 혼합되어 있어야합니다. 다른 데이터 포인트를 다른 혼합 성분과 연결하여 가우스 혼합 모델과 유사한 "회귀 기 혼합"모델을 작성할 수 있습니다.

시작하는 데 필요한 코드를 포함 시켰습니다. 이 코드는 두 회귀 분석기의 혼합물에 대해 EM 알고리즘을 구현합니다 (더 큰 혼합물로 확장하기가 비교적 쉬워야합니다). 이 코드는 임의의 데이터 세트에 대해 상당히 강력한 것으로 보입니다. 그러나 선형 회귀 분석과 달리 혼합 모형에는 볼록하지 않은 목표가 있으므로 실제 데이터 세트의 경우 다른 임의의 시작점으로 몇 번의 시행을 수행해야 할 수도 있습니다.

import numpy as np
import matplotlib.pyplot as plt 
import scipy.linalg as lin

#generate some random data
N=100
x=np.random.rand(N,2)
x[:,1]=1

w=np.random.rand(2,2)
y=np.zeros(N)

n=int(np.random.rand()*N)
y[:n]=np.dot(x[:n,:],w[0,:])+np.random.normal(size=n)*.01
y[n:]=np.dot(x[n:,:],w[1,:])+np.random.normal(size=N-n)*.01


rx=np.ones( (100,2) )
r=np.arange(0,1,.01)
rx[:,0]=r

#plot the random dataset
plt.plot(x[:,0],y,'.b')
plt.plot(r,np.dot(rx,w[0,:]),':k',linewidth=2)
plt.plot(r,np.dot(rx,w[1,:]),':k',linewidth=2)

# regularization parameter for the regression weights
lam=.01

def em():
    # mixture weights
    rpi=np.zeros( (2) )+.5

    # expected mixture weights for each data point
    pi=np.zeros( (len(x),2) )+.5

    #the regression weights
    w1=np.random.rand(2)
    w2=np.random.rand(2)

    #precision term for the probability of the data under the regression function 
    eta=100

    for _ in xrange(100):
        if 0:
            plt.plot(r,np.dot(rx,w1),'-r',alpha=.5)
            plt.plot(r,np.dot(rx,w2),'-g',alpha=.5)

        #compute lhood for each data point
        err1=y-np.dot(x,w1)
        err2=y-np.dot(x,w2)
        prbs=np.zeros( (len(y),2) )
        prbs[:,0]=-.5*eta*err1**2
        prbs[:,1]=-.5*eta*err2**2

        #compute expected mixture weights
        pi=np.tile(rpi,(len(x),1))*np.exp(prbs)
        pi/=np.tile(np.sum(pi,1),(2,1)).T

        #max with respect to the mixture probabilities
        rpi=np.sum(pi,0)
        rpi/=np.sum(rpi)

        #max with respect to the regression weights
        pi1x=np.tile(pi[:,0],(2,1)).T*x
        xp1=np.dot(pi1x.T,x)+np.eye(2)*lam/eta
        yp1=np.dot(pi1x.T,y)
        w1=lin.solve(xp1,yp1)

        pi2x=np.tile(pi[:,1],(2,1)).T*x
        xp2=np.dot(pi2x.T,x)+np.eye(2)*lam/eta
        yp2=np.dot(pi[:,1]*y,x)
        w2=lin.solve(xp2,yp2)

        #max wrt the precision term
        eta=np.sum(pi)/np.sum(-prbs/eta*pi)

        #objective function - unstable as the pi's become concentrated on a single component
        obj=np.sum(prbs*pi)-np.sum(pi[pi>1e-50]*np.log(pi[pi>1e-50]))+np.sum(pi*np.log(np.tile(rpi,(len(x),1))))+np.log(eta)*np.sum(pi)
        print obj,eta,rpi,w1,w2

        try:
            if np.isnan(obj): break
            if np.abs(obj-oldobj)<1e-2: break
        except:
            pass

        oldobj=obj

    return w1,w2


#run the em algorithm and plot the solution
rw1,rw2=em()
plt.plot(r,np.dot(rx,rw1),'-r')
plt.plot(r,np.dot(rx,rw2),'-g')

plt.show()

25

이 스레드의 다른 곳에서 user1149913은 강력한 조언 (EM 추정)을위한 훌륭한 조언 (확률 모델 정의)과 코드를 제공합니다. 두 가지 문제가 해결되어야합니다.

  1. 확률 모델에서 벗어남에 대처하는 방법 (2011-2012 데이터에서 매우 분명하고 기울기가 적은 점의 파동에서 다소 분명함).

  2. EM 알고리즘 (또는 다른 알고리즘)의 올바른 시작 값을 식별하는 방법

# 2를 해결하려면 Hough 변환 사용을 고려하십시오 . 이것은 특징의 선형 스트레치를 찾기 위해 효율적으로 라돈 변환 으로 계산할 수있는 특징 탐지 알고리즘입니다 .

개념적으로 Hough 변환은 선 집합을 나타냅니다. 평면의 선은 기울기 와 고정 원점으로부터의 거리 로 매개 변수화 할 수 있습니다 . 이 좌표 시스템 의 점은 단일 선을 지정합니다. 원래 그림의 각 점은 해당 점을 통과하는 선의 연필을 결정합니다.이 연필 은 Hough 변환에서 곡선 으로 나타납니다 . 원래 플롯의 피처가 공통 선을 따라 떨어지거나 1에 가까워지면 Hough 변환에서 생성 된 곡선 모음이 해당 공통 선에 해당하는 공통 교차점을 갖는 경향이 있습니다. Hough 변환에서 가장 큰 강도의 점을 찾아서 원래 문제에 대한 좋은 솔루션을 읽을 수 있습니다.y x , yxyx,y

이 데이터를 시작하기 위해 먼저 보조 재료 (축, 눈금 표시 및 레이블)를 잘라 내고 오른쪽 하단의 명백한 지점을 잘라내어 아래쪽 축을 따라 뿌렸습니다. (그 물건이 잘리지 않으면 절차는 여전히 잘 작동하지만 축, 프레임, 진드기의 선형 시퀀스, 선형 레이블 및 심지어 축을 아래쪽 축에 산발적으로 감지합니다)

img = Import["http://i.stack.imgur.com/SkEm3.png"]
i = ColorNegate[Binarize[img]]
crop2 = ImageCrop[ImageCrop[i, {694, 531}, {Left, Bottom}], {565, 467}, {Right, Top}]

(이 코드와 나머지 코드는 Mathematica에 있습니다.)

자른 이미지

이 이미지의 각 점은 여기에서 볼 수있는 Hough 변환의 좁은 범위의 곡선에 해당합니다. 그들은 사인파입니다.

hough2 = Radon[crop2, Method -> "Hough"]  // ImageAdjust

허프 변환

이것은 질문이 라인 클러스터링 문제 라는 시각적 의미를 나타냅니다 . 허프 변환은 포인트 클러스터링 문제로 줄여서 원하는 클러스터링 방법을 적용 할 수 있습니다.

이 경우 클러스터링이 매우 명확하여 Hough 변환의 간단한 사후 처리가 완료되었습니다. 변환에서 가장 큰 강도의 위치를 ​​식별하기 위해 대비를 늘리고 약 1 %의 반경으로 변환을 흐리게했습니다. 이는 원본 이미지의 플롯 포인트 직경과 비슷합니다.

blur = ImageAdjust[Blur[ImageAdjust[hough2, {1, 0}], 8]]

흐릿한 변환

결과를 임계 값으로 지정하면 중심이 가장 큰 강도의 점을 합리적으로 식별하는 두 개의 작은 얼룩으로 범위가 좁아졌습니다.

comp = MorphologicalComponents[blur, 0.777]) // Colorize

( 의 임계 값은 경험적으로 발견되었습니다. 두 영역 만 생성하고 두 영역 중 작은 영역은 가능한 한 작습니다.)0.777

임계 값 이진화 된 변환

이미지의 왼쪽은 0도 (가로) 방향에 해당하며 왼쪽에서 오른쪽으로 보면 각도가 선형으로 180 도로 증가합니다. 보간, 나는 두 얼룩이 각각 19도 및 57.1 도의 중심에 있다고 계산합니다. 블롭의 수직 위치에서 절편을 읽을 수도 있습니다. 이 정보는 초기 적합치를 산출합니다.

width = ImageDimensions[blur][[1]];
slopes =  Module[{x, y, z}, ComponentMeasurements[comp, "Centroid"] /. 
          Rule[x_, {y_, z_}] :>  Round[((y - 1/2)/(width - 1))  180., 0.1]
  ]

{19., 57.1}

비슷한 방식으로 이러한 기울기에 해당하는 절편을 계산하여 다음과 같은 결과를 얻을 수 있습니다.

적합 선

(빨간색 선은 이전 그림의 작은 분홍색 점에 해당하고 파란색 선은 더 큰 아쿠아 얼룩에 해당합니다.)

대부분의 경우이 접근 방식은 첫 번째 문제를 자동으로 처리했습니다. 선형성의 편차는 가장 큰 강도의 점이 지워지지 만 일반적으로 많이 이동하지는 않습니다. 솔직하게 외곽에있는 점은 후프 변환 전체에서 낮은 수준의 노이즈에 영향을 미치며 후 처리 과정에서는 사라집니다.

이 시점에서 이러한 추정값을 EM 알고리즘 또는 가능성 최소화 기 (좋은 추정값이 주어지면 빠르게 수렴 됨)의 시작 값으로 제공 할 수 있습니다. 그러나 반복적으로 가중 된 최소 제곱 과 같은 강력한 회귀 추정기를 사용하는 것이 좋습니다 . 모든 지점에 회귀 가중치 를 제공 할 수 있습니다. 가중치가 낮 으면 점이 선에 닿지 않음을 나타냅니다. 원하는 경우이 가중치를 사용하여 각 점을 해당 선에 지정하십시오. 그런 다음 점을 분류 한 후 두 점 그룹에서 보통 최소 제곱 (또는 다른 회귀 절차)을 별도로 사용할 수 있습니다.


1
그림은 천 단어를 말해 당신은 5가 있습니다. 이것은 내가이 질문의 목적을 위해 만든 빠른 그래프에서 놀라운 작품입니다! 명성!
jbbiomed

2
허프 변환은 컴퓨터 비전 필드에서 이미지에서 직선을 식별하는 데 널리 사용됩니다. 통계에서도 사용해서는 안되는 이유는 무엇입니까? ;)
Lucas Reis

@Lucas, 흥미로운 질문입니다. 그러나 많은 통계적 응용에서 와 변수 사이에는 비대칭 성이 있습니다 . 하나는 정확하게 측정 된 것으로 간주되고 다른 하나는 임의의 변동이있는 것으로 간주됩니다. 이러한 응용 프로그램의 경우 이미지 처리 방법으로 올바른 결과를 얻지 못합니다 (많은 응용 프로그램에서는 유용한 결과를 전혀 얻지 못합니다). 그러나 때때로 두 분야 사이에 유익한 중복이있을 수 있습니다. yxy
whuber

예. 예를 들어, 두 이미지를 비교하여 동일한 피사체의 이미지인지 감지하는 데 관련된 특이 치의 양을 상상해보십시오. 그리고 무엇보다도 실시간으로해야한다고 상상해보십시오. "속도"는 컴퓨터 비전에서 매우 중요한 요소이며 통계에서는 그다지 중요하지 않습니다.
루카스 Reis

@RoyalTS 코드 스 니펫 중 하나에 대한 수정의 필요성을 지적 해 주셔서 감사합니다. 제안한 변경 사항을 발견했을 때 거부되었습니다 (정확하지 않았기 때문에 올바르게 수정되지는 않았지만 오류가 있음을 알게되어 감사합니다). 에 대한 참조를 제거하여 수정했습니다. rotation원래는 0으로 설정되었으므로 아무런 차이가 없었습니다.
whuber

15

이 질문은 다른 질문 과 관련이 있습니다. 실제로 이런 종류의 문제에 대한 학문적 연구를했습니다. 내 대답 "최소 제곱근"피팅을 확인하십시오. 자세한 내용은 최소값이 여러 개인 피팅 방법입니다 .

whuber의 Hough 변환 기반 접근 방식은 사용자가 제공 한 간단한 시나리오에 매우 적합한 솔루션입니다. 나는 다음과 같이보다 복잡한 데이터로 시나리오를 작업했습니다.

데이터 연관 문제-캔디 데이터 세트

저의 공동 저자들과 저는 이것을 "데이터 연결"문제로 표시했습니다. 해결하려고 할 때 주된 문제는 일반적으로 기하 급수적 인 데이터 조합으로 인한 조합입니다.

우리는 반복적 인 기술로 N 곡선의 일반적인 문제에 접근하여 매우 좋은 결과를주는 " 데이터 연관 문제에 대한 가우시안 프로세스의 겹치는 혼합물 "출판물을 보유하고 있습니다 . 종이에 링크 된 Matlab 코드를 찾을 수 있습니다.

[업데이트] OMGP 기법의 Python 구현은 GPClust 라이브러리 에서 찾을 수 있습니다 .

볼록 최적화 문제를 해결하기 위해 문제를 완화 한 또 다른 논문이 있지만 아직 출판되지 않았습니다. 2 개의 곡선에만 적용되므로 데이터에서 완벽하게 작동합니다. 관심이 있으시면 알려주십시오.


1
2 년 동안 아무도이 독창적이고 귀중한 답변을지지 한 사람이 없다는 것이 유감입니다. 그동안 언급 한 마지막 논문이 접수 되었습니까?
whuber

1
이 논문은 실제로 몇 달 전에 받아 들여졌습니다. 여기에서 다운로드 할 수 있습니다 gtas.unican.es/pub/378 . 이것은 실제로 매우 드문 문제이지만 (인기 부족을 설명 할 수 있음) 여전히 흥미로운 응용 프로그램을 찾을 수있었습니다. 원하는 경우 논문 끝에있는 실험을 살펴보십시오.
Steven

2

user1149913은 훌륭한 답변 (+ 1)을 가지고 있지만 2011 년 말에 데이터 수집이 분리 된 것으로 보입니다. 따라서 데이터의 해당 부분을 잘라낸 다음 여전히 다른 임의의 항목으로 몇 번 실행해야합니다 당신이 무엇을 얻을 시작 계수.

일을하는 간단한 방법은 데이터를 눈으로 두 세트로 분리 한 다음 익숙한 선형 모델 기술을 사용하는 것입니다. R에서는 lm함수가됩니다.

또는 두 줄을 눈으로 맞 춥니 다. R에서는 abline이 작업을 수행 하는 데 사용 합니다.

데이터가 뒤죽박죽 났고, 이상 치가 있으며 끝이났습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.