분할 회귀를위한 Python 라이브러리 (일부 단편 회귀)


16

세그먼트 회귀 (일부 단편 회귀)를 수행 할 수있는 Python 라이브러리를 찾고 있습니다 .

:

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



이 질문은 함수를 정의하고 표준 파이썬 라이브러리를 사용하여 부분 회귀를 수행하는 방법을 제공합니다. stackoverflow.com/questions/29382903/…

비슷한 질문 ( stackoverflow.com/questions/29382903/... )와 구분 회귀에 대한 유용한 라이브러리 ( pypi.org/project/pwlf )
프라 샨스

답변:


7

numpy.piecewise 이것을 할 수 있습니다.

조각 단위 (x, condlist, funclist, * args, ** kw)

구간 별 함수를 평가하십시오.

일련의 조건과 해당 기능이 주어지면 해당 조건이 참이 될 때마다 입력 데이터에서 각 기능을 평가하십시오.

SO에 대한 예가 여기에 있습니다 . 완성도를 높이기위한 예는 다음과 같습니다.

from scipy import optimize
import matplotlib.pyplot as plt
import numpy as np

x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ,11, 12, 13, 14, 15], dtype=float)
y = np.array([5, 7, 9, 11, 13, 15, 28.92, 42.81, 56.7, 70.59, 84.47, 98.36, 112.25, 126.14, 140.03])

def piecewise_linear(x, x0, y0, k1, k2):
    return np.piecewise(x, [x < x0, x >= x0], [lambda x:k1*x + y0-k1*x0, lambda x:k2*x + y0-k2*x0])

p , e = optimize.curve_fit(piecewise_linear, x, y)
xd = np.linspace(0, 15, 100)
plt.plot(x, y, "o")
plt.plot(xd, piecewise_linear(xd, *p))

4

Vito MR Muggeo [1]가 제안한 방법은 비교적 간단하고 효율적입니다. 지정된 수의 세그먼트와 연속 기능에 작동합니다. 중단 점의 위치는 각 반복에 대해 중단 점에서 점프를 허용하는 세그먼트 선형 회귀를 수행하여 반복적으로 추정 됩니다. 점프 값에서 더 이상 불연속 (점프)이 없을 때까지 다음 중단 점 위치가 추론됩니다.

"수렴이 가능할 때까지 프로세스가 반복되며 일반적으로 보장되지 않습니다"

특히, 수렴 또는 결과는 브레이크 포인트의 제 1 추정에 의존 할 수있다.

이것은 R 세그먼트 패키지 에서 사용되는 방법 입니다.

다음은 파이썬으로 구현 한 것입니다.

import numpy as np
from numpy.linalg import lstsq

ramp = lambda u: np.maximum( u, 0 )
step = lambda u: ( u > 0 ).astype(float)

def SegmentedLinearReg( X, Y, breakpoints ):
    nIterationMax = 10

    breakpoints = np.sort( np.array(breakpoints) )

    dt = np.min( np.diff(X) )
    ones = np.ones_like(X)

    for i in range( nIterationMax ):
        # Linear regression:  solve A*p = Y
        Rk = [ramp( X - xk ) for xk in breakpoints ]
        Sk = [step( X - xk ) for xk in breakpoints ]
        A = np.array([ ones, X ] + Rk + Sk )
        p =  lstsq(A.transpose(), Y, rcond=None)[0] 

        # Parameters identification:
        a, b = p[0:2]
        ck = p[ 2:2+len(breakpoints) ]
        dk = p[ 2+len(breakpoints): ]

        # Estimation of the next break-points:
        newBreakpoints = breakpoints - dk/ck 

        # Stop condition
        if np.max(np.abs(newBreakpoints - breakpoints)) < dt/5:
            break

        breakpoints = newBreakpoints
    else:
        print( 'maximum iteration reached' )

    # Compute the final segmented fit:
    Xsolution = np.insert( np.append( breakpoints, max(X) ), 0, min(X) )
    ones =  np.ones_like(Xsolution) 
    Rk = [ c*ramp( Xsolution - x0 ) for x0, c in zip(breakpoints, ck) ]

    Ysolution = a*ones + b*Xsolution + np.sum( Rk, axis=0 )

    return Xsolution, Ysolution

예:

import matplotlib.pyplot as plt

X = np.linspace( 0, 10, 27 )
Y = 0.2*X  - 0.3* ramp(X-2) + 0.3*ramp(X-6) + 0.05*np.random.randn(len(X))
plt.plot( X, Y, 'ok' );

initialBreakpoints = [1, 7]
plt.plot( *SegmentedLinearReg( X, Y, initialBreakpoints ), '-r' );
plt.xlabel('X'); plt.ylabel('Y');

그래프

[1] : Muggeo, VM (2003). 알려지지 않은 중단 점으로 회귀 모형 추정 의학 통계, 22 (19), 3055-3071.


3

나는 똑같은 것을 찾고 있었고 불행히도 현재는없는 것처럼 보입니다. 진행 방법에 대한 몇 가지 제안은이 이전 질문 에서 찾을 수 있습니다 .

또는 segmented, SiZer, strucchange와 같은 일부 R 라이브러리를 살펴볼 수 있으며, 작동하는 것이 있으면 rpy2 로 python에 R 코드를 삽입하십시오 .

py-earth 에 대한 링크를 추가하기 위해 편집 , "Jerome Friedman의 다변량 적응 회귀 스플라인의 Python 구현".


2

조각 별 회귀를 재귀 적으로 구현 한 블로그 게시물 이 있습니다 . 이 솔루션은 불연속 회귀에 적합합니다.

불연속 모델에 만족하지 않고 연속 설정을 원한다면 k희소성을 위해 Lasso를 사용하여 L 자형 곡선을 기준으로 곡선을 찾으십시오 .

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Lasso
# generate data
np.random.seed(42)
x = np.sort(np.random.normal(size=100))
y_expected = 3 + 0.5 * x + 1.25 * x * (x>0)
y = y_expected + np.random.normal(size=x.size, scale=0.5)
# prepare a basis
k = 10
thresholds = np.percentile(x, np.linspace(0, 1, k+2)[1:-1]*100)
basis = np.hstack([x[:, np.newaxis],  np.maximum(0,  np.column_stack([x]*k)-thresholds)]) 
# fit a model
model = Lasso(0.03).fit(basis, y)
print(model.intercept_)
print(model.coef_.round(3))
plt.scatter(x, y)
plt.plot(x, y_expected, color = 'b')
plt.plot(x, model.predict(basis), color='k')
plt.legend(['true', 'predicted'])
plt.xlabel('x')
plt.ylabel('y')
plt.title('fitting segmented regression')
plt.show()

이 코드는 추정 계수로 구성된 벡터를 사용자에게 반환합니다.

[ 0.57   0.     0.     0.     0.     0.825  0.     0.     0.     0.     0.   ]

올가미 접근 방식으로 인해 드문 경우입니다.이 모델은 가능한 10 가지 중 하나의 중단 점을 발견했습니다. 실제 DGP에서 숫자 0.57 및 0.825는 0.5 및 1.25에 해당합니다. 매우 근접하지는 않지만 적합 곡선은 다음과 같습니다.

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

이 방법을 사용하면 중단 점을 정확하게 추정 할 수 없습니다. 그러나 데이터 집합이 충분히 큰 경우 다른 방식으로 재생하고 k(교차 유효성 검사로 조정 가능) 중단 점을 정확하게 예측할 수 있습니다.

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