Definitieve gids voor logistieke regressie in Python PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Definitieve gids voor logistieke regressie in Python

Introductie

Soms verward met lineaire regressie door beginners - vanwege het delen van de term regressie - logistische regressie is heel anders dan lineaire regressie. Terwijl lineaire regressie waarden voorspelt zoals 2, 2.45, 6.77 of continue waarden, waardoor het een regressie algoritme, logistische regressie voorspelt waarden zoals 0 of 1, 1 of 2 of 3, die zijn discrete waarden, waardoor het een classificatie algoritme. Ja, het heet regressie maar is een classificatie algoritme. Daarover straks meer.

Als uw datawetenschapsprobleem continue waarden betreft, kunt u daarom een regressie algoritme (lineaire regressie is er een van). Anders, als het gaat om het classificeren van invoer, discrete waarden of klassen, kunt u een classificatie algoritme (logistieke regressie is er een van).

In deze handleiding voeren we logistische regressie uit in Python met de Scikit-Learn-bibliotheek. We zullen ook uitleggen waarom het woord "regressie" aanwezig is in de naam en hoe logistische regressie werkt.

Om dat te doen, zullen we eerst gegevens laden die worden geclassificeerd, gevisualiseerd en voorverwerkt. Vervolgens zullen we een logistisch regressiemodel bouwen dat die gegevens zal begrijpen. Dit model zal vervolgens worden geรซvalueerd en gebruikt om waarden te voorspellen op basis van nieuwe invoer.

Motivatie

Het bedrijf waarvoor u werkt heeft een samenwerking met een Turkse landbouwboerderij. Deze samenwerking omvat de verkoop van pompoenpitten. Pompoenpitten zijn erg belangrijk voor de menselijke voeding. Ze bevatten een goede verhouding koolhydraten, vetten, eiwitten, calcium, kalium, fosfor, magnesium, ijzer en zink.

In het data science-team is het jouw taak om het verschil te zien tussen de soorten pompoenpitten, gewoon door gegevens te gebruiken โ€“ of classificeren de gegevens per zaadtype.

De Turkse boerderij werkt met twee soorten pompoenpitten, de ene heet erรงevelik en de andere rgรผp Sivrisi.

Om de pompoenpitten te classificeren, heeft uw team de 2021-paper gevolgd โ€œHet gebruik van machine learning-methoden bij de classificatie van pompoenpitten (Cucurbita pepo L.). Genetische bronnen en gewasevolutieโ€ van Koklu, Sarigil en Ozbek - in dit artikel is er een methode voor het fotograferen en extraheren van de zaadmetingen uit de afbeeldingen.

Na het voltooien van het proces dat in het document wordt beschreven, werden de volgende metingen geรซxtraheerd:

  • De Omgeving โ€“ het aantal pixels binnen de randen van een pompoenpit
  • Omtrek โ€“ de omtrek in pixels van een pompoenpit
  • Lengte hoofdas โ€“ ook de omtrek in pixels van een pompoenpit
  • Kleine aslengte โ€“ de kleine asafstand van een pompoenzaad
  • Excentriciteit โ€“ de excentriciteit van een pompoenpit
  • Convex gebied โ€“ het aantal pixels van de kleinste bolle schil in het gebied gevormd door het pompoenzaad
  • Omvang โ€“ de verhouding van een pompoenpitgebied tot de pixels van de begrenzingsbox
  • Equivalente diameter โ€“ de vierkantswortel van de vermenigvuldiging van de oppervlakte van de pompoenpit met vier gedeeld door pi
  • Compactheid โ€“ de verhouding van de oppervlakte van de pompoenpit ten opzichte van de oppervlakte van de cirkel met dezelfde omtrek
  • Stevigheid โ€“ de bolle en bolle toestand van de pompoenpitten
  • Rondheid โ€“ de ovaliteit van pompoenpitten zonder rekening te houden met de vervormingen van de randen
  • Aspect Ratio โ€“ de beeldverhouding van de pompoenpitten

Dat zijn de maten waar je mee aan de slag moet. Naast de afmetingen is er ook de Klasse label voor de twee soorten pompoenpitten.

Laten we, om te beginnen met het classificeren van de zaden, de gegevens importeren en ernaar gaan kijken.

De gegevensset begrijpen

Opmerking: Je kunt de pompoendataset downloaden hier.

Na het downloaden van de dataset kunnen we deze in een dataframestructuur laden met behulp van de pandas bibliotheek. Omdat het een Excel-bestand is, gebruiken we de read_excel() methode:

import pandas as pd

fpath = 'dataset/pumpkin_seeds_dataset.xlsx' 
df = pd.read_excel(fpath)

Zodra de gegevens zijn geladen, kunnen we een snelle blik werpen op de eerste 5 rijen met behulp van de head() methode:

df.head() 

Dit resulteert in:

	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

Hier hebben we alle metingen in hun respectievelijke kolommen, onze functionaliteiten, en ook de Klasse kolom, onze doel, de laatste in het dataframe. We kunnen zien hoeveel metingen we hebben met behulp van de shape attribuut:

df.shape 

De uitvoer is:

(2500, 13)

Het vormresultaat vertelt ons dat er 2500 items (of rijen) in de dataset en 13 kolommen zijn. Omdat we weten dat er รฉรฉn doelkolom is, betekent dit dat we 12 functiekolommen hebben.

We kunnen nu de doelvariabele, het pompoenzaad, onderzoeken Class. Omdat we die variabele zullen voorspellen, is het interessant om te zien hoeveel monsters van elk pompoenzaad we hebben. Gewoonlijk geldt: hoe kleiner het verschil tussen het aantal instanties in onze klassen, hoe evenwichtiger onze steekproef is en hoe beter onze voorspellingen.

Deze inspectie kan worden gedaan door elk zaadmonster te tellen met de value_counts() methode:

df['Class'].value_counts() 

De bovenstaande code wordt weergegeven:

ร‡erรงevelik       1300
รœrgรผp Sivrisi    1200
Name: Class, dtype: int64

We kunnen zien dat er 1300 monsters zijn van de erรงevelik zaad en 1200 monsters van de rgรผp Sivrisi zaad. Merk op dat het verschil tussen hen 100 monsters is, een heel klein verschil, wat goed voor ons is en aangeeft dat het niet nodig is om het aantal monsters opnieuw in evenwicht te brengen.

Laten we ook eens kijken naar de beschrijvende statistieken van onze functies met de describe() methode om te zien hoe goed de gegevens zijn verdeeld. We zullen de resulterende tabel ook transponeren met T om het vergelijken van statistieken gemakkelijker te maken:

df.describe().T

De resulterende tabel is:

					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

Door naar de tabel te kijken, bij het vergelijken van de gemiddelde en standaardafwijking (std) kolommen, is te zien dat de meeste kenmerken een gemiddelde hebben dat ver van de standaarddeviatie ligt. Dat geeft aan dat de gegevenswaarden niet geconcentreerd zijn rond de gemiddelde waarde, maar meer verspreid eromheen - met andere woorden, ze hebben hoge variabiliteit.

Ook bij het kijken naar de minimum (min) en maximaal (max) kolommen, sommige functies, zoals Area en Convex_Area, hebben grote verschillen tussen minimum- en maximumwaarden. Dit betekent dat die kolommen zeer kleine gegevens hebben en ook zeer grote gegevenswaarden, of hogere amplitude tussen gegevenswaarden.

Met een hoge variabiliteit, hoge amplitude en kenmerken met verschillende meeteenheden, zouden de meeste van onze gegevens baat hebben bij dezelfde schaal voor alle kenmerken of als geschubd. Het schalen van gegevens centreert gegevens rond het gemiddelde en vermindert de variantie.

Dit scenario geeft waarschijnlijk ook aan dat er uitschieters en extreme waarden in data zitten. Dus het is het beste om wat te hebben uitbijter behandeling naast het schalen van de gegevens.

Er zijn enkele machine learning-algoritmen, bijvoorbeeld op bomen gebaseerde algoritmen zoals: Willekeurige bosclassificatie, die niet worden beรฏnvloed door hoge gegevensvariantie, uitbijters en extreme waarden. Logistische regressie is anders, het is gebaseerd op een functie die onze waarden categoriseert, en de parameters van die functie kunnen worden beรฏnvloed door waarden die buiten de algemene gegevenstrend vallen en een hoge variantie hebben.

We zullen meer over logistische regressie begrijpen wanneer we het kunnen implementeren. Voorlopig kunnen we onze gegevens blijven verkennen.

Opmerking: Er is een populair gezegde in de informatica: "Vuilnis erin, afval eruit" (GIGO), dat zeer geschikt is voor machine learning. Dit betekent dat wanneer we afvalgegevens hebben - metingen die de verschijnselen op zich niet beschrijven, gegevens die niet werden begrepen en goed voorbereid volgens het soort algoritme of model, waarschijnlijk een onjuiste uitvoer genereren die niet werkt op een dagelijkse basis.
Dit is een van de redenen waarom het verkennen, begrijpen van gegevens en hoe het gekozen model werkt zo belangrijk zijn. Door dat te doen, kunnen we voorkomen dat we afval in ons model stoppen - er waarde in plaatsen en er waarde uit halen.

De gegevens visualiseren

Tot nu toe hebben we met de beschrijvende statistieken een ietwat abstracte momentopname van enkele kwaliteiten van de gegevens. Een andere belangrijke stap is om het te visualiseren en onze hypothese van hoge variantie, amplitude en uitbijters te bevestigen. Om te zien of wat we tot nu toe hebben waargenomen in de gegevens wordt weergegeven, kunnen we enkele grafieken plotten.

Het is ook interessant om te zien hoe de kenmerken zich verhouden tot de twee klassen die zullen worden voorspeld. Laten we hiervoor de . importeren seaborn pakket en gebruik de pairplot grafiek om naar elke functieverdeling en elke klassenscheiding per functie te kijken:

import seaborn as sns


sns.pairplot(data=df, hue='Class')

Opmerking: Het kan even duren voordat de bovenstaande code is uitgevoerd, aangezien de pairplot scatterplots van alle features combineert (dat kan) en ook de feature-distributies weergeeft.

Als we naar de pairplot kijken, kunnen we zien dat in de meeste gevallen de punten van de ร‡erรงevelik klasse zijn duidelijk gescheiden van de punten van de รœrgรผp Sivrisi klas. Ofwel de punten van de ene klasse zijn naar rechts wanneer de anderen naar links zijn, of sommige zijn omhoog terwijl de anderen naar beneden zijn. Als we een soort curve of lijn zouden gebruiken om klassen te scheiden, laat dit zien dat het gemakkelijker is om ze te scheiden, als ze gemengd waren, zou classificatie een moeilijkere taak zijn.

In het Eccentricity, Compactness en Aspect_Ration kolommen, kunnen sommige punten die "geรฏsoleerd" zijn of afwijken van de algemene gegevenstrend - uitbijters - ook gemakkelijk worden opgemerkt.

Als u naar de diagonaal van linksboven naar rechtsonder in de grafiek kijkt, ziet u dat de gegevensverdelingen ook een kleurcode hebben volgens onze klassen. De verdelingsvormen en de afstand tussen beide curven zijn andere indicatoren van hoe scheidbaar ze zijn - hoe verder van elkaar, hoe beter. In de meeste gevallen zijn ze niet over elkaar heen gelegd, wat inhoudt dat ze gemakkelijker te scheiden zijn, wat ook bijdraagt โ€‹โ€‹aan onze taak.

In volgorde kunnen we ook de boxplots van alle variabelen plotten met de sns.boxplot() methode. Meestal is het handig om de boxplots horizontaal te oriรซnteren, zodat de vormen van de boxplots hetzelfde zijn als de distributievormen, dat kunnen we doen met de orient argument:


sns.boxplot(data=df, orient='h') 

Definitieve gids voor logistieke regressie in Python PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Merk in de bovenstaande plot op dat: Area en Convex_Area hebben zo'n hoge magnitude in vergelijking met de magnitudes van de andere kolommen, dat ze de andere boxplots verpletteren. Om alle boxplots te kunnen bekijken, kunnen we de features schalen en opnieuw plotten.

Laten we, voordat we dat doen, begrijpen dat als er waarden zijn van functies die nauw verwant zijn aan andere waarden, bijvoorbeeld โ€“ als er waarden zijn die ook groter worden wanneer andere functiewaarden groter worden, met een positieve correlatie; of als er waarden zijn die het tegenovergestelde doen, worden kleiner terwijl andere waarden kleiner worden, met a negatieve correlatie.

Dit is belangrijk om naar te kijken, omdat het hebben van sterke relaties in gegevens kan betekenen dat sommige kolommen zijn afgeleid van andere kolommen of een vergelijkbare betekenis hebben als ons model. Als dat gebeurt, kunnen de modelresultaten worden overschat en willen we resultaten die dichter bij de werkelijkheid liggen. Als er sterke correlaties zijn, betekent dit ook dat we het aantal kenmerken kunnen verminderen en minder kolommen kunnen gebruiken, waardoor het model meer wordt karig.

Opmerking: De standaardcorrelatie berekend met de corr() methode is de Pearson-correlatiecoรซfficiรซnt. Deze coรซfficiรซnt wordt aangegeven wanneer gegevens kwantitatief zijn, normaal verdeeld, geen uitbijters hebben en een lineair verband hebben.

Een andere keuze zou zijn om te berekenen Spearmans correlatiecoรซfficiรซnt. De Spearman-coรซfficiรซnt wordt gebruikt wanneer gegevens ordinaal en niet-lineair zijn, een willekeurige verdeling hebben en uitbijters hebben. Merk op dat onze gegevens niet helemaal passen in de aannames van Pearson of Spearman (er zijn ook meer correlatiemethoden, zoals die van Kendall). Aangezien onze gegevens kwantitatief zijn en het voor ons belangrijk is om de lineaire relatie te meten, zullen we de coรซfficiรซnt van Pearson gebruiken.

Laten we eens kijken naar de correlaties tussen variabelen en dan kunnen we de gegevens voorbewerken. We berekenen de correlaties met de corr() methode en visualiseer ze met Seaborn's heatmap(). Het standaardformaat van de heatmap is meestal klein, dus we zullen importeren matplotlib (algemene visualisatie-engine/bibliotheek waarop Seaborn is gebouwd) en verander de grootte met figsize:

import matplotlib.pyplot as plt
plt.figure(figsize=(15, 10))

correlations = df.corr()
sns.heatmap(correlations, annot=True) 

Definitieve gids voor logistieke regressie in Python PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

In deze heatmap zijn de waarden die dichter bij 1 of -1 liggen de waarden waar we op moeten letten. Het eerste geval duidt op een hoge positieve correlatie en het tweede geval duidt op een hoge negatieve correlatie. Beide waarden, indien niet hoger dan 0.8 of -0.8 zullen gunstig zijn voor ons logistische regressiemodel.

Wanneer er hoge correlaties zijn, zoals die van 0.99 tussen Aspec_Ration en Compactness, dit betekent dat we ervoor kunnen kiezen om alleen te gebruiken Aspec_Ration of alleen Compactness, in plaats van beide (aangezien ze bijna gelijk zouden zijn) voorspellers van elkaar). Hetzelfde geldt voor Eccentricity en Compactness met een -0.98 correlatie, voor Area en Perimeter met een 0.94 correlatie en enkele andere kolommen.

Voorbewerking van de gegevens

Omdat we de gegevens al een tijdje hebben verkend, kunnen we beginnen met de voorbewerking ervan. Laten we nu alle functies voor de klassevoorspelling gebruiken. Na het verkrijgen van een eerste model, een baseline, kunnen we enkele van de sterk gecorreleerde kolommen verwijderen en vergelijken met de baseline.

De functiekolommen zijn onze X data en de klassenkolom, onze y doel gegevens:

y = df['Class']
X = df.drop(columns=['Class'], axis=1)

Categorische functies omzetten in numerieke functies

met betrekking tot onze Class kolom - de waarden zijn geen getallen, dit betekent dat we ze ook moeten transformeren. Er zijn veel manieren om deze transformatie te doen; hier zullen we de . gebruiken replace() methode en vervang ร‡erรงevelik naar 0 en รœrgรผp Sivrisi naar 1.

y = y.replace('ร‡erรงevelik', 0).replace('รœrgรผp Sivrisi', 1)

Houd de kaart in gedachten! Wanneer u resultaten van uw model leest, wilt u deze in ieder geval in uw gedachten terugzetten, of terug in de klassenaam voor andere gebruikers.

Gegevens opdelen in trein- en testsets

In onze verkenning hebben we opgemerkt dat de functies moesten worden geschaald. Als we de schaal nu zouden doen, of op een automatische manier, zouden we waarden schalen met het geheel van X en y. In dat geval zouden we introduceren data lekkage, omdat de waarden van de binnenkort te testen set de schaal zouden hebben beรฏnvloed. Gegevenslekkage is een veelvoorkomende oorzaak van niet-reproduceerbare resultaten en illusoire hoge prestaties van ML-modellen.

Nadenken over de schaal laat zien dat we eerst moeten splitsen X en y gegevens verder in trein- en testsets en vervolgens naar geschikt een scaler op de trainingsset, en om transformeren zowel de trein als de testsets (zonder dat de testset ooit invloed heeft op de scaler die dit doet). Hiervoor gebruiken we Scikit-Learn's train_test_split() methode:

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)

omgeving test_size=.25 zorgt ervoor dat we 25% van de gegevens gebruiken voor testen en 75% voor training. Dit kan worden weggelaten, zodra het de standaardsplitsing is, maar de Pythonisch manier om code te schrijven adviseert dat "expliciet beter is dan impliciet".

Opmerking: De zin "expliciet is beter dan impliciet" is een verwijzing naar: De zen van Python, of PEP20. Het bevat enkele suggesties voor het schrijven van Python-code. Als die suggesties worden opgevolgd, wordt de code in overweging genomen Pythonisch. U kunt er meer over weten hier.

Na het splitsen van de gegevens in trein- en testsets, is het een goede gewoonte om te kijken hoeveel records er in elke set zitten. Dat kan met de shape attribuut:

X_train.shape, X_test.shape, y_train.shape, y_test.shape

Dit toont:

((1875, 12), (625, 12), (1875,), (625,))

We kunnen zien dat we na de splitsing 1875 records hebben voor training en 625 voor testen.

Gegevens schalen

Zodra we onze trein- en testsets klaar hebben, kunnen we doorgaan met het schalen van de gegevens met Scikit-Learn StandardScaler object (of andere scalers geleverd door de bibliotheek). Om lekkage te voorkomen, wordt de scaler op de X_train gegevens en de treinwaarden worden vervolgens gebruikt om zowel de trein- als testgegevens te schalen โ€“ of te transformeren:

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

Aangezien je meestal belt:

scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

De eerste twee regels kunnen worden samengevouwen met een enkelvoud fit_transform() call, die de scaler op de set past, en in รฉรฉn keer transformeert. We kunnen nu de boxplot-grafieken reproduceren om het verschil te zien na het schalen van gegevens.

Aangezien de schaling kolomnamen verwijdert, kunnen we voorafgaand aan het plotten treingegevens in een dataframe met kolomnamen organiseren om de visualisatie te vergemakkelijken:

column_names = df.columns[:12] 
X_train = pd.DataFrame(X_train, columns=column_names)

sns.boxplot(data=X_train, orient='h')

Definitieve gids voor logistieke regressie in Python PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

We kunnen eindelijk al onze boxplots zien! Merk op dat ze allemaal uitbijters hebben, en de kenmerken die een verdeling presenteren die verder van normaal is (die krommen hebben die ofwel scheef naar links of naar rechts zijn), zoals Solidity, Extent, Aspect_Ration en Compactedness, zijn dezelfde die hogere correlaties hadden.

Uitschieters verwijderen met IQR-methode

We weten al dat logistische regressie kan worden beรฏnvloed door uitbijters. Een van de manieren om ze te behandelen is het gebruik van een methode genaamd Interkwartielbereik or I.Q.R.. De eerste stap van de IQR-methode is om onze treingegevens in vier delen te verdelen, kwartielen genaamd. Het eerste kwartiel, Q1, bedraagt โ€‹โ€‹25% van de gegevens, de tweede, Q2, tot 50%, de derde, Q3, tot 75%, en de laatste, Q4, tot 100%. De boxen in de boxplot worden gedefinieerd door de IQR-methode en zijn daar een visuele weergave van.

Bij een horizontale boxplot markeert de verticale lijn aan de linkerkant 25% van de gegevens, de verticale lijn in het midden, 50% van de gegevens (of de mediaan) en de laatste verticale lijn aan de rechterkant, 75% van de gegevens . Hoe gelijker in grootte beide vierkanten gedefinieerd door de verticale lijnen โ€“ of hoe meer de verticale mediaanlijn in het midden is โ€“ betekent dat onze gegevens dichter bij de normale verdeling liggen of minder scheef zijn, wat handig is voor onze analyse.

Naast de IQR-box zijn er aan weerszijden ook horizontale lijnen. Die lijnen markeren de minimum- en maximumverdelingswaarden gedefinieerd door

$$
Minimum = Q1 โ€“ 1.5*IQR
$$

en

$$
Maximaal = Q3 + 1.5*IQR
$$

IQR is precies het verschil tussen Q3 en Q1 (of Q3 โ€“ Q1) en het is het meest centrale datapunt. Dat is de reden waarom we bij het vinden van de IQR uiteindelijk de uitbijters filteren in de data-uiteinden, of in de minimum- en maximumpunten. Boxplots geven ons een voorproefje van wat het resultaat van de IQR-methode zal zijn.

Definitieve gids voor logistieke regressie in Python PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

We kunnen panda's gebruiken quantile() methode om onze kwantielen te vinden, en iqr van het scipy.stats pakket om het interkwartielgegevensbereik voor elke kolom te verkrijgen:

from scipy.stats import iqr

Q1 = X_train.quantile(q=.25)
Q3 = X_train.quantile(q=.75)

IQR = X_train.apply(iqr)

Nu we Q1, Q3 en IQR hebben, kunnen we de waarden uitfilteren die dichter bij de mediaan liggen:


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]

Nadat we onze trainingsrijen hebben gefilterd, kunnen we zien hoeveel ervan nog in de gegevens staan โ€‹โ€‹met shape:

X_train.shape

Dit resulteert in:

(1714, 12)

We kunnen zien dat het aantal rijen na filtering van 1875 naar 1714 ging. Dit betekent dat 161 rijen uitschieters bevatten of 8.5% van de gegevens.

Opmerking: Het wordt aanbevolen dat het filteren van uitbijters, het verwijderen van NaN-waarden en andere acties waarbij gegevens worden gefilterd en opgeschoond, onder of tot 10% van de gegevens blijft. Probeer andere oplossingen te bedenken als uw filtering of verwijdering meer dan 10% van uw gegevens bedraagt.

Na het verwijderen van uitbijters zijn we bijna klaar om data in het model op te nemen. Voor de modelaanpassing zullen we treingegevens gebruiken. X_train wordt gefilterd, maar hoe zit het met? y_train?

y_train.shape

Dit levert op:

(1875,)

Let erop dat y_train heeft nog steeds 1875 rijen. We moeten overeenkomen met het aantal y_train rijen naar het aantal X_train rijen en niet zomaar willekeurig. We moeten de y-waarden verwijderen van de exemplaren van pompoenpitten die we hebben verwijderd, die waarschijnlijk verspreid zijn door de y_train set. de gefilterde X_train stil heeft zijn originele indices en de index heeft hiaten waar we uitbijters hebben verwijderd! We kunnen dan de index van de X_train DataFrame om te zoeken naar de corresponderende waarden in y_train:

y_train = y_train.iloc[X_train.index]

Nadat we dat hebben gedaan, kunnen we kijken naar de y_train vorm opnieuw:

y_train.shape

Welke outputs:

(1714,)

Bekijk onze praktische, praktische gids voor het leren van Git, met best-practices, door de industrie geaccepteerde normen en bijgevoegd spiekbriefje. Stop met Googlen op Git-commando's en eigenlijk leren het!

Nu, y_train heeft ook 1714 rijen en ze zijn hetzelfde als de X_train rijen. We zijn eindelijk klaar om ons logistische regressiemodel te maken!

Het logistieke regressiemodel implementeren

Het moeilijke deel is gedaan! Voorbewerking is meestal moeilijker dan modelontwikkeling, als het gaat om het gebruik van bibliotheken zoals Scikit-Learn, die de toepassing van ML-modellen hebben gestroomlijnd tot slechts een paar regels.

Eerst importeren we de LogisticRegression class en instantiรซren, het creรซren van een LogisticRegression voorwerp:

from sklearn.linear_model import LogisticRegression
logreg = LogisticRegression(random_state=SEED)

Ten tweede passen we onze treingegevens aan de logreg model met de fit() methode, en voorspellen onze testgegevens met de predict() methode, waarbij de resultaten worden opgeslagen als y_pred:



logreg.fit(X_train.values, y_train)
y_pred = logreg.predict(X_test)

We hebben al voorspellingen gedaan met ons model! Laten we eens kijken naar de eerste 3 rijen in X_train om te zien welke gegevens we hebben gebruikt:

X_train[:3]

De bovenstaande code geeft het volgende weer:

       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

En bij de eerste 3 voorspellingen in y_pred om de resultaten te zien:

y_pred[:3] 

Dit resulteert in:

array([0, 0, 0])

Voor die drie rijen waren onze voorspellingen dat het zaden van de eerste klasse waren, ร‡erรงevelik.

met logistische regressie, in plaats van de laatste klasse te voorspellen, zoals 0, kunnen we ook de kans voorspellen dat de rij betrekking heeft op de 0 klas. Dit is wat er feitelijk gebeurt wanneer logistische regressie gegevens classificeert, en de predict() methode passeert deze voorspelling vervolgens door een drempelwaarde om een โ€‹โ€‹"harde" klasse te retourneren. Om de kans te voorspellen om tot een klasse te behoren, predict_proba() is gebruikt:

y_pred_proba = logreg.predict_proba(X_test)

Laten we ook eens kijken naar de eerste 3 waarden van de y-kansenvoorspellingen:

y_pred_proba[:3] 

Welke outputs:

        # class 0   class 1   
array([[0.54726628, 0.45273372],
       [0.56324527, 0.43675473],
       [0.86233349, 0.13766651]])

In plaats van drie nullen hebben we nu รฉรฉn kolom voor elke klasse. In de kolom links, beginnend met 0.54726628, zijn de waarschijnlijkheden van de gegevens die betrekking hebben op de klasse 0; en in de rechterkolom, beginnend met 0.45273372, is de kans dat het betrekking heeft op de klasse 1.

Opmerking: Dit verschil in classificatie staat ook bekend als: hard en zacht voorspelling. Harde voorspelling zet de voorspelling in een klasse, terwijl zachte voorspellingen de waarschijnlijkheid van de instantie die tot een klasse behoort.

Er is meer informatie over hoe de voorspelde output is gemaakt. Het was eigenlijk niet 0, maar 55% kans op klasse 0, en 45% kans op klasse 1. Dit laat zien hoe de eerste drie X_test datapunten, met betrekking tot klasse 0, zijn alleen echt duidelijk met betrekking tot het derde gegevenspunt, met een waarschijnlijkheid van 86% - en niet zozeer voor de eerste twee gegevenspunten.

Bij het communiceren van bevindingen met behulp van ML-methoden is het meestal het beste om een โ€‹โ€‹zachte klasse te retourneren, en de bijbehorende waarschijnlijkheid als de "vertrouwen" van die classificatie.

We zullen meer praten over hoe dat wordt berekend als we dieper op het model ingaan. Op dit moment kunnen we doorgaan naar de volgende stap.

Het model evalueren met classificatierapporten

De derde stap is om te zien hoe het model presteert op testgegevens. We kunnen Scikit-Learn . importeren classification_report() en passeer onze y_test en y_pred als argumenten. Daarna kunnen we de reactie afdrukken.

Het classificatierapport bevat de meest gebruikte classificatiestatistieken, zoals: nauwkeurigheid, herinneren, f1-score en nauwkeurigheid.

  1. precisie: om te begrijpen welke correcte voorspellingswaarden door onze classifier als correct werden beschouwd. Precisie zal die echte positieve waarden delen door alles dat als positief werd voorspeld:

$$
precisie = frac{text{true positive}}{text{true positive} + tekst{false positive}}
$$

  1. Terugroepen: om te begrijpen hoeveel van de echte positieven werden geรฏdentificeerd door onze classifier. De terugroepactie wordt berekend door de echte positieven te delen door alles wat als positief had moeten worden voorspeld:

$$
recall = frac{tekst{true positive}}{text{true positive} + text{false negative}}
$$

  1. F1-score: is de gebalanceerde of harmonisch gemiddelde van precisie en herinnering. De laagste waarde is 0 en de hoogste is 1. Wanneer f1-score is gelijk aan 1, dit betekent dat alle klassen correct zijn voorspeld - dit is een zeer moeilijke score om te verkrijgen met echte gegevens:

$$
tekst{f1-score} = 2* frac{tekst{precisie} * tekst{herinnering}}{tekst{precisie} + tekst{herinnering}}
$$

  1. Nauwkeurigheid: beschrijft hoeveel voorspellingen onze classifier juist had. De laagste nauwkeurigheidswaarde is 0 en de hoogste is 1. Die waarde wordt meestal vermenigvuldigd met 100 om een โ€‹โ€‹percentage te verkrijgen:

$$
nauwkeurigheid = frac{text{aantal correcte voorspellingen}}{text{totaal aantal voorspellingen}}
$$

Opmerking: Het is buitengewoon moeilijk om 100% nauwkeurigheid te verkrijgen op echte gegevens, als dat gebeurt, houd er dan rekening mee dat er een lekkage of iets verkeerds kan gebeuren - er is geen consensus over een ideale nauwkeurigheidswaarde en het is ook contextafhankelijk. Een waarde van 70%, wat betekent dat de classifier fouten maakt op 30% van de gegevens, of meer dan 70% is meestal voldoende voor de meeste modellen.

from sklearn.metrics import classification_report
cr = classification_report(y_test, y_pred)
print(cr)

We kunnen dan kijken naar de output van het classificatierapport:

				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

Dit is ons resultaat. Let erop dat precision, recall, f1-score en accuracy statistieken zijn allemaal erg hoog, boven de 80%, wat ideaal is - maar die resultaten werden waarschijnlijk beรฏnvloed door hoge correlaties en zullen op de lange termijn niet standhouden.

De nauwkeurigheid van het model is 86%, wat betekent dat de classificatie 14% van de tijd verkeerd is. We hebben die algemene informatie, maar het zou interessant zijn om te weten of de 14% fouten gebeuren met betrekking tot de classificatie van klasse 0 of klasse 1. Om te identificeren welke klassen ten onrechte als welke zijn geรฏdentificeerd, en in welke frequentie, kunnen we een berekenen en plotten verwarring matrix van de voorspellingen van ons model.

Het model evalueren met een verwarringsmatrix

Laten we de verwarringsmatrix berekenen en plotten. Nadat we dat hebben gedaan, kunnen we elk deel ervan begrijpen. Om de verwarringsmatrix te plotten, gebruiken we Scikit-Learn confusion_matrix(), die we importeren uit de metrics module.

De verwarringsmatrix is โ€‹โ€‹gemakkelijker te visualiseren met een Seaborn heatmap(). Dus, na het genereren ervan, zullen we onze verwarringsmatrix doorgeven als argument voor de heatmap:

from sklearn.metrics import confusion_matrix

cm = confusion_matrix(y_test, y_pred)
sns.heatmap(cm, annot=True, fmt='d')

Definitieve gids voor logistieke regressie in Python PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

  1. Verwarring Matrix: de matrix laat zien hoeveel steekproeven het model goed of fout had voor elke klasse. De waarden die correct en correct voorspeld waren, worden genoemd echte positieven, en degenen die werden voorspeld als positief maar niet positief waren, worden genoemd valse positieven. Dezelfde nomenclatuur van echte negatieven en valse negatieven wordt gebruikt voor negatieve waarden;

Door naar de verwarringsmatrixplot te kijken, kunnen we zien dat we 287 waarden die waren 0 en voorspeld als 0 - of echte positieven voor de les 0 (de ร‡erรงevelik-zaden). We hebben ook 250 echte positieven voor de klas 1 (รœrgรผp Sivrisi-zaden). De echte positieven bevinden zich altijd in de matrixdiagonaal die van linksboven naar rechtsonder loopt.

We hebben ook 29 waarden die zouden moeten zijn 0, maar voorspeld als 1 (valse positieven) en 59 waarden die waren 1 en voorspeld als 0 (valse negatieven). Met die cijfers kunnen we begrijpen dat de fout die het model het meest maakt, is dat het valse negatieven voorspelt. Dus het kan er uiteindelijk toe leiden dat een รœrgรผp Sivrisi-zaad als een ร‡erรงevelik-zaad wordt geclassificeerd.

Dit soort fouten wordt ook verklaard door de 81% terugroepactie van de klas 1. Merk op dat de metrieken met elkaar verbonden zijn. En het verschil in de terugroepactie komt van het hebben van 100 minder monsters van de รœrgรผp Sivrisi-klasse. Dit is een van de implicaties van het hebben van slechts een paar monsters minder dan de andere klasse. Om het terugroepen verder te verbeteren, kunt u experimenteren met klassegewichten of meer รœrgรผp Sivrisi-monsters gebruiken.

Tot nu toe hebben we de meeste traditionele stappen in de datawetenschap uitgevoerd en het logistische regressiemodel als een zwarte doos gebruikt.

Opmerking: Als je verder wilt gaan, gebruik dan Kruisvalidatie (CV) en raster zoeken om respectievelijk te zoeken naar het model dat het meest generaliseert met betrekking tot gegevens, en de beste modelparameters die vรณรณr de training worden gekozen, of hyperparameters.

Idealiter zou u met CV en Grid Search ook een aaneengeschakelde manier kunnen implementeren om gegevensvoorbewerkingsstappen, gegevenssplitsing, modellering en evaluatie uit te voeren - wat gemakkelijk wordt gemaakt met Scikit-Learn pijpleidingen.

Nu is het tijd om de zwarte doos te openen en erin te kijken, om dieper te begrijpen hoe logistische regressie werkt.

Dieper ingaan op hoe logistieke regressie echt werkt

De regressie woord is er niet per ongeluk, om te begrijpen wat logistische regressie doet, kunnen we ons herinneren wat zijn broer of zus, lineaire regressie, doet met de gegevens. De lineaire regressieformule was de volgende:

$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n
$$

waarin b0 was de regressie onderscheppen, b1 de coรซfficiรซnt en x1 de data.

Die vergelijking resulteerde in een rechte lijn die werd gebruikt om nieuwe waarden te voorspellen. De introductie herinnerend, is het verschil nu dat we geen nieuwe waarden voorspellen, maar een klasse. Dus die rechte lijn moet veranderen. Met logistische regressie introduceren we een niet-lineariteit en de voorspelling wordt nu gedaan met behulp van een curve in plaats van een lijn:

Definitieve gids voor logistieke regressie in Python PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Merk op dat terwijl de lineaire regressielijn doorgaat en is gemaakt van continue oneindige waarden, de logistische regressiecurve in het midden kan worden verdeeld en extremen heeft in 0 en 1 waarden. Die "S"-vorm is de reden waarom het gegevens classificeert - de punten die dichterbij zijn of op het hoogste uiteinde vallen, behoren tot klasse 1, terwijl de punten die in het onderste kwadrant of dichter bij 0 liggen, tot klasse 0 behoren. de "S" is het midden tussen 0 en 1, 0.5 - het is de drempel voor de logistische regressiepunten.

Definitieve gids voor logistieke regressie in Python PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

We begrijpen het visuele verschil tussen logistische en lineaire regressie al, maar hoe zit het met de formule? De formule voor logistische regressie is de volgende:

$$
y = b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n
$$

Het kan ook worden geschreven als:

$$
y_{prob} = frac{1}{1 + e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}}
$$

Of zelfs worden geschreven als:

$$
y_{prob} = frac{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)}}
$$

In de bovenstaande vergelijking hebben we de kans op invoer, in plaats van de waarde. Het heeft 1 als teller, dus het kan resulteren in een waarde tussen 0 en 1, en 1 plus een waarde in de noemer, zodat de waarde 1 is en zoiets - dit betekent dat het resultaat van de hele breuk niet groter kan zijn dan 1 .

En wat is de waarde die in de noemer staat? Het is e, de basis van de natuurlijke logaritme (ongeveer 2.718282), verheven tot de macht van lineaire regressie:

$$
e^{(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$

Een andere manier om het te schrijven zou zijn:

$$
ln links( frac{p}{1-p} rechts) = {(b_0 + b_1 * x_1 + b_2 * x_2 + b_3 * x_3 + ldots + b_n * x_n)}
$$

In die laatste vergelijking, ln is de natuurlijke logaritme (grondtal e) en p is de kans, dus de logaritme van de kans op het resultaat is hetzelfde als het lineaire regressieresultaat.

Met andere woorden, met het lineaire regressieresultaat en de natuurlijke logaritme kunnen we komen tot de waarschijnlijkheid dat een invoer al dan niet behoort tot een ontworpen klasse.

Het hele proces voor het afleiden van logistische regressie is als volgt:

$$
p{X} = frac{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 + ldots + 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 + ldots + 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)}
$$

$$
ln links( frac{p}{1-p} rechts) = (b_0 + b_1 * x_1 + b_2 *x_2 + b_3 * x_3 + ldots + b_n * x_n)
$$

Dit betekent dat het logistische regressiemodel ook coรซfficiรซnten en een interceptwaarde heeft. Omdat het een lineaire regressie gebruikt en er een niet-lineaire component aan toevoegt met de natuurlijke logaritme (e).

We kunnen de waarden van de coรซfficiรซnten en het snijpunt van ons model zien, op dezelfde manier als bij lineaire regressie, met behulp van coef_ en intercept_ eigendommen:

logreg.coef_

Die de coรซfficiรซnten van elk van de 12 kenmerken weergeeft:

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_

Dat resulteert in:

array([0.08735782])

Met de coรซfficiรซnten en intercept-waarden kunnen we de voorspelde kansen van onze gegevens berekenen. Laten we de eerste pakken X_test waarden nogmaals, als voorbeeld:

X_test[:1]

Dit geeft de eerste rij van X_test als een NumPy-array:

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

Na de initiรซle vergelijking:

$$
p{X} = frac{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)}}
$$

In Python hebben we:

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

Dit resulteert in:

0.45273372469369133

Als we nog eens kijken naar de predict_proba resultaat van de eerste X_test lijn hebben we:

logreg.predict_proba(X_test[:1])


Dit betekent dat de oorspronkelijke logistische regressievergelijking ons de waarschijnlijkheid geeft van de invoer met betrekking tot klasse 1, om erachter te komen welke kans voor klasse is 0, kunnen we eenvoudig:

1 - px


Merk op dat beide px en 1-px zijn identiek aan predict_proba resultaten. Dit is hoe logistische regressie wordt berekend en waarom regressie maakt deel uit van zijn naam. Maar hoe zit het met de term? logistieke?

De term logistieke komt van logit, wat een functie is die we al hebben gezien:

$$
ln links( frac{p}{1-p} rechts)
$$

We hebben het zojuist berekend met px en 1-px. Dit is de logit, ook wel log-kans omdat het gelijk is aan de logaritme van de kansen waarbij p is een waarschijnlijkheid.

Conclusie

In deze gids hebben we een van de meest fundamentele classificatiealgoritmen voor machine learning bestudeerd, namelijk: logistische regressie.

Aanvankelijk implementeerden we logistische regressie als een zwarte doos met Scikit-Learn's machine learning-bibliotheek, en later begrepen we het stap voor stap om duidelijk te hebben waarom en waar de termen regressie en logistiek vandaan komen.

We hebben de gegevens ook verkend en bestudeerd, in het besef dat dit een van de meest cruciale onderdelen van een datawetenschapsanalyse is.

Vanaf hier zou ik je aanraden om te spelen met multiclass logistische regressie, logistische regressie voor meer dan twee klassen โ€“ u kunt hetzelfde logistische regressie-algoritme toepassen op andere datasets met meerdere klassen, en de resultaten interpreteren.

Opmerking: Er is een goede verzameling datasets beschikbaar hier voor jou om mee te spelen.

Ik zou je ook aanraden om de L1 en L2 . te bestuderen regularisaties, ze zijn een manier om de hogere gegevens te 'straffen' zodat deze dichter bij normaal worden, waarbij de complexiteit van het model wordt tegengehouden, zodat het algoritme tot een beter resultaat kan komen. De Scikit-Learn-implementatie die we gebruikten, heeft standaard al L2-regularisatie. Een ander ding om naar te kijken is de verschillende oplossers, zoals lbgs, die de prestaties van het logistische regressiealgoritme optimaliseren.

Het is ook belangrijk om te kijken naar de statistisch benadering van logistische regressie. Het heeft veronderstellingen over het gedrag van gegevens en over andere statistieken die moeten gelden om bevredigende resultaten te garanderen, zoals:

  • de waarnemingen zijn onafhankelijk;
  • er is geen multicollineariteit tussen verklarende variabelen;
  • er zijn geen extreme uitschieters;
  • er is een lineair verband tussen verklarende variabelen en de logit van de responsvariabele;
  • de steekproefomvang voldoende groot is.

Merk op hoeveel van die veronderstellingen al zijn behandeld in onze analyse en behandeling van gegevens.

Ik hoop dat je blijft onderzoeken wat logistieke regressie te bieden heeft in al zijn verschillende benaderingen!

Tijdstempel:

Meer van Stapelmisbruik