Recrutarea în campus: o problemă de clasificare cu regresie logistică

Recrutarea în campus: o problemă de clasificare cu regresie logistică

Nodul sursă: 1996810

Introducere

În acest proiect, ne vom concentra pe datele din India. Și scopul nostru este să creăm un model predictiv, precum Regresia Logistică etc. astfel încât atunci când dăm caracteristicile unui candidat, modelul poate prezice dacă acesta va recruta.

 date CCD se învârte în jurul sezonului de plasare a unei școli de afaceri din India. Setul de date are diverși factori asupra candidaților, cum ar fi experiența de muncă, procentul de examen etc. În cele din urmă, conține detalii despre starea recrutării și remunerarea.

Problemă de știință a datelor cu regresia logistică

Recrutarea în campus este o strategie pentru aprovizionarea, implicarea și angajarea tinerilor talente pentru stagii și poziții de nivel de intrare. Adesea implică lucrul cu centrele universitare de servicii de carieră și participarea la târguri de carieră pentru a se întâlni în persoană cu studenți și proaspăt absolvenți.

Acest articol a fost publicat ca parte a Blogathonul științei datelor.

Cuprins

  1. Pași implicați în rezolvarea problemei
  2. Pregătiți datele
  3. Construiți un model de regresie logistică
  4. Rezultatele modelului de regresie logistică
  5. Concluzie

Pași implicați în rezolvarea problemei

În acest articol, vom importa acel set de date, îl vom curăța și apoi îl vom pregăti pentru a construi un model de regresie logistică. Obiectivele noastre aici sunt următoarele:

În primul rând, ne vom pregăti setul de date pentru clasificare binară. Acum, ce vreau să spun? când încercăm să prezicem o valoare continuă, cum ar fi prețul unui apartament, poate fi orice număr între zero și multe milioane de dolari. O numim o problemă de regresie.

Dar în acest proiect lucrurile stau puțin diferit. În loc să prezicem o valoare continuă, avem grupuri sau clase discrete pe care încercăm să le prezicem între ele. Deci aceasta se numește o problemă de clasificare și pentru că în proiectul nostru, vom avea doar două grupuri dintre care încercăm să alegem, ceea ce o face o clasificare binară.

Al doilea obiectiv este crearea unui model de regresie logistică pentru a prezice recrutarea. Și al treilea obiectiv este să explicăm predicțiile modelului nostru folosind raportul de cote.

Acum, în ceea ce privește fluxul de lucru de învățare automată, pașii pe care îi vom urma și unele dintre lucrurile noi, vom învăța pe parcurs. Deci, în faza de import, ne vom pregăti datele pentru a lucra cu o țintă binară. În faza de explorare, ne vom uita la echilibrul clasei. Deci, practic, ce proporție de candidați a fost angajat și ce proporții nu? iar în faza de codificare a caracteristicilor, vom face codificarea caracteristicilor noastre categorice. În partea împărțită, vom face o împărțire aleatorie a testului de tren.

Pentru faza de construire a modelului, în primul rând, ne vom stabili linia de bază și, deoarece vom folosi scoruri de precizie, vom vorbi mai multe despre ce este un scor de precizie și cum să construim o linie de bază atunci când aceasta este metrica care ne interesează. În al doilea rând, vom face regresia logistică. Și apoi, nu în ultimul rând, vom avea faza de evaluare. Ne vom concentra din nou pe scorul de precizie. În cele din urmă, pentru a comunica rezultatele, ne vom uita la raportul de cote.

În cele din urmă, înainte de a ne scufunda în lucrare, să ne prezentăm bibliotecile pe care le vom folosi pentru proiect. În primul rând, ne vom importa datele în blocnotesul Google Colabe în biblioteca io. Apoi, deoarece vom folosi un model de regresie logistică, îl vom importa din scikit-learn. După aceea, tot din scikit-learn, vom importa valorile noastre de performanță, scorul de precizie și împărțirea testului de tren.

Noi vom folosi matplotlib și pe mare pentru vizualizarea noastră și NumPy  va fi doar pentru putina matematica.
Avem nevoie panda pentru a ne manipula datele, labelencoder pentru a codifica variabilele noastre categorice și scaler standard pentru a normaliza datele. Acestea vor fi bibliotecile de care avem nevoie.

Să trecem la pregătirea datelor.

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

Pregătiți datele

Import

Pentru a începe pregătirea datelor, să începem munca noastră importantă. Mai întâi, încărcăm fișierul nostru de date și apoi trebuie să le punem într-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 de date pentru regresia logistică

Putem vedea frumosul nostru DataFrame și avem 215 înregistrări și 15 coloane care includ atributul `status`, ținta noastră. Aceasta este descrierea tuturor caracteristicilor.

Regresie logistică

Explorează

Acum avem toate aceste caracteristici pe care le vom explora. Deci, să începem analiza datelor exploratorii. Mai întâi, să aruncăm o privire la informațiile pentru acest cadru de date și să vedem dacă ar putea fi nevoie să păstrăm vreunul dintre ele sau dacă ar trebui să renunțăm.

# 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

Acum, când ne uităm la informațiile `df`, există câteva lucruri pe care le căutăm, avem 215 rânduri în cadrul nostru de date și întrebarea pe care vrem să ne-o punem este dacă lipsesc date? Și dacă ne uităm aici, se pare că nu avem date lipsă în afară de coloana de salariu, așa cum era de așteptat, din cauza candidaților care nu au fost angajați.

O altă preocupare pentru noi aici este, există caracteristici care nu le-ar oferi modelului nostru informații pe care nu le-ar avea dacă ar fi implementat în lumea reală? Amintiți-vă că vrem ca modelul nostru să prezică dacă un candidat se va plasa sau nu și dorim ca modelul nostru să facă acele predicții înainte de recrutarea. Deci nu dorim să oferim nicio informație despre acești candidați după recrutare.

Deci, este destul de clar că această caracteristică „salariu” oferă informații despre salariul oferit de companie. Și pentru că acest salariu este pentru cei acceptați, această caracteristică aici constituie scurgere și trebuie să-l renunțăm.

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

Al doilea lucru pe care vreau să-l privesc sunt tipurile de date pentru aceste caracteristici diferite. Deci, privind aceste tipuri de date, avem opt caracteristici categorice cu ținta noastră și șapte caracteristici numerice și totul este corect. Deci, acum că avem aceste idei, să luăm ceva timp pentru a le explora mai profund.

Știm că ținta noastră are două clase. Am plasat candidați și nu candidați plasați. Întrebarea este, care este proporția relativă a acestor două clase? Sunt cam același echilibru? Sau unul este mult mai mult decât celălalt? Este ceva la care trebuie să te uiți atunci când faci probleme de clasificare. Deci, acesta este un pas semnificativ în EDA noastră.

# Plot class balance
df["status"].value_counts(normalize=True).plot( kind="bar", xlabel="Class", ylabel="Relative Frequency", title="Class Balance"
);
Dezechilibru de clasă pentru regresia logistică

Clasa noastră pozitivă „plasat” contează pentru mai mult de 65% din observațiile noastre, iar clasa noastră negativă „Neplasat” este de aproximativ 30%. Acum, dacă acestea ar fi super dezechilibrate, de exemplu, dacă ar fi mai mult de 80 sau chiar mai mult decât atât, aș spune că acestea sunt clase dezechilibrate. Și ar trebui să lucrăm pentru a ne asigura că modelul nostru va funcționa corect. Dar acesta este un echilibru ok.

Să facem o altă vizualizare pentru a observa legătura dintre caracteristicile noastre și țintă. Să începem cu caracteristicile numerice.

În primul rând, vom vedea distribuția individuală a caracteristicilor utilizând un diagramă de distribuție și, de asemenea, vom vedea relația dintre caracteristicile numerice și ținta noastră folosind un diagramă cu casete.

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]);
"Regresie logistică

În prima coloană din graficul nostru, putem observa că toate distribuțiile urmează o distribuție normală, iar majoritatea performanțelor educaționale ale candidatului sunt între 60-80%.

În a doua coloană, avem o diagramă dublă cu casete cu clasa „Placed” în dreapta și apoi clasa „Not Placed” în stânga. Pentru caracteristicile „etest_p” și „mba_p”, nu există o mare diferență între aceste două distribuții din perspectiva construirii modelului. Există o suprapunere semnificativă în distribuția dintre clase, astfel încât aceste caracteristici nu ar fi un bun predictor al țintei noastre. În ceea ce privește restul caracteristicilor, există suficient de distincte pentru a le considera potențiali buni predictori ai țintei noastre. Să trecem la trăsăturile categoriale. Și pentru a le explora, vom folosi un complot de numărare.

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")
"Regresie logistică

Privind complotul, vedem că avem mai mulți candidați bărbați decât femei. Și majoritatea candidaților noștri nu au experiență de lucru, dar acești candidați au fost angajați mai mult decât cei care au avut. Avem candidați care au făcut comerț ca cursul lor „hsc” și, pe lângă o licență, candidații cu studii științifice sunt pe locul doi în ambele cazuri.

O mică notă despre modelele de regresie logistică, deși sunt pentru clasificare, sunt în același grup cu alte modele liniare, cum ar fi regresia liniară, și din acest motiv, deoarece ambele sunt modele liniare. De asemenea, trebuie să ne îngrijorăm cu privire la problema multicoliniarității. Deci trebuie să creăm o matrice de corelație, apoi trebuie să o trasăm într-o hartă termică. Nu vrem să ne uităm la toate caracteristicile de aici, vrem să ne uităm doar la caracteristicile numerice și nu vrem să includem ținta noastră. Deoarece dacă ținta noastră se corelează cu unele dintre caracteristicile noastre, este foarte bine.

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');
matricea de corelare

Iată albastrul deschis, care înseamnă puțină sau deloc corelație, și albastrul închis, cu care avem o corelație mai mare. Așa că vrem să fim în căutarea acelor albastru închis. Putem vedea o linie albastru închis, o linie diagonală care coboară în mijlocul acestei parcele. Acestea sunt caracteristicile care sunt corelate cu ele însele. Și apoi, vedem niște pătrate întunecate. Asta înseamnă că avem o grămadă de corelații între caracteristici.

La pasul final al EDA, trebuie să verificăm cardinalitatea mare-scăzută în caracteristicile categoriale. Cardinalitatea se referă la numărul de valori unice dintr-o variabilă categorială. Cardinalitatea ridicată înseamnă că caracteristicile categoriale au un număr mare de valori unice. Nu există un număr exact de valori unice care să facă o caracteristică să aibă o cardinalitate ridicată. Dar dacă valoarea trăsăturii categoriale este unică pentru aproape toate observațiile, de obicei poate fi renunțată.

# 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

Nu văd nicio coloană în care numărul de valori unice este unul sau ceva foarte mare. Dar cred că există o coloană de tip categoric care ne lipsește aici. Și motivul este că nu este codificat ca obiect, ci ca număr întreg. Coloana „sl_no” nu este un număr întreg în sensul pe care îl știm. Acești candidați sunt clasați într-o anumită ordine. Doar o etichetă de nume unică, iar numele este ca o categorie, nu? Deci aceasta este o variabilă categorică. Și nu are nicio informație, așa că trebuie să o renunțăm.

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

Caracteristici Codificare

Ne-am terminat analiza și următorul lucru pe care trebuie să-l facem este să ne codificăm caracteristicile categoriale, voi folosi „LabelEncoder”. Codificarea etichetelor este o tehnică de codificare populară pentru manipularea variabilelor categorice. Prin utilizarea acestei tehnici, fiecărei etichete i se atribuie un număr întreg unic bazat pe ordinea alfabetică.

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()
ieșire de cod

Despică

Ne-am importat și ne-am curățat datele. Am făcut un pic de analiză exploratorie a datelor, iar acum trebuie să ne împărțim datele. Avem două tipuri de split: vertical split sau feature-target și orizontal split sau train-test sets. Să începem cu cel vertical. Vom crea matricea noastră de caracteristici „X” și vectorul țintă „y”. Ținta noastră este „statutul”. Caracteristicile noastre ar trebui să fie toate coloanele care rămân în „df”.

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

În general, modelele funcționează mai bine atunci când au date normalizate cu care să se antreneze, deci ce este normalizarea? Normalizare este transformarea valorilor mai multor variabile într-un interval similar. Ținta noastră este să ne normalizăm variabilele. Deci intervalele lor de valori vor fi de la 0 la 1. Să facem asta și voi folosi „StandardScaler”.

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

Acum să facem seturile de divizare orizontală sau tren-test. Trebuie să ne împărțim datele (X și y) în seturi de antrenament și de testare folosind o împărțire randomizată de tren-test. setul nostru de testare ar trebui să fie 20% din datele noastre totale. Și nu uităm să setăm o stare aleatorie pentru reproductibilitate.

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

Construiți un model de regresie logistică

De bază

Așa că acum trebuie să începem construirea modelului nostru și va trebui să începem să comandăm pentru a ne stabili linia de bază. Amintiți-vă că tipul de problemă cu care avem de-a face este o problemă de clasificare și există diferite metrici pentru a evalua modelele de clasificare. Cel pe care vreau să mă concentrez este scorul de precizie.

Acum, care este scorul de precizie? Scorul de acuratețe în învățarea automată este o măsurătoare de evaluare care măsoară numărul de predicții corecte făcute de un model la numărul total de predicții făcute. O calculăm împărțind numărul de predicții corecte la numărul total de predicții. Deci ceea ce înseamnă este că scorul de precizie este între 0 și 1. Zero nu este bun. Acolo nu vrei să fii, iar unul este perfect. Deci, să ținem cont de asta și să ne amintim că linia de bază este un model care oferă o predicție din nou și din nou, indiferent de care este observația, o singură presupunere pentru noi.

În cazul nostru, avem două clase, plasate sau nu. Deci, dacă am putea face o singură predicție, care ar fi singura noastră presupunere? Dacă ai spus clasa majoritară. Cred că are sens, nu? Dacă putem avea o singură predicție, probabil că ar trebui să o alegem pe cea cu cele mai mari observații din setul nostru de date. Deci, linia noastră de referință va folosi procentul pe care clasa majoritară îl apare în datele de antrenament. Dacă modelul nu depășește această linie de bază, caracteristicile nu adaugă informații valoroase pentru a clasifica observațiile noastre.

Putem folosi metoda „value_counts” cu argumentul „normalize = True” pentru a calcula acuratețea liniei de bază:

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

Putem vedea că acuratețea noastră de bază este de 68% sau 0.68 ca proporție. Deci, pentru a adăuga valoare pentru a fi de folos, vrem să trecem peste acest număr și să ne apropiem de unul. Acesta este scopul nostru și acum să începem să ne construim modelul.

Repeta

Acum este timpul să ne construim modelul folosind Regresia Logistică. Vom folosi regresia logistică, dar înainte de a o face, să vorbim puțin despre ce este regresia logistică și cum funcționează, apoi putem face chestiile de codare. Și pentru asta, aici avem o mică grilă.

De-a lungul axei x, să presupunem că am p_degrees ale candidaților în setul nostru de date. Și pe măsură ce mă deplasez de la dreapta la stânga, gradele devin din ce în ce mai mari, iar apoi de-a lungul axei Y, am clasele posibile pentru plasare: zero și unu.

grafic pentru regresia logistică

Deci, dacă ar fi să trasăm punctele noastre de date, cum ar arăta? Analiza noastră arată că un candidat cu grad înalt „p_degree” are mai multe șanse să fie angajat. Deci, probabil ar arăta cam așa, unde candidatul cu un mic „p_degree” ar fi scăzut la zero. Iar candidatul cu un `p_degree` mare ar fi sus la unu.

p-grad pentru regresie logistică

Acum să presupunem că am vrut să facem regresia liniară cu aceasta. Să presupunem că am vrut să trasăm o linie.
Acum, dacă am face asta, ceea ce s-ar întâmpla este că acea linie ar fi trasată în așa fel încât să încerce să fie cât mai aproape de toate punctele posibil. Și așa am ajunge probabil cu o linie care arăta cam așa. Ar fi acesta un model bun?

repeta

Nu chiar. Ceea ce s-ar întâmpla este că, indiferent de p_degree al candidatului, am obține întotdeauna un fel de valoare. Și asta nu ne va ajuta pentru că cifrele, în acest context, nu înseamnă nimic. Această problemă de clasificare trebuie să fie zero sau unu. Deci, nu va funcționa așa.

Pe de altă parte, deoarece aceasta este o linie, ce se întâmplă dacă avem un candidat cu un p_degree foarte scăzut? Ei bine, dintr-o dată, estimarea noastră este un număr negativ. Și din nou, acest lucru nu are niciun sens. Nu există nici un număr negativ care trebuie să fie zero sau unu. Și la fel, dacă avem un candidat cu un p_degree foarte mare, s-ar putea să am un pozitiv, ceva peste unul. Și din nou, asta nu are niciun sens. Trebuie să avem fie un zero, fie unul.

prezicere

Deci ceea ce vedem aici sunt câteva limitări serioase ale utilizării regresiei liniare pentru clasificare. Deci, ce trebuie să facem? Trebuie să creăm un model care să aibă numărul unu: să nu coboare sub zero sau peste unu, așa că trebuie să fie legat între zero și unu. Iar numărul doi, orice iese din acea funcție, acea ecuație pe care o creăm, poate nu ar trebui să o tratăm ca predicție în sine, ci ca pe un pas către realizarea predicției noastre finale.

Acum, permiteți-mi să despachetez ceea ce tocmai am spus și să ne reamintim că atunci când facem modelele noastre de regresie liniară, ajungem la această ecuație liniară, care este cea mai simplă formă. Și aceasta este acea ecuație sau funcție care ne oferă acea linie dreaptă.

img

Există o modalitate de a lega acea linie între 0 și 1. Și ceea ce putem face este să luăm această funcție pe care tocmai am creat-o și să o includem într-o altă funcție, ceea ce se numește funcție sigmoidă.

funcția de regresie logistică

Deci, voi lua ecuația liniară pe care tocmai am avut-o și o voi micșora în funcția sigmoidă și o voi pune ca exponențială.

funcția de regresie logistică

Ceea ce se întâmplă este, în loc să obținem o linie dreaptă, obținem o linie care arată cam așa. S-a blocat la unu. Intră și se mârâie în jos. Apoi este blocat la zero.

regresie logistică

Corect, așa arată linia și putem vedea că am rezolvat prima noastră problemă. Orice obținem din această funcție va fi între 0 și 1. În al doilea pas, nu vom trata ceea ce iese din această ecuație ca predicție finală. În schimb, o vom trata ca pe o probabilitate.

regresie logistică

Ce vreau să spun? Asta înseamnă că atunci când fac o predicție, voi obține o valoare în virgulă mobilă între 0 și 1. Și ceea ce voi face este să o tratez ca pe probabilitatea ca predicția mea să aparțină clasei pozitive.

Deci primesc o valoare în creștere la 0.9999. Voi spune că probabilitatea ca acest candidat să aparțină clasei noastre pozitive, clasate este de 99%. Deci sunt aproape sigur că aparține clasei pozitive. În schimb, dacă este în jos la punctul 0.001 sau orice altceva, voi spune că acest număr este scăzut. Probabilitatea ca această observație specială să aparțină clasei pozitive, plasate este aproape zero. Și așa, o să spun că aparține clasei zero.

Deci, asta are sens pentru numere care sunt aproape de unu sau aproape de zero. Dar s-ar putea să vă întrebați, ce fac cu alte valori între ele? Modul care funcționează este să punem o linie de tăiere chiar la 0.5, deci orice valoare pe care o obțin sub acea linie, o voi pune la zero, deci predicția mea este nu și dacă este deasupra acelei linii, dacă este peste punctul cinci , Voi pune asta în clasa pozitivă, predicția mea este una.

gradul p

Deci, acum am o funcție care îmi oferă o predicție între zero și unu și o tratez ca pe o probabilitate. Și dacă această probabilitate este peste 0.5 sau 50%, spun, bine, clasa unu pozitivă. Și dacă e sub 50%, eu zic, e clasa negativă, zero. Deci, așa funcționează regresia logistică. Și acum înțelegem asta, hai să-l codificăm și să-l potrivim. Voi seta hiperparametrul „max_iter” la 1000. Acest parametru se referă la numărul maxim de iterații pentru ca solutorii să convergă.

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

Evalua

Acum este timpul să vedem cum merge modelul nostru. Este timpul să evaluăm modelul de regresie logistică. Așadar, să ne amintim că de data aceasta, valoarea de performanță care ne interesează este scorul de precizie și dorim unul precis. Și vrem să depășim linia de bază de 0.68. Precizia modelului poate fi calculată utilizând funcția accuracy_score. Funcția necesită două argumente, etichetele adevărate și etichetele prezise.

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

Putem vedea precizia antrenamentului nostru la 90%. Bate linia de bază. Precizia testului nostru a fost puțin mai mică, la 88%. De asemenea, a depășit linia de bază și a fost foarte aproape de precizia antrenamentului nostru. Deci, aceasta este o veste bună, deoarece asta înseamnă că modelul nostru nu este prea potrivit sau altceva.

Rezultatele modelului de regresie logistică

Amintiți-vă că, cu regresia logistică, ajungem cu aceste predicții finale de zero sau unu. Dar sub această predicție, există o probabilitate a unui număr în virgulă mobilă între zero sau unu și, uneori, poate fi util să vedem care sunt acele estimări de probabilitate. Să ne uităm la previziunile noastre de antrenament și să ne uităm la primele cinci. Metoda „predict” prezice ținta unei observații neetichetate.

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

Deci, acestea au fost predicțiile finale, dar care sunt probabilitățile în spatele lor? Pentru a le obține, trebuie să facem un cod ușor diferit. În loc să folosesc metoda „predict” cu modelul nostru, voi folosi „predict_proba” cu datele noastre de antrenament.

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

Putem vedea un fel de listă imbricată cu două coloane diferite în ea. Coloana din stânga reprezintă probabilitatea ca un candidat să nu fie plasat sau clasa noastră negativă „Nu este plasat”. Cealaltă coloană reprezintă clasa pozitivă „Plasat” sau probabilitatea ca un candidat să fie plasat. Ne vom concentra pe a doua coloană. Dacă ne uităm corect la prima estimare a probabilității, putem vedea că aceasta este 0.07. Deci, deoarece aceasta este sub 50%, spune modelul nostru, predicția mea este zero. Și pentru următoarele predicții, putem vedea că toate sunt peste 0.5 și de aceea modelul nostru a prezis una în cele din urmă.

Acum vrem să extragem numele caracteristicilor și importanța și să le punem într-o serie. Și pentru că trebuie să afișăm importanța caracteristicii ca cote de cote, trebuie să facem doar o mică transformare matematică luând exponențialul importanței noastre.

# 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

Înainte de a discuta cotele de cote și care sunt acestea, să le punem pe o diagramă cu bare orizontale. Să folosim panda pentru a face complotul și să ne amintim că vom căuta cei cinci coeficienți cei mai mari. Și nu vrem să folosim toate cotele de cote. Deci vrem să folosim coada.

# Horizontal bar chart, five largest coefficients
odds_ratios.tail().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("High Importance Features");
# Diagramă cu bare orizontale, cinci coeficienți cei mai mari odds_ratios.tail().plot(kind=

Acum vreau să vă imaginați o linie verticală chiar la 5 și vreau să încep prin a o privi. Să vorbim despre fiecare dintre acestea individual sau doar despre primul cuplu. Deci, să începem aici cu „ssc_p”, care se referă la „procentul învățământului secundar – clasa a X-a”. Și putem vedea că raportul de cote este de 10. Acum, ce înseamnă asta? Înseamnă că dacă un candidat are un „ssc_p” mare, șansele de plasare sunt de șase ori mai mari decât alți candidați, toate lucrurile fiind egale. Deci, un alt mod de a ne gândi la asta este atunci când candidatul are `ssc_p`, șansa de recrutare a candidatului crește de șase ori.

Deci, orice cotă de peste cinci crește șansele ca candidații să fie plasați. Și de aceea avem acea linie verticală la cinci. Și aceste cinci tipuri de trăsături sunt caracteristici care sunt cele mai asociate cu creșterea recrutării. Deci, acesta este cota noastră de cote. Acum, ne-am uitat la caracteristicile care sunt cele mai asociate cu o creștere a recrutării. Să ne uităm la caracteristicile care sunt asociate cu acesta, scăderea recrutării. Așa că acum este timpul să ne uităm la cele mai mici. Deci, în loc să ne uităm la coadă, ne vom uita la ea.

odds_ratios.head().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("Low Importance Features");
caracteristică de importanță redusă

Primul lucru pe care trebuie să-l vedem aici este că observația pe axa x este totul unul sau mai jos. Acum, ce înseamnă asta? Așa că haideți să aruncăm o privire la cea mai mică cotă a noastră aici. Este mba_p care se referă la procentul MBA. Putem vedea că este gata la aproximativ 0.45. Acum, ce înseamnă asta? Ei bine, diferența dintre 0.45 și 1 este 0.55. În regulă? Și ce înseamnă acel număr? Acei candidați cu MBA sunt mai puțin probabil să fie recrutați cu 55%, toate celelalte lucruri fiind egale. În regulă? Deci a scăzut șansele de recrutare cu un factor de 0.55 sau 55%. Și asta este valabil pentru tot ce este aici.

Concluzie

Deci ce am învățat? În primul rând, în faza de pregătire a datelor, am aflat că lucrăm cu clasificare, în special cu clasificare binară, folosind regresia logistică. În ceea ce privește explorarea datelor, am făcut o mulțime de lucruri, dar în ceea ce privește aspectele evidențiate, ne-am uitat la echilibrul clasei, nu? Proporția claselor noastre pozitive și negative. Apoi ne împărțim datele.

Deoarece regresia logistică este un model de clasificare, am aflat despre o nouă măsurătoare de performanță, scorul de precizie. Acum, scorul de precizie este între 0 și 1. Zero este rău, iar unul este bun. Când repetam, am aflat despre regresia logistică. Acesta este un mod magic, în care puteți lua o ecuație liniară, o linie dreaptă și o puteți pune în interiorul unei alte funcții, o funcție sigmoidă și o funcție de activare, și puteți obține o estimare a probabilității din ea și transforma acea estimare a probabilității în predicție.

În cele din urmă, am aflat despre raportul de cote și despre modul în care putem interpreta coeficienții pentru a vedea dacă o anumită caracteristică va crește șansele că am recrutat un candidat sau nu.

Cod sursa proiectului: https://github.com/SawsanYusuf/Campus-Recruitment.git

Media prezentată în acest articol nu este deținută de Analytics Vidhya și este utilizată la discreția Autorului. 

Timestamp-ul:

Mai mult de la Analize Vidhya