ชุดของ regressors ชนิดต่าง ๆ โดยใช้ scikit-Learn (หรือโครงร่างหลามอื่น ๆ )


27

ฉันพยายามที่จะแก้ปัญหาการถดถอย ฉันพบว่า 3 รุ่นทำงานได้ดีกับชุดย่อยของข้อมูลที่แตกต่างกัน: LassoLARS, SVR และการไล่ระดับต้นไม้แบบไล่ระดับ ฉันสังเกตเห็นว่าเมื่อฉันทำการทำนายโดยใช้ทั้ง 3 โมเดลจากนั้นสร้างตารางของ 'เอาท์พุทที่แท้จริง' และเอาท์พุทของโมเดล 3 ของฉันฉันเห็นว่าในแต่ละครั้งที่อย่างน้อยหนึ่งโมเดลนั้นใกล้เคียงกับเอาต์พุตจริง อาจอยู่ค่อนข้างไกล

เมื่อฉันคำนวณข้อผิดพลาดน้อยที่สุดที่เป็นไปได้ (ถ้าฉันใช้การทำนายจากตัวทำนายที่ดีที่สุดสำหรับแต่ละตัวอย่างการทดสอบ) ฉันได้รับข้อผิดพลาดซึ่งเล็กกว่าข้อผิดพลาดของแบบจำลองใด ๆ เพียงอย่างเดียว ดังนั้นฉันจึงคิดว่าจะพยายามรวมการทำนายจากแบบจำลองต่าง ๆ ทั้งสามนี้เข้าด้วยกันเป็นชุด คำถามคือทำอย่างไรให้ถูกต้อง? โมเดล 3 แบบของฉันทั้งหมดได้รับการสร้างและปรับแต่งโดยใช้ Scikit-Learn มันมีวิธีการบางอย่างที่สามารถใช้ในการแพ็คแบบจำลองเป็นชุดหรือไม่? ปัญหาตรงนี้คือฉันไม่ต้องการเพียงแค่การคาดคะเนค่าเฉลี่ยจากทั้งสามรุ่นฉันต้องการทำสิ่งนี้ด้วยการถ่วงน้ำหนักซึ่งควรกำหนดน้ำหนักตามคุณสมบัติของตัวอย่างเฉพาะ

แม้ว่า Scikit-Learn จะไม่ได้มีฟังก์ชั่นดังกล่าว แต่มันก็ดีถ้ามีคนรู้วิธีที่จะจัดการกับงานนี้ - การหาน้ำหนักของแต่ละรุ่นสำหรับแต่ละตัวอย่างในข้อมูล ฉันคิดว่ามันอาจจะทำได้โดย regressor แยกต่างหากที่สร้างไว้ด้านบนของทั้งสามรุ่นซึ่งจะลองใช้น้ำหนักที่เหมาะสมที่สุดสำหรับแต่ละรุ่น 3 รุ่น แต่ฉันไม่แน่ใจว่านี่เป็นวิธีที่ดีที่สุดในการทำสิ่งนี้หรือไม่

คำตอบ:


32

จริงๆแล้วscikit-learnมันมีฟังก์ชั่นดังกล่าวแม้ว่ามันอาจจะยุ่งยากเล็กน้อยในการใช้งาน นี่คือตัวอย่างการทำงานที่สมบูรณ์ของเครื่องมือถอยหลังแบบธรรมดาที่สร้างขึ้นจากด้านบนของทั้งสามรุ่น ก่อนอื่นเรามานำเข้าแพ็คเกจที่จำเป็นทั้งหมด:

from sklearn.base import TransformerMixin
from sklearn.datasets import make_regression
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.neighbors import KNeighborsRegressor
from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.linear_model import LinearRegression, Ridge

จากนั้นเราจำเป็นต้องแปลงแบบจำลองการถดถอยทั้งสามของเราเป็นหม้อแปลง สิ่งนี้จะช่วยให้เราสามารถรวมการทำนายของพวกเขาเป็นเวกเตอร์คุณลักษณะเดียวโดยใช้FeatureUnion:

class RidgeTransformer(Ridge, TransformerMixin):

    def transform(self, X, *_):
        return self.predict(X)


class RandomForestTransformer(RandomForestRegressor, TransformerMixin):

    def transform(self, X, *_):
        return self.predict(X)


class KNeighborsTransformer(KNeighborsRegressor, TransformerMixin):

    def transform(self, X, *_):
        return self.predict(X)

ตอนนี้เรามากำหนดฟังก์ชั่นการสร้างสำหรับรุ่นแฟรงเกนสไตน์ของเรา:

def build_model():
    ridge_transformer = Pipeline(steps=[
        ('scaler', StandardScaler()),
        ('poly_feats', PolynomialFeatures()),
        ('ridge', RidgeTransformer())
    ])

    pred_union = FeatureUnion(
        transformer_list=[
            ('ridge', ridge_transformer),
            ('rand_forest', RandomForestTransformer()),
            ('knn', KNeighborsTransformer())
        ],
        n_jobs=2
    )

    model = Pipeline(steps=[
        ('pred_union', pred_union),
        ('lin_regr', LinearRegression())
    ])

    return model

สุดท้ายให้พอดีกับโมเดล:

print('Build and fit a model...')

model = build_model()

X, y = make_regression(n_features=10, n_targets=2)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

model.fit(X_train, y_train)
score = model.score(X_test, y_test)

print('Done. Score:', score)

เอาท์พุท:

Build and fit a model...
Done. Score: 0.9600413867438636

ทำไมต้องยุ่งสิ่งต่าง ๆ ในลักษณะเช่นนี้? ดีวิธีนี้ช่วยให้เราสามารถเพิ่มประสิทธิภาพ hyperparameters รูปแบบโดยใช้มาตรฐานscikit-learnโมดูลเช่นหรือGridSearchCV RandomizedSearchCVนอกจากนี้ตอนนี้มันเป็นไปได้ที่จะบันทึกและโหลดจากดิสก์ที่ได้รับการฝึกอบรมมาล่วงหน้า


เมื่อใช้วิธีนี้มีวิธีง่าย ๆ ในการแยก algo ที่จะใช้เมื่อ / เศษส่วนของแต่ละ algo หรือไม่
David Hagan

บางทีการดูค่าสัมประสิทธิ์ของโมเดลเชิงเส้นที่ได้ ( model.named_steps['lin_regr'].coef_) จะทำให้คุณเข้าใจถึงจำนวนของแต่ละโมเดลในวงดนตรีที่มีส่วนช่วยแก้ปัญหาสุดท้าย
constt

@constt คุณไม่จำเป็นต้องใช้ cross_val_predict ในโมเดลพื้นฐานของคุณใช่ไหม ดูเหมือนว่าแบบจำลองระดับบนสุดของคุณจะได้รับสัญญาณ overoptimistic จากแบบจำลองฐานของคุณเนื่องจากมีการใช้งานในปัจจุบัน
Brian Bien

1
นี่เป็นเพียงตัวอย่างที่พิสูจน์แนวคิดได้ฉันไม่ได้ระบุการเลือกรุ่นที่นี่ ฉันคิดว่ารูปแบบดังกล่าวควรได้รับการปรับให้เหมาะสมที่สุดโดยรวมคือการปรับพารามิเตอร์ไฮเปอร์ของโมเดลในตัวทั้งหมดพร้อมกันโดยใช้วิธีการตรวจสอบข้าม
constt

ถ้าเราใส่ n_targets = 1 X, y = make_regression(n_features=10, n_targets=1)มันให้มิติข้อผิดพลาด ใครช่วยอธิบายสิ่งที่ต้องทำ
Mohit Yadav

9

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

ฉันฝึกชุดรูปแบบการถดถอยของฉัน (ตามที่กล่าวถึง SVR, LassoLars และ GradientBoostingRegressor) จากนั้นฉันเรียกใช้ข้อมูลการฝึกอบรมทั้งหมด (ข้อมูลเดียวกันซึ่งใช้สำหรับการฝึกอบรมของผู้ลงทะเบียนทั้ง 3 รายนี้) ฉันได้รับการคาดการณ์สำหรับตัวอย่างด้วยอัลกอริทึมของฉันและบันทึกผลลัพธ์ 3 รายการเหล่านี้ลงในดาต้าดาต้าแพนด้าของคอลัมน์ 'ทำนายล่วงหน้า SVR', 'ปฎิเส ธ แลสโซ' และ 'คาดการณ์ GBR' และฉันเพิ่มคอลัมน์สุดท้ายลงใน datafrane นี้ซึ่งฉันเรียกว่า 'ทำนาย' ซึ่งเป็นค่าการทำนายที่แท้จริง

จากนั้นฉันก็ฝึกการถดถอยเชิงเส้นสำหรับดาต้าเฟรมใหม่นี้:

 #df - dataframe with results of 3 regressors and true output

 from sklearn linear_model
 stacker= linear_model.LinearRegression()
 stacker.fit(df[['predictedSVR', 'predictedLASSO', 'predictedGBR']], df['predicted'])

ดังนั้นเมื่อฉันต้องการทำนายสำหรับตัวอย่างใหม่ฉันแค่เรียกใช้ 3 regressors ของฉันแยกกันจากนั้นฉันก็:

 stacker.predict() 

ในผลลัพธ์ของ 3 regressors ของฉัน และรับผล

ปัญหาที่นี่คือฉันกำลังหาน้ำหนักที่เหมาะสมที่สุดสำหรับ regressors 'โดยเฉลี่ยน้ำหนักจะเหมือนกันสำหรับแต่ละตัวอย่างที่ฉันจะพยายามทำนาย

หากใครมีความคิดเห็นใด ๆ เกี่ยวกับวิธีการซ้อน (น้ำหนัก) โดยใช้คุณสมบัติของตัวอย่างปัจจุบันจะเป็นการดีหากได้ยิน


ว้าวฉันชอบวิธีนี้มาก! แต่ทำไมคุณถึงใช้โมเดลLinearRegression()แทน LogisticRegression()?
harrison4

1
@ harrison4 เพราะฉันทำการถดถอยไม่ใช่งานการจัดหมวดหมู่ใช่หรือไม่ ดังนั้นฉันต้องการที่จะ 'ส่งออก' น้ำหนัก 'จากแต่ละรุ่น อย่างไรก็ตามนี่เป็นวิธีการที่ไม่ดีมีการอธิบายวิธีการที่ดี: stackoverflow.com/a/35170149/3633250
Maksim Khaitovich

ใช่ขอโทษคุณพูดถูก! ขอบคุณที่แชร์ลิงค์!
harrison4

5

หากข้อมูลของคุณมีชุดย่อยที่ชัดเจนคุณสามารถเรียกใช้อัลกอริทึมการจัดกลุ่มเช่น k-mean จากนั้นเชื่อมโยงตัวแยกประเภทแต่ละตัวกับกลุ่มที่ทำงานได้ดี เมื่อจุดข้อมูลใหม่มาถึงให้กำหนดคลัสเตอร์ที่อยู่ในนั้นและเรียกใช้ตัวจําแนกที่เกี่ยวข้อง

นอกจากนี้คุณยังสามารถใช้ระยะทางผกผันจากเซนทรอยด์เพื่อรับชุดน้ำหนักสำหรับตัวจําแนกแต่ละตัวและคาดการณ์โดยใช้การผสมเชิงเส้นของตัวจําแนกทั้งหมด


ฉันพบกระดาษทดสอบ stategy นี้ (พร้อมกับการเปรียบเทียบความคิดที่คล้ายกัน): กระดาษ
anthonybell

ความคิดที่น่าสนใจ แต่ต้องใช้งานมากเพื่อ appy ขอบคุณสำหรับกระดาษ!
Maksim Khaitovich

1

ฉันทำน้ำหนักประเภทหนึ่งสำเร็จโดยทำสิ่งต่อไปนี้เมื่อแบบจำลองทั้งหมดของคุณได้รับการฝึกอบรมอย่างเต็มที่และทำงานได้ดี:

  1. ใช้แบบจำลองทั้งหมดของคุณในชุดข้อมูลการทดสอบที่มองไม่เห็นจำนวนมาก
  2. เก็บคะแนน f1 ไว้ในชุดทดสอบสำหรับแต่ละชั้นเรียนสำหรับแต่ละรุ่น
  3. เมื่อคุณคาดการณ์กับทั้งมวลแต่ละโมเดลจะให้คลาสที่เป็นไปได้มากที่สุดดังนั้นให้ลดความมั่นใจหรือความน่าจะเป็นด้วยคะแนน f1 สำหรับโมเดลนั้นในคลาสนั้น หากคุณกำลังจัดการกับระยะทาง (เช่นใน SVM เป็นต้น) ให้ทำการปรับระยะทางปกติเพื่อให้ได้ความมั่นใจโดยทั่วไปแล้วดำเนินการตามการถ่วงน้ำหนักต่อคลาส f1

คุณสามารถปรับวงดนตรีของคุณต่อไปโดยการวัดเปอร์เซ็นต์ที่ถูกต้องในบางครั้ง เมื่อคุณมีชุดข้อมูลใหม่ที่มีขนาดใหญ่และมีคะแนนอย่างมากคุณสามารถพล็อตขีด จำกัด ในขั้นตอนที่ 0.1 เช่นเทียบกับเปอร์เซ็นต์ที่ถูกต้องหากใช้ขีด จำกัด นั้นเพื่อให้คะแนนเพื่อให้ทราบว่าเกณฑ์ใดจะให้คุณพูด สำหรับชั้น 1 และอื่น ๆ คุณสามารถอัปเดตชุดการทดสอบและคะแนน f1 ต่อไปเมื่อมีข้อมูลใหม่เข้ามาและติดตามการดริฟท์สร้างโมเดลใหม่เมื่อขีด จำกัด หรือความแม่นยำลดลง


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