Pitanje:
Ansambl različitih vrsta regresora pomoću scikit-learn (ili bilo kojeg drugog python okvira)
Maksim Khaitovich
2015-02-24 20:29:46 UTC
view on stackexchange narkive permalink

Pokušavam riješiti zadatak regresije. Otkrio sam da 3 modela lijepo rade za različite podskupove podataka: LassoLARS, SVR i Gradient Tree Boosting. Primijetio sam da kada izrađujem predviđanja koristeći sva ova 3 modela, a zatim napravim tablicu 'istinitih rezultata' i izlaza svoja 3 modela, vidim da je svaki put barem jedan od modela stvarno blizu istinitog rezultata, iako 2 druga mogao biti relativno daleko.

Kada izračunam minimalnu moguću pogrešku (ako za svaki testni primjer uzmem predviđanje iz 'najboljeg' prediktora), dobit ću pogrešku koja je puno manja od pogreške bilo kojeg modela sama. Pa sam razmišljao o pokušaju kombiniranja predviđanja iz ova tri različita modela u nekakav ansambl. Pitanje je, kako to pravilno učiniti? Sva moja 3 modela izrađena su i podešena pomoću scikit-learn-a, pruža li neka vrsta metode koja bi se mogla koristiti za spakiranje modela u ansambl? Ovdje je problem u tome što ne želim samo prosječno predviđati sva tri modela, želim to raditi s ponderiranjem, gdje bi se ponderiranje trebalo odrediti na temelju svojstava konkretnog primjera.

Čak i ako scikit- learn ne pruža takvu funkcionalnost, bilo bi lijepo kad bi netko znao kako se svojstvo pozabaviti tim zadatkom - utvrđivanjem ponderiranja svakog modela za svaki primjer u podacima. Mislim da bi to mogao učiniti zasebni regresor izgrađen na vrhu sva ova 3 modela, koji će pokušati dati optimalne težine za svaki od 3 modela, ali nisam siguran je li to najbolji način za to.

četiri odgovori:
constt
2017-04-17 19:05:15 UTC
view on stackexchange narkive permalink

Zapravo, scikit-learn pruža takvu funkcionalnost, iako bi to moglo biti malo nezgodno implementirati. Evo cjelovitog radnog primjera tako prosječnog regresora izgrađenog na vrhu tri modela. Prije svega, uvezimo sve potrebne pakete:

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

Zatim moramo pretvoriti naša tri modela regresora u transformatore. To će nam omogućiti spajanje njihovih predviđanja u jedan vektor značajke pomoću FeatureUnion :

  klasa RidgeTransformer (Ridge, TransformerMixin):

    def transformacija (self, X, * _):
        povratak self.predict (X) .reshape (len (X), -1)


klasa RandomForestTransformer (RandomForestRegressor, TransformerMixin):

    def transformacija (self, X, * _):
        povratak self.predict (X) .reshape (len (X), -1)


klasa KNeighborsTransformer (KNeighborsRegressor, TransformerMixin):

    def transformacija (self, X, * _):
        povratak self.predict (X) .reshape (len (X), -1)
 

Sada, definirajmo funkciju graditelja za naš frankensteinski model:

  def build_model ():
    ridge_transformer = Cjevovod (koraci = [
        ('skaler', StandardScaler ()),
        ('poly_feats', PolynomialFeatures ()),
        ('greben', RidgeTransformer ())
    ]))

    pred_union = FeatureUnion (
        popis_ transformatora = [
            ('greben', greben_transformer),
            ('rand_forest', RandomForestTransformer ()),
            ('knn', KNeighborsTransformer ())
        ],
        n_poslova = 2
    )

    model = cjevovod (koraci = [
        ('pred_union', pred_union),
        ('lin_regr', Linearna regresija ())
    ]))

    model povratka
 

Napokon, uklopimo model:

  print ('Izraditi i uklopiti model ...')

model = graditi_model ()

X, y = regresija_napravke (n_karakteristike = 10)
X_train, X_test, y_train, y_test = vlak_test_split (X, y, test_size = 0.2)

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

print ('Gotovo. Rezultat:', rezultat)
 

Izlaz:

  Izradite i uklopite model ...
Gotovo.Ocjena: 0,9600413867438636
 

Zašto se truditi komplicirati stvari na takav način?Pa, ovaj pristup omogućuje nam optimizaciju hiperparametara modela pomoću standardnih scikit-learn modula kao što su GridSearchCV ili RandomizedSearchCV .Također, sada je moguće jednostavno spremiti i učitati s diska unaprijed obučeni model.

Kada se koristi ovaj pristup, postoji li jednostavan način da se izdvoji koji se algo koristi kada / koji udio svakog alga?
Možda će vam gledanje koeficijenata rezultirajućeg linearnog modela (`model.named_steps ['lin_regr']. Coef_`) dati neke uvide u to koliko svaki model u cjelini doprinosi konačnom rješenju.
@constt Ne biste li trebali koristiti cross_val_predict u svojim osnovnim modelima?Čini se da bi vaš model najviše razine dobio pretjerano optimističan signal od vaših osnovnih modela jer je ovo trenutno implementirano.
Ovo je samo nekako dokaz koncepta, ovdje se nisam bavio odabirom modela.Mislim da bi takve modele trebalo optimizirati u cjelini, tj. Optimizirati hiper-parametre svih ugrađenih modela istovremeno koristeći pristup unakrsne provjere.
ako stavimo n_targets = 1 `X, y = make_regression (n_features = 10, n_targets = 1)` to daje dimenzijsku pogrešku.moze li netko objasniti sta da radim?
@constt `model.fit (X_train, y_train)` ovaj redak mi daje pogrešku, kada napravim skup podataka poput ovog `X, y = make_regression (n_features = 10, n_targets = 1)`.
Ako dam `n_targets = 1` (ili ga ne navedem), dobit ću pogrešku:` ValueError: Očekivani 2D niz, umjesto njega dobio 1D niz ... Preoblikujte svoje podatke pomoću array.reshape (-1, 1)ako vaši podaci imaju jednu značajku ili array.reshape (1, -1) ako sadrže jedan uzorak. `Pa, učinio sam predloženo preoblikovanje i X i y, odvojeno kao i obje zajedno, ali pogreška ne značiodlazi.Nadalje, kada sam napravio `X = np.array (X)`, dobio sam `Win 32 PermissionError`.Kako mogu popraviti ove pogreške kada moj cilj ima samo 1 stupac?
Oprostite, momci, nisam bio ovdje već neko vrijeme.Molimo provjerite uređivanja koja sam napravio za "transformiranje" metoda klasa transformatora, sada model radi za podatke o "1D" obuci.
Zaglavi tijekom `modela.fit (X_train, y_train)`, čak i s malim brojem uzoraka, i proizvodi zastarjela upozorenja `DeprecationWarning: numpy.core.umath_tests je interni NumPy modul i ne smije se uvoziti.Uklonit će se u budućem izdanju NumPy-a. `.
@shahar_m Ne znam, za mene to djeluje kao šarm.Bez upozorenja.Python 3.6.9, scikit-learn 0.23.1, numpy 1.18.4
@constt Koristim scikit-learn verziju 0.19.2 jer jedina podržava onnx pretvorbu.
Maksim Khaitovich
2015-02-26 22:41:20 UTC
view on stackexchange narkive permalink

Ok, nakon što sam proveo neko vrijeme na guglanju, otkrio sam kako mogu izvršiti ponderiranje u pythonu čak i sa scikit-learnom. Razmotrite dolje:

Treniram niz svojih regresijskih modela (kao što je spomenuto SVR, LassoLars i GradientBoostingRegressor). Zatim ih sve pokrenem na podacima o treningu (istim podacima koji su korišteni za trening svakog od ova 3 regresora). Dobivam predviđanja za primjere sa svakim od svojih algoritama i spremam ova 3 rezultata u podatkovni okvir pandi sa stupcima 'predvidjenSVR', 'predvidjeniLASSO' i 'predvidjeniGBR'. I dodajem završni stupac u ovaj datafrane koji nazivam 'predvidjenim' što je stvarna vrijednost predviđanja.

Tada samo treniram linearnu regresiju na ovom novom podatkovnom okviru:

  #df - podatkovni okvir s rezultatima 3 regresora i istinskim izlazom iz sklearn line_model stacker = linear_model.LinearRegression () stacker.fit (df [['predvidioSVR', 'predvidioLASSO', 'predvidioGBR']], df ['predvidio'] )  

Dakle, kada želim izraditi predviđanje za novi primjer, jednostavno pokrenem svaki od svoja 3 regresora odvojeno, a zatim radim:

  stacker.predict () 

na izlazima moja 3 regresora. I postići rezultat.

Ovdje je problem što u prosjeku pronalazim optimalne težine za regresore, težine će biti jednake za svaki primjer na kojem ću pokušati predvidjeti.

Ako netko ima ideje o načinu slaganja (ponderiranja) koristeći značajke trenutnog primjera, bilo bi lijepo čuti ih.

Wow, jako mi se sviđa ovaj pristup!Ali zašto ste koristili `LinearRegression ()` umjesto `LogisticRegression ()` model?
@harrison4 jer sam radio regresiju, a ne klasifikacijski zadatak?Stoga sam želio 'težiti' rezultate svakog modela.U svakom slučaju, ovo je loš pristup, dobar je opisan ovdje: http://stackoverflow.com/a/35170149/3633250
Da, oprosti što si u pravu!hvala što ste podijelili vezu!
anthonybell
2015-03-24 16:22:49 UTC
view on stackexchange narkive permalink

Ako vaši podaci imaju očite podskupove, mogli biste pokrenuti algoritam klasterizacije poput k-znači, a zatim svaki klasifikator povezati s klasterima na kojima dobro izvodi. Kada stigne nova podatkovna točka, tada odredite u kojoj se grupi nalazi i pokrenite pridruženi klasifikator.

Možete koristiti i inverzne udaljenosti od centroida da biste dobili skup pondera za svaki klasifikator i predvidjeli pomoću linearne kombinacije svih klasifikatora.

Pronašao sam rad koji je testirao ovo stanje (zajedno s usporedbom nekih sličnih ideja): [rad] (http://pages.bangor.ac.uk/~mas00a/papers/lkKES00.pdf)
Zanimljiva ideja, premda zahtijeva puno rada kako bi je primijenila.Hvala na papiru!
wwwslinger
2015-02-28 21:52:06 UTC
view on stackexchange narkive permalink

Ostvarujem ponderiranje na sljedeći način, nakon što svi vaši modeli budu u potpunosti obučeni i imaju dobru izvedbu:

  1. Pokrenite sve svoje modele na velikom skupu neviđenih podataka o testiranju
  2. Pohranite ocjene f1 na testnom skupu za svaki razred, za svaki model
  3. Kada predviđate s ansamblom, svaki će vam model dati najvjerojatniju klasu, pa izmjerite pouzdanost ili vjerojatnost po ocjeni f1 za taj model u toj klasi. Ako imate posla s udaljenostom (kao na primjer u SVM-u), samo normalizirajte udaljenosti da biste dobili opće povjerenje, a zatim nastavite s ponderiranjem po klasi f1.

Možete dalje podesite svoj ansambl mjereći postotak ispravnosti tijekom određenog vremena. Jednom kada postignete znatno velik, postignut novi skup podataka, možete ucrtati prag u koracima od 0,1, na primjer, prema postotku ispravnosti ako se taj prag koristi za ocjenu, da biste dobili ideju o tome koji će vam prag dati, recimo, 95% ispravnosti za razred 1 i tako dalje. Možete nastaviti ažurirati testni set i rezultate f1 kako dolaze novi podaci i pratiti zanošenje, obnavljajući modele kad padnu pragovi ili točnost.

To je zanimljivo, ali djeluje samo za klasifikacijske zadatke, koliko vidim, dok pokušavam riješiti regresijski zadatak.Stoga ne mogu izračunati F1 rezultat.


Ova pitanja su automatski prevedena s engleskog jezika.Izvorni sadržaj dostupan je na stackexchange-u, što zahvaljujemo na cc by-sa 3.0 licenci pod kojom se distribuira.
Loading...