Kampusrekrytointi: Logistisen regression luokitteluongelma

Kampusrekrytointi: Logistisen regression luokitteluongelma

Lähdesolmu: 1996810

esittely

Tässä projektissa keskitymme Intiasta peräisin olevaan dataan. Ja tavoitteemme on luoda a ennustava malli, kuten Logistic Regression, jne. jotta kun annamme ehdokkaan ominaisuudet, malli voi ennustaa, rekrytoiko hän.

aineisto pyörii intialaisen Business Schoolin harjoittelukauden ympärillä. Aineisto sisältää erilaisia ​​hakijoita koskevia tekijöitä, kuten työkokemusta, tenttiprosenttia jne. Lopuksi se sisältää rekrytoinnin tilan ja palkkatiedot.

Datatieteen ongelma logistisen regression kanssa

Kampusrekrytointi on strategia nuorten kykyjen hankkimiseen, sitouttamiseen ja palkkaamiseen harjoittelu- ja lähtötason tehtäviin. Usein siihen kuuluu työskentely yliopistojen urapalvelukeskusten kanssa ja uramessuille osallistuminen tapaamaan henkilökohtaisesti korkeakouluopiskelijoita ja vastavalmistuneita.

Tämä artikkeli julkaistiin osana Data Science Blogathon.

Sisällysluettelo

  1. Ongelman ratkaisemiseen liittyvät vaiheet
  2. Valmistele tiedot
  3. Rakenna logistinen regressiomalli
  4. Logistisen regressiomallin tulokset
  5. Yhteenveto

Ongelman ratkaisemiseen liittyvät vaiheet

Tässä artikkelissa tuomme kyseisen tietojoukon, puhdistamme sen ja valmistelemme sen sitten logistisen regressiomallin luomiseksi. Tavoitteemme tässä ovat seuraavat:

Ensinnäkin aiomme valmistella tietojoukkomme binääriluokitus. Mitä nyt tarkoitan? kun yritämme ennustaa jatkuvaa arvoa, kuten asunnon hintaa, se voi olla mikä tahansa luku nollan ja usean miljoonan dollarin välillä. Kutsumme sitä regressioongelmaksi.

Mutta tässä projektissa asiat ovat hieman toisin. Jatkuvan arvon ennustamisen sijaan meillä on erillisiä ryhmiä tai luokkia, joita yritämme ennustaa niiden välillä. Joten tätä kutsutaan luokitteluongelmaksi, ja koska projektissamme on vain kaksi ryhmää, joiden välillä yritämme valita, se tekee siitä binääriluokituksen.

Toinen tavoite on luoda logistinen regressiomalli rekrytoinnin ennustamiseksi. Kolmas tavoitteemme on selittää mallimme ennusteet todennäköisyyssuhteen avulla.

Mitä tulee koneoppimisen työnkulkuun, seuraaviin vaiheisiin ja joihinkin uusiin asioihin, joita opimme matkan varrella. Joten tuontivaiheessa valmistelemme tietomme toimimaan binäärikohteen kanssa. Tutkimusvaiheessa tarkastelemme luokkatasapainoa. Eli mikä osa ehdokkaista oli palkattuja ja mikä ei? ja ominaisuuksien koodausvaiheessa teemme koodauksen kategorisille piirteillemme. Jaetussa osassa teemme satunnaistetun junatestijaon.

Mallinrakennusvaiheessa määritämme ensin perustasomme, ja koska käytämme tarkkuuspisteitä, puhumme enemmän siitä, mitä tarkkuuspisteet ovat ja kuinka perustaa voidaan rakentaa, kun se on meitä kiinnostava mittari. Toiseksi teemme logistisen regression. Ja sitten viimeisenä mutta ei vähäisimpänä, meillä on arviointivaihe. Keskitymme jälleen tarkkuuspisteisiin. Lopuksi, jotta voimme ilmoittaa tulokset, tarkastelemme kerroinsuhdetta.

Lopuksi, ennen kuin sukeltaa työhön, esittelemme itsemme kirjastoille, joita käytämme heittäkää projekti. Ensin tuomme tietomme Google Colabe -muistikirjaan io-kirjastoon. Sitten, kun käytämme logistista regressiomallia, tuomme sen scikit-learnistä. Sen jälkeen myös alkaen scikit opittava, tuomme suorituskykymittarimme, tarkkuuspisteet ja junatestin jaon.

Käytämme Matplotlib ja merestä syntynyt visualisointiamme varten, ja nuhjuinen  on vain pientä matematiikkaa varten.
Me tarvitsemme pandas muokata tietojamme, labelencoder koodaa kategoristen muuttujamme ja standardi skaalaus tietojen normalisoimiseksi. Nämä ovat kirjastot, joita tarvitsemme.

Siirrytään tietojen valmisteluun.

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

Valmistele tiedot

Tuo

Aloitamme tietojen valmistelun tekemällä tärkeä työmme. Ensin lataamme datatiedostomme ja sitten meidän on asetettava ne DataFrame-kehykseen `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()
Dataset for Logistic Regression

Näemme kauniin DataFrame-kehyksemme, ja meillä on 215 tietuetta ja 15 saraketta, jotka sisältävät `status` -attribuutin, tavoitteemme. Tämä on kaikkien ominaisuuksien kuvaus.

Logistinen regressio

Tutkia

Nyt meillä on kaikki nämä ominaisuudet, joita aiomme tutkia. Joten aloitetaan omamme tutkittava tietojen analyysi. Katsotaanpa ensin tämän tietokehyksen tietoja ja katsotaan, onko meidän ehkä säilytettävä jokin niistä vai onko meidän ehkä luovuttava.

# 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

Nyt kun tarkastelemme df-tietoja, etsimme pari asiaa. Tietokehyksessämme on 215 riviä, ja haluamme kysyä itseltämme, puuttuuko tietoja? Ja jos katsomme täällä, näyttää siltä, ​​että meiltä ei ole puuttuvia tietoja paitsi palkkasarake, kuten odotettiin, johtuen ehdokkaista, joita ei ole palkattu.

Toinen huolenaihe meitä kohtaan on, onko olemassa mitään vuotavia ominaisuuksia, jotka antaisivat mallillemme tietoa, jota sillä ei olisi, jos se otettaisiin käyttöön todellisessa maailmassa? Muista, että haluamme mallimme ennustavan, sijoittuuko ehdokas vai ei, ja haluamme mallimme tekevän nämä ennusteet ennen rekrytointia. Emme siis halua antaa näistä hakijoista mitään tietoja rekrytoinnin jälkeen.

Joten on melko selvää, että tämä "palkka"-ominaisuus antaa tietoa yrityksen tarjoamasta palkasta. Ja koska tämä palkka on hyväksytyille, tämä ominaisuus tässä on vuoto, ja meidän on luovuttava siitä.

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

Toinen asia, jota haluan tarkastella, on näiden eri ominaisuuksien tietotyypit. Näitä tietotyyppejä tarkasteltaessa meillä on siis kahdeksan kategorista ominaisuutta tavoitteemme kanssa ja seitsemän numeerista ominaisuutta, ja kaikki on oikein. Joten nyt, kun meillä on nämä ideat, otetaan hetki aikaa niiden tutkimiseen.

Tiedämme, että tavoitteessamme on kaksi luokkaa. Olemme asettaneet ehdokkaita emmekä asettaneet ehdokkaita. Kysymys kuuluu, mikä on näiden kahden luokan suhteellinen osuus? Onko ne samassa tasapainossa? Vai onko toinen paljon enemmän kuin toinen? Tämä on asia, jota sinun on tarkasteltava, kun teet luokitteluongelmia. Tämä on siis merkittävä askel EDA:ssamme.

# Plot class balance
df["status"].value_counts(normalize=True).plot( kind="bar", xlabel="Class", ylabel="Relative Frequency", title="Class Balance"
);
Logistisen regression luokan epätasapaino

Positiivinen luokkamme "sijoitettu" muodostaa yli 65 % havainnoistamme, ja negatiivinen luokkamme "Ei sijoitettu" on noin 30 %. Nyt, jos nämä olisivat erittäin epätasapainoisia, jos ne olisivat enemmän kuin 80 tai jopa enemmän, sanoisin, että nämä ovat epätasapainoisia luokkia. Ja meidän on tehtävä työtä varmistaaksemme, että mallimme toimii oikein. Mutta tämä on ihan ok tasapaino.

Tehdään toinen visualisointi havaitaksemme ominaisuuksiemme ja kohteen välisen yhteyden. Aloitetaan numeerisista ominaisuuksista.

Ensin näemme piirteiden yksittäisen jakauman jakauman avulla, ja näemme myös numeeristen ominaisuuksien ja kohteen välisen suhteen käyttämällä laatikkokaaviota.

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]);
"Logistinen regressio

Juonemme ensimmäisessä sarakkeessa näemme, että kaikki jakaumat noudattavat normaalijakaumaa ja suurin osa ehdokkaan koulutussuorituksista on 60-80 %.

Toisessa sarakkeessa meillä on kaksoislaatikkokaavio, jossa on oikealla luokka "Placed" ja sitten vasemmalla luokka "Ei sijoitettu". Ominaisuuksien "etest_p" ja "mba_p" osalta näissä kahdessa jakelussa ei ole paljon eroa mallinrakennuksen näkökulmasta. Jakaumassa luokkien välillä on merkittävää päällekkäisyyttä, joten nämä ominaisuudet eivät olisi hyvä ennustaja tavoitteellemme. Mitä tulee muihin ominaisuuksiin, ne ovat tarpeeksi erilaisia, jotta niitä voidaan pitää mahdollisina hyvinä tavoitteemme ennustajina. Siirrytäänpä kategorisiin ominaisuuksiin. Ja tutkiaksemme niitä, käytämme laskentakaaviota.

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")
"Logistinen regressio

Juonetta tarkasteltaessa näemme, että meillä on enemmän miesehdokkaita kuin naisia. Ja suurimmalla osalla hakijoistamme ei ole työkokemusta, mutta näitä hakijoita palkattiin enemmän kuin niitä, joilla oli. Meillä on kauppaa suorittaneita hakijoita "hsc"-kurssina, ja ala-asteen lisäksi tiedetaustaiset hakijat ovat molemmissa tapauksissa toiseksi korkeimmat.

Pieni huomautus logistisista regressiomalleista, vaikka ne ovat luokittelua varten, ne ovat samassa ryhmässä muiden lineaaristen mallien, kuten lineaarisen regression, kanssa, ja tästä syystä, koska ne ovat molemmat lineaarisia malleja. Meidän on myös huolehdittava monikollineaarisuudesta. Joten meidän täytyy luoda korrelaatiomatriisi ja sitten piirtää se lämpökartalla. Emme halua tarkastella kaikkia ominaisuuksia tässä, haluamme tarkastella vain numeerisia ominaisuuksia, emmekä halua sisällyttää tavoitettamme. Koska jos tavoitteemme korreloi joidenkin ominaisuuksiemme kanssa, se on erittäin hyvä.

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

Tässä ovat vaaleansininen, joka tarkoittaa vähän tai ei ollenkaan korrelaatiota, ja tummansininen, jonka kanssa meillä on korkeampi korrelaatio. Haluamme siis olla tarkkana noita tummansinisiä. Voimme nähdä tummansinisen viivan, diagonaaliviivan, joka kulkee alas tämän juonen keskellä. Nämä ovat ominaisuuksia, jotka korreloivat itsensä kanssa. Ja sitten näemme joitain tummia neliöitä. Tämä tarkoittaa, että meillä on joukko korrelaatioita ominaisuuksien välillä.

EDA:n viimeisessä vaiheessa meidän on tarkistettava, onko kategorisissa piirteissä korkea-matala kardinaalisuus. Kardinaalisuus viittaa yksilöllisten arvojen määrään kategorisessa muuttujassa. Suuri kardinaalisuus tarkoittaa, että kategorisilla ominaisuuksilla on suuri määrä ainutlaatuisia arvoja. Ei ole olemassa tarkkaa määrää yksilöllisiä arvoja, jotka tekevät ominaisuudesta erittäin kardinaalisen. Mutta jos kategorisen ominaisuuden arvo on ainutlaatuinen lähes kaikissa havainnoissa, se voidaan yleensä jättää pois.

# 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

En näe sarakkeita, joissa yksilöllisten arvojen määrä on yksi tai mikään erittäin korkea. Mutta luulen, että meiltä puuttuu yksi kategorinen sarake. Syynä on se, että sitä ei ole koodattu objektina vaan kokonaislukuna. 'sl_no' -sarake ei ole kokonaisluku siinä mielessä kuin tunnemme. Nämä ehdokkaat ovat jossain järjestyksessä. Vain ainutlaatuinen nimilappu, ja nimi on kuin luokka, eikö niin? Tämä on siis kategorinen muuttuja. Eikä sillä ole mitään tietoa, joten meidän on hylättävä se.

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

Ominaisuudet Koodaus

Saimme analyysimme valmiiksi, ja seuraavaksi meidän on koodattava kategoriset ominaisuudet. Käytän 'LabelEncoder'ia. Label Encoding on suosittu koodaustekniikka kategoristen muuttujien käsittelemiseen. Tätä tekniikkaa käytettäessä jokaiselle tarralle määritetään yksilöllinen kokonaisluku aakkosjärjestyksen perusteella.

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()
koodin ulostulo

Jakaa

Toimme ja puhdistimme tietomme. Olemme tehneet vähän tutkivaa data-analyysiä, ja nyt meidän on jaettava tietomme. Meillä on kahden tyyppisiä jakoja: pystyjako eli ominaisuuskohde ja vaakajako tai junatestisarjat. Aloitetaan pystysuorasta. Luomme ominaisuusmatriisin "X" ja kohdevektorin "y". Tavoitteemme on "status". Ominaisuuksien tulisi olla kaikki sarakkeet, jotka jäävät df:ään.

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

Mallit toimivat yleensä paremmin, kun niillä on normalisoitua dataa harjoittelua varten, joten mitä normalisointi on? normalisointi on muuntaa useiden muuttujien arvot samanlaiselle alueelle. Tavoitteemme on normalisoida muuttujamme. Joten niiden arvoalueet ovat 0-1. Tehdään niin, ja käytän "StandardScaleria".

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

Tehdään nyt vaakajako- tai junatestisarjat. Meidän on jaettava tietomme (X ja y) harjoitus- ja testisarjoihin käyttämällä satunnaistettua junatestijakoa. testisarjamme tulisi olla 20 % kokonaistiedoistamme. Ja emme unohda asettaa random_statea toistettavuutta varten.

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

Rakenna logistinen regressiomalli

Lähtötilanne

Joten nyt meidän on aloitettava mallimme rakentaminen ja meidän on alettava tilata perustaa. Muista, että käsittelemämme ongelmatyyppi on luokitusongelma, ja luokitusmallien arvioimiseksi on erilaisia ​​mittareita. Yksi, johon haluan keskittyä, on tarkkuuspisteet.

Mikä nyt on tarkkuuspisteet? Tarkkuuspisteet koneoppimisessa on arviointimittari, joka mittaa mallin tekemien oikeiden ennusteiden määrää tehtyjen ennusteiden kokonaismäärään. Laskemme sen jakamalla oikeiden ennusteiden lukumäärän ennusteiden kokonaismäärällä. Tämä tarkoittaa siis sitä, että tarkkuuspisteet ovat välillä 0 ja 1. Nolla ei ole hyvä. Siellä et halua olla, ja yksi on täydellinen. Joten Pidetään tämä mielessä ja muistetaan, että perusviiva on malli, joka antaa yhden ennusteen yhä uudelleen, riippumatta siitä, mikä havainto on, vain yksi arvaus meille.

Meidän tapauksessamme meillä on kaksi luokkaa, sijoitettu tai ei. Joten jos voisimme tehdä vain yhden ennusteen, mikä olisi arvauksemme? Jos sanoit enemmistöluokkaa. Minusta siinä on järkeä, eikö? Jos meillä voi olla vain yksi ennuste, meidän pitäisi luultavasti valita se, jolla on korkeimmat havainnot tietojoukostamme. Joten lähtötasomme käyttää prosenttiosuutta, jonka enemmistöluokka näkyy harjoitustiedoissa. Jos malli ei lyö tätä perusviivaa, ominaisuudet eivät lisää arvokasta tietoa havaintojen luokitteluun.

Voimme käyttää "value_counts" -menetelmää "normalize = True" -argumentin kanssa laskeaksemme perustason tarkkuuden:

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

Näemme, että perustarkkuutemme on 68 % tai 0.68 suhteessa. Jotta lisäarvoa voidaan käyttää, haluamme päästä tämän luvun yläpuolelle ja päästä lähemmäksi yhtä. Se on tavoitteemme, ja nyt aletaan rakentaa malliamme.

Toistaa

Nyt on aika rakentaa mallimme Logistic Regressionin avulla. Käytämme logistista regressiota, mutta ennen kuin teemme, puhutaan vähän siitä, mitä logistinen regressio on ja miten se toimii, ja sitten voimme tehdä koodauksen. Ja sitä varten meillä on pieni ruudukko.

Oletetaan, että x-akselilla minulla on tietojoukossamme ehdokkaiden p_aste. Ja kun liikun oikealta vasemmalle, asteet nousevat yhä korkeammalle, ja sitten Y-akselia pitkin minulla on mahdolliset sijoitusluokat: nolla ja yksi.

Logistic Regression -kaavio

Joten jos meidän pitäisi piirtää datapisteemme, miltä se näyttäisi? Analyysimme osoittaa, että korkean p_aste-ehdokas palkataan todennäköisemmin. Joten se näyttäisi luultavasti tältä, jossa ehdokas, jolla on pieni "p_aste", olisi nollassa. Ja ehdokas, jolla on korkea p_aste, olisi yksi.

Logistisen regression p-tutkinto

Oletetaan nyt, että halusimme tehdä tämän kanssa lineaarisen regression. Oletetaan, että halusimme piirtää linjan.
Jos nyt tekisimme niin, se viiva piirrettäisiin siten, että se yrittäisi olla mahdollisimman lähellä kaikkia pisteitä. Ja niin luultavasti päätyisimme linjaan, joka näytti tältä. Olisiko tämä hyvä malli?

kerrata

Ei oikeastaan. Mitä tapahtuisi, riippumatta ehdokkaan p_asteesta, saisimme aina jonkinlaisen arvon. Ja se ei auta meitä, koska luvut eivät tässä yhteydessä merkitse mitään. Tämän luokitusongelman on oltava joko nolla tai yksi. Eli se ei tule toimimaan noin.

Toisaalta, koska tämä on linja, entä jos meillä on ehdokas, jolla on erittäin alhainen p_aste? No, yhtäkkiä arviomme on negatiivinen luku. Ja taas, tässä ei ole mitään järkeä. Negatiivisen luvun ei tarvitse olla nolla tai yksi. Ja samalla tavalla, jos meillä on ehdokas, jolla on erittäin korkea p_aste, minulla saattaa olla positiivinen, jotain yli yhden. Ja taas, siinä ei ole mitään järkeä. Meillä on oltava joko nolla tai yksi.

ennustus

Joten mitä näemme tässä, on joitain vakavia rajoituksia lineaarisen regression käytölle luokittelussa. Mitä meidän pitää tehdä? Meidän on luotava malli, joka numero yksi: ei mene alle nollan tai yli yhden, joten se on sidottava nollan ja yhden välille. Ja numero kaksi, mitä tahansa siitä funktiosta, tuosta yhtälöstä, jonka luomme, meidän ei ehkä pitäisi käsitellä ennusteena sinänsä, vaan askeleena kohti lopullista ennustettamme.

Avaan nyt, mitä juuri sanoin, ja muistutetaan itseämme siitä, että kun teemme lineaarista regressiomallejamme, päädymme tähän lineaariseen yhtälöön, joka on yksinkertaisin muoto. Ja tämä on se yhtälö tai funktio, joka antaa meille tuon suoran.

img

On olemassa tapa sitoa tuo rivi 0:n ja 1:n välille. Ja mitä voimme tehdä, on ottaa tämä juuri luomamme funktio ja sulkea se toiseen funktioon, jota kutsutaan sigmoidifunktioksi.

Logistic Regression -toiminto

Joten otan juuri saamamme lineaarisen yhtälön ja pienennän sitä sigmoidifunktiossa ja laitan sen eksponentiaaliksi.

Logistic Regression -toiminto

Tapahtuu suoran viivan sijaan viiva, joka näyttää tältä. Se on juuttunut yhteen. Se tulee sisään ja kiemurtelee alas. Sitten se on jumissa nollassa.

logistinen regressio

Aivan, tältä linja näyttää, ja voimme nähdä, että olemme ratkaisseet ensimmäisen ongelmamme. Mitä tahansa tästä funktiosta saammekin, on välillä 0 ja 1. Toisessa vaiheessa emme käsittele mitä tahansa tästä yhtälöstä tulevaa lopullista ennustetta. Sen sijaan käsittelemme sitä todennäköisyytenä.

logistinen regressio

Mitä tarkoitan? Tämä tarkoittaa, että kun teen ennusteen, saan jonkin liukulukuarvon välillä 0 ja 1. Ja mitä teen, on käsitellä sitä todennäköisyydellä, että ennusteeni kuuluu positiiviseen luokkaan.

Joten saan arvon 0.9999:ään. Sanon, että todennäköisyys, että tämä ehdokas kuuluu positiiviseen, sijoitusluokkaamme, on 99%. Joten olen melkein varma, että se kuuluu positiiviseen luokkaan. Päinvastoin, jos se on alas pisteessä 0.001 tai missä tahansa, sanon, että tämä luku on pieni. Todennäköisyys, että tämä havainto kuuluu positiiviseen, sijoitettu luokka on lähes nolla. Ja niin, aion sanoa, että se kuuluu luokkaan nolla.

Joten se on järkevää numeroille, jotka ovat lähellä yhtä tai lähellä nollaa. Mutta saatat kysyä itseltäsi, mitä teen muiden arvojen välillä? Toimintatapa on, että asetamme rajaviivan arvoon 0.5, joten minkä tahansa arvon, jonka saan tämän viivan alapuolelle, laitan sen nollaan, joten ennusteeni on ei, ja jos se on tämän viivan yläpuolella, jos se on pisteen viisi yläpuolella , laitan tämän positiiviseen luokkaan, ennusteeni on yksi.

p-aste

Joten nyt minulla on funktio, joka antaa minulle ennusteen nollan ja yhden välillä, ja käsittelen sitä todennäköisyytenä. Ja jos tämä todennäköisyys on yli 0.5 tai 50%, sanon, okei, positiivinen luokka yksi. Ja jos se on alle 50%, sanon, että se on negatiivinen luokka, nolla. Joten se on tapa, jolla logistinen regressio toimii. Ja nyt ymmärrämme sen, koodataan se ja sovitetaan se. Asetan hyperparametrin 'max_iter' arvoon 1000. Tämä parametri viittaa iteraatioiden enimmäismäärään, jonka ratkaisijat voivat lähentyä.

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

Arvioida

Nyt on aika katsoa, ​​miten mallimme toimii. On aika arvioida Logistic Regression -malli. Muistetaan siis, että tällä kertaa meitä kiinnostava suorituskykymittari on tarkkuuspisteet, ja haluamme tarkan. Ja haluamme päihittää perusviivan 0.68. Mallin tarkkuus voidaan laskea käyttämällä accuracy_score-funktiota. Funktio vaatii kaksi argumenttia, tositunnisteet ja ennustetut tunnisteet.

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

Näemme harjoitustarkkuutemme 90 %. Se voittaa perusviivan. Testin tarkkuus oli hieman pienempi, 88 %. Se ylitti myös lähtötason ja oli hyvin lähellä harjoitustarkkuuttamme. Tämä on siis hyvä uutinen, koska se tarkoittaa, että mallimme ei ole liian istuva tai mitään muuta.

Logistisen regressiomallin tulokset

Muista, että logistisella regressiolla päädymme näihin lopullisiin ennusteisiin nolla tai yksi. Mutta tämän ennusteen alla on todennäköisyys, että liukuluku on nollan tai yhden välillä, ja joskus voi olla hyödyllistä nähdä, mitkä nuo todennäköisyysarviot ovat. Katsotaanpa harjoitusennusteitamme ja viittä ensimmäistä. "Ennustava" menetelmä ennustaa merkitsemättömän havainnon kohteen.

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

Nämä olivat siis lopulliset ennusteet, mutta mitkä ovat niiden takana olevat todennäköisyydet? Saadaksemme ne, meidän on tehtävä hieman erilainen koodi. Sen sijaan, että käyttäisin 'predict'-menetelmää mallissamme, käytän 'predict_proba'-menetelmää harjoitustiedoissamme.

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

Voimme nähdä eräänlaisen sisäkkäisen luettelon, jossa on kaksi eri saraketta. Vasemmalla oleva sarake edustaa todennäköisyyttä, että ehdokasta ei sijoiteta, tai negatiivista luokkaamme "Ei sijoitettu". Toinen sarake edustaa positiivista luokkaa "Placed" tai todennäköisyyttä, että ehdokas sijoitetaan. Keskitymme toiseen sarakkeeseen. Jos katsomme ensimmäistä todennäköisyysarviota oikein, voimme nähdä, että tämä on 0.07. Joten koska se on alle 50%, mallimme sanoo, että ennusteeni on nolla. Ja seuraavien ennusteiden osalta voimme nähdä, että ne ovat kaikki yli 0.5, ja siksi mallimme ennusti lopulta yhden.

Nyt haluamme poimia ominaisuuksien nimet ja tärkeyden ja laittaa ne sarjaan. Ja koska meidän on näytettävä ominaisuuden tärkeys kerroinsuhteina, meidän on tehtävä vain pieni matemaattinen muunnos ottamalla tärkeydestämme eksponentiaalinen.

# 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

Ennen kuin keskustelemme kerroinsuhteista ja siitä, mitä ne ovat, esitellään ne vaakasuoraan pylväskaavioon. Tehdään juoni pandoilla ja muista, että etsimme viisi suurinta kerrointa. Emmekä halua käyttää kaikkia kerroinsuhteita. Joten haluamme käyttää häntää.

# Horizontal bar chart, five largest coefficients
odds_ratios.tail().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("High Importance Features");
# Vaakasuuntainen pylväskaavio, viisi suurinta kerrointa odds_ratios.tail().plot(kind=

Nyt haluan sinun kuvittelevan pystysuoran viivan 5:ssä, ja haluan aloittaa katsomalla sitä. Puhutaanpa jokaisesta näistä erikseen tai vain ensimmäisestä parista. Joten aloitetaan tästä "ssc_p", joka viittaa "Secondary Education -prosenttiin – 10. luokka". Ja voimme nähdä, että kerroinsuhde on 30. Mitä se nyt tarkoittaa? Se tarkoittaa, että jos ehdokkaalla on korkea "ssc_p", hänen sijoituksensa todennäköisyys on kuusi kertaa suurempi kuin muiden ehdokkaiden, kun kaikki asiat ovat samoin. Toinen tapa ajatella sitä on, että kun ehdokkaalla on "ssc_p", ehdokkaan rekrytoinnin mahdollisuus kasvaa kuusinkertaiseksi.

Joten mikä tahansa kerroinsuhde yli viiden lisää todennäköisyyttä, että ehdokkaat sijoitetaan. Ja siksi meillä on pystysuora viiva viidessä. Ja nämä viisi erilaista ominaisuutta ovat ominaisuuksia, jotka liittyvät eniten lisääntyneeseen rekrytointiin. Tämä on siis kertoimemme. Nyt olemme tarkastelleet ominaisuuksia, jotka liittyvät eniten rekrytoinnin kasvuun. Katsotaanpa siihen liittyviä ominaisuuksia, rekrytoinnin vähenemistä. Joten nyt on aika katsoa pienimmät. Joten sen sijaan, että katsoisimme häntää, katsomme sitä.

odds_ratios.head().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("Low Importance Features");
vähämerkityksinen ominaisuus

Ensimmäinen asia, joka meidän on nähtävä tässä, on se, että x-akselilla kaikki on yksi tai sen alapuolella. Mitä se nyt tarkoittaa? Joten katsotaanpa pienintä kerroinsuhdettamme täällä. Se on mba_p, joka viittaa MBA-prosenttiin. Voimme nähdä, että se on valmis noin 0.45. Mitä se nyt tarkoittaa? No, ero 0.45:n ja 1:n välillä on 0.55. Selvä? Ja mitä tuo numero tarkoittaa? MBA-hakijoita on vähemmän todennäköisesti rekrytoitu 55 %:lla, jos kaikki muut asiat ovat samat. Selvä? Joten se pienensi rekrytointitodennäköisyyttä kertoimella 0.55 tai 55%. Ja se pätee kaikkeen täällä.

Yhteenveto

Joten mitä opimme? Ensinnäkin, valmistelussa datavaiheessa saimme tietää, että työskentelemme luokittelun, erityisesti binääriluokituksen, parissa käyttämällä logistista regressiota. Mitä tulee tietojen tutkimiseen, teimme paljon asioita, mutta kohokohtien osalta tarkastelimme luokkatasapainoa, eikö niin? Positiivisten ja negatiivisten luokkiemme osuus. Sitten jaamme tietomme.

Koska Logistic Regression on luokitusmalli, opimme uudesta suorituskykymittarista, tarkkuuspisteistä. Nyt tarkkuuspisteet ovat 0 ja 1 välillä. Nolla on huono ja yksi hyvä. Kun iteroimme, opimme logistisesta regressiosta. Se on maaginen tapa, jossa voit ottaa lineaarisen yhtälön, suoran ja laittaa sen toiseen funktioon, sigmoidifunktioon ja aktivointifunktioon, ja saada siitä todennäköisyysestimaatin ja muuttaa sen todennäköisyysarvion ennusteeksi.

Lopuksi opimme kertoimesta ja siitä, kuinka voimme tulkita kertoimia nähdäksemme, lisääkö tietty ominaisuus todennäköisyyttä sille, että olemme rekrytoineet ehdokkaan vai ei.

Projektin lähdekoodi: https://github.com/SawsanYusuf/Campus-Recruitment.git

Tässä artikkelissa näkyvä media ei ole Analytics Vidhyan omistuksessa, ja sitä käytetään tekijän harkinnan mukaan. 

Aikaleima:

Lisää aiheesta Analyysi Vidhya