Reclutamento nel campus: un problema di classificazione con la regressione logistica

Reclutamento nel campus: un problema di classificazione con la regressione logistica

Nodo di origine: 1996810

Introduzione

In questo progetto, ci concentreremo sui dati provenienti dall'India. E il nostro obiettivo è creare un modello predittivo, come Logistic Regression, ecc. in modo che quando forniamo le caratteristiche di un candidato, il modello può prevedere se assumerà.

dataset ruota attorno alla stagione di collocamento di una Business School in India. Il set di dati ha vari fattori sui candidati, come l'esperienza lavorativa, la percentuale di esame, ecc. Infine, contiene lo stato di assunzione e i dettagli sulla retribuzione.

Problema di scienza dei dati con regressione logistica

Il reclutamento nel campus è una strategia per l'approvvigionamento, il coinvolgimento e l'assunzione di giovani talenti per stage e posizioni di livello base. Spesso comporta la collaborazione con i centri di servizi per la carriera universitaria e la partecipazione a fiere del lavoro per incontrare di persona studenti universitari e neolaureati.

Questo articolo è stato pubblicato come parte di Blogathon sulla scienza dei dati.

Sommario

  1. Passi coinvolti nella risoluzione del problema
  2. Prepara i dati
  3. Costruisci un modello di regressione logistica
  4. Risultati del modello di regressione logistica
  5. Conclusione

Passi coinvolti nella risoluzione del problema

In questo articolo, importeremo quel set di dati, lo puliremo e quindi lo prepareremo per costruire un modello di regressione logistica. I nostri obiettivi qui sono i seguenti:

Innanzitutto, prepareremo il nostro set di dati per classificazione binaria. Ora, cosa voglio dire? quando proviamo a prevedere un valore continuo, come il prezzo di un appartamento, può essere qualsiasi numero compreso tra zero e molti milioni di dollari. Lo chiamiamo un problema di regressione.

Ma in questo progetto le cose sono leggermente diverse. Invece di prevedere un valore continuo, abbiamo gruppi o classi discreti che stiamo cercando di prevedere tra di loro. Quindi questo si chiama problema di classificazione e poiché nel nostro progetto avremo solo due gruppi tra cui stiamo cercando di scegliere, questo lo rende una classificazione binaria.

Il secondo obiettivo è creare un modello di regressione logistica per prevedere il reclutamento. E il nostro terzo obiettivo è spiegare le previsioni del nostro modello usando il rapporto di probabilità.

Ora, in termini di flusso di lavoro di apprendimento automatico, i passaggi che seguiremo e alcune delle novità che impareremo strada facendo. Quindi, nella fase di importazione, prepareremo i nostri dati per lavorare con un target binario. Nella fase di esplorazione, esamineremo il bilanciamento delle classi. Quindi, in sostanza, quale proporzione di candidati era terza e quali proporzioni no? e nella fase di codifica delle caratteristiche, eseguiremo la codifica delle nostre caratteristiche categoriche. Nella parte divisa, faremo una divisione randomizzata del test del treno.

Per la fase di creazione del modello, in primo luogo, imposteremo la nostra linea di base e, poiché utilizzeremo i punteggi di accuratezza, parleremo di più di cos'è un punteggio di accuratezza e di come costruire una linea di base quando questa è la metrica che ci interessa. In secondo luogo, eseguiremo la regressione logistica. E poi, ultimo ma non meno importante, avremo la fase di valutazione. Ci concentreremo nuovamente sul punteggio di accuratezza. Infine, per comunicare i risultati, esamineremo l'odds ratio.

Infine, prima di addentrarci nel lavoro, presentiamoci alle librerie che utilizzeremo per il progetto. Innanzitutto, importeremo i nostri dati nel taccuino Google Colabe nella libreria io. Quindi, poiché utilizzeremo un modello di regressione logistica, lo importeremo da scikit-learn. Dopodiché, anche da scikit-impara, importeremo le nostre metriche sulle prestazioni, il punteggio di accuratezza e la suddivisione del test del treno.

Noi useremo matplotlib e seaborn per la nostra visualizzazione, e NumPy  sarà solo per un po' di matematica.
Abbiamo bisogno panda per manipolare i nostri dati, labelencoder per codificare le nostre variabili categoriali e lo scaler standard per normalizzare i dati. Saranno le biblioteche di cui abbiamo bisogno.

Passiamo alla preparazione dei dati.

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

Prepara i dati

Importare

Per iniziare a preparare i dati, prendiamo il nostro importante lavoro. Per prima cosa, carichiamo il nostro file di dati, quindi dobbiamo inserirli in un DataFrame `df.`

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()
Set di dati per la regressione logistica

Possiamo vedere il nostro bellissimo DataFrame e abbiamo 215 record e 15 colonne che includono l'attributo `status`, il nostro obiettivo. Questa è la descrizione di tutte le funzionalità.

Regressione logistica

Esplora

Ora abbiamo tutte queste funzionalità che esploreremo. Quindi iniziamo il nostro analisi dei dati esplorativi. Per prima cosa, diamo un'occhiata alle informazioni per questo dataframe e vediamo se qualcuno di essi potrebbe essere necessario conservarlo o se forse è necessario eliminarlo.

# 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

Ora, quando guardiamo le informazioni su `df`, ci sono un paio di cose che stiamo cercando, abbiamo 215 righe nel nostro dataframe e la domanda che vogliamo porci è: ci sono dati mancanti? E se guardiamo qui, sembra che non ci siano dati mancanti ad eccezione della colonna dello stipendio, come previsto, a causa di candidati che non sono stati assunti.

Un'altra preoccupazione per noi qui è: ci sono caratteristiche che perdono che darebbero informazioni al nostro modello che non avrebbe se fosse distribuito nel mondo reale? Ricorda che vogliamo che il nostro modello preveda se un candidato si posizionerà o meno e vogliamo che il nostro modello faccia tali previsioni prima che avvenga il reclutamento. Quindi non vogliamo fornire alcuna informazione su questi candidati dopo il reclutamento.

Quindi, è abbastanza chiaro che questa funzione "stipendio" fornisce informazioni sullo stipendio offerto dall'azienda. E poiché questo stipendio è per quelli accettati, questa caratteristica qui costituisce una perdita e dobbiamo eliminarla.

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

La seconda cosa che voglio esaminare sono i tipi di dati per queste diverse funzionalità. Quindi, osservando questi tipi di dati, abbiamo otto caratteristiche categoriche con il nostro obiettivo e sette caratteristiche numeriche, e tutto è corretto. Quindi, ora che abbiamo queste idee, prendiamoci del tempo per esplorarle più a fondo.

Sappiamo che il nostro obiettivo ha due classi. Abbiamo posto candidati e non posti candidati. La domanda è: qual è la proporzione relativa di queste due classi? Hanno più o meno lo stesso equilibrio? O uno è molto più dell'altro? Questo è qualcosa a cui devi dare un'occhiata quando stai facendo problemi di classificazione. Quindi questo è un passo significativo nella nostra EDA.

# Plot class balance
df["status"].value_counts(normalize=True).plot( kind="bar", xlabel="Class", ylabel="Relative Frequency", title="Class Balance"
);
Sbilanciamento di classe per la regressione logistica

La nostra classe positiva "posizionato" conta per oltre il 65% delle nostre osservazioni e la nostra classe negativa "non posizionato" è di circa il 30%. Ora, se queste fossero super sbilanciate, tipo, se fossero più simili a 80 o anche di più, direi che queste sono classi sbilanciate. E dovremmo fare del lavoro per assicurarci che il nostro modello funzioni nel modo giusto. Ma questo è un buon equilibrio.

Facciamo un'altra visualizzazione per notare la connessione tra le nostre caratteristiche e il target. Iniziamo con le caratteristiche numeriche.

In primo luogo, vedremo la distribuzione individuale delle caratteristiche utilizzando un diagramma di distribuzione e vedremo anche la relazione tra le caratteristiche numeriche e il nostro obiettivo utilizzando un diagramma a scatola.

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]);
"Regressione logistica

Nella prima colonna del nostro grafico, possiamo vedere che tutte le distribuzioni seguono una distribuzione normale e la maggior parte delle prestazioni educative del candidato è compresa tra il 60 e l'80%.

Nella seconda colonna, abbiamo un doppio box plot con la classe 'Placed' a destra e poi la classe 'Not Placed' a sinistra. Per le funzionalità 'etest_p' e 'mba_p', non c'è molta differenza in queste due distribuzioni dal punto di vista della costruzione del modello. C'è una significativa sovrapposizione nella distribuzione tra le classi, quindi queste caratteristiche non sarebbero un buon predittore del nostro obiettivo. Per quanto riguarda il resto delle funzionalità, sono abbastanza distinte da considerarle come potenziali buoni predittori del nostro obiettivo. Passiamo alle caratteristiche categoriche. E per esplorarli, useremo un grafico di conteggio.

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")
"Regressione logistica

Guardando la trama, vediamo che abbiamo più candidati maschi che femmine. E la maggior parte dei nostri candidati non ha alcuna esperienza lavorativa, ma questi candidati sono stati assunti più di quelli che ne avevano. Abbiamo candidati che hanno fatto commercio come corso "hsc" e, oltre a studenti universitari, i candidati con un background scientifico sono i secondi più alti in entrambi i casi.

Una piccola nota sui modelli di regressione logistica, sebbene siano per la classificazione, sono nello stesso gruppo di altri modelli lineari come la regressione lineare, e per questo motivo, poiché sono entrambi modelli lineari. Dobbiamo anche preoccuparci della questione della multicollinearità. Quindi dobbiamo creare una matrice di correlazione, e poi dobbiamo tracciarla in una heatmap. Non vogliamo guardare a tutte le caratteristiche qui, vogliamo guardare solo alle caratteristiche numeriche e non vogliamo includere il nostro obiettivo. Dal momento che se il nostro obiettivo è correlato ad alcune delle nostre caratteristiche, è molto buono.

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');
matrice di correlazione

Qui ci sono l'azzurro, che significa poca o nessuna correlazione, e il blu scuro, con il quale abbiamo una correlazione maggiore. Quindi vogliamo essere alla ricerca di quei blu scuro. Possiamo vedere una linea blu scuro, una linea diagonale che scende al centro di questo grafico. Queste sono le caratteristiche che sono correlate con se stesse. E poi, vediamo alcuni quadrati scuri. Ciò significa che abbiamo un sacco di correlazioni tra le caratteristiche.

Nella fase finale del nostro EDA, dobbiamo verificare la cardinalità alto-basso nelle caratteristiche categoriali. La cardinalità si riferisce al numero di valori univoci in una variabile categoriale. Cardinalità elevata significa che le caratteristiche categoriali hanno un numero elevato di valori univoci. Non esiste un numero esatto di valori univoci che renda una caratteristica altamente cardinale. Ma se il valore della caratteristica categorica è unico per quasi tutte le osservazioni, di solito può essere eliminato.

# 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

Non vedo colonne in cui il numero di valori univoci è uno o qualcosa di molto alto. Ma penso che ci sia una colonna di tipo categoriale che ci manca qui. E il motivo è che non è codificato come un oggetto ma come un numero intero. La colonna 'sl_no' non è un numero intero nel senso che conosciamo. Questi candidati sono classificati in un certo ordine. Solo una targhetta univoca e il nome è come una categoria, giusto? Quindi questa è una variabile categoriale. E non ha alcuna informazione, quindi dobbiamo eliminarlo.

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

Caratteristiche Codifica

Abbiamo terminato la nostra analisi e la prossima cosa che dobbiamo fare è codificare le nostre caratteristiche categoriche, userò "LabelEncoder". La codifica delle etichette è una tecnica di codifica popolare per la gestione delle variabili categoriali. Con l'utilizzo di questa tecnica, a ciascuna etichetta viene assegnato un numero intero univoco in base all'ordine alfabetico.

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()
uscita del codice

Diviso

Abbiamo importato e pulito i nostri dati. Abbiamo fatto un po' di analisi esplorativa dei dati, e ora dobbiamo suddividere i nostri dati. Abbiamo due tipi di split: split verticale o features-target e split orizzontale o train-test set. Cominciamo con quello verticale. Creeremo la nostra matrice di caratteristiche "X" e il vettore di destinazione "y". Il nostro obiettivo è lo "status". Le nostre caratteristiche dovrebbero essere tutte le colonne che rimangono nel 'df.'

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

I modelli generalmente funzionano meglio quando hanno dati normalizzati con cui allenarsi, quindi cos'è la normalizzazione? Normalizzazione sta trasformando i valori di diverse variabili in un intervallo simile. Il nostro obiettivo è normalizzare le nostre variabili. Quindi i loro intervalli di valori saranno compresi tra 0 e 1. Facciamolo e userò `StandardScaler.`

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

Ora facciamo la divisione orizzontale o le serie di prova del treno. Dobbiamo dividere i nostri dati (X e y) in set di addestramento e test utilizzando una suddivisione randomizzata del test di addestramento. il nostro set di test dovrebbe essere il 20% dei nostri dati totali. E non dimentichiamo di impostare un random_state per la riproducibilità.

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

Costruisci un modello di regressione logistica

Linea di base

Quindi ora dobbiamo iniziare a costruire il nostro modello e dovremo iniziare a ordinare per impostare la nostra linea di base. Ricorda che il tipo di problema con cui abbiamo a che fare è un problema di classificazione e ci sono diverse metriche per valutare i modelli di classificazione. Quello su cui voglio concentrarmi è il punteggio di precisione.

Ora, qual è il punteggio di accuratezza? Il punteggio di accuratezza nell'apprendimento automatico è una metrica di valutazione che misura il numero di previsioni corrette effettuate da un modello rispetto al numero totale di previsioni effettuate. Lo calcoliamo dividendo il numero di previsioni corrette per il numero totale di previsioni. Ciò significa che il punteggio di accuratezza va da 0 a 1. Zero non va bene. È lì che non vuoi essere, e uno è perfetto. Quindi teniamolo a mente e ricordiamo che la linea di base è un modello che fornisce una previsione più e più volte, indipendentemente da quale sia l'osservazione, solo un'ipotesi per noi.

Nel nostro caso, abbiamo due classi, posizionate o meno. Quindi, se potessimo fare una sola previsione, quale sarebbe la nostra ipotesi? Se hai detto la classe di maggioranza. Penso che abbia senso, giusto? Se possiamo avere solo una previsione, dovremmo probabilmente scegliere quella con le osservazioni più alte nel nostro set di dati. Quindi, la nostra linea di base utilizzerà la percentuale che la classe di maggioranza mostra nei dati di addestramento. Se il modello non supera questa linea di base, le funzionalità non aggiungono informazioni preziose per classificare le nostre osservazioni.

Possiamo usare il metodo 'value_counts' con l'argomento `normalize = True` per calcolare l'accuratezza della linea di base:

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

Possiamo vedere che la nostra precisione di riferimento è del 68% o 0.68 in proporzione. Quindi, per aggiungere valore per essere utili, vogliamo superare quel numero e avvicinarci a uno. Questo è il nostro obiettivo e ora iniziamo a costruire il nostro modello.

iterare

Ora è il momento di costruire il nostro modello utilizzando la regressione logistica. Useremo la regressione logistica, ma prima di farlo, parliamo un po' di cos'è la regressione logistica e di come funziona, e poi possiamo fare il codice. E per questo, qui abbiamo una piccola griglia.

Lungo l'asse x, diciamo che ho i p_gradi dei candidati nel nostro set di dati. E mentre mi sposto da destra a sinistra, i gradi diventano sempre più alti, e poi lungo l'asse Y, ho le possibili classi per il posizionamento: zero e uno.

grafico per la regressione logistica

Quindi, se dovessimo tracciare i nostri punti dati, come sarebbero? La nostra analisi mostra che è più probabile che un candidato con "p_grado" elevato venga assunto. Quindi, probabilmente sarebbe simile a questo, dove il candidato con un piccolo `p_degree` sarebbe a zero. E il candidato con un alto `p_grade` sarebbe all'altezza di uno.

grado p per la regressione logistica

Ora diciamo che vogliamo fare una regressione lineare con questo. Diciamo che volevamo tracciare una linea.
Ora, se lo facessimo, ciò che accadrebbe è che la linea verrebbe tracciata in modo tale da cercare di essere il più vicino possibile a tutti i punti. E quindi probabilmente ci ritroveremmo con una linea simile a questa. Sarebbe un buon modello?

iterate

Non proprio. Ciò che accadrebbe è indipendentemente dal p_grado del candidato, otterremmo sempre una sorta di valore. E questo non ci aiuterà perché i numeri, in questo contesto, non significano niente. Questo problema di classificazione deve essere zero o uno. Quindi, non funzionerà in questo modo.

D'altra parte, poiché questa è una linea, cosa succede se abbiamo un candidato con un p_grado molto basso? Bene, all'improvviso, la nostra stima è un numero negativo. E ancora, questo non ha alcun senso. Non esiste un numero negativo né deve essere zero o uno. E allo stesso modo, se abbiamo un candidato con un p_grade molto alto, potrei avere un positivo, qualcosa al di sopra di uno. E ancora, non ha alcun senso. Dobbiamo avere uno zero o uno.

predizione

Quindi ciò che vediamo qui sono alcune serie limitazioni all'utilizzo della regressione lineare per la classificazione. Quindi cosa dobbiamo fare? Dobbiamo creare un modello che numeri uno: non va sotto zero o sopra uno, quindi deve essere limitato tra zero e uno. E il numero due, qualunque cosa esca da quella funzione, quell'equazione che creiamo, forse non dovremmo trattarla come la previsione in sé ma come un passo verso la nostra previsione finale.

Ora, lasciatemi spiegare cosa ho appena detto, e ricordiamoci che quando stiamo facendo i nostri modelli di regressione lineare, finiamo con questa equazione lineare, che è la forma più semplice. E questa è quell'equazione o funzione che ci dà quella linea retta.

img

C'è un modo per legare quella linea tra 0 e 1. E quello che possiamo fare è prendere questa funzione che abbiamo appena creato e racchiuderla in un'altra funzione, quella che si chiama funzione sigmoide.

funzione per la regressione logistica

Quindi, prenderò l'equazione lineare che abbiamo appena avuto, e la rimpicciolirò nella funzione sigmoidea e la metterò come esponenziale.

funzione per la regressione logistica

Quello che succede è che invece di ottenere una linea retta, otteniamo una linea che assomiglia a questa. È fermo all'una. Entra e scende. Quindi è bloccato a zero.

regressione logistica

Bene, ecco come appare la linea, e possiamo vedere che abbiamo risolto il nostro primo problema. Qualunque cosa otteniamo da questa funzione sarà compresa tra 0 e 1. Nella seconda fase, non tratteremo ciò che esce da questa equazione come la previsione definitiva. Invece, lo tratteremo come una probabilità.

regressione logistica

Cosa voglio dire? Ciò significa che quando faccio una previsione, otterrò un valore in virgola mobile compreso tra 0 e 1. E quello che farò è trattarlo come la probabilità che la mia previsione appartenga alla classe positiva.

Quindi ottengo un valore fino a 0.9999. Dirò che la probabilità che questo candidato appartenga alla nostra classe classificata positiva è del 99%. Quindi sono quasi sicuro che appartenga alla classe positiva. Al contrario, se scende al punto 0.001 o qualsiasi altra cosa, dirò che questo numero è basso. La probabilità che questa particolare osservazione appartenga alla classe positiva classificata è quasi zero. E quindi, dirò che appartiene alla classe zero.

Quindi ha senso per numeri vicini a uno o vicini a zero. Ma potresti chiederti, cosa devo fare con altri valori intermedi? Il modo in cui funziona è che mettiamo una linea di demarcazione proprio a 0.5, quindi qualsiasi valore ottengo al di sotto di quella linea, lo metto a zero, quindi la mia previsione è no, e se è sopra quella linea, se è sopra il punto cinque , Lo inserirò nella classe positiva, la mia previsione è una.

p-grado

Quindi, ora ho una funzione che mi dà una previsione tra zero e uno, e la tratto come una probabilità. E se quella probabilità è superiore allo 0.5 o al 50%, dico, okay, classe uno positiva. E se è inferiore al 50%, dico, è classe negativa, zero. Questo è il modo in cui funziona la regressione logistica. E ora lo capiamo, codifichiamolo e adattiamolo. Imposterò l'iperparametro 'max_iter' su 1000. Questo parametro si riferisce al numero massimo di iterazioni per la convergenza dei risolutori.

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

Valutare

Ora è il momento di vedere come funziona il nostro modello. È ora di valutare il modello di regressione logistica. Quindi, ricordiamo che questa volta, la metrica delle prestazioni che ci interessa è il punteggio di accuratezza e ne vogliamo uno accurato. E vogliamo battere la linea di base di 0.68. L'accuratezza del modello può essere calcolata utilizzando la funzione precision_score. La funzione richiede due argomenti, le etichette vere e le etichette previste.

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

Possiamo vedere la nostra precisione di allenamento al 90%. Sta battendo la linea di fondo. La precisione del nostro test era leggermente inferiore all'88%. Ha anche battuto la linea di fondo ed è stato molto vicino alla nostra precisione di allenamento. Quindi questa è una buona notizia perché significa che il nostro modello non si adatta eccessivamente o altro.

Risultati del modello di regressione logistica

Ricorda che con la regressione logistica, finiamo con queste previsioni finali di zero o uno. Ma al di sotto di quella previsione, c'è una probabilità di un numero in virgola mobile compreso tra zero e uno, e talvolta può essere utile vedere quali sono queste stime di probabilità. Diamo un'occhiata alle nostre previsioni di allenamento e diamo un'occhiata ai primi cinque. Il metodo "predict" prevede l'obiettivo di un'osservazione senza etichetta.

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

Quindi quelle erano le previsioni finali, ma quali sono le probabilità dietro di esse? Per ottenerli, dobbiamo creare un codice leggermente diverso. Invece di usare il metodo `predict` con il nostro modello, userò 'predict_proba' con i nostri dati di addestramento.

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

Possiamo vedere una sorta di elenco nidificato con due diverse colonne al suo interno. La colonna a sinistra rappresenta la probabilità che un candidato non venga inserito o la nostra classe negativa 'Not Placed'. L'altra colonna rappresenta la classe positiva "Placed" o la probabilità che un candidato venga piazzato. Ci concentreremo sulla seconda colonna. Se guardiamo bene la prima stima di probabilità, possiamo vedere che è 0.07. Quindi dato che è inferiore al 50%, dice il nostro modello, la mia previsione è zero. E per le seguenti previsioni, possiamo vedere che sono tutte superiori a 0.5, ed è per questo che il nostro modello ne ha previsto uno alla fine.

Ora vogliamo estrarre i nomi e l'importanza delle caratteristiche e inserirli in una serie. E poiché abbiamo bisogno di visualizzare l'importanza della caratteristica come rapporti di probabilità, dobbiamo fare solo una piccola trasformazione matematica prendendo l'esponenziale della nostra importanza.

# 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

Prima di discutere gli odds ratio e cosa sono, mettiamoli su un grafico a barre orizzontali. Usiamo i panda per creare la trama e ricordiamo che cercheremo i cinque coefficienti maggiori. E non vogliamo usare tutti i rapporti di probabilità. Quindi vogliamo usare la coda.

# Horizontal bar chart, five largest coefficients
odds_ratios.tail().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("High Importance Features");
# Grafico a barre orizzontale, cinque coefficienti maggiori odds_ratios.tail().plot(kind=

Ora voglio che immagini una linea verticale proprio al 5, e voglio iniziare guardandola. Parliamo di ciascuno di questi individualmente o solo della prima coppia. Quindi iniziamo qui con 'ssc_p', che si riferisce alla 'Percentuale di istruzione secondaria – 10th Grade'. E possiamo vedere che l'odds ratio è a 30. Ora, cosa significa? Significa che se un candidato ha un 'ssc_p' alto, le probabilità del suo posizionamento sono sei volte maggiori rispetto agli altri candidati, a parità di condizioni. Quindi un altro modo di pensarci è quando il candidato ha `ssc_p`, la possibilità di assunzione del candidato aumenta di sei volte.

Quindi qualsiasi rapporto di probabilità superiore a cinque aumenta le probabilità che i candidati vengano piazzati. Ed è per questo che abbiamo quella linea verticale alle cinque. E questi cinque tipi di caratteristiche sono le caratteristiche più associate a un aumento del reclutamento. Quindi, questo è il nostro rapporto di probabilità. Ora, abbiamo esaminato le caratteristiche più associate a un aumento del reclutamento. Diamo un'occhiata alle caratteristiche ad esso associate, la diminuzione del reclutamento. Quindi ora è il momento di guardare i più piccoli. Quindi, invece di guardare la coda, la guarderemo.

odds_ratios.head().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("Low Importance Features");
caratteristica di bassa importanza

La prima cosa che dobbiamo vedere qui è notare che sull'asse x tutto è uno o sotto. Ora, cosa significa? Quindi diamo un'occhiata al nostro rapporto di probabilità più piccolo qui. È mba_p che si riferisce alla percentuale MBA. Possiamo vedere che è pronto a circa 0.45. Ora, cosa significa? Ebbene, la differenza tra 0.45 e 1 è 0.55. Va bene? E cosa significa quel numero? I candidati con MBA hanno meno probabilità di essere assunti del 55%, ceteris paribus. Va bene? Quindi ha ridotto le probabilità di reclutamento di un fattore dello 0.55 o del 55%. E questo è vero per tutto qui.

Conclusione

Quindi cosa abbiamo imparato? Innanzitutto, nella fase di preparazione dei dati, abbiamo appreso che stiamo lavorando con la classificazione, in particolare la classificazione binaria, utilizzando la regressione logistica. In termini di esplorazione dei dati, abbiamo fatto un sacco di cose, ma in termini di punti salienti, abbiamo esaminato il bilanciamento delle classi, giusto? La proporzione delle nostre classi positive e negative. Quindi dividiamo i nostri dati.

Poiché Logistic Regression è un modello di classificazione, abbiamo appreso di una nuova metrica delle prestazioni, il punteggio di accuratezza. Ora, il punteggio di precisione va da 0 a 1. Zero è cattivo e uno è buono. Durante l'iterazione, abbiamo appreso della regressione logistica. Questo è un modo magico, in cui puoi prendere un'equazione lineare, una linea retta, e metterla all'interno di un'altra funzione, una funzione sigmoidea e una funzione di attivazione, e ricavarne una stima di probabilità e trasformare quella stima di probabilità in previsione.

Infine, abbiamo appreso l'odds ratio e il modo in cui possiamo interpretare i coefficienti per vedere se una data caratteristica aumenterà le probabilità che abbiamo reclutato o meno un candidato.

Codice sorgente del progetto: https://github.com/SawsanYusuf/Campus-Recruitment.git

I media mostrati in questo articolo non sono di proprietà di Analytics Vidhya e vengono utilizzati a discrezione dell'autore. 

Timestamp:

Di più da Analisi Vidhya