ไลบรารี Python สำหรับการแบ่งกลุ่มแบบแบ่งส่วน (หรือการถดถอยแบบชิ้นเดียว)


16

ฉันกำลังมองหาไลบรารี Python ที่สามารถทำการแบ่งกลุ่มได้

ตัวอย่าง :

ป้อนคำอธิบายรูปภาพที่นี่



คำถามนี้ให้วิธีในการดำเนินการถดถอยแบบชิ้นเดียวโดยกำหนดฟังก์ชั่นและการใช้ห้องสมุดหลามมาตรฐาน stackoverflow.com/questions/29382903/…

คำถามที่คล้ายกัน ( stackoverflow.com/questions/29382903/ … ) และห้องสมุดที่มีประโยชน์สำหรับการถดถอยแบบชิ้นเล็ก ๆ ( pypi.org/project/pwlf )
prashanth

คำตอบ:


7

numpy.piecewise สามารถทำได้

ทีละชิ้น (x, condlist, funclist, * args, ** kw)

ประเมินฟังก์ชั่นที่กำหนดเป็นชิ้น ๆ

กำหนดชุดเงื่อนไขและฟังก์ชั่นที่เกี่ยวข้องประเมินแต่ละฟังก์ชั่นในข้อมูลอินพุตที่ใดก็ตามที่เงื่อนไขเป็นจริง

ตัวอย่างที่จะได้รับในดังนั้นที่นี่ เพื่อความสมบูรณ์นี่คือตัวอย่าง:

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] นั้นค่อนข้างง่ายและมีประสิทธิภาพ มันทำงานได้ตามจำนวนเซ็กเมนต์ที่ระบุและสำหรับฟังก์ชั่นต่อเนื่อง ตำแหน่งของเบรกพอยต์นั้นมีการประเมินซ้ำโดยการทำซ้ำแต่ละครั้งการถดถอยเชิงเส้นแบบแบ่งส่วนทำให้กระโดดได้ที่เบรกพอยต์ จากค่าของการกระโดดตำแหน่งจุดพักถัดไปจะถูกอนุมานจนกระทั่งไม่มีการหยุดชะงักอีกต่อไป (การข้าม)

"กระบวนการทำซ้ำจนกว่าการบรรจบที่เป็นไปได้ซึ่งโดยทั่วไปไม่ได้รับประกัน"

โดยเฉพาะอย่างยิ่งการบรรจบกันหรือผลลัพธ์อาจขึ้นอยู่กับการประเมินครั้งแรกของเบรกพอยต์

นี่คือวิธีการที่ใช้ในการวิจัยแพคเกจคละคลุ้ง

นี่คือการดำเนินการในหลาม:

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

ฉันกำลังมองหาสิ่งเดียวกันและน่าเสียดายที่ตอนนี้ดูเหมือนว่ายังไม่มีใคร คำแนะนำเกี่ยวกับวิธีดำเนินการต่อสามารถพบได้ในคำถามก่อนหน้านี้คำถามก่อนหน้านี้

หรือคุณสามารถมองเข้าไปในบาง R ห้องสมุดเช่นแบ่ง Sizer, strucchange และถ้ามีบางสิ่งบางอย่างที่เหมาะกับคุณลองฝังโค้ด R ในหลามกับrpy2

การแก้ไขเพื่อเพิ่มลิงก์ไปยังpy-earth "การใช้งาน Python ของ Multivariate Adaptive Regration Splines ของเจอโรมฟรีดแมน"


2

มีการโพสต์บล็อกมีการนำ recursive ของการถดถอยแบบ โซลูชันนั้นเหมาะกับการถดถอยที่ไม่ต่อเนื่อง

หากคุณไม่พอใจกับแบบจำลองที่ไม่ต่อเนื่องและต้องการตั้งค่าแบบต่อเนื่องฉันจะเสนอให้มองหาเส้นโค้งของคุณในkรูปของเส้นโค้งรูปตัว L โดยใช้ Lasso เพื่อหาช่องว่าง:

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.   ]

เนื่องจากวิธี Lasso มันกระจัดกระจาย: โมเดลพบว่าเบรกพอยต์หนึ่งใน 10 ที่เป็นไปได้ หมายเลข 0.57 และ 0.825 ตรงกับ 0.5 และ 1.25 ใน DGP จริง แม้ว่าพวกเขาจะไม่ได้อยู่ใกล้มาก

ป้อนคำอธิบายรูปภาพที่นี่

วิธีนี้ไม่อนุญาตให้คุณประเมินเบรกพอยต์อย่างแน่นอน แต่ถ้าชุดข้อมูลของคุณมีขนาดใหญ่พอคุณสามารถเล่นกับชุดอื่นk(อาจจะปรับแต่งโดยการตรวจสอบข้าม) และประเมินจุดพักได้อย่างแม่นยำพอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.