Campus-Rekrutierung: Ein Klassifizierungsproblem mit logistischer Regression

Campus-Rekrutierung: Ein Klassifizierungsproblem mit logistischer Regression

Quellknoten: 1996810

Einleitung

In diesem Projekt konzentrieren wir uns auf Daten aus Indien. Und unser Ziel ist es, eine zu schaffen Vorhersagemodell, wie z. B. logistische Regression usw., sodass das Modell, wenn wir die Eigenschaften eines Kandidaten angeben, vorhersagen kann, ob er rekrutieren wird.

Das Datensatz dreht sich um die Praktikumssaison einer Business School in Indien. Der Datensatz enthält verschiedene Faktoren zu Kandidaten, wie z. B. Berufserfahrung, Prüfungsprozentsatz usw. Schließlich enthält er den Status der Einstellung und Details zur Vergütung.

Datenwissenschaftliches Problem mit logistischer Regression

Campus-Rekrutierung ist eine Strategie zur Suche, Einbindung und Einstellung junger Talente für Praktika und Einstiegspositionen. Es beinhaltet oft die Zusammenarbeit mit den Career Services Centern der Universitäten und die Teilnahme an Karrieremessen, um College-Studenten und frischgebackene Absolventen persönlich zu treffen.

Dieser Artikel wurde als Teil des veröffentlicht Data Science-Blogathon.

Inhaltsverzeichnis

  1. Schritte zur Lösung des Problems
  2. Daten vorbereiten
  3. Erstellen Sie ein logistisches Regressionsmodell
  4. Ergebnisse des logistischen Regressionsmodells
  5. Zusammenfassung

Schritte zur Lösung des Problems

In diesem Artikel importieren wir dieses Dataset, bereinigen es und bereiten es dann vor, um ein logistisches Regressionsmodell zu erstellen. Unsere Ziele hier sind die folgenden:

Zuerst bereiten wir unseren Datensatz vor binäre Klassifikation. Nun, was meine ich? Wenn wir versuchen, einen kontinuierlichen Wert vorherzusagen, wie den Preis einer Wohnung, kann es sich um eine beliebige Zahl zwischen null und vielen Millionen Dollar handeln. Wir nennen es ein Regressionsproblem.

Aber in diesem Projekt sind die Dinge ein bisschen anders. Anstatt einen kontinuierlichen Wert vorherzusagen, haben wir diskrete Gruppen oder Klassen, die wir zwischen ihnen vorherzusagen versuchen. Dies wird also als Klassifizierungsproblem bezeichnet, und da wir in unserem Projekt nur zwei Gruppen haben, zwischen denen wir zu wählen versuchen, ist es eine binäre Klassifizierung.

Das zweite Ziel ist die Erstellung eines logistischen Regressionsmodells zur Vorhersage der Rekrutierung. Und unser drittes Ziel ist es, die Vorhersagen unseres Modells anhand des Quotenverhältnisses zu erklären.

Was nun den Workflow für maschinelles Lernen betrifft, die Schritte, die wir befolgen werden, und einige der neuen Dinge, die wir auf dem Weg lernen werden. In der Importphase werden wir also unsere Daten für die Arbeit mit einem binären Ziel vorbereiten. In der Erkundungsphase werden wir uns die Klassenbalance ansehen. Also im Grunde genommen, welcher Anteil der Kandidaten war Dritter und welcher Anteil nicht? und in der Phase der Feature-Codierung werden wir unsere kategorialen Features codieren. Im Split-Teil werden wir einen randomisierten Zugtest-Split durchführen.

Für die Modellerstellungsphase werden wir zunächst unsere Baseline festlegen, und da wir Genauigkeits-Scores verwenden, werden wir mehr darüber sprechen, was ein Genauigkeits-Score ist und wie man eine Baseline erstellt, wenn dies die Metrik ist, an der wir interessiert sind. Zweitens werden wir eine logistische Regression durchführen. Und zu guter Letzt haben wir noch die Evaluierungsphase. Wir werden uns wieder auf die Genauigkeitsbewertung konzentrieren. Um die Ergebnisse zu kommunizieren, werden wir uns schließlich das Quotenverhältnis ansehen.

Bevor wir in die Arbeit eintauchen, stellen wir uns zu guter Letzt den Bibliotheken vor, die wir für das Projekt verwenden werden. Zuerst importieren wir unsere Daten in das Google Colabe-Notebook in die io-Bibliothek. Da wir dann ein logistisches Regressionsmodell verwenden, importieren wir dieses aus scikit-learn. Danach auch ab scikit-lernen, importieren wir unsere Leistungsmetriken, die Genauigkeitsbewertung und die Trainings-Test-Aufteilung.

Wir werden verwenden Matplotlib und Seaborn für unsere Visualisierung und NumPy  wird nur für wenig Mathematik sein.
Wir brauchen Pandas um unsere Daten zu manipulieren, Labelencoder um unsere kategorialen Variablen zu kodieren und Standard-Scaler um die Daten zu normalisieren. Das sind die Bibliotheken, die wir brauchen.

Lassen Sie uns mit der Vorbereitung der Daten beginnen.

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

Daten vorbereiten

Import

Beginnen wir mit der Vorbereitung der Daten, beginnen wir mit unserer wichtigen Arbeit. Zuerst laden wir unsere Datendatei und müssen sie dann in einen DataFrame „df.“ einfügen

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()
Datensatz für logistische Regression

Wir können unseren schönen DataFrame sehen, und wir haben 215 Datensätze und 15 Spalten, die das Attribut „Status“, unser Ziel, enthalten. Dies ist die Beschreibung für alle Funktionen.

Logistische Regression

Entdecken

Jetzt haben wir all diese Funktionen, die wir untersuchen werden. Beginnen wir also mit unserem explorative Datenanalyse. Schauen wir uns zunächst die Informationen für diesen Datenrahmen an und prüfen, ob wir einige davon behalten oder löschen müssen.

# 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

Wenn wir uns nun die `df`-Info ansehen, gibt es ein paar Dinge, nach denen wir suchen, wir haben 215 Zeilen in unserem Datenrahmen, und die Frage, die wir uns stellen möchten, ist, ob irgendwelche Daten fehlen? Und wenn wir hier nachsehen, scheinen wir keine fehlenden Daten außer der Gehaltsspalte zu haben, wie erwartet, aufgrund von Kandidaten, die nicht eingestellt wurden.

Eine weitere Sorge für uns hier ist, gibt es undichte Merkmale, die unserem Modell Informationen liefern würden, die es nicht hätte, wenn es in der realen Welt eingesetzt würde? Denken Sie daran, dass unser Modell vorhersagen soll, ob ein Kandidat platziert wird oder nicht, und wir möchten, dass unser Modell diese Vorhersagen trifft, bevor die Einstellung erfolgt. Daher möchten wir nach der Rekrutierung keine Angaben zu diesen Kandidaten machen.

Es ist also ziemlich klar, dass diese „Gehalts“-Funktion Informationen über das vom Unternehmen angebotene Gehalt liefert. Und weil dieses Gehalt für diejenigen gilt, die angenommen werden, stellt dieses Merkmal hier eine Leckage dar, und wir müssen es fallen lassen.

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

Das zweite, was ich mir ansehen möchte, sind die Datentypen für diese verschiedenen Funktionen. Wenn wir uns also diese Datentypen ansehen, haben wir acht kategoriale Merkmale mit unserem Ziel und sieben numerische Merkmale, und alles ist richtig. Nun, da wir diese Ideen haben, nehmen wir uns etwas Zeit, um sie eingehender zu untersuchen.

Wir wissen, dass unser Ziel zwei Klassen hat. Wir haben Kandidaten vermittelt und keine Kandidaten vermittelt. Die Frage ist, wie hoch ist der relative Anteil dieser beiden Klassen? Sind sie etwa gleich ausbalanciert? Oder ist das eine viel mehr als das andere? Darauf müssen Sie achten, wenn Sie Klassifizierungsprobleme lösen. Das ist also ein bedeutender Schritt in unserer EDA.

# Plot class balance
df["status"].value_counts(normalize=True).plot( kind="bar", xlabel="Class", ylabel="Relative Frequency", title="Class Balance"
);
Klassenungleichgewicht für die logistische Regression

Unsere positive Klasse „platziert“ macht mehr als 65 % unserer Beobachtungen aus, und unsere negative Klasse „nicht platziert“ macht etwa 30 % aus. Nun, wenn diese extrem unausgewogen wären, etwa 80 oder sogar mehr, würde ich sagen, dass dies unausgewogene Klassen sind. Und wir müssten einiges tun, um sicherzustellen, dass unser Modell richtig funktioniert. Aber das ist eine gute Balance.

Lassen Sie uns eine weitere Visualisierung erstellen, um die Verbindung zwischen unseren Features und dem Ziel zu erkennen. Beginnen wir mit den numerischen Merkmalen.

Zuerst sehen wir die individuelle Verteilung der Merkmale anhand eines Verteilungsplots, und wir sehen auch die Beziehung zwischen den numerischen Merkmalen und unserem Ziel anhand eines Boxplots.

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 Regression

In der ersten Spalte unseres Diagramms können wir sehen, dass alle Verteilungen einer Normalverteilung folgen und die meisten Bildungsleistungen des Kandidaten zwischen 60 und 80 % liegen.

In der zweiten Spalte haben wir einen doppelten Boxplot mit der Klasse „Platziert“ auf der rechten Seite und dann der Klasse „Nicht platziert“ auf der linken Seite. Für die Funktionen „etest_p“ und „mba_p“ gibt es aus Sicht der Modellerstellung zwischen diesen beiden Distributionen keinen großen Unterschied. Es gibt eine signifikante Überschneidung in der Verteilung über die Klassen, daher wären diese Merkmale kein guter Prädiktor für unser Ziel. Was den Rest der Merkmale betrifft, so sind sie deutlich genug, um sie als potenziell gute Prädiktoren für unser Ziel zu betrachten. Kommen wir zu den kategorialen Merkmalen. Und um sie zu untersuchen, verwenden wir ein Zähldiagramm.

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 Regression

Wenn wir uns die Handlung ansehen, sehen wir, dass wir mehr männliche Kandidaten als weibliche haben. Und die meisten unserer Kandidaten haben keine Berufserfahrung, aber diese Kandidaten wurden häufiger eingestellt als diejenigen, die Erfahrung hatten. Wir haben Kandidaten mit kaufmännischem HSC-Studiengang, und neben einem Bachelor sind die Kandidaten mit naturwissenschaftlichem Hintergrund in beiden Fällen am zweitbesten.

Eine kleine Anmerkung zu logistischen Regressionsmodellen: Obwohl sie zur Klassifizierung dienen, gehören sie zur selben Gruppe wie andere lineare Modelle wie die lineare Regression, und aus diesem Grund sind sie beide lineare Modelle. Wir müssen uns auch um das Thema Multikollinearität kümmern. Wir müssen also eine Korrelationsmatrix erstellen und diese dann in einer Heatmap darstellen. Wir wollen hier nicht alle Merkmale betrachten, wir wollen nur die numerischen Merkmale betrachten, und wir wollen unser Ziel nicht einbeziehen. Denn wenn unser Ziel mit einigen unserer Merkmale korreliert, ist das sehr gut.

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');
Korrelationsmatrix

Hier sind das Hellblau, das wenig bis gar keine Korrelation bedeutet, und das Dunkelblau, mit dem wir eine höhere Korrelation haben. Also wollen wir nach diesen Dunkelblauen Ausschau halten. Wir können eine dunkelblaue Linie sehen, eine diagonale Linie, die durch die Mitte dieses Diagramms verläuft. Das sind die Merkmale, die mit sich selbst korrelieren. Und dann sehen wir einige dunkle Quadrate. Das bedeutet, dass wir eine Reihe von Korrelationen zwischen Merkmalen haben.

Im letzten Schritt unseres EDA müssen wir die kategorialen Merkmale auf Hoch-Tief-Kardinalität prüfen. Kardinalität bezieht sich auf die Anzahl eindeutiger Werte in einer kategorialen Variablen. Hohe Kardinalität bedeutet, dass kategoriale Merkmale eine große Anzahl eindeutiger Werte haben. Es gibt keine genaue Anzahl eindeutiger Werte, die einem Feature eine hohe Kardinalität verleihen. Wenn der Wert des kategorialen Merkmals jedoch für fast alle Beobachtungen eindeutig ist, kann es normalerweise weggelassen werden.

# 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

Ich sehe keine Spalten, in denen die Anzahl der eindeutigen Werte eins oder etwas sehr hohes ist. Aber ich denke, es gibt eine kategorische Spalte, die uns hier fehlt. Und der Grund dafür ist, dass es nicht als Objekt, sondern als Ganzzahl codiert ist. Die Spalte 'sl_no' ist keine ganze Zahl in dem uns bekannten Sinne. Diese Kandidaten sind in einer bestimmten Reihenfolge angeordnet. Nur ein eindeutiges Namensschild, und der Name ist wie eine Kategorie, oder? Das ist also eine kategoriale Variable. Und es hat keine Informationen, also müssen wir es fallen lassen.

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

Funktionen Codierung

Wir haben unsere Analyse abgeschlossen, und als Nächstes müssen wir unsere kategorialen Merkmale codieren. Ich werde den „LabelEncoder“ verwenden. Label Encoding ist eine beliebte Codierungstechnik für die Handhabung kategorialer Variablen. Bei Verwendung dieser Technik wird jedem Etikett eine eindeutige Ganzzahl basierend auf einer alphabetischen Reihenfolge zugewiesen.

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()
Codeausgabe

Split

Wir haben unsere Daten importiert und bereinigt. Wir haben ein wenig explorative Datenanalyse durchgeführt, und jetzt müssen wir unsere Daten aufteilen. Wir haben zwei Arten der Teilung: vertikale Teilung oder Features-Target und horizontale Teilung oder Train-Test-Sets. Fangen wir mit der vertikalen an. Wir erstellen unsere Merkmalsmatrix 'X' und den Zielvektor 'y'. Unser Ziel ist „Status“. Unsere Features sollten alle Spalten sein, die im 'df' verbleiben.

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

Modelle funktionieren im Allgemeinen besser, wenn sie über normalisierte Daten verfügen, mit denen sie trainieren können. Was ist also Normalisierung? Normalisierung transformiert die Werte mehrerer Variablen in einen ähnlichen Bereich. Unser Ziel ist es, unsere Variablen zu normalisieren. Ihre Wertebereiche reichen also von 0 bis 1. Lassen Sie uns das tun, und ich werde den `StandardScaler.` verwenden

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

Lassen Sie uns nun den horizontalen Split oder die Train-Test-Sets durchführen. Wir müssen unsere Daten (X und y) mithilfe einer randomisierten Zug-Test-Aufteilung in Trainings- und Testsätze aufteilen. Unser Testsatz sollte 20 % unserer Gesamtdaten umfassen. Und wir vergessen nicht, einen random_state für die Reproduzierbarkeit zu setzen.

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

Erstellen Sie ein logistisches Regressionsmodell

Baseline

Jetzt müssen wir also mit dem Aufbau unseres Modells beginnen, und wir müssen mit der Bestellung beginnen, um unsere Basislinie festzulegen. Denken Sie daran, dass es sich bei der Art von Problem, mit der wir es zu tun haben, um ein Klassifizierungsproblem handelt, und dass es verschiedene Metriken zur Bewertung von Klassifizierungsmodellen gibt. Worauf ich mich konzentrieren möchte, ist die Genauigkeitsbewertung.

Was ist nun die Genauigkeitsbewertung? Der Genauigkeitswert beim maschinellen Lernen ist eine Bewertungsmetrik, die die Anzahl der korrekten Vorhersagen eines Modells im Verhältnis zur Gesamtzahl der getroffenen Vorhersagen misst. Wir berechnen es, indem wir die Anzahl der richtigen Vorhersagen durch die Gesamtzahl der Vorhersagen dividieren. Das bedeutet also, dass der Genauigkeitswert zwischen 0 und 1 liegt. Null ist nicht gut. Das ist, wo Sie nicht sein wollen, und man ist perfekt. Behalten wir das also im Hinterkopf und erinnern uns daran, dass die Basislinie ein Modell ist, das immer wieder eine Vorhersage liefert, unabhängig davon, was die Beobachtung ist, nur eine Vermutung für uns.

In unserem Fall haben wir zwei Klassen, platziert oder nicht. Wenn wir also nur eine Vorhersage machen könnten, was wäre unsere einzige Vermutung? Wenn Sie die Mehrheitsklasse sagten. Ich denke, das macht Sinn, oder? Wenn wir nur eine Vorhersage haben können, sollten wir wahrscheinlich diejenige mit den höchsten Beobachtungen in unserem Datensatz wählen. Unsere Basislinie verwendet also den Prozentsatz, den die Mehrheitsklasse in den Trainingsdaten auftaucht. Wenn das Modell diese Basislinie nicht übertrifft, fügen die Merkmale keine wertvollen Informationen hinzu, um unsere Beobachtungen zu klassifizieren.

Wir können die Methode „value_counts“ mit dem Argument „normalize = True“ verwenden, um die Basisgenauigkeit zu berechnen:

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

Wir können sehen, dass unsere Basisgenauigkeit 68 % oder 0.68 im Verhältnis beträgt. Um einen nützlichen Mehrwert zu schaffen, wollen wir diese Zahl übersteigen und näher an eins herankommen. Das ist unser Ziel, und jetzt fangen wir an, unser Modell zu bauen.

Iterieren

Jetzt ist es an der Zeit, unser Modell mithilfe der logistischen Regression zu erstellen. Wir werden die logistische Regression verwenden, aber bevor wir das tun, lassen Sie uns ein wenig darüber sprechen, was die logistische Regression ist und wie sie funktioniert, und dann können wir die Codierung erledigen. Und dafür haben wir hier ein kleines Raster.

Angenommen, ich habe entlang der x-Achse die p_degrees der Kandidaten in unserem Datensatz. Und wenn ich mich von rechts nach links bewege, werden die Grade höher und höher, und dann habe ich entlang der Y-Achse die möglichen Klassen für die Platzierung: null und eins.

Diagramm für die logistische Regression

Wenn wir also unsere Datenpunkte aufzeichnen würden, wie würde das aussehen? Unsere Analyse zeigt, dass ein Kandidat mit einem hohen „p_graduate“ eher eingestellt wird. Also würde es wahrscheinlich ungefähr so ​​aussehen, wo der Kandidat mit einem kleinen `p_degree` bei null liegen würde. Und der Kandidat mit einem hohen „p_degree“ wäre um eins oben.

p-Grad für logistische Regression

Nehmen wir nun an, dass wir damit eine lineare Regression durchführen wollten. Nehmen wir an, wir wollten eine Linie zeichnen.
Wenn wir das jetzt tun würden, würde passieren, dass diese Linie so gezeichnet würde, dass sie versuchen würde, so nah wie möglich an allen Punkten zu sein. Und so würden wir wahrscheinlich mit einer Linie enden, die ungefähr so ​​​​aussieht. Wäre das ein gutes Modell?

iterieren

Nicht wirklich. Was passieren würde, ist, dass wir unabhängig vom P_Grad des Kandidaten immer eine Art Wert erhalten würden. Und das wird uns nicht helfen, denn die Zahlen sagen in diesem Zusammenhang nichts aus. Dieses Klassifizierungsproblem muss entweder null oder eins sein. So wird es also nicht funktionieren.

Da dies andererseits eine Linie ist, was ist, wenn wir einen Kandidaten mit einem sehr niedrigen p_degree haben? Nun, plötzlich ist unsere Schätzung eine negative Zahl. Und das ergibt wiederum keinen Sinn. Es gibt keine negative Zahl, die entweder Null oder Eins sein muss. Und auf die gleiche Weise, wenn wir einen Kandidaten mit einem sehr hohen p_grad haben, könnte ich einen positiven, etwas über eins haben. Und das macht wiederum keinen Sinn. Wir müssen entweder eine Null oder eine Eins haben.

Prognose

Was wir hier also sehen, sind einige schwerwiegende Einschränkungen bei der Verwendung der linearen Regression für die Klassifizierung. Was müssen wir also tun? Wir müssen ein Modell erstellen, das die Nummer eins ist: nicht unter Null oder über Eins geht, also muss es zwischen Null und Eins gebunden sein. Und die Nummer zwei, was auch immer aus dieser Funktion, dieser Gleichung, die wir erstellen, herauskommt, wir sollten sie vielleicht nicht als die Vorhersage per se behandeln, sondern als einen Schritt hin zu unserer endgültigen Vorhersage.

Lassen Sie mich nun das, was ich gerade gesagt habe, auspacken und uns daran erinnern, dass wir bei unseren linearen Regressionsmodellen mit dieser linearen Gleichung enden, die die einfachste Form ist. Und das ist diese Gleichung oder Funktion, die uns diese gerade Linie gibt.

img

Es gibt eine Möglichkeit, diese Linie zwischen 0 und 1 zu binden. Und was wir tun können, ist, diese Funktion, die wir gerade erstellt haben, zu nehmen und sie in eine andere Funktion einzuschließen, eine sogenannte Sigmoid-Funktion.

Funktion für die logistische Regression

Also nehme ich die lineare Gleichung, die wir gerade hatten, und ich werde sie in die Sigmoidfunktion verkleinern und sie als Exponentialfunktion einsetzen.

Funktion für die logistische Regression

Was passiert ist, dass wir statt einer geraden Linie eine Linie bekommen, die ungefähr so ​​aussieht. Es bleibt bei eins hängen. Es kommt herein und kringelt herunter. Dann bleibt es bei null hängen.

logistische Regression

Richtig, so sieht die Linie aus und wir können sehen, dass wir unser erstes Problem gelöst haben. Was auch immer wir aus dieser Funktion herausbekommen, wird zwischen 0 und 1 liegen. Im zweiten Schritt behandeln wir das, was aus dieser Gleichung herauskommt, nicht als die endgültige Vorhersage. Stattdessen behandeln wir es als Wahrscheinlichkeit.

logistische Regression

Was meine ich? Das heißt, wenn ich eine Vorhersage mache, erhalte ich einen Fließkommawert zwischen 0 und 1. Und was ich tun werde, ist es als die Wahrscheinlichkeit zu behandeln, dass meine Vorhersage zur positiven Klasse gehört.

Ich bekomme also einen Wert von 0.9999. Ich werde sagen, dass die Wahrscheinlichkeit, dass dieser Kandidat zu unserer positiv platzierten Klasse gehört, 99 % beträgt. Ich bin mir also fast sicher, dass es zur positiven Klasse gehört. Umgekehrt, wenn es bei Punkt 0.001 oder was auch immer unten ist, werde ich sagen, dass diese Zahl niedrig ist. Die Wahrscheinlichkeit, dass diese spezielle Beobachtung zu der positiven, platzierten Klasse gehört, ist nahezu null. Und deshalb werde ich sagen, dass es zur Klasse Null gehört.

Das ist also sinnvoll für Zahlen, die nahe bei eins oder nahe bei null liegen. Aber Sie fragen sich vielleicht, was mache ich mit anderen Werten dazwischen? Das funktioniert so, dass wir eine Abschneidelinie direkt bei 0.5 setzen, also setze ich jeden Wert, den ich unter dieser Linie erhalte, auf Null, also ist meine Vorhersage nein, und wenn er über dieser Linie liegt, wenn er über Punkt fünf liegt , ich werde dies in die positive Klasse einordnen, meine Vorhersage ist eine.

p-grad

Jetzt habe ich also eine Funktion, die mir eine Vorhersage zwischen null und eins gibt, und ich behandle das als Wahrscheinlichkeit. Und wenn diese Wahrscheinlichkeit über 0.5 oder 50 % liegt, sage ich, okay, positive Klasse eins. Und wenn es unter 50 % ist, sage ich, ist das negative Klasse, null. So funktioniert also die logistische Regression. Und jetzt verstehen wir das, lasst es uns codieren und anpassen. Ich werde den Hyperparameter „max_iter“ auf 1000 setzen. Dieser Parameter bezieht sich auf die maximale Anzahl von Iterationen für die Konvergenz der Solver.

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

Bewerten

Jetzt ist es an der Zeit zu sehen, wie sich unser Modell verhält. Es ist an der Zeit, das logistische Regressionsmodell zu evaluieren. Denken wir also daran, dass die Leistungsmetrik, an der wir interessiert sind, diesmal die Genauigkeitsbewertung ist, und wir wollen eine genaue. Und wir wollen die Basislinie von 0.68 übertreffen. Die Modellgenauigkeit kann mit der Funktion precision_score berechnet werden. Die Funktion erfordert zwei Argumente, die wahren Labels und die vorhergesagten 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

Wir können unsere Trainingsgenauigkeit bei 90 % sehen. Es schlägt die Grundlinie. Unsere Testgenauigkeit war mit 88 % etwas geringer. Es übertraf auch die Grundlinie und kam unserer Trainingsgenauigkeit sehr nahe. Das sind also gute Nachrichten, denn das bedeutet, dass unser Modell nicht überangepasst ist oder so.

Ergebnisse des logistischen Regressionsmodells

Denken Sie daran, dass wir bei der logistischen Regression mit diesen endgültigen Vorhersagen von null oder eins enden. Aber unter dieser Vorhersage gibt es eine Wahrscheinlichkeit einer Gleitkommazahl zwischen null und eins, und manchmal kann es hilfreich sein, zu sehen, was diese Wahrscheinlichkeitsschätzungen sind. Schauen wir uns unsere Trainingsvorhersagen an, und schauen wir uns die ersten fünf an. Die 'Predict'-Methode sagt das Ziel einer unbeschrifteten Beobachtung voraus.

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

Das waren also die endgültigen Vorhersagen, aber was sind die Wahrscheinlichkeiten dahinter? Um diese zu erhalten, müssen wir einen etwas anderen Code ausführen. Anstatt die „predict“-Methode mit unserem Modell zu verwenden, werde ich die „predict_proba“-Methode mit unseren Trainingsdaten verwenden.

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

Wir sehen eine Art verschachtelte Liste mit zwei verschiedenen Spalten darin. Die linke Spalte stellt die Wahrscheinlichkeit dar, dass ein Kandidat nicht platziert wird, oder unsere Negativklasse „Nicht platziert“. Die andere Spalte repräsentiert die Positivklasse „Platziert“ bzw. die Wahrscheinlichkeit, dass ein Kandidat platziert wird. Wir konzentrieren uns auf die zweite Spalte. Wenn wir uns die erste Wahrscheinlichkeitsschätzung von rechts ansehen, können wir sehen, dass diese 0.07 beträgt. Da das also unter 50 % liegt, sagt unser Modell, ist meine Vorhersage null. Und für die folgenden Vorhersagen können wir sehen, dass diese alle über 0.5 liegen, und deshalb hat unser Modell am Ende einen vorhergesagt.

Jetzt wollen wir die Merkmalsnamen und die Wichtigkeit extrahieren und sie in eine Reihe stellen. Und weil wir die Wichtigkeit von Merkmalen als Wahrscheinlichkeitsverhältnisse anzeigen müssen, müssen wir nur eine kleine mathematische Transformation durchführen, indem wir das Exponential unserer Wichtigkeit nehmen.

# 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

Bevor wir über die Quotenverhältnisse sprechen und was sie sind, lassen Sie uns sie auf einem horizontalen Balkendiagramm darstellen. Lassen Sie uns Pandas verwenden, um das Diagramm zu erstellen, und denken Sie daran, dass wir nach den fünf größten Koeffizienten suchen werden. Und wir wollen nicht alle Odds Ratios verwenden. Also wollen wir den Schwanz verwenden.

# Horizontal bar chart, five largest coefficients
odds_ratios.tail().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("High Importance Features");
# Horizontales Balkendiagramm, fünf größte Koeffizienten odds_ratios.tail().plot(kind=

Jetzt möchte ich, dass Sie sich eine vertikale Linie genau bei 5 vorstellen, und ich möchte damit beginnen, sie zu betrachten. Lassen Sie uns über jedes davon einzeln oder nur über das erste Paar sprechen. Beginnen wir also hier mit „ssc_p“, was sich auf den „Sekundarschulprozentsatz – 10. Klasse“ bezieht. Und wir können sehen, dass das Odds Ratio bei 30 liegt. Was bedeutet das nun? Das heißt, wenn ein Kandidat einen hohen 'ssc_p' hat, sind die Chancen auf seine Platzierung sechsmal höher als bei anderen Kandidaten, wenn alle Dinge gleich sind. Man kann es sich also anders vorstellen, wenn der Kandidat `ssc_p` hat, erhöht sich die Wahrscheinlichkeit, dass der Kandidat rekrutiert wird, um das Sechsfache.

Jedes Quotenverhältnis über fünf erhöht also die Wahrscheinlichkeit, dass Kandidaten platziert werden. Und deshalb haben wir diese vertikale Linie bei fünf. Und diese fünf Arten von Merkmalen sind Merkmale, die am häufigsten mit einer erhöhten Rekrutierung in Verbindung gebracht werden. Das ist also unser Quotenverhältnis. Nun haben wir uns die Funktionen angesehen, die am ehesten mit einer Zunahme der Rekrutierung in Verbindung gebracht werden. Schauen wir uns die Merkmale an, die damit verbunden sind, der Rückgang der Rekrutierung. Jetzt ist es an der Zeit, sich die Kleinsten anzusehen. Anstatt also auf den Schwanz zu schauen, schauen wir ihn an.

odds_ratios.head().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("Low Importance Features");
Funktion von geringer Bedeutung

Das erste, was wir hier sehen müssen, ist, dass auf der x-Achse alles eins oder darunter ist. Nun, was bedeutet das? Werfen wir also einen Blick auf unser kleinstes Quotenverhältnis hier. Es ist mba_p, was sich auf den MBA-Prozentsatz bezieht. Wir können sehen, dass es bei etwa 0.45 fertig ist. Nun, was bedeutet das? Nun, der Unterschied zwischen 0.45 und 1 beträgt 0.55. In Ordnung? Und was bedeutet diese Zahl? Kandidaten mit MBA werden mit einer um 55 % geringeren Wahrscheinlichkeit rekrutiert, wenn alle anderen Dinge gleich bleiben. In Ordnung? Es verringerte also die Rekrutierungschancen um den Faktor 0.55 oder 55 %. Und das gilt hier für alles.

Zusammenfassung

Was haben wir also gelernt? Zunächst haben wir in der Phase der vorbereiteten Daten gelernt, dass wir mit der Klassifizierung, insbesondere der binären Klassifizierung, unter Verwendung der logistischen Regression arbeiten. In Bezug auf die Untersuchung der Daten haben wir eine Menge Dinge getan, aber in Bezug auf die Highlights haben wir uns die Klassenbalance angesehen, richtig? Der Anteil unserer positiven und negativen Klassen. Dann teilen wir unsere Daten auf.

Da es sich bei der logistischen Regression um ein Klassifizierungsmodell handelt, haben wir eine neue Leistungsmetrik kennengelernt, die Genauigkeitsbewertung. Jetzt liegt der Genauigkeitswert zwischen 0 und 1. Null ist schlecht und eins ist gut. Als wir iterierten, lernten wir etwas über die logistische Regression. Das ist ein magischer Weg, bei dem Sie eine lineare Gleichung, eine gerade Linie, in eine andere Funktion, eine Sigmoidfunktion und eine Aktivierungsfunktion stecken und daraus eine Wahrscheinlichkeitsschätzung erhalten und diese Wahrscheinlichkeitsschätzung in eine Vorhersage umwandeln können.

Schließlich haben wir etwas über das Quotenverhältnis gelernt und wie wir die Koeffizienten interpretieren können, um zu sehen, ob ein bestimmtes Merkmal die Wahrscheinlichkeit erhöht, dass wir einen Kandidaten rekrutiert haben oder nicht.

Quellcode des Projekts: https://github.com/SawsanYusuf/Campus-Recruitment.git

Die in diesem Artikel gezeigten Medien sind nicht Eigentum von Analytics Vidhya und werden nach Ermessen des Autors verwendet. 

Zeitstempel:

Mehr von Analytics-Vidhya