Sissejuhatus
Mõnikord segamini lineaarse regressiooni algajate poolt – termini jagamise tõttu regressioon - logistiline regressioon on palju erinev lineaarse regressiooni. Kui lineaarne regressioon ennustab selliseid väärtusi nagu 2, 2.45, 6.77 või pidevad väärtused, muutes selle a regressioon algoritm, logistiline regressioon ennustab selliseid väärtusi nagu 0 või 1, 1 või 2 või 3, mis on diskreetsed väärtused, muutes selle a klassifikatsioon algoritm. Jah, seda nimetatakse regressioon kuid on a klassifikatsioon algoritm. Rohkem sellest hetke pärast.
Seega, kui teie andmeteaduse probleem hõlmab pidevaid väärtusi, võite rakendada a regressioon algoritm (lineaarne regressioon on üks neist). Vastasel juhul, kui see hõlmab sisendite, diskreetsete väärtuste või klasside klassifitseerimist, saate rakendada a klassifikatsioon algoritm (logistiline regressioon on üks neist).
Selles juhendis teostame Pythonis logistilise regressiooni koos Scikit-Learni teegiga. Samuti selgitame, miks see sõna "taandareng" on nimes olemas ja kuidas logistiline regressioon toimib.
Selleks laadime esmalt andmed, mis klassifitseeritakse, visualiseeritakse ja eeltöödeldakse. Seejärel koostame logistilise regressioonimudeli, mis mõistab neid andmeid. Seejärel hinnatakse seda mudelit ja seda kasutatakse väärtuste ennustamiseks uue sisendi põhjal.
Motiveerimine
Ettevõte, kus töötate, sõlmis partnerluse Türgi põllumajandusfarmiga. See partnerlus hõlmab kõrvitsaseemnete müüki. Kõrvitsaseemned on inimeste toitumises väga olulised. Need sisaldavad heas koguses süsivesikuid, rasvu, valke, kaltsiumi, kaaliumi, fosforit, magneesiumi, rauda ja tsinki.
Andmeteaduse meeskonnas on teie ülesanne teha vahet kõrvitsaseemnete tüüpide vahel lihtsalt andmete abil – või klassifitseerimine andmed vastavalt seemnetüübile.
Türgi farm töötab kahe kõrvitsaseemnetüübiga, ühte nimetatakse Çerçevelik ja see teine Ürgüp Sivrisi.
Kõrvitsaseemnete klassifitseerimisel on teie meeskond järginud 2021. aasta paberit “Masinõppemeetodite kasutamine kõrvitsaseemnete (Cucurbita pepo L.) klassifitseerimisel. Geneetilised ressursid ja põllukultuuride evolutsioon” Koklast, Sarigilist ja Ozbekist – selles artiklis on metoodika seemnete mõõtude pildistamiseks ja piltidelt eraldamiseks.
Pärast dokumendis kirjeldatud protsessi lõpetamist ekstraheeriti järgmised mõõtmised:
- Piirkond – pikslite arv kõrvitsaseemne piirides
- Ümbermõõt – kõrvitsaseemne ümbermõõt pikslites
- Põhitelje pikkus – ka kõrvitsaseemne ümbermõõt pikslites
- Väikese telje pikkus – kõrvitsaseemne väikese telje kaugus
- Ekstsentrilisus – kõrvitsaseemne ekstsentrilisus
- Kumer ala – kõrvitsaseemne moodustatud piirkonna väikseima kumera kesta pikslite arv
- Maht – kõrvitsaseemne pindala ja piirdekasti pikslite suhe
- Samaväärne läbimõõt – ruutjuur kõrvitsaseemne pindala korrutisest neljaga jagatud pi-ga
- Kompaktsus – kõrvitsaseemne pindala suhe sama ümbermõõduga ringi pindala suhtes
- Tahked – kõrvitsaseemnete kumer ja kumer seisund
- Ümarus – kõrvitsaseemnete ovaalsus, arvestamata selle servade moonutusi
- Kuvasuhe – kõrvitsaseemnete kuvasuhe
Need on mõõdud, millega peate töötama. Lisaks mõõtudele on olemas ka klass kahte tüüpi kõrvitsaseemnete silt.
Seemnete klassifitseerimise alustamiseks impordime andmed ja hakkame neid vaatama.
Andmestiku mõistmine
Märge: Saate alla laadida kõrvitsa andmestiku siin.
Pärast andmestiku allalaadimist saame selle laadida andmeraami struktuuri, kasutades pandas
raamatukogu. Kuna tegemist on Exceli failiga, kasutame faili read_excel()
meetod:
import pandas as pd
fpath = 'dataset/pumpkin_seeds_dataset.xlsx'
df = pd.read_excel(fpath)
Kui andmed on laaditud, saame kiirelt vaadata esimest 5 rida, kasutades head()
meetod:
df.head()
Selle tulemuseks on:
Area Perimeter Major_Axis_Length Minor_Axis_Length Convex_Area Equiv_Diameter Eccentricity Solidity Extent Roundness Aspect_Ration Compactness Class
0 56276 888.242 326.1485 220.2388 56831 267.6805 0.7376 0.9902 0.7453 0.8963 1.4809 0.8207 Çerçevelik
1 76631 1068.146 417.1932 234.2289 77280 312.3614 0.8275 0.9916 0.7151 0.8440 1.7811 0.7487 Çerçevelik
2 71623 1082.987 435.8328 211.0457 72663 301.9822 0.8749 0.9857 0.7400 0.7674 2.0651 0.6929 Çerçevelik
3 66458 992.051 381.5638 222.5322 67118 290.8899 0.8123 0.9902 0.7396 0.8486 1.7146 0.7624 Çerçevelik
4 66107 998.146 383.8883 220.4545 67117 290.1207 0.8187 0.9850 0.6752 0.8338 1.7413 0.7557 Çerçevelik
Siin on meil kõik mõõtmised vastavates veergudes, meie Omadused, ja ka klass veerg, meie sihtmärk, mis on andmeraami viimane. Näeme, kui palju mõõtmisi meil on kasutades shape
atribuut:
df.shape
Väljund on:
(2500, 13)
Kujutulemus ütleb meile, et andmekogumis ja 2500 veerus on 13 kirjet (või rida). Kuna me teame, et sihtveerg on üks, tähendab see, et meil on 12 funktsioonide veergu.
Nüüd saame uurida sihtmuutujat, kõrvitsaseemneid Class
. Kuna me ennustame seda muutujat, on huvitav näha, kui palju proove igast kõrvitsaseemnest meil on. Tavaliselt, mida väiksem on erinevus meie klasside esinemisjuhtude arvu vahel, seda tasakaalustatum on meie valim ja seda paremad on meie prognoosid.
Seda kontrolli saab teha, loendades iga seemneproovi koos value_counts()
meetod:
df['Class'].value_counts()
Ülaltoodud kood kuvab:
Çerçevelik 1300
Ürgüp Sivrisi 1200
Name: Class, dtype: int64
Näeme, et seal on 1300 näidist Çerçevelik seemne ja 1200 proovi Ürgüp Sivrisi seeme. Pange tähele, et nende erinevus on 100 proovi, mis on väga väike erinevus, mis on meile kasulik ja näitab, et proovide arvu pole vaja uuesti tasakaalustada.
Vaatame ka meie funktsioonide kirjeldavat statistikat describe()
meetod, et näha, kui hästi andmed on jaotunud. Samuti võtame saadud tabeli üle T
statistika võrdlemise hõlbustamiseks:
df.describe().T
Saadud tabel on:
count mean std min 25% 50% 75% max
Area 2500.0 80658.220800 13664.510228 47939.0000 70765.000000 79076.00000 89757.500000 136574.0000
Perimeter 2500.0 1130.279015 109.256418 868.4850 1048.829750 1123.67200 1203.340500 1559.4500
Major_Axis_Length 2500.0 456.601840 56.235704 320.8446 414.957850 449.49660 492.737650 661.9113
Minor_Axis_Length 2500.0 225.794921 23.297245 152.1718 211.245925 224.70310 240.672875 305.8180
Convex_Area 2500.0 81508.084400 13764.092788 48366.0000 71512.000000 79872.00000 90797.750000 138384.0000
Equiv_Diameter 2500.0 319.334230 26.891920 247.0584 300.167975 317.30535 338.057375 417.0029
Eccentricity 2500.0 0.860879 0.045167 0.4921 0.831700 0.86370 0.897025 0.9481
Solidity 2500.0 0.989492 0.003494 0.9186 0.988300 0.99030 0.991500 0.9944
Extent 2500.0 0.693205 0.060914 0.4680 0.658900 0.71305 0.740225 0.8296
Roundness 2500.0 0.791533 0.055924 0.5546 0.751900 0.79775 0.834325 0.9396
Aspect_Ration 2500.0 2.041702 0.315997 1.1487 1.801050 1.98420 2.262075 3.1444
Compactness 2500.0 0.704121 0.053067 0.5608 0.663475 0.70770 0.743500 0.9049
Tabelit vaadates, kui võrrelda keskmine ja standardhälve (std
) veergudes on näha, et enamiku funktsioonide keskmine on standardhälbest kaugel. See näitab, et andmeväärtused ei ole koondunud keskmise väärtuse ümber, vaid on selle ümber rohkem hajutatud – teisisõnu, neil on suur varieeruvus.
Samuti, kui vaadata miinimum (min
) Ja maksimaalne (max
) veerud, mõned funktsioonid, nt Area
ja Convex_Area
, on minimaalsete ja maksimaalsete väärtuste vahel suured erinevused. See tähendab, et nendes veergudes on väga väikesed andmed ja ka väga suured andmeväärtused, või suurem amplituud andmeväärtuste vahel.
Suure varieeruvuse, suure amplituudi ja erinevate mõõtühikutega funktsioonide tõttu tuleks enamikule meie andmetest kasu, kui kõigi funktsioonide jaoks oleks sama skaala või skaleeritud. Andmete skaleerimine koondab andmed keskmise ümber ja vähendab selle dispersiooni.
See stsenaarium viitab ilmselt ka sellele, et andmetes on kõrvalekaldeid ja äärmuslikke väärtusi. Seega on parem omada mõnda kõrvaline ravi peale andmete skaleerimise.
On mõned masinõppe algoritmid, näiteks puupõhised algoritmid nagu Juhuslik metsade klassifikatsioon, mida ei mõjuta andmete suur dispersioon, kõrvalekalded ega äärmuslikud väärtused. Logistiline regressioon on erinev, see põhineb funktsioonil, mis kategoriseerib meie väärtused, ja selle funktsiooni parameetreid võivad mõjutada väärtused, mis jäävad välja üldisest andmete trendist ja millel on suur dispersioon.
Logistilisest regressioonist saame rohkem aru mõne aja pärast, kui jõuame selle ellu viia. Praegu saame oma andmete uurimist jätkata.
Märge: Arvutiteaduses on populaarne ütlus: "Prügi sisse, prügi välja" (GIGO), mis sobib hästi masinõppeks. See tähendab, et kui meil on prügiandmed – mõõtmised, mis ei kirjelda nähtusi iseenesest, andmed, mida ei mõistetud ja mis on algoritmi või mudeli järgi hästi ette valmistatud, tekitavad tõenäoliselt vale väljundi, mis ei tööta igapäevaselt.
See on üks põhjusi, miks andmete uurimine, mõistmine ja valitud mudeli toimimine on nii olulised. Seda tehes saame vältida oma mudelisse prügi panemist – selle asemel väärtustamist ja väärtuse saamist.
Andmete visualiseerimine
Siiani on meil kirjeldava statistikaga veidi abstraktne ülevaade andmete teatud omadustest. Teine oluline samm on selle visualiseerimine ja meie suure dispersiooni, amplituudi ja kõrvalekallete hüpoteesi kinnitamine. Et näha, kas seni vaadeldud andmetes kajastuvad, saame joonistada mõned graafikud.
Samuti on huvitav näha, kuidas funktsioonid on seotud kahe ennustatava klassiga. Selleks impordime seaborn
pakkida ja kasutada pairplot
graafik, et vaadata iga funktsioonide jaotust ja klasside eraldamist funktsiooni kohta:
import seaborn as sns
sns.pairplot(data=df, hue='Class')
Märge: Ülaltoodud koodi käitamine võib veidi aega võtta, kuna paarisdiagramm ühendab kõigi funktsioonide hajuvusgraafikud (saab) ja kuvab ka funktsioonide jaotused.
Paaridiagrammi vaadates näeme, et enamikul juhtudel on punktid Çerçevelik
klass on punktidest selgelt eraldatud Ürgüp Sivrisi
klass. Kas ühe klassi punktid on paremal, kui teised on vasakul, või mõned on üleval, teised aga all. Kui kasutaksime klasside eraldamiseks mingit kõverat või joont, siis see näitab, et neid on lihtsam eraldada, segades oleks klassifitseerimine raskem ülesanne.
aasta Eccentricity
, Compactness
ja Aspect_Ration
veergudes on ka mõned punktid, mis on "eraldatud" või üldisest andmetrendist kõrvalekalduvad – kõrvalekalded – kergesti märgatavad.
Diagonaali vaatamisel graafiku vasakust ülanurgast all paremale märkige, et andmete jaotus on ka meie klasside järgi värvikoodiga. Jaotuskujud ja mõlema kõvera vaheline kaugus on teised näitajad selle kohta, kui hästi need on eraldatavad – mida kaugemal üksteisest, seda parem. Enamikul juhtudel ei ole need üksteise peale asetatud, mis tähendab, et neid on lihtsam eraldada, aidates kaasa ka meie ülesande täitmisele.
Järjestuses saame joonistada ka kõigi muutujate kastdiagrammid sns.boxplot()
meetod. Enamasti on kasulik orienteerida kastplotsid horisontaalselt, nii et kastdiagrammide kujud on samad, mis jaotuskujunditel, saame seda teha orient
argument:
sns.boxplot(data=df, orient='h')
Pange tähele seda ülaltoodud süžees Area
ja Convex_Area
on teiste veergude suurusjärkudega võrreldes nii kõrged, et need nihutavad teisi kastplotte. Kõigi kastdiagrammide vaatamiseks saame funktsioone skaleerida ja uuesti joonistada.
Enne seda mõelgem lihtsalt, et kui on näiteks funktsioonide väärtusi, mis on tihedalt seotud teiste väärtustega – kui on väärtusi, mis samuti muutuvad suuremaks, kui muud funktsiooni väärtused suurenevad, on positiivne korrelatsioon; või kui on väärtusi, mis toimivad vastupidiselt, muutuvad väiksemaks, samas kui teised väärtused muutuvad väiksemaks, võttes a negatiivne korrelatsioon.
Seda on oluline vaadata, sest tugevate andmete seos võib tähendada, et mõned veerud on tuletatud teistest veergudest või neil on meie mudeliga sarnane tähendus. Kui see juhtub, võidakse mudeli tulemusi ülehinnata ja me tahame tulemusi, mis oleksid tegelikkusele lähemal. Tugevate korrelatsioonide olemasolu tähendab ka seda, et saame vähendada funktsioonide arvu ja kasutada vähem veerge, muutes mudeli paremaks tagasihoidlik.
Märge: Vaikimisi arvutatud korrelatsioon corr()
meetod on Pearsoni korrelatsioonikordaja. Seda koefitsienti näidatakse, kui andmed on kvantitatiivsed, normaalse jaotusega, neil ei ole kõrvalekaldeid ja neil on lineaarne seos.
Teine valik oleks arvutada Spearmani korrelatsioonikordaja. Spearmani koefitsienti kasutatakse siis, kui andmed on järgulised, mittelineaarsed, neil on mis tahes jaotus ja neil on kõrvalekalded. Pange tähele, et meie andmed ei sobi täielikult Pearsoni või Spearmani eeldustega (on ka rohkem korrelatsioonimeetodeid, näiteks Kendalli oma). Kuna meie andmed on kvantitatiivsed ja meie jaoks on oluline mõõta nende lineaarset seost, kasutame Pearsoni koefitsienti.
Vaatame üle muutujate omavahelised seosed ja siis saame üle minna andmete eeltöötlemisele. Arvutame korrelatsioonid corr()
meetodit ja visualiseerige need Seaborn'siga heatmap()
. Heamapi standardsuurus kipub olema väike, seega impordime matplotlib
(üldine visualiseerimismootor/teek, mille peale Seaborn on ehitatud) ja muutke selle suurust figsize
:
import matplotlib.pyplot as plt
plt.figure(figsize=(15, 10))
correlations = df.corr()
sns.heatmap(correlations, annot=True)
Sellel soojuskaardil on 1-le või -1-le lähemal olevad väärtused väärtused, millele peame tähelepanu pöörama. Esimene juhtum tähistab kõrget positiivset korrelatsiooni ja teine kõrget negatiivset korrelatsiooni. Mõlemad väärtused, kui mitte üle 0.8 või -0.8, on meie logistilise regressioonimudeli jaoks kasulikud.
Kui on kõrged korrelatsioonid, näiteks üks 0.99
vahel Aspec_Ration
ja Compactness
, see tähendab, et saame kasutada ainult Aspec_Ration
või ainult Compactness
, nende mõlema asemel (kuna nad oleksid peaaegu võrdsed ennustajad üksteisest). Sama kehtib ka Eccentricity
ja Compactness
koos -0.98
korrelatsioon, jaoks Area
ja Perimeter
koos 0.94
korrelatsioon ja mõned muud veerud.
Andmete eeltöötlemine
Kuna oleme andmeid juba mõnda aega uurinud, saame hakata neid eeltöötlema. Praegu kasutame klassi ennustamiseks kõiki funktsioone. Pärast esimese mudeli ehk baasjoone saamist saame eemaldada mõned tugevalt korrelatsiooniga veerud ja võrrelda seda lähtejoonega.
Funktsioonide veerud on meie X
andmed ja klassi veerg, meie y
sihtandmed:
y = df['Class']
X = df.drop(columns=['Class'], axis=1)
Kategooriliste tunnuste muutmine numbrilisteks tunnusteks
Seoses meie Class
veerg – selle väärtused ei ole numbrid, see tähendab, et peame ka need teisendama. Selle teisenduse tegemiseks on palju viise; siin kasutame replace()
meetod ja asendada Çerçevelik
et 0
ja Ürgüp Sivrisi
et 1
.
y = y.replace('Çerçevelik', 0).replace('Ürgüp Sivrisi', 1)
Pidage kaardistamist meeles! Mudeli tulemusi lugedes soovite need vähemalt mõttes tagasi teisendada või teiste kasutajate jaoks klassinimeks tagasi teisendada.
Andmete jagamine rongi- ja katsekomplektideks
Oleme oma uurimise käigus märkinud, et funktsioone on vaja skaleerida. Kui me skaleeriksime praegu või automaatselt, skaleeriksime väärtusi tervikuga X
ja y
. Sel juhul tutvustaksime andmete leke, kuna peagi valmiva testikomplekti väärtused oleksid skaleerimist mõjutanud. Andmete lekkimine on ML-mudelite kordumatute tulemuste ja illusoorselt suure jõudluse sagedane põhjus.
Skaleerimisele mõtlemine näitab, et esmalt tuleb jagada X
ja y
andmed edasi rongi- ja katsekomplektidesse ning seejärel edasi sobima skaalerit treeningkomplektil ja kuni muutma nii rong kui ka katsekomplektid (ilma, et katsekomplekt oleks kunagi mõjutanud seda tegevat skalerit). Selleks kasutame Scikit-Learni train_test_split()
meetod:
from sklearn.model_selection import train_test_split
SEED = 42
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=.25,
random_state=SEED)
Kehtestamine test_size=.25
tagab, et kasutame 25% andmetest testimiseks ja 75% koolituseks. Selle võib ära jätta, kui see on vaikejaotus, kuid pütooniline Koodi kirjutamise viis soovitab, et "selgesõnalisus on parem kui kaudne".
Märge: Lause "selgesõnaline on parem kui kaudne" on viide Pythoni zenvõi PEP20. See annab mõned soovitused Pythoni koodi kirjutamiseks. Kui neid soovitusi järgitakse, võetakse koodi arvesse pütooniline. Saate sellest rohkem teada siin.
Pärast andmete jagamist rongi- ja katsekomplektideks on hea tava vaadata, kui palju kirjeid igas komplektis on. Seda saab teha koos shape
atribuut:
X_train.shape, X_test.shape, y_train.shape, y_test.shape
See kuvab:
((1875, 12), (625, 12), (1875,), (625,))
Näeme, et pärast jagunemist on meil treeninguteks 1875 ja testimiseks 625 rekordit.
Andmete skaleerimine
Kui oleme oma rongi- ja katsekomplektid valmis, saame jätkata andmete skaleerimist Scikit-Learniga StandardScaler
objekt (või muu raamatukogu pakutav skaleerija). Lekke vältimiseks paigaldatakse katlakivi eemaldaja X_train
andmeid ja rongi väärtusi kasutatakse seejärel nii rongi kui ka katseandmete skaleerimiseks või teisendamiseks:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
Kuna tavaliselt helistate:
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
Esimesed kaks rida võib ainsuse abil ahendada fit_transform()
kõne, mis sobib komplekti kuuluva skaleriga ja muudab selle ühe hooga. Nüüd saame taasesitada boxploti graafikuid, et näha erinevust pärast andmete skaleerimist.
Arvestades, et skaleerimine eemaldab veergude nimed, saame enne joonistamist korraldada rongi andmed uuesti veerunimedega andmeraamiks, et hõlbustada visualiseerimist:
column_names = df.columns[:12]
X_train = pd.DataFrame(X_train, columns=column_names)
sns.boxplot(data=X_train, orient='h')
Lõpuks ometi näeme kõiki meie kastplotte! Pange tähele, et kõigil neil on kõrvalekalded ja tunnused, mis jaotavad tavapärasest kaugemal (mille kõverad on kas vasakule või paremale kaldu), näiteks Solidity
, Extent
, Aspect_Ration
ja Compactedness
, on samad, millel oli suurem korrelatsioon.
Kõrvalekalde eemaldamine IQR-meetodiga
Teame juba, et logistilist regressiooni võivad mõjutada kõrvalekalded. Üks nende ravimise viise on kasutada meetodit nn Interkvartiilne vahemik or I.Q.R.. IQR-meetodi esimene samm on meie rongiandmete jagamine neljaks osaks, mida nimetatakse kvartiilideks. Esimene kvartiil, Q1, moodustab 25% andmetest, teine, Q2, 50%, kolmas, Q3, kuni 75% ja viimane, Q4, kuni 100%. Kastplotis olevad kastid on määratletud IQR-meetodiga ja kujutavad seda visuaalselt.
Arvestades horisontaalset kastdiagrammi, tähistab vasakpoolne vertikaaljoon 25% andmetest, vertikaalne joon keskel 50% andmetest (või mediaan) ja viimane vertikaaljoon paremal 75% andmetest. . Mida ühtlasemad on mõlemad vertikaaljoontega määratletud ruudud – või mida rohkem on keskmine vertikaaljoon keskel –, tähendab, et meie andmed on normaaljaotusele lähemal või vähem kallutatud, mis on meie analüüsi jaoks abiks.
Lisaks IQR-kastile on selle mõlemal küljel ka horisontaalsed jooned. Need jooned tähistavad minimaalset ja maksimaalset jaotuse väärtust, mis on määratletud
$$
Miinimum = Q1 – 1.5*IQR
$$
ja
$$
Maksimaalne = Q3 + 1.5*IQR
$$
IQR on täpselt erinevus Q3 ja Q1 (või Q3 – Q1) vahel ning see on andmete keskseim punkt. Seetõttu filtreerime IQR-i leidmisel kõrvalekalded andmete äärmustesse ehk miinimum- ja maksimumpunktidesse. Kastigraafikud annavad meile ülevaate sellest, milline on IQR-meetodi tulemus.
Pandasid saame kasutada quantile()
meetod meie kvantiilide leidmiseks ja iqr
alates scipy.stats
pakett iga veeru interkvartiilsete andmevahemike saamiseks:
from scipy.stats import iqr
Q1 = X_train.quantile(q=.25)
Q3 = X_train.quantile(q=.75)
IQR = X_train.apply(iqr)
Nüüd on meil Q1, Q3 ja IQR, saame filtreerida mediaanile lähemal olevad väärtused:
minimum = X_train < (Q1-1.5*IQR)
maximum = X_train > (Q3+1.5*IQR)
filter = ~(minimum | maximum).any(axis=1)
X_train = X_train[filter]
Pärast meie koolitusridade filtreerimist näeme, kui palju neist on veel andmetes shape
:
X_train.shape
Selle tulemuseks on:
(1714, 12)
Näeme, et ridade arv muutus pärast filtreerimist 1875-lt 1714-le. See tähendab, et 161 rida sisaldas kõrvalekaldeid ehk 8.5% andmetest.
Märge: On soovitatav, et kõrvalekallete filtreerimine, NaN väärtuste eemaldamine ja muud toimingud, mis hõlmavad andmete filtreerimist ja puhastamist, jääksid alla või kuni 10% andmetest. Proovige mõelda muudele lahendustele, kui teie filtreerimine või eemaldamine ületab 10% teie andmetest.
Pärast kõrvalekallete eemaldamist oleme peaaegu valmis andmeid mudelisse kaasama. Mudeli sobitamiseks kasutame rongi andmeid. X_train
filtreeritakse, aga kuidas on y_train
?
y_train.shape
See annab väljundi:
(1875,)
Märka seda y_train
on veel 1875 rida. Peame vastama arvule y_train
ridade arvuni X_train
ridade kaupa ja mitte ainult meelevaldselt. Peame eemaldama eemaldatud kõrvitsaseemnete esinemisjuhtude y-väärtused, mis on tõenäoliselt laiali laiali. y_train
seatud. Filtreeritud X_train
stil on oma algsed indeksid ja indeksil on lünki, kust eemaldasime kõrvalekalded! Seejärel saame kasutada indeksit X_train
DataFrame vastavate väärtuste otsimiseks y_train
:
y_train = y_train.iloc[X_train.index]
Pärast seda saame vaadata y_train
kuju uuesti:
y_train.shape
Millised väljundid:
(1714,)
Tutvuge meie praktilise ja praktilise Giti õppimise juhendiga, mis sisaldab parimaid tavasid, tööstusharus aktsepteeritud standardeid ja kaasas olevat petulehte. Lõpetage Giti käskude guugeldamine ja tegelikult õppima seda!
Nüüd, y_train
Samuti on 1714 rida ja need on samad, mis X_train
read. Oleme lõpuks valmis looma oma logistilise regressiooni mudeli!
Logistilise regressiooni mudeli rakendamine
Raske osa on tehtud! Eeltöötlus on tavaliselt keerulisem kui mudeliarendus, kui tegemist on Scikit-Learni teekide kasutamisega, mis on lihtsustanud ML-mudelite rakendamist vaid paarile reale.
Esiteks impordime LogisticRegression
klassi ja instantseerige see, luues a LogisticRegression
objekt:
from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression(random_state=SEED)
Teiseks sobitame oma rongi andmed logreg
mudel koos fit()
meetodit ja ennustada meie katseandmeid predict()
meetodit, salvestades tulemused kujul y_pred
:
logreg.fit(X_train.values, y_train)
y_pred = logreg.predict(X_test)
Oleme oma mudeliga juba ennustusi teinud! Vaatame 3 esimest rida X_train
et näha, milliseid andmeid oleme kasutanud:
X_train[:3]
Ülaltoodud kood väljastab:
Area Perimeter Major_Axis_Length Minor_Axis_Length Convex_Area Equiv_Diameter Eccentricity Solidity Extent Roundness Aspect_Ration Compactness
0 -1.098308 -0.936518 -0.607941 -1.132551 -1.082768 -1.122359 0.458911 -1.078259 0.562847 -0.176041 0.236617 -0.360134
1 -0.501526 -0.468936 -0.387303 -0.376176 -0.507652 -0.475015 0.125764 0.258195 0.211703 0.094213 -0.122270 0.019480
2 0.012372 -0.209168 -0.354107 0.465095 0.003871 0.054384 -0.453911 0.432515 0.794735 0.647084 -0.617427 0.571137
Ja esimese 3 ennustuse juures y_pred
tulemuste nägemiseks:
y_pred[:3]
Selle tulemuseks on:
array([0, 0, 0])
Nende kolme rea puhul ennustasime, et need on esimese klassi seemned, Çerçevelik
.
koos logistiline regressioon, selle asemel, et ennustada lõppklassi, nt 0
, saame ennustada ka tõenäosust, et rida on seotud 0
klass. See juhtub tegelikult siis, kui logistiline regressioon klassifitseerib andmed ja predict()
meetod läbib seejärel selle ennustuse läbi läve, et tagastada "kõva" klass. Et ennustada klassiga seotuse tõenäosust, predict_proba()
kasutatakse:
y_pred_proba = logreg.predict_proba(X_test)
Vaatame ka y tõenäosuste ennustuste kolme esimest väärtust:
y_pred_proba[:3]
Millised väljundid:
# class 0 class 1
array([[0.54726628, 0.45273372],
[0.56324527, 0.43675473],
[0.86233349, 0.13766651]])
Nüüd on meil iga klassi jaoks kolme nulli asemel üks veerg. Vasakpoolses veerus, alustades 0.54726628
, on klassiga seotud andmete tõenäosused 0
; ja paremas veerus, alustades 0.45273372
, on selle klassiga seotud tõenäosus 1
.
Märge: Seda klassifikatsiooni erinevust tuntakse ka kui raske ja pehme ennustus. Kõva ennustus kastib ennustuse klassi, pehme ennustus aga väljastab tõenäosus klassi kuuluvast eksemplarist.
Seal on rohkem teavet selle kohta, kuidas ennustatud väljund tehti. Tegelikult ei olnud 0
, kuid klassi tõenäosus on 55%. 0
ja 45% tõenäosusega klassi 1
. See näitab, kuidas esimesed kolm X_test
klassiga seotud andmepunktid 0
, on tõeliselt selged ainult kolmanda andmepunkti puhul 86% tõenäosusega – ja mitte niivõrd kahe esimese andmepunkti puhul.
Leidude edastamisel ML-meetodite abil – tavaliselt on kõige parem tagastada pehme klass ja sellega seotud tõenäosus "usaldus" sellest klassifikatsioonist.
Sellest, kuidas seda arvutatakse, räägime lähemalt, kui läheme mudelisse sügavamale. Sel ajal saame jätkata järgmise sammuga.
Mudeli hindamine klassifikatsiooniaruannetega
Kolmas samm on näha, kuidas mudel katseandmetega toimib. Saame importida Scikit-Learni classification_report()
ja möödu meie y_test
ja y_pred
argumentidena. Pärast seda saame selle vastuse välja printida.
Klassifitseerimisaruanne sisaldab enim kasutatavaid klassifitseerimismõõdikuid, nt täpsus, tagasikutsumine, f1-skoorja täpsus.
- Täpsus: et mõista, milliseid õigeid ennustusväärtusi meie klassifikaator õigeks pidas. Täpsus jagab need tõelised positiivsed väärtused kõigega, mida ennustati positiivsena:
$$
täpsus = frac{tekst{tõene positiivne}}{tekst{tõene positiivne} + tekst{vale positiivne}}
$$
- Tagasikutsumine: et mõista, kui palju tõelisi positiivseid omadusi meie klassifikaator tuvastas. Tagasikutsumine arvutatakse, jagades tõelised positiivsed väärtused kõigega, mida oleks pidanud positiivseks ennustama:
$$
meenutada = frac{tekst{tõene positiivne}}{tekst{tõene positiivne} + tekst{valenegatiivne}}
$$
- F1 skoor: on tasakaalustatud või harmooniline keskmine täpsusest ja meeldejätmisest. Väikseim väärtus on 0 ja kõrgeim on 1. Millal
f1-score
on võrdne 1-ga, see tähendab, et kõik klassid olid õigesti ennustatud – seda on reaalsete andmetega väga raske saada:
$$
tekst{f1-skoor} = 2* frac{tekst{täpsus} * tekst{taaskutsumine}}{tekst{täpsus} + tekst{taaskutsumine}}
$$
- Täpsus: kirjeldab, kui palju ennustusi meie klassifikaator õigesti tegi. Väikseim täpsusväärtus on 0 ja kõrgeim on 1. Tavaliselt korrutatakse see väärtus 100-ga, et saada protsent:
$$
täpsus = frac{tekst{õigete ennustuste arv}}{tekst{ennustuste koguarv}}
$$
Märge: Pärisandmete 100% täpsuse saavutamine on äärmiselt raske, kui see juhtub, pidage meeles, et võib juhtuda leke või midagi valesti – ideaalse täpsuse väärtuse osas pole üksmeelt ja see sõltub ka kontekstist. Väärtus 70%, mis tähendab, et klassifikaator teeb vigu 30% andmetega või üle 70% on enamiku mudelite jaoks piisav.
from sklearn.metrics import classification_report
cr = classification_report(y_test, y_pred)
print(cr)
Seejärel saame vaadata klassifikatsiooniaruande väljundit:
precision recall f1-score support
0 0.83 0.91 0.87 316
1 0.90 0.81 0.85 309
accuracy 0.86 625
macro avg 0.86 0.86 0.86 625
weighted avg 0.86 0.86 0.86 625
See on meie tulemus. Märka seda precision
, recall
, f1-score
ja accuracy
mõõdikud on kõik väga kõrged, üle 80%, mis on ideaalne – kuid tõenäoliselt mõjutasid neid tulemusi kõrged korrelatsioonid ja need ei püsi pikemas perspektiivis.
Mudeli täpsus on 86%, mis tähendab, et see eksib 14% ajast. Meil on see üldine teave olemas, kuid oleks huvitav teada, kas klasside klassifitseerimisel juhtub 14% vigu 0
või klass 1
. Et tuvastada, millised klassid on valesti tuvastatud ja millise sagedusega – saame arvutada ja joonistada a segaduse maatriks meie mudeli ennustustest.
Mudeli hindamine segadusmaatriksiga
Arvutame ja seejärel joonistame segadusmaatriksi. Pärast seda saame aru igast osast. Segaduse maatriksi joonistamiseks kasutame Scikit-Learni confusion_matrix()
, mille impordime lehelt metrics
moodul.
Segadusmaatriksit on Seaborni abil lihtsam visualiseerida heatmap()
. Seega anname pärast selle genereerimist oma segadusmaatriksi soojuskaardi argumendiks:
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d')
- Segadusmaatriks: maatriks näitab, mitu valimit mudelil iga klassi jaoks õige või vale oli. Väärtused, mis olid õiged ja õigesti ennustatud, nimetatakse tõelised positiivsed küljed, ja neid, mida ennustati positiivsetena, kuid mis ei olnud positiivsed, nimetatakse valepositiivsed. Sama nomenklatuur tõelised negatiivsed ja valenegatiivid kasutatakse negatiivsete väärtuste jaoks;
Segaduse maatriksi graafikut vaadates näeme, et meil on 287
väärtused, mis olid 0
ja ennustati kui 0
- või tõelised positiivsed küljed klassi jaoks 0
(Çerçevelik seemned). Meil on ka 250
klassi jaoks tõelisi positiivseid külgi 1
(Ürgüp Sivrisi seemned). Tõelised positiivsed asuvad alati maatriksi diagonaalis, mis läheb ülevalt vasakult alla paremale.
Meil on ka 29
väärtused, mis pidid olema 0
, kuid ennustatud kui 1
(valepositiivsed) Ja 59
väärtused, mis olid 1
ja ennustati kui 0
(valenegatiivid). Nende numbrite abil saame aru, et viga, mida mudel kõige rohkem teeb, on see, et see ennustab valenegatiivseid tulemusi. Seega võib see enamasti lõppeda Ürgüp Sivrisi seemne klassifitseerimisega Çerçeveliku seemneks.
Seda tüüpi viga on seletatav ka 81% klassi meeldejätmisega 1
. Pange tähele, et mõõdikud on ühendatud. Ja tagasikutsumise erinevus tuleneb sellest, et Ürgüp Sivrisi klassi näidiseid on 100 vähem. See on üks tagajärgi, kui teises klassis on vaid mõne proovi vähem. Meenutamise edasiseks parandamiseks võite katsetada klassikaaludega või kasutada rohkem Ürgüp Sivrisi näidiseid.
Seni oleme teostanud enamiku andmeteaduse traditsioonilistest sammudest ja kasutanud logistilise regressiooni mudelit musta kastina.
Märge: Kui soovite minna kaugemale, kasutage Ristkinnitus (CV) ja ruudustikuotsing otsida vastavalt mudelit, mis üldistab andmeid kõige rohkem, ja parimaid mudeli parameetreid, mis valitakse enne treeningut või hüperparameetrid.
Ideaaljuhul saaksite CV ja ruudustikuotsinguga rakendada ka ühendatud viisi andmete eeltöötluse, andmete jagamise, modelleerimise ja hindamise sammude tegemiseks – see on Scikit-Learniga lihtne. torujuhtmed.
Nüüd on aeg avada must kast ja vaadata selle sisse, et süveneda logistilise regressiooni toimimise mõistmisse.
Läheme sügavamale sellesse, kuidas logistiline regressioon tegelikult toimib
. regressioon sõna pole seal juhuslikult, et mõista, mida logistiline regressioon teeb, võime meeles pidada, mida teeb selle õde, lineaarne regressioon andmetega. Lineaarse regressiooni valem oli järgmine:
$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n
$$
Milles b0 oli regressioonilõik, b1 koefitsient ja x1 andmed.
Selle võrrandi tulemuseks oli sirgjoon, mida kasutati uute väärtuste ennustamiseks. Sissejuhatust meenutades on erinevus nüüd selles, et me ei ennusta uusi väärtusi, vaid klassi. Nii et seda sirget tuleb muuta. Logistilise regressiooniga võtame kasutusele mittelineaarsuse ja ennustus tehakse nüüd joone asemel kõvera abil:
Pange tähele, et kuigi lineaarne regressioonijoon jätkub ja koosneb pidevatest lõpmatutest väärtustest, saab logistilise regressioonikõvera jagada keskele ja sellel on äärmuslikud väärtused 0 ja 1. See "S" kuju on põhjus, miks ta andmeid klassifitseerib – punktid, mis on lähemal või langevad kõrgeimale otsale, kuuluvad klassi 1, samas kui punktid, mis asuvad alumises kvadrandis või lähemal 0-le, kuuluvad klassi 0. "S" on keskmine 0 ja 1 vahel, 0.5 – see on logistiliste regressioonipunktide lävi.
Me juba mõistame visuaalset erinevust logistilise ja lineaarse regressiooni vahel, aga kuidas on valemiga? Logistilise regressiooni valem on järgmine:
$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n
$$
Selle võib kirjutada ka järgmiselt:
$$
y_{tõenäosus} = murd{1}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
Või isegi kirjutada järgmiselt:
$$
y_{tõenäosus} = murd{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
Ülaltoodud võrrandis on meil selle väärtuse asemel sisendi tõenäosus. Selle lugejaks on 1, nii et selle tulemuseks võib olla väärtus vahemikus 0 kuni 1 ja 1 pluss väärtus nimetajas, nii et selle väärtus on 1 ja midagi – see tähendab, et kogu murdosa tulemus ei saa olla suurem kui 1 .
Ja mis on see väärtus, mis on nimetajas? see on e, naturaallogaritmi alus (ligikaudu 2.718282), tõstetud lineaarse regressiooni astmele:
$$
e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
Teine viis selle kirjutamiseks oleks:
$$
Vasakpoolne (frak{p}{1-p} parem) = {(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
Selles viimases võrrandis ln on naturaallogaritm (baas e) ja p on tõenäosus, seega on tulemuse tõenäosuse logaritm sama, mis lineaarse regressiooni tulemus.
Teisisõnu, lineaarse regressiooni tulemuse ja naturaallogaritmi abil saame jõuda tõenäosuseni, et sisend kuulub kavandatud klassi või mitte.
Kogu logistilise regressiooni tuletamise protsess on järgmine:
$$
p{X} = murd{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
$$
p(1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}) = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + lpunktid + b_n * x_n)}
$$
$$
p + p*e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)} = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + lpunktid + b_n * x_n)}
$$
p
=
e
(
b
0
+
b
1
∗
x
1
+
b
2
∗
x
2
+
b
3
∗
x
3
+
...
+
b
n
∗
x
n
)
-
p
∗
e
(
b
0
+
b
1
∗
x
1
+
b
2
∗
x
2
+
b
3
∗
x
3
+
...
+
b
n
∗
x
n
)
$$
frac{p}{1-p} = e^{(b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$
$$
Vasakpoolne (frak{p}{1-p} parem) = (b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)
$$
See tähendab, et logistilise regressiooni mudelil on ka koefitsiendid ja lõikeväärtus. Kuna see kasutab lineaarset regressiooni ja lisab sellele mittelineaarse komponendi naturaallogaritmiga (e
).
Näeme oma mudeli koefitsientide ja lõikepunkti väärtusi samamoodi nagu lineaarse regressiooni puhul, kasutades coef_
ja intercept_
omadused:
logreg.coef_
Mis näitab kõigi 12 tunnuse koefitsiente:
array([[ 1.43726172, -1.03136968, 0.24099522, -0.61180768, 1.36538261,
-1.45321951, -1.22826034, 0.98766966, 0.0438686 , -0.78687889,
1.9601197 , -1.77226097]])
logreg.intercept_
Selle tulemuseks on:
array([0.08735782])
Koefitsientide ja lõikeväärtuste abil saame arvutada meie andmete prognoositud tõenäosused. Võtame esimesed X_test
väärtused uuesti, näiteks:
X_test[:1]
See tagastab esimese rea X_test
NumPy massiivina:
array([[-1.09830823, -0.93651823, -0.60794138, -1.13255059, -1.0827684 ,
-1.12235877, 0.45891056, -1.07825898, 0.56284738, -0.17604099,
0.23661678, -0.36013424]])
Esialgse võrrandi järgi:
$$
p{X} = murd{e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$
Pythonis on meil:
import math
lin_reg = logreg.intercept_[0] +
((logreg.coef_[0][0]* X_test[:1][0][0])+
(logreg.coef_[0][1]* X_test[:1][0][1])+
(logreg.coef_[0][2]* X_test[:1][0][2])+
(logreg.coef_[0][3]* X_test[:1][0][3])+
(logreg.coef_[0][4]* X_test[:1][0][4])+
(logreg.coef_[0][5]* X_test[:1][0][5])+
(logreg.coef_[0][6]* X_test[:1][0][6])+
(logreg.coef_[0][7]* X_test[:1][0][7])+
(logreg.coef_[0][8]* X_test[:1][0][8])+
(logreg.coef_[0][9]* X_test[:1][0][9])+
(logreg.coef_[0][10]* X_test[:1][0][10])+
(logreg.coef_[0][11]* X_test[:1][0][11]))
px = math.exp(lin_reg)/(1 +(math.exp(lin_reg)))
px
Selle tulemuseks on:
0.45273372469369133
Kui vaatame uuesti predict_proba
esimese tulemus X_test
rida, meil on:
logreg.predict_proba(X_test[:1])
See tähendab, et algne logistilise regressiooni võrrand annab meile klassiga seotud sisendi tõenäosuse 1
, et teada saada, milline tõenäosus on klassi jaoks 0
, saame lihtsalt:
1 - px
Pange tähele, et mõlemad px
ja 1-px
on identsed predict_proba
tulemused. Nii arvutatakse logistiline regressioon ja miks regressioon on osa selle nimest. Aga kuidas on terminiga logistika?
Mõiste logistika pärineb logit, mis on funktsioon, mida oleme juba näinud:
$$
vasakpoolne (frak{p}{1-p} parem)
$$
Oleme selle äsja arvutanud px
ja 1-px
. See on logit, mida nimetatakse ka log-koefitsiendid kuna see on võrdne koefitsiendi logaritmiga kus p
on tõenäosus.
Järeldus
Selles juhendis oleme uurinud üht kõige põhilisemat masinõppe klassifitseerimisalgoritmi, st logistiline regressioon.
Algselt rakendasime logistilist regressiooni musta kastina Scikit-Learni masinõppe raamatukoguga ja hiljem saime sellest samm-sammult aru, et oleks selge, miks ja kust tulevad terminid regressioon ja logistika.
Oleme ka andmeid uurinud ja uurinud, mõistes, et see on andmeteaduse analüüsi üks olulisemaid osi.
Siit soovitan teil mängida mitmeklassiline logistiline regressioon, logistiline regressioon rohkem kui kahe klassi jaoks – saate sama logistilise regressiooni algoritmi rakendada ka teiste mitme klassiga andmekogumite jaoks ja tulemusi tõlgendada.
Märge: Saadaval on hea andmekogumite kogu siin et saaksid mängida.
Samuti soovitaksin teil uurida L1 ja L2 regulaarsused, need on viis kõrgemate andmete "karistamiseks", et need muutuksid tavapärasele lähemale, hoides välja mudeli keerukuse, et algoritm saaks parema tulemuse. Meie kasutatud Scikit-Learni teostusel on vaikimisi juba L2-regulatsioon. Teine asi, mida vaadata, on erinev lahendajadNagu lbgs
, mis optimeerivad logistilise regressiooni algoritmi jõudlust.
Samuti on oluline heita pilk peale statistiline lähenemine logistilisele regressioonile. Sellel on eeldused andmete käitumise ja muu statistika kohta, mida peab säilitama, et tagada rahuldavad tulemused, näiteks:
- vaatlused on sõltumatud;
- selgitavate muutujate hulgas puudub multikollineaarsus;
- puuduvad äärmuslikud kõrvalekalded;
- selgitavate muutujate ja vastuse muutuja logiti vahel on lineaarne seos;
- valimi suurus on piisavalt suur.
Pange tähele, kui paljusid neist eeldustest oli meie analüüsis ja andmete käsitlemises juba käsitletud.
Loodan, et uurite jätkuvalt, mida logistilisel regressioonil on kõigis selle erinevates lähenemisviisides pakkuda!
- blockchain
- C + +
- kood
- coingenius
- andmeteadus
- andmete visualiseerimine
- Java
- matplotlib
- mitte vahetatav märk
- tuim
- OpenSea
- pandas
- PHP
- Platon
- plato ai
- Platoni andmete intelligentsus
- Platoni mäng
- Platvormplokk
- PlatoData
- platogaming
- hulknurk
- Python
- Reageerima
- skikit õppima
- meres sündinud
- arukas leping
- Solana
- Stackabus
- Vyper
- Web3
- sephyrnet