Linijinė regresija naudojama, kai norime nuspėti skaitinę reikšmę (pavyzdžiui, namo kainą, temperatūrą ar pardavimus). Ji veikia ieškodama tiesės, kuri geriausiai atspindi ryšį tarp įvesties požymių ir išvesties.
Šiame pamokoje daugiausia dėmesio skiriame koncepcijos supratimui, prieš nagrinėjant pažangesnes regresijos technikas.

Infografika autoriaus Dasani Madipalli
Iki šiol jūs susipažinote, kas yra regresija, naudodami pavyzdinius duomenis iš moliūgų kainų rinkinio, kurį naudosime per visą pamoką. Taip pat juos vizualizavote naudodami Matplotlib.
Dabar esate pasiruošę giliau gilintis į regresiją ML kontekste. Nors vizualizacija leidžia geriau suprasti duomenis, tikroji Mašininio Mokymosi galia kyla iš modelių mokymo. Modeliai mokomi pagal istorinį duomenų rinkinį, kad automatiškai užfiksuotų duomenų priklausomybes ir leistų prognozuoti rezultatus naujiems, anksčiau nematytiems duomenims.
Šioje pamokoje sužinosite daugiau apie du regresijos tipus: pagrindinę linijinę regresiją ir polininę regresiją, taip pat apie dalį matematikos, esančios šių metodų pagrindu. Šie modeliai leis mums prognozuoti moliūgų kainas, remiantis skirtingais įvesties duomenimis.
🎥 Paspauskite aukščiau esančią nuotrauką, kad peržiūrėtumėte trumpą linijinės regresijos apžvalgą.
Per visą šią kurso programą mes laikome, kad matematikos žinios minimalios ir stengiamės jas padaryti prieinamas studentams iš kitų sričių, todėl atkreipkite dėmesį į pastabas, 🧮 iškylamuosius langus, diagramas ir kitus mokymosi įrankius, padedančius suvokimui.
Jau turėtumėte būti susipažinę su moliūgų duomenų struktūra, kurią nagrinėjame. Ją galite rasti iš anksto įkeltą ir išvalytą šios pamokos notebook.ipynb faile. Faile moliūgų kaina rodoma už bushelį naujame duomenų rinkinyje. Užtikrinkite, kad galite paleisti šiuos užrašų knygelių failus Visual Studio Code branduoliuose.
Primename, kad duomenis įkeliame tam, kad galėtume užduoti klausimus.
- Kada geriausia pirkti moliūgus?
- Kokios kainos galiu tikėtis už iešminius moliūgus dėžėje?
- Ar pirkti juos per pusės bushelio krepšius, ar per 1 1/9 bushelio dėžutes? Toliau gilinamės į šiuos duomenis.
Praeitoje pamokoje sukūrėte Pandas duomenų rinkinį ir užpildėte jį dalimi originalių duomenų, standartizuodami kainas pagal bushelį. Tačiau tai leido surinkti tik apie 400 duomenų taškų ir tik rudens mėnesiams.
Pažiūrėkite į duomenis, kuriuos iš anksto įkėlėme šios pamokos užrašų knygelėje. Duomenys įkelti ir parodytas pradinis sklaidos grafikas rodo mėnesio duomenis. Galbūt galime dar šiek tiek plačiau pažvelgti į duomenų pobūdį, juos dar labiau išvalydami.
Kaip sužinojote 1-pamokoje, linijinės regresijos užduotis yra nubraižyti tiesę, kuri:
- Atvaizduoja kintamųjų ryšius. Parodo sąryšį tarp kintamųjų
- Leidžia prognozuoti. Tiksliai numatyti, kur naujas duomenų taškas kris santykyje su ta tiesė.
Įprasta mažiausių kvadratų regresijoje piešti tokį tiesiųjį grafiką. Terminas „Mažiausių kvadratų“ reiškia procesą, kurio metu minimalizuojama bendroji klaida modelyje. Kiekvienam duomenų taškui matuojame vertikalų atstumą (vadinamą likučiu) tarp tikrosios reikšmės ir mūsų regresijos linijos.
Šiuos atstumus kvadratuojame dėl dviejų pagrindinių priežasčių:
-
Dydžio svarba, o ne kryptis: Norime, kad klaida -5 būtų vertinama taip pat kaip +5. Kvadratuojant visos reikšmės tampa teigiamos.
-
Išskirtinių atvejų bausmė: Kvadratuojant didelės klaidos įgauna didesnį svorį, dėl to tiesė stengiasi būti arčiau toli esančių taškų.
Tada sudedame visus kvadratuotus atstumus. Mūsų tikslas – rasti tą tiesę, kuri minimizuoja šį sumą (mažiausia įmanoma reikšmė) – todėl vadinama „mažiausių kvadratų“ metodu.
🧮 Parodykite man matematiką
Ši tiesė, vadinama geriausiai pritaikyta tiesė, gali būti išreikšta lygtimi:
Y = a + bX
Xyra 'paaiškinamasis kintamasis'.Yyra 'priklausomas kintamasis'. Tiesės nuolydis yrab, oayra y-interceptas, kuris reiškiaYreikšmę, kaiX = 0.Pirmiausia apskaičiuojame nuolydį
b. Infografika autoriaus Jen LooperKitaip tariant, kalbant apie mūsų moliūgų duomenų pradinį klausimą: „prognozuoti moliūgų kainą už bushelį pagal mėnesį“,
Xreikštų kainą, oYbūtų pardavimo mėnuo.Apskaičiuokite
Yreikšmę. Jei mokate apie 4 USD, tai turi būti balandis! Infografika autoriaus Jen LooperMatematikos formule turi parodyti linijos nuolydį, kuris taip pat priklauso nuo sankirtos, arba kur
Yyra, kaiX=0.Galite stebėti skaičiavimo metodą šioje svetainėje Math is Fun. Taip pat apsilankykite Šiame mažiausių kvadratų skaičiuoklyje, kad pamatytumėte, kaip skaičių vertės veikia tiesę.
Dar vienas svarbus terminas yra koreliacijos koeficientas tarp tam tikrų X ir Y kintamųjų. Naudodami sklaidos grafiką greitai galite vizualizuoti šį koeficientą. Grafikas su duomenų taškais, susitelkusiais į tvarkingą liniją, turi aukštą koreliaciją, o su duomenų taškais išsibarsčiusiais tarp X ir Y - žemą koreliaciją.
Geras linijinės regresijos modelis turi būti toks, kurio koreliacijos koeficientas pagal mažiausių kvadratų regresijos metodą yra aukštas (arčiau 1 nei 0).
✅ Paleiskite šios pamokos užrašų knygelę ir pažiūrėkite į Month–Price sklaidos grafiką. Ar duomenys, susiejantys mėnesį su moliūgų kainomis, atrodo turintys aukštą ar žemą koreliaciją pagal jūsų vizualinę sklaidos grafiką? Ar tai pasikeičia, jei vietoje Month panaudojate smulkesnį matavimą, pvz., metų dieną (t.y. dienų skaičių nuo metų pradžios)?
Toliau pateiktame kode skelbiame, kad duomenys buvo sutvarkyti ir mes turime duomenų rėmelį new_pumpkins, panašų į šį:
| ID | Mėnuo | MetųDiena | Veislė | Miestas | Pakuotė | Žemiausia kaina | Aukščiausia kaina | Kaina |
|---|---|---|---|---|---|---|---|---|
| 70 | 9 | 267 | PYRAGO TIPO | BALTIMORA | 1 1/9 bushelio dėžutės | 15.0 | 15.0 | 13.636364 |
| 71 | 9 | 267 | PYRAGO TIPO | BALTIMORA | 1 1/9 bushelio dėžutės | 18.0 | 18.0 | 16.363636 |
| 72 | 10 | 274 | PYRAGO TIPO | BALTIMORA | 1 1/9 bushelio dėžutės | 18.0 | 18.0 | 16.363636 |
| 73 | 10 | 274 | PYRAGO TIPO | BALTIMORA | 1 1/9 bushelio dėžutės | 17.0 | 17.0 | 15.454545 |
| 74 | 10 | 281 | PYRAGO TIPO | BALTIMORA | 1 1/9 bushelio dėžutės | 15.0 | 15.0 | 13.636364 |
Duomenų valymo kodas yra prieinamas faile
notebook.ipynb. Atlikome tuos pačius valymo žingsnius kaip ir ankstesnėje pamokoje ir apskaičiavomeDayOfYearstulpelį naudodami šią išraišką:
day_of_year = pd.to_datetime(pumpkins['Date']).apply(lambda dt: (dt-datetime(dt.year,1,1)).days)Dabar, kai suprantate linijinės regresijos matematinius pagrindus, sukurkime Regresijos modelį, kad sužinotume, ar galime prognozuoti, kuri moliūgų pakuotė turės geriausias kainas. Kas nors, perkantis moliūgus šventiniam moliūgų laukui, norėtų turėti šią informaciją, kad galėtų optimizuoti moliūgų pirkimus.
🎥 Paspauskite aukščiau esančią nuotrauką, kad peržiūrėtumėte trumpą koreliacijos apžvalgą.
Iš ankstesnės pamokos greičiausiai jau matėte, kad vidutinė kainų tendencija pagal mėnesius atrodo maždaug taip:
Tai rodo, kad turėtų būti kažkokia koreliacija, ir galime bandyti apmokyti linijinės regresijos modelį prognozuoti ryšį tarp Month ir Price arba tarp DayOfYear ir Price. Štai sklaidos grafikas, rodantis pastarąjį ryšį:
Pažiūrėkime, ar yra koreliacija naudodami funkciją corr:
print(new_pumpkins['Month'].corr(new_pumpkins['Price']))
print(new_pumpkins['DayOfYear'].corr(new_pumpkins['Price']))Atrodo, kad koreliacija gana maža, -0,15 pagal Month ir -0,17 pagal DayOfMonth, bet gali būti kitas svarbus ryšys. Atrodo, kad kainų grupės atitinka skirtingas moliūgų veisles. Norėdami patvirtinti šią hipotezę, nubraižykime kiekvieną moliūgų kategoriją skirtingomis spalvomis. Paduodami ax parametrą funkcijai scatter, galime nubraižyti visus taškus vienoje diagramoje:
ax=None
colors = ['red','blue','green','yellow']
for i,var in enumerate(new_pumpkins['Variety'].unique()):
df = new_pumpkins[new_pumpkins['Variety']==var]
ax = df.plot.scatter('DayOfYear','Price',ax=ax,c=colors[i],label=var)Mūsų tyrimas rodo, kad veislė labiau veikia bendrą kainą nei tikroji pardavimo data. Tai galime pamatyti ir juostinėje diagramoje:
new_pumpkins.groupby('Variety')['Price'].mean().plot(kind='bar')Tuo tarpu sutelkime dėmesį tik į vieną moliūgų veislę, ‘pie type’, ir pažiūrėkime, kokį poveikį data turi kainai:
pie_pumpkins = new_pumpkins[new_pumpkins['Variety']=='PIE TYPE']
pie_pumpkins.plot.scatter('DayOfYear','Price') Jei dabar apskaičiuosime koreliaciją tarp Price ir DayOfYear panaudodami funkciją corr, gausime kažką panašaus į -0.27 – o tai reiškia, kad verta apmokyti prognozuojamą modelį.
Prieš pradėdami apmokyti linijinės regresijos modelį, svarbu įsitikinti, kad duomenys yra švarūs. Linijinė regresija prastai veikia su trūkstamomis reikšmėmis, todėl verta pašalinti visas tuščias langelius:
pie_pumpkins.dropna(inplace=True)
pie_pumpkins.info()Kitas būdas - užpildyti tuščias reikšmes atitinkamų stulpelių vidurkiais.
🎥 Paspauskite aukščiau esančią nuotrauką, kad peržiūrėtumėte trumpą linijinės ir polininės regresijos apžvalgą.
Mūsų Linijinės regresijos modelio mokymui naudosime Scikit-learn biblioteką.
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_splitPradėsime atskirdami įvesties reikšmes ( požymius) ir laukiamą išvestį (etiketę) į atskirus numpy masyvus:
X = pie_pumpkins['DayOfYear'].to_numpy().reshape(-1,1)
y = pie_pumpkins['Price']Atkreipkite dėmesį, kad reikėjo atlikti
reshapesu įvesties duomenimis, kad Linijinės regresijos paketas suprastų juos teisingai. Linijinė regresija laukia 2D masyvo kaip įvesties, kur kiekviena masyvo eilutė atitinka požymių vektorių. Mūsų atveju, kai turime tik vieną įvestį, mums reikia masyvo formos N×1, kur N – duomenų rinkinio dydis.
Tada turime padalinti duomenis į mokymo ir testavimo rinkinius, kad galėtume modelį patikrinti po mokymo:
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)Galiausiai, faktinis Linijinės regresijos modelio mokymas užima tik dvi kodo eilutes. Apibrėžiame LinearRegression objektą ir pritaikome jį mūsų duomenims naudodami fit metodą:
lin_reg = LinearRegression()
lin_reg.fit(X_train,y_train)LinearRegression objektas po fit pritaikymo turi visus regresijos koeficientus, prie kurių galima prieiti naudodami .coef_ savybę. Mūsų atveju yra tik vienas koeficientas, kuris turėtų būti maždaug -0.017. Tai reiškia, kad kainos, atrodo, šiek tiek krinta laikui bėgant, bet ne per daug, apie 2 centus per dieną. Taip pat galime prieiti prie regresijos susikirtimo su Y ašimi naudodami lin_reg.intercept_ – mūsų atveju jis bus maždaug 21, rodantis kainą metų pradžioje.
Norėdami pamatyti, kokia tiksliai yra mūsų modelio kokybė, galime prognozuoti kainas testiniame duomenų rinkinyje ir tada pamatuoti, kiek mūsų prognozės yra arti tikėtinų reikšmių. Tai galima padaryti naudojant vidurinės kvadratinės paklaidos (MSE) metriką, kuri yra visų kvadratinių skirtumų tarp tikėtinos ir prognozuotos reikšmės vidurkis.
pred = lin_reg.predict(X_test)
mse = np.sqrt(mean_squared_error(y_test,pred))
print(f'Mean error: {mse:3.3} ({mse/np.mean(pred)*100:3.3}%)')Mūsų klaida atrodo apie 2 taškus, tai apie ~17%. Ne per gera. Kitas modelio kokybės indikatorius yra nustatymo koeficientas, kurį galima gauti taip:
score = lin_reg.score(X_train,y_train)
print('Model determination: ', score)Jei reikšmė yra 0, tai reiškia, kad modelis neatsižvelgia į įvesties duomenis ir veikia kaip blogiausias tiesinis prognozuotojas, kuris tiesiog paima vidutinę reikšmę. Reikšmė 1 reiškia, kad galime tobulai prognozuoti visas tikėtinas reikšmes. Mūsų atveju koeficientas yra apie 0.06, kas yra gan žema.
Taip pat galime nupiešti testinius duomenis kartu su regresijos linija, kad geriau matytume, kaip regresija veikia mūsų atveju:
plt.scatter(X_test,y_test)
plt.plot(X_test,pred)Kitas linijinės regresijos tipas yra polinominė regresija. Nors kartais tarp kintamųjų yra tiesinė priklausomybė – kuo didesnis moliūnas tūriu, tuo didesnė kaina – kartais šių priklausomybių negalima nubraižyti plokštuma ar tiesia linija.
✅ Čia yra daugiau pavyzdžių duomenų, kuriems gali tikti polinominė regresija
Dar kartą pažiūrėkite į priklausomybę tarp Datos ir Kainos. Ar šis taškų debesis būtinai turėtų būti analizuojamas tiesia linija? Ar kainos negali svyruoti? Tokiu atveju galite išbandyti polinominę regresiją.
✅ Polinomai yra matematiniai išraiškos, kurios gali susidaryti iš vieno ar daugiau kintamųjų ir koeficientų
Polinominė regresija sukuria išlenktą liniją, kad geriau pritaikytų netiesinius duomenis. Mūsų atveju, jei į įvesties duomenis įtrauksime pakeltą kvadratu DayOfYear kintamąjį, galėsime pritaikyti duomenis parabolės formai, turinčiai minimumą metų viduje.
Scikit-learn turi naudingą pipeline API, leidžiančią sujungti skirtingus duomenų apdorojimo žingsnius. Pipeline yra lankų seka. Mūsų atveju sukursime pipeline, kuris pirmiausia prideda polinominius požymius prie mūsų modelio ir tada treniruoja regresiją:
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
pipeline.fit(X_train,y_train)Naudojant PolynomialFeatures(2) reiškia, kad įtraukiame visus antro laipsnio polinomus iš įvesties duomenų. Mūsų atveju tai reikštų tik DayOfYear2, bet turint du kintamuosius X ir Y, bus pridedama X2, XY ir Y2. Taip pat galime naudoti aukštesnio laipsnio polinomus, jei norime.
Pipelines galima naudoti taip pat kaip originalų LinearRegression objektą, t.y. galime pritaikyti fit pipeline, o paskui naudoti predict, kad gautume prognozių rezultatus. Čia pateiktas grafikas, rodantis testinius duomenis ir aproksimacinę kreivę:
Naudodami polinominę regresiją galime gauti šiek tiek mažesnį MSE ir didesnį nustatymo koeficientą, bet ne žymiai. Turime atsižvelgti į daugiau požymių!
Galite pastebėti, kad mažiausios moliūnų kainos fiksuojamos kažkur apie Heloviną. Kaip tai galėtumėte paaiškinti?
🎃 Sveikiname, ką tik sukūrėte modelį, kuris gali padėti prognozuoti pyraginių moliūnų kainą. Tikriausiai galite tą patį padaryti visoms moliūnų rūšims, bet tai būtų varginanti užduotis. Dabar išmoksime, kaip atsižvelgti į moliūnų veislę mūsų modelyje!
Idealioje pasaulyje norėtume galėti prognozuoti kainas skirtingoms moliūnų veislėms naudojant tą patį modelį. Tačiau stulpelis Variety yra šiek tiek kitoks nei, pavyzdžiui, Month, nes jame yra ne skaitinės reikšmės. Tokie stulpeliai vadinami kategoriniais.
🎥 Paspauskite aukščiau esančią nuotrauką, jei norite trumpą vaizdo įrašą apie kategorinių požymių naudojimą.
Čia matote, kaip vidutinė kaina priklauso nuo veislės:
Norėdami atsižvelgti į veislę, pirmiausia turime ją paversti skaitine reikšme, arba užkoduoti ją. Yra keli būdai, kaip tai padaryti:
- Paprastas skaitmeninis kodavimas sukurs skirtingų veislių lentelę, o tada veislės pavadinimą pakeis indeksu šioje lentelėje. Tai nėra geriausias sprendimas tiesinei regresijai, nes tiesinė regresija naudoja tikrąją skaitinę indekso reikšmę ir prideda ją prie rezultato pasvėrusi tam tikru koeficientu. Mūsų atveju priklausomybė tarp indekso numerio ir kainos yra aiškiai netiesinė, net jei užtikrintume, kad indeksai būtų išdėstyti tam tikra tvarka.
- One-hot kodavimas pakeis
Varietystulpelį 4 skirtingais stulpeliais, po vieną kiekvienai veislei. Kiekviename stulpelyje bus1, jei atitinkamas įrašas yra tos veislės, ir0kitu atveju. Tai reiškia, kad tiesinėje regresijoje bus keturi koeficientai, po vieną kiekvienai moliūnų veislei, atsakingi už "pradinę kainą" (ar tiksliau - "papildomą kainą") konkrečiai veislei.
Žemiau pateiktas kodas, rodantis, kaip galima one-hot koduoti veislę:
pd.get_dummies(new_pumpkins['Variety'])| ID | FAIRYTALE | MINIATURE | MIXED HEIRLOOM VARIETIES | PIE TYPE |
|---|---|---|---|---|
| 70 | 0 | 0 | 0 | 1 |
| 71 | 0 | 0 | 0 | 1 |
| ... | ... | ... | ... | ... |
| 1738 | 0 | 1 | 0 | 0 |
| 1739 | 0 | 1 | 0 | 0 |
| 1740 | 0 | 1 | 0 | 0 |
| 1741 | 0 | 1 | 0 | 0 |
| 1742 | 0 | 1 | 0 | 0 |
Norėdami apmokyti tiesinę regresiją, naudodami one-hot koduotą veislę kaip įvestį, tiesiog turime teisingai inicializuoti X ir y duomenis:
X = pd.get_dummies(new_pumpkins['Variety'])
y = new_pumpkins['Price']Likusi kodo dalis tokia pati kaip aukščiau naudota tiesinei regresijai treniruoti. Jei išbandysite, pamatysite, kad vidutinė kvadratinė klaida bus maždaug tokia pati, bet gausime daug didesnį nustatymo koeficientą (~77%). Norėdami gauti dar tikslesnes prognozes, galime atsižvelgti į daugiau kategorinių požymių, taip pat į skaitinius požymius, tokius kaip Month ar DayOfYear. Norėdami gauti vieną didelį požymių masyvą, galime naudoti join:
X = pd.get_dummies(new_pumpkins['Variety']) \
.join(new_pumpkins['Month']) \
.join(pd.get_dummies(new_pumpkins['City'])) \
.join(pd.get_dummies(new_pumpkins['Package']))
y = new_pumpkins['Price']Čia taip pat atsižvelgiame į City ir Package tipą, kas duoda MSE 2.84 (10%) ir nustatymo koeficientą 0.94!
Kad sukurtume geriausią modelį, galime naudoti sujungtus (one-hot koduotus kategorinius + skaitinius) duomenis kartu su polinomine regresija. Štai viso kodo pavyzdys jūsų patogumui:
# nustatyti mokymo duomenis
X = pd.get_dummies(new_pumpkins['Variety']) \
.join(new_pumpkins['Month']) \
.join(pd.get_dummies(new_pumpkins['City'])) \
.join(pd.get_dummies(new_pumpkins['Package']))
y = new_pumpkins['Price']
# padaryti treniruočių ir testavimo skaidymą
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
# sukonfigūruoti ir apmokyti procesų seką
pipeline = make_pipeline(PolynomialFeatures(2), LinearRegression())
pipeline.fit(X_train,y_train)
# prognozuoti rezultatus testavimo duomenims
pred = pipeline.predict(X_test)
# apskaičiuoti vidutinę kvadratinę paklaidą ir determinacijos koeficientą
mse = np.sqrt(mean_squared_error(y_test,pred))
print(f'Mean error: {mse:3.3} ({mse/np.mean(pred)*100:3.3}%)')
score = pipeline.score(X_train,y_train)
print('Model determination: ', score)Tai turėtų duoti geriausią nustatymo koeficientą beveik 97% ir MSE=2.23 (~8% prognozės klaida).
| Modelis | MSE | Nustatymas |
|---|---|---|
DayOfYear Tiesinė |
2.77 (17.2%) | 0.07 |
DayOfYear Polinominė |
2.73 (17.0%) | 0.08 |
Variety Tiesinė |
5.24 (19.7%) | 0.77 |
| Visi požymiai Tiesinė | 2.84 (10.5%) | 0.94 |
| Visi požymiai Polinominė | 2.23 (8.25%) | 0.97 |
🏆 Puikiai! Pamokoje sukūrėte keturis regresijos modelius ir pagerinote modelio kokybę iki 97%. Galutinėje regresijos dalyje susipažinsite su logistinę regresiją, skirtą kategorijoms nustatyti.
Išbandykite kelis skirtingus kintamuosius šiame sąsiuvinyje, kad pamatytumėte, kaip koreliacija atitinka modelio tikslumą.
Šioje pamokoje išmokome apie tiesinę regresiją. Yra ir kitų svarbių regresijos tipų. Perskaitykite apie žingsninę, „ridge“, lasso ir elasticnet technikas. Geras kursas, norint sužinoti daugiau, yra Stanford statistinio mokymosi kursas
Atsakomybės apribojimas:
Šis dokumentas buvo išverstas naudojant dirbtinio intelekto vertimo paslaugą Co-op Translator. Nors siekiame tikslumo, atkreipkite dėmesį, kad automatizuoti vertimai gali turėti klaidų ar netikslumų. Originalus dokumentas jo gimtąja kalba turėtų būti laikomas autoritetingu šaltiniu. Svarbiai informacijai rekomenduojame pasitelkti profesionalų žmogišką vertimą. Mes neatsakome už bet kokius nesusipratimus ar klaidingą interpretaciją, kilusią naudojant šį vertimą.












