खंडित प्रतिगमन के लिए पायथन पुस्तकालय (उर्फ टुकड़े करने वाला प्रतिगमन)


16

मैं एक पायथन लाइब्रेरी की तलाश कर रहा हूं जो खंडित प्रतिगमन (उर्फ टुकड़ा-दाता प्रतिगमन) कर सकती है

उदाहरण :

यहाँ छवि विवरण दर्ज करें



यह प्रश्न किसी फ़ंक्शन को परिभाषित करके और मानक अजगर पुस्तकालयों का उपयोग करके एक टुकड़ा-दाता प्रतिगमन करने के लिए एक विधि देता है। stackoverflow.com/questions/29382903/…

ऐसा ही एक सवाल ( stackoverflow.com/questions/29382903/... ) और piecewise प्रतिगमन के लिए एक उपयोगी पुस्तकालय ( pypi.org/project/pwlf )
प्रशांत

जवाबों:


7

numpy.piecewise यह कर सकता है।

टुकड़ावार (x, संघनित्र, कवक, * आर्ग, ** किलोवाट)

एक टुकड़ा-परिभाषित फ़ंक्शन का मूल्यांकन करें।

शर्तों और संबंधित कार्यों के एक सेट को देखते हुए, इनपुट डेटा पर प्रत्येक फ़ंक्शन का मूल्यांकन करें जहां भी इसकी स्थिति सत्य है।

एक उदाहरण एसओ पर यहां दिया गया है । पूर्णता के लिए, यहाँ एक उदाहरण है:

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

वीटो एमआर मुगेजो [1] द्वारा प्रस्तावित विधि अपेक्षाकृत सरल और कुशल है। यह सेगमेंट की एक निर्दिष्ट संख्या और एक निरंतर फ़ंक्शन के लिए काम करता है। ब्रेकपॉइंट की स्थिति का अनुमान लगाने के द्वारा पुनरावृत्त रूप से अनुमान लगाया जाता है, प्रत्येक पुनरावृत्ति के लिए, एक खंडित रैखिक प्रतिगमन ब्रेकपॉइंट्स पर कूदता है। जंप के मूल्यों से, अगले ब्रेकपॉइंट पदों को काट दिया जाता है, जब तक कि कोई और अधिक असंतोष (कूदता) नहीं होता है।

"इस प्रक्रिया को संभव अभिसरण तक पुनरावृत्त किया जाता है, जो सामान्य रूप से गारंटीकृत नहीं है"

विशेष रूप से, अभिसरण या परिणाम ब्रेकपॉइंट के पहले अनुमान पर निर्भर करता है।

यह आर सेगमेंटेड पैकेज में उपयोग की जाने वाली विधि है ।

यहाँ अजगर में एक कार्यान्वयन है:

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');

ग्राफ

[१]: मुग्गेओ, वीएम (२००३)। अज्ञात विराम बिंदुओं के साथ प्रतिगमन मॉडल का अनुमान लगाना। चिकित्सा में सांख्यिकी, 22 (19), 3055-3071।


3

मैं एक ही चीज़ की तलाश में हूँ, और दुर्भाग्य से ऐसा लगता है कि इस समय कोई नहीं है। आगे बढ़ने के लिए कुछ सुझाव इस पिछले प्रश्न में पाए जा सकते हैं ।

वैकल्पिक रूप से आप कुछ R लाइब्रेरियों जैसे कि खंडित, SiZer, स्ट्रैचेंज में देख सकते हैं, और अगर आपके लिए कुछ काम करता है तो rpy2 के साथ python में R कोड एम्बेड करने का प्रयास करें ।

Py-earth की एक कड़ी जोड़ने का संपादन , "जेरोम फ्रीडमैन के मल्टीवेरेट एडेप्टिव रिग्रेशन स्प्लिन्स का एक पायथन कार्यान्वयन"।


2

एक ब्लॉग पोस्ट है जिसमें टुकड़ा करने योग्य प्रतिगमन का पुनरावर्ती कार्यान्वयन है। यह समाधान असंतुलित प्रतिगमन पर फिट बैठता है।

यदि आप बंद मॉडल से असंतुष्ट हैं और निरंतर सेटिंग चाहते हैं, तो मैं kएल-आकार के घटता के आधार पर आपके कर्व की तलाश करना चाहूंगा , लारसो का उपयोग स्पार्सिटी के लिए:

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 संभव के बीच बिल्कुल एक ब्रेकपॉइंट मिला। संख्या 0.57 और 0.825, सच्चे DGP में 0.5 और 1.25 के अनुरूप हैं। हालांकि वे बहुत करीब नहीं हैं, फिट घटता हैं:

यहाँ छवि विवरण दर्ज करें

यह दृष्टिकोण आपको ब्रेकपॉइंट का सटीक अनुमान लगाने की अनुमति नहीं देता है। लेकिन अगर आपका डेटासेट काफी बड़ा है, तो आप अलग-अलग के साथ खेल सकते हैं k(हो सकता है कि इसे क्रॉस-वेलिडेशन द्वारा ट्यून करें) और ब्रेकपॉइंट का ठीक-ठीक अनुमान लगा लें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.