Campuswerving: een classificatieprobleem met logistieke regressie

Campuswerving: een classificatieprobleem met logistieke regressie

Bronknooppunt: 1996810

Introductie

In dit project richten we ons op data uit India. En ons doel is om een voorspellend model, zoals Logistic Regression, enz. zodat wanneer we de kenmerken van een kandidaat geven, het model kan voorspellen of ze zullen werven.

De dataset draait om het stageseizoen van een Business School in India. De dataset heeft verschillende factoren over kandidaten, zoals werkervaring, examenpercentage, etc. Tot slot bevat het de status van werving en beloningsdetails.

Datawetenschapsprobleem met Logistische Regressie

Campuswerving is een strategie voor het vinden, binden en aannemen van jong talent voor stage- en instapfuncties. Het gaat vaak om het werken met universitaire carrièreservicecentra en het bijwonen van carrièrebeurzen om persoonlijke studenten en pas afgestudeerden te ontmoeten.

Dit artikel is gepubliceerd als onderdeel van het Data Science-blogathon.

Inhoudsopgave

  1. Stappen die betrokken zijn bij het oplossen van het probleem
  2. Bereid gegevens voor
  3. Bouw een logistiek regressiemodel
  4. Resultaten van het Logistische Regressiemodel
  5. Conclusie

Stappen die betrokken zijn bij het oplossen van het probleem

In dit artikel zullen we die dataset importeren, opschonen en vervolgens voorbereiden om een ​​logistiek regressiemodel te bouwen. Onze doelen hier zijn de volgende:

Eerst gaan we onze dataset voorbereiden binaire classificatie. Nu, wat bedoel ik? wanneer we een continue waarde proberen te voorspellen, zoals de prijs van een appartement, kan dit elk getal zijn tussen nul en vele miljoenen dollars. We noemen het een regressieprobleem.

Maar in dit project zijn de dingen een beetje anders. In plaats van een continue waarde te voorspellen, hebben we afzonderlijke groepen of klassen die we daartussen proberen te voorspellen. Dit wordt dus een classificatieprobleem genoemd, en omdat we in ons project slechts twee groepen hebben waaruit we proberen te kiezen, wordt het een binaire classificatie.

Het tweede doel is het creëren van een logistisch regressiemodel om rekrutering te voorspellen. En ons derde doel is om de voorspellingen van ons model uit te leggen met behulp van de odds ratio.

Nu in termen van de machine learning-workflow, de stappen die we zullen volgen, en enkele van de nieuwe dingen die we gaandeweg zullen leren. Dus in de importfase zullen we onze gegevens voorbereiden om met een binair doel te werken. In de verkenningsfase gaan we kijken naar de klassenbalans. Dus eigenlijk, welk deel van de kandidaten was aangenomen en welk deel niet? en in de coderingsfase van de functies zullen we coderen voor onze categorische functies. In het gesplitste gedeelte zullen we een gerandomiseerde treintestsplitsing doen.

Voor de modelbouwfase zullen we eerst onze basislijn bepalen, en omdat we nauwkeurigheidsscores zullen gebruiken, zullen we meer praten over wat een nauwkeurigheidsscore is en hoe we een basislijn kunnen bouwen als dat de statistiek is waarin we geïnteresseerd zijn. Ten tweede gaan we logistische regressie uitvoeren. En dan, last but not least, hebben we de evaluatiefase. We zullen ons opnieuw concentreren op de nauwkeurigheidsscore. Ten slotte zullen we, om resultaten te communiceren, kijken naar de odds ratio.

Ten slotte, voordat we in het werk duiken, laten we onszelf voorstellen aan de bibliotheken die we voor het project zullen gebruiken. Eerst importeren we onze gegevens naar het Google Colabe-notebook in de io-bibliotheek. Vervolgens zullen we, aangezien we een logistisch regressiemodel gebruiken, dat importeren uit scikit-learn. Daarna ook van scikit-leren, zullen we onze prestatiestatistieken, de nauwkeurigheidsscore en de trein-test-splitsing importeren.

We zullen gebruiken matplotlib en seaborn voor onze visualisatie, en NumPy  zal alleen voor weinig wiskunde zijn.
Wij hebben nodig panda's om onze gegevens te manipuleren, labelencoder om onze categorische variabelen te coderen, en standaard scaler om de gegevens te normaliseren. Dat zullen de bibliotheken zijn die we nodig hebben.

Laten we beginnen met het voorbereiden van de gegevens.

#import libraries
import io
import warnings import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn.preprocessing import LabelEncoder
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler warnings.simplefilter(action="ignore", category=FutureWarning)

Bereid gegevens voor

import

Om te beginnen met het voorbereiden van de gegevens, laten we ons belangrijke werk doen. Eerst laden we ons databestand en dan moeten we ze in een DataFrame `df.` plaatsen

from google.colab import files
uploaded = files.upload()
# Read CSV file
df = pd.read_csv(io.BytesIO(uploaded["Placement_Data_Full_Class.csv"]))
print(df.shape)
df.head()
Dataset voor Logistische Regressie

We kunnen ons mooie DataFrame zien, en we hebben 215 records en 15 kolommen die het `status` attribuut bevatten, ons doel. Dit is de beschrijving voor alle functies.

Logistische regressie

Ga op onderzoek uit

Nu hebben we al deze functies die we gaan verkennen. Dus laten we beginnen met onze verkennende gegevensanalyse. Laten we eerst eens kijken naar de informatie voor dit dataframe en kijken of we een van deze moeten behouden of misschien moeten laten vallen.

# Inspect DataFrame
df.info() <class 'pandas.core.frame.DataFrame'>
RangeIndex: 215 entries, 0 to 214
Data columns (total 15 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 sl_no 215 non-null int64 1 gender 215 non-null object 2 ssc_p 215 non-null float64 3 ssc_b 215 non-null object 4 hsc_p 215 non-null float64 5 hsc_b 215 non-null object 6 hsc_s 215 non-null object 7 degree_p 215 non-null float64 8 degree_t 215 non-null object 9 workex 215 non-null object 10 etest_p 215 non-null float64 11 specialisation 215 non-null object 12 mba_p 215 non-null float64 13 status 215 non-null object 14 salary 148 non-null float64
dtypes: float64(6), int64(1), object(8)
memory usage: 25.3+ KB

Als we nu naar `df` info kijken, zijn er een aantal dingen waar we naar op zoek zijn, we hebben 215 rijen in ons dataframe en de vraag die we onszelf willen stellen is: ontbreken er gegevens? En als we hier kijken, lijkt het erop dat we geen ontbrekende gegevens hebben behalve de salariskolom, zoals verwacht, vanwege kandidaten die niet zijn aangenomen.

Een andere zorg voor ons hier is: zijn er lekkende functies die informatie aan ons model zouden geven die het niet zou hebben als het in de echte wereld zou worden ingezet? Onthoud dat we willen dat ons model voorspelt of een kandidaat zal plaatsen of niet, en we willen dat ons model die voorspellingen doet voordat de werving plaatsvindt. We willen dus na de aanwerving geen informatie over deze kandidaten geven.

Het is dus vrij duidelijk dat deze 'salaris'-functie informatie geeft over het salaris dat door het bedrijf wordt aangeboden. En omdat dit salaris voor degenen is die worden geaccepteerd, vormt deze functie hier een lek en moeten we het laten vallen.

df.drop(columns="salary", inplace=True)

Het tweede waar ik naar wil kijken, zijn de gegevenstypen voor deze verschillende functies. Dus als we naar deze gegevenstypen kijken, hebben we acht categorische kenmerken met ons doel en zeven numerieke kenmerken, en alles is correct. Laten we, nu we deze ideeën hebben, even de tijd nemen om ze dieper te onderzoeken.

We weten dat ons doelwit twee klassen heeft. We hebben geplaatste kandidaten en geen geplaatste kandidaten. De vraag is, wat is het relatieve aandeel van die twee klassen? Zijn ze ongeveer hetzelfde saldo? Of is de een veel meer dan de ander? Dat is iets waar je naar moet kijken als je classificatieproblemen aan het oplossen bent. Dit is dus een belangrijke stap in ons EDA.

# Plot class balance
df["status"].value_counts(normalize=True).plot( kind="bar", xlabel="Class", ylabel="Relative Frequency", title="Class Balance"
);
Klasse-onbalans voor logistische regressie

Onze positieve klasse 'geplaatst' telt voor meer dan 65% van onze waarnemingen en onze negatieve klasse 'Niet geplaatst' is ongeveer 30%. Nu, als deze super onevenwichtig waren, zoals, als het meer dan 80 of zelfs meer dan dat waren, zou ik zeggen dat dit onevenwichtige klassen zijn. En we zouden wat werk moeten verzetten om ervoor te zorgen dat ons model op de juiste manier gaat functioneren. Maar dit is een prima balans.

Laten we nog een visualisatie maken om het verband tussen onze kenmerken en het doelwit op te merken. Laten we beginnen met de numerieke kenmerken.

Eerst zullen we de individuele verdeling van de kenmerken zien met behulp van een verdelingsplot, en we zullen ook de relatie zien tussen de numerieke kenmerken en ons doel met behulp van een boxplot.

fig,ax=plt.subplots(5,2,figsize=(15,35))
for index,i in enumerate(df.select_dtypes("number").drop(columns="sl_no")): plt.suptitle("Visualizing Distribution of Numerical Columns Indivualy and by Class",size=20) sns.histplot(data=df, x=i, kde=True, ax=ax[index,0]) sns.boxplot(data=df, x='status', y=i, ax=ax[index,1]);
"Logistische regressie

In de eerste kolom van onze grafiek kunnen we zien dat alle verdelingen een normale verdeling volgen en dat de meeste onderwijsprestaties van de kandidaat tussen de 60-80% liggen.

In de tweede kolom hebben we een dubbele boxplot met de klasse 'Placed' aan de rechterkant en vervolgens de klasse 'Not Placed' aan de linkerkant. Voor de functies 'etest_p' en 'mba_p' is er niet veel verschil tussen deze twee distributies vanuit het perspectief van modelbouw. Er is een flinke overlap in de verdeling over de klassen, dus deze kenmerken zouden geen goede voorspeller zijn van ons doel. Wat de rest van de kenmerken betreft, die zijn duidelijk genoeg om ze als potentiële goede voorspellers van ons doelwit te beschouwen. Laten we verder gaan met de categorische kenmerken. En om ze te verkennen, gebruiken we een telplot.

fig,ax=plt.subplots(7,2,figsize=(15,35))
for index,i in enumerate(df.select_dtypes("object").drop(columns="status")): plt.suptitle("Visualizing Count of Categorical Columns",size=20) sns.countplot(data=df,x=i,ax=ax[index,0]) sns.countplot(data=df,x=i,ax=ax[index,1],hue="status")
"Logistische regressie

Als we naar de plot kijken, zien we dat we meer mannelijke kandidaten hebben dan vrouwen. En de meeste van onze kandidaten hebben geen werkervaring, maar deze kandidaten werden meer aangenomen dan degenen die dat wel hadden. We hebben kandidaten die commercie hebben gedaan als hun 'hsc'-cursus, en naast een undergrad zijn de kandidaten met een wetenschappelijke achtergrond in beide gevallen de op één na hoogste.

Een kleine opmerking over logistische regressiemodellen, hoewel ze voor classificatie zijn, zitten ze in dezelfde groep als andere lineaire modellen zoals lineaire regressie, en daarom, aangezien het beide lineaire modellen zijn. We moeten ons ook zorgen maken over de kwestie van multicollineariteit. We moeten dus een correlatiematrix maken en die vervolgens uitzetten in een heatmap. We willen hier niet naar alle kenmerken kijken, we willen alleen naar de numerieke kenmerken kijken en we willen ons doel niet opnemen. Want als ons doelwit correleert met enkele van onze kenmerken, is dat heel goed.

corr = df.select_dtypes("number").corr()
# Plot heatmap of `correlation`
plt.title('Correlation Matrix')
sns.heatmap(corr, vmax=1, square=True, annot=True, cmap='GnBu');
correlatiematrix

Hier zijn het lichtblauw, wat weinig tot geen correlatie betekent, en het donkerblauw, waarmee we een hogere correlatie hebben. Dus we willen uitkijken naar die donkerblauwe. We zien een donkerblauwe lijn, een diagonale lijn die door het midden van dit perceel loopt. Dat zijn de kenmerken die met zichzelf zijn gecorreleerd. En dan zien we enkele donkere vierkanten. Dat betekent dat we een heleboel correlaties hebben tussen functies.

In de laatste stap van onze EDA moeten we controleren op hoog-laag kardinaliteit in de categorische kenmerken. Kardinaliteit verwijst naar het aantal unieke waarden in een categorische variabele. Hoge kardinaliteit betekent dat categorische kenmerken een groot aantal unieke waarden hebben. Er is geen exact aantal unieke waarden dat een kenmerk een hoge cardinaliteit geeft. Maar als de waarde van het categorische kenmerk uniek is voor bijna alle waarnemingen, kan het meestal worden weggelaten.

# Check for high- and low-cardinality categorical features
df.select_dtypes("object").nunique() gender 2
ssc_b 2
hsc_b 2
hsc_s 3
degree_t 3
workex 2
specialisation 2
status 2
dtype: int64

Ik zie geen kolommen waar het aantal unieke waarden één of iets superhoog is. Maar ik denk dat er één kolom van het categorische type is die we hier missen. En de reden is dat het niet is gecodeerd als een object, maar als een geheel getal. De kolom 'sl_no' is geen geheel getal in de zin die we kennen. Deze kandidaten worden in een bepaalde volgorde gerangschikt. Gewoon een uniek naamplaatje, en de naam is als een categorie, toch? Dit is dus een categorische variabele. En het heeft geen informatie, dus we moeten het laten vallen.

df.drop(columns="sl_no", inplace=True)

Functies Codering

We hebben onze analyse voltooid en het volgende dat we moeten doen is onze categorische kenmerken coderen, ik zal de 'LabelEncoder' gebruiken. Labelcodering is een populaire coderingstechniek voor het verwerken van categorische variabelen. Met deze techniek krijgt elk label een uniek geheel getal toegewezen op basis van alfabetische volgorde.

lb = LabelEncoder () cat_data = ['gender', 'ssc_b', 'hsc_b', 'hsc_s', 'degree_t', 'workex', 'specialisation', 'status']
for i in cat_data: df[i] = lb.fit_transform(df[i]) df.head()
code-uitvoer

Split

We hebben onze gegevens geïmporteerd en opgeschoond. We hebben wat verkennende data-analyse gedaan en nu moeten we onze data splitsen. We hebben twee soorten splitsing: verticale splitsing of features-target en horizontale splitsing of treintestsets. Laten we beginnen met de verticale. We zullen onze functiematrix 'X' en doelvector 'y' maken. Ons doel is 'status'. Onze functies zouden alle kolommen moeten zijn die in de 'df.' blijven staan.

#vertical split
target = "status"
X = df.drop(columns = target)
y = df[target]

Modellen presteren over het algemeen beter als ze genormaliseerde gegevens hebben om mee te trainen, dus wat is normalisatie? Normalisatie transformeert de waarden van verschillende variabelen in een vergelijkbaar bereik. Ons doel is om onze variabelen te normaliseren. Hun waardebereik is dus van 0 tot 1. Laten we dat doen, en ik zal de `StandardScaler` gebruiken.

scaler = StandardScaler()
X = scaler.fit_transform(X)

Laten we nu de horizontale split- of train-testsets doen. We moeten onze gegevens (X en y) verdelen in trainings- en testsets met behulp van een gerandomiseerde trein-testsplitsing. onze testset zou 20% van onze totale gegevens moeten zijn. En we vergeten niet een random_state in te stellen voor reproduceerbaarheid.

X_train, X_test, y_train, y_test = train_test_split( X, y, test_size = 0.2, random_state = 42 ) print("X_train shape:", X_train.shape)
print("y_train shape:", y_train.shape)
print("X_test shape:", X_test.shape)
print("y_test shape:", y_test.shape) X_train shape: (172, 12)
y_train shape: (172,)
X_test shape: (43, 12)
y_test shape: (43,)

Bouw een logistiek regressiemodel

Baseline

Dus nu moeten we beginnen met het bouwen van ons model, en we moeten beginnen met bestellen om onze basislijn vast te stellen. Onthoud dat het type probleem waar we mee te maken hebben een classificatieprobleem is en dat er verschillende statistieken zijn om classificatiemodellen te evalueren. Waar ik me op wil concentreren, is de nauwkeurigheidsscore.

Wat is nu de nauwkeurigheidsscore? Nauwkeurigheidsscore bij machine learning is een evaluatiestatistiek die het aantal correcte voorspellingen van een model meet ten opzichte van het totale aantal gemaakte voorspellingen. We berekenen het door het aantal juiste voorspellingen te delen door het totale aantal voorspellingen. Dat betekent dus dat de nauwkeurigheidsscore tussen 0 en 1 ligt. Nul is niet goed. Dat is waar je niet wilt zijn, en één is perfect. Dus laten we dat in gedachten houden en onthouden dat de basislijn een model is dat keer op keer één voorspelling geeft, ongeacht wat de waarneming is, slechts één gok voor ons.

In ons geval hebben we twee klassen, geplaatst of niet. Dus als we maar één voorspelling konden doen, wat zou dan onze enige gok zijn? Als je de meerderheidsklasse zei. Ik denk dat dat logisch is, toch? Als we maar één voorspelling kunnen hebben, moeten we waarschijnlijk degene kiezen met de hoogste waarnemingen in onze dataset. Onze basislijn gebruikt dus het percentage dat de meerderheidsklasse in de trainingsgegevens verschijnt. Als het model deze basislijn niet verslaat, voegen de kenmerken geen waardevolle informatie toe om onze waarnemingen te classificeren.

We kunnen de methode 'value_counts' gebruiken met het argument 'normalize = True' om de basisnauwkeurigheid te berekenen:

acc_baseline = y_train.value_counts(normalize=True).max()
print("Baseline Accuracy:", round(acc_baseline, 2)) Baseline Accuracy: 0.68

We kunnen zien dat onze basisnauwkeurigheid 68% of 0.68 is als verhouding. Dus om waarde toe te voegen om van nut te zijn, willen we boven dat aantal komen en dichter bij één komen. Dat is ons doel, en laten we nu beginnen met het bouwen van ons model.

Herhalen

Nu is het tijd om ons model te bouwen met behulp van Logistic Regression. We zullen logistische regressie gebruiken, maar laten we, voordat we dat doen, een beetje praten over wat logistische regressie is en hoe het werkt, en dan kunnen we gaan coderen. En daarvoor hebben we hier een klein raster.

Laten we langs de x-as zeggen dat ik de p_degrees van kandidaten in onze dataset heb. En terwijl ik van rechts naar links ga, worden de graden hoger en hoger, en langs de Y-as heb ik de mogelijke klassen voor plaatsing: nul en één.

grafiek voor Logistische Regressie

Dus als we onze datapunten zouden uitzetten, hoe zou dat er dan uitzien? Uit onze analyse blijkt dat een kandidaat met een hoge `p_degree` meer kans heeft om aangenomen te worden. Dus het zou er waarschijnlijk ongeveer zo uitzien, waarbij de kandidaat met een kleine `p_degree` op nul zou staan. En de kandidaat met een hoge `p_degree` zou op één staan.

p-graad voor Logistische Regressie

Laten we nu zeggen dat we hiermee lineaire regressie wilden doen. Laten we zeggen dat we een lijn wilden uitzetten.
Als we dat zouden doen, zou die lijn zo worden uitgezet dat hij zou proberen zo dicht mogelijk bij alle punten te komen. En dus zouden we waarschijnlijk eindigen met een regel die er ongeveer zo uitzag. Zou dit een goed model zijn?

herhalen

Niet echt. Wat er zou gebeuren, is dat we, ongeacht de graad van de kandidaat, altijd een soort waarde zouden krijgen. En dat zal ons niet helpen, want de cijfers zeggen in deze context niets. Dit classificatieprobleem moet nul of één zijn. Dus zo gaat het niet werken.

Aan de andere kant, omdat dit een regel is, wat als we een kandidaat hebben met een zeer lage p_degree? Nou, opeens is onze schatting een negatief getal. En nogmaals, dit slaat nergens op. Er is geen negatief getal dat nul of één moet zijn. En op dezelfde manier, als we een kandidaat hebben met een zeer hoge p_degree, heb ik misschien een positieve, iets meer dan één. En nogmaals, dat slaat nergens op. We moeten een nul of een hebben.

voorspelling

Dus wat we hier zien zijn enkele serieuze beperkingen aan het gebruik van lineaire regressie voor classificatie. Dus wat moeten we doen? We moeten een model maken dat nummer één is: niet onder nul of boven één gaat, dus het moet tussen nul en één worden gebonden. En het getal twee, wat er ook uit die functie komt, die vergelijking die we creëren, moeten we misschien niet als de voorspelling op zich beschouwen, maar als een stap in de richting van onze uiteindelijke voorspelling.

Laat me nu uitpakken wat ik net zei, en laten we onszelf eraan herinneren dat wanneer we onze lineaire regressiemodellen doen, we eindigen met deze lineaire vergelijking, wat de eenvoudigste vorm is. En dit is die vergelijking of functie die ons die rechte lijn geeft.

img

Er is een manier om die lijn tussen 0 en 1 te binden. Wat we kunnen doen, is deze functie die we zojuist hebben gemaakt, insluiten in een andere functie, een zogenaamde sigmoïde functie.

functie voor Logistische Regressie

Dus ik ga de lineaire vergelijking nemen die we net hadden, en ik ga het verkleinen in de sigmoïde functie en het als de exponentiële functie plaatsen.

functie voor Logistische Regressie

Wat er gebeurt, is dat we in plaats van een rechte lijn een lijn krijgen die er ongeveer zo uitziet. Het blijft steken op één. Het komt binnen en kronkelt naar beneden. Dan blijft het op nul steken.

logistische regressie

Juist, zo ziet de lijn eruit, en we kunnen zien dat we ons eerste probleem hebben opgelost. Wat we ook uit deze functie halen, het zal tussen 0 en 1 liggen. In de tweede stap behandelen we wat er uit deze vergelijking komt niet als de ultieme voorspelling. In plaats daarvan behandelen we het als een waarschijnlijkheid.

logistische regressie

Wat bedoel ik? Dat betekent dat wanneer ik een voorspelling doe, ik een drijvende-kommawaarde krijg tussen 0 en 1. En wat ik zal doen is het behandelen als de waarschijnlijkheid dat mijn voorspelling tot de positieve klasse behoort.

Dus ik krijg een waarde omhoog naar 0.9999. Ik zal zeggen dat de kans dat deze kandidaat tot onze positief geplaatste klas behoort 99% is. Dus ik ben er bijna zeker van dat het tot de positieve klasse behoort. Omgekeerd, als het lager is dan 0.001 of wat dan ook, zal ik zeggen dat dit aantal laag is. De kans dat deze specifieke waarneming tot de positieve, de geplaatste klasse behoort, is bijna nul. En dus ga ik zeggen dat het tot klasse nul behoort.

Dus dat is logisch voor getallen die dicht bij één of bijna nul liggen. Maar je kunt je afvragen, wat doe ik met andere waarden daar tussenin? De manier waarop dat werkt, is dat we een grenslijn precies op 0.5 zetten, dus elke waarde die ik onder die lijn krijg, zet ik op nul, dus mijn voorspelling is nee, en als het boven die lijn is, als het boven punt vijf is , Ik zal dit in de positieve klasse plaatsen, mijn voorspelling is er een.

p-graad

Dus nu heb ik een functie die me een voorspelling tussen nul en één geeft, en ik behandel dat als een waarschijnlijkheid. En als die kans groter is dan 0.5 of 50%, zeg ik, oké, positieve klasse één. En als het minder dan 50% is, zeg ik, is dat een negatieve klasse, nul. Dus dat is de manier waarop logistische regressie werkt. En nu we dat begrijpen, laten we het coderen en passen. Ik zal de hyperparameter 'max_iter' instellen op 1000. Deze parameter verwijst naar het maximale aantal iteraties voor de oplossers om te convergeren.

# Build model
model = LogisticRegression(max_iter=1000) # Fit model to training data
model.fit(X_train, y_train) LogisticRegression(max_iter=1000)

Schatten

Nu is het tijd om te zien hoe ons model het doet. Het is tijd om het Logistic Regression-model te evalueren. Laten we dus niet vergeten dat de prestatiemaatstaf waarin we geïnteresseerd zijn deze keer de nauwkeurigheidsscore is, en we willen een nauwkeurige score. En we willen de baseline van 0.68 verslaan. Modelnauwkeurigheid kan worden berekend met behulp van de functie accuratesse_score. De functie vereist twee argumenten, de echte labels en de voorspelde labels.

acc_train = accuracy_score(y_train, model.predict(X_train))
acc_test = model.score(X_test, y_test) print("Training Accuracy:", round(acc_train, 2))
print("Test Accuracy:", round(acc_test, 2)) Training Accuracy: 0.9
Test Accuracy: 0.88

We kunnen onze trainingsnauwkeurigheid op 90% zien. Het verslaat de basislijn. Onze testnauwkeurigheid was met 88% iets lager. Het versloeg ook de basislijn en kwam heel dicht bij onze trainingsnauwkeurigheid. Dus dat is goed nieuws, want dat betekent dat ons model niet overfit is of zo.

Resultaten van het Logistische Regressiemodel

Onthoud dat we met logistische regressie eindigen met deze laatste voorspellingen van nul of één. Maar onder die voorspelling zit een waarschijnlijkheid van een getal met drijvende komma tussen nul of één, en soms kan het handig zijn om te zien wat die waarschijnlijkheidsschattingen zijn. Laten we eens kijken naar onze trainingsvoorspellingen en laten we naar de eerste vijf kijken. De 'predict'-methode voorspelt het doel van een niet-gelabelde waarneming.

model.predict(X_train)[:5] array([0, 1, 1, 1, 1])

Dus dat waren de laatste voorspellingen, maar wat zijn de waarschijnlijkheden erachter? Om die te krijgen, moeten we een iets andere code doen. In plaats van de `predict`-methode te gebruiken met ons model, zal ik de 'predict_proba' gebruiken met onze trainingsgegevens.

y_train_pred_proba = model.predict_proba(X_train)
print(y_train_pred_proba[:5]) [[0.92003219 0.07996781] [0.03202019 0.96797981] [0.00678421 0.99321579] [0.03889446 0.96110554] [0.00245525 0.99754475]]

We zien een soort geneste lijst met twee verschillende kolommen erin. De kolom aan de linkerkant geeft de kans weer dat een kandidaat niet geplaatst wordt of onze negatieve klasse 'Niet geplaatst'. De andere kolom vertegenwoordigt de positieve klasse `Placed` of de kans dat een kandidaat wordt geplaatst. We zullen ons concentreren op de tweede kolom. Als we naar de eerste kansschatting kijken, zien we dat deze 0.07 is. Dus aangezien dat minder dan 50% is, zegt ons model, is mijn voorspelling nul. En voor de volgende voorspellingen kunnen we zien dat die allemaal boven de 0.5 liggen, en daarom heeft ons model er uiteindelijk één voorspeld.

Nu willen we de functienamen en het belang ervan extraheren en in een reeks plaatsen. En omdat we de belangrijkheid van het kenmerk moeten weergeven als odds ratio's, moeten we een kleine wiskundige transformatie uitvoeren door de exponentiële waarde van onze belangrijkheid te nemen.

# Features names
features = ['gender', 'ssc_p', 'ssc_b', 'hsc_p', 'hsc_b', 'hsc_s', 'degree_p' ,'degree_t', 'workex', 'etest_p', 'specialisation', 'mba_p']
# Get importances
importances = model.coef_[0]
# Put importances into a Series
odds_ratios = pd.Series(np.exp(importances), index= features).sort_values()
# Review odds_ratios.head() mba_p 0.406590
degree_t 0.706021
specialisation 0.850301
hsc_b 0.876864
etest_p 0.877831
dtype: float64

Voordat we de odds ratio's bespreken en wat ze zijn, laten we ze op een horizontaal staafdiagram zetten. Laten we panda's gebruiken om de plot te maken, en onthoud dat we zullen zoeken naar de vijf grootste coëfficiënten. En we willen niet alle odds ratio's gebruiken. Dus we willen de staart gebruiken.

# Horizontal bar chart, five largest coefficients
odds_ratios.tail().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("High Importance Features");
# Horizontaal staafdiagram, vijf grootste coëfficiënten odds_ratios.tail().plot(kind=

Nu wil ik dat je je een verticale lijn voorstelt precies op 5, en ik wil beginnen met ernaar te kijken. Laten we het hebben over elk van deze afzonderlijk of alleen over het eerste paar. Dus laten we hier beginnen met de 'ssc_p', die verwijst naar het 'percentage secundair onderwijs – 10e klas'. En we kunnen zien dat de odds ratio 30 is. Wat betekent dat nu? Het betekent dat als een kandidaat een hoge 'ssc_p' heeft, de kans op plaatsing zes keer groter is dan die van andere kandidaten, bij gelijkblijvende omstandigheden. Dus een andere manier om erover na te denken is dat wanneer de kandidaat `ssc_p` heeft, de kans dat de kandidaat wordt aangenomen zes keer zo groot wordt.

Dus elke odds ratio van meer dan vijf verhoogt de kans dat kandidaten worden geplaatst. En daarom hebben we die verticale lijn op vijf. En deze vijf soorten kenmerken zijn kenmerken die het meest worden geassocieerd met meer werving. Dus dat is wat onze odds ratio is. Nu hebben we gekeken naar de kenmerken die het meest geassocieerd worden met een toename in werving. Laten we eens kijken naar de kenmerken die ermee samenhangen, de afname van de rekrutering. Dus nu is het tijd om naar de kleinste te kijken. Dus in plaats van naar de staart te kijken, kijken we ernaar.

odds_ratios.head().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("Low Importance Features");
kenmerk van laag belang

Het eerste dat we hier moeten zien, is dat op de x-as alles één of lager is. Nu, wat betekent dat? Dus laten we eens kijken naar onze kleinste odds ratio hier. Het is mba_p wat verwijst naar het MBA-percentage. We kunnen zien dat het rond 0.45 uur klaar is. Nu, wat betekent dat? Het verschil tussen 0.45 en 1 is 0.55. Oke? En wat betekent dat getal? Die Kandidaten met MBA zullen minder snel worden aangeworven met 55%, als alle andere dingen gelijk blijven. Oke? Dus het verminderde de kans op rekrutering met een factor 0.55 of 55%. En dat geldt voor alles hier.

Conclusie

Dus wat hebben we geleerd? Ten eerste hebben we in de voorbereide gegevensfase geleerd dat we werken met classificatie, met name binaire classificatie, met behulp van logistische regressie. Wat betreft het verkennen van de gegevens, hebben we heel veel dingen gedaan, maar wat de hoogtepunten betreft, hebben we gekeken naar de klassenbalans, toch? Het aandeel van onze positieve en negatieve klassen. Daarna splitsen we onze gegevens.

Aangezien Logistic Regression een classificatiemodel is, leerden we over een nieuwe prestatiemaatstaf, de nauwkeurigheidsscore. Nu gaat de nauwkeurigheidsscore tussen 0 en 1. Nul is slecht en één is goed. Toen we itereerden, leerden we over logistische regressie. Dat is een magische manier, waarbij je een lineaire vergelijking kunt nemen, een rechte lijn, en deze in een andere functie, een sigmoïde functie en een activeringsfunctie kunt plaatsen, en er een waarschijnlijkheidsschatting uit kunt halen en die waarschijnlijkheidsschatting in een voorspelling kunt veranderen.

Ten slotte leerden we over de odds ratio en de manier waarop we de coëfficiënten kunnen interpreteren om te zien of een bepaald kenmerk de kans vergroot dat we een kandidaat hebben aangeworven of niet.

Projectbroncode: https://github.com/SawsanYusuf/Campus-Recruitment.git

De in dit artikel getoonde media zijn geen eigendom van Analytics Vidhya en worden naar goeddunken van de auteur gebruikt. 

Tijdstempel:

Meer van Analytics Vidhya