Applicazioni pratiche di machine learning/Trovare lavoro
Caricamento librerie
[modifica | modifica sorgente] library(dplyr)
library(ggplot2)
library(statsr)
Parte 1: Dati
[modifica | modifica sorgente]Il dataset Job_Placement_Data.csv scaricabile da kaggle contiene 215 records di 13 variabili, relativi a neolaureati assunti o non assunti (placed or not placed) . Si vogliono evidenziare i fattori che influenzano positivamente l'assunzione di un candidato. Ecco la spiegazione sulle variabili:
- gender: sesso del candidato
- ssc_percentage: percentuale dei voti di scuola media
- ssc_board: Consiglio didattico per gli esami ssc
- hsc_percentage: percentuale dei voti di scuola superiore
- hsc_board: consiglio didattico per gli esami hsc
- hsc_subject: oggetto di studio per hsc (arte, commercio, scienza)
- Degree_percentage: percentuale dei voti ottenuti nella laurea
- undergrad_degree: titoli di studio universitari
- work_experience: esperienza lavorativa passata
- emp_test_percentage: percentuale del test attitudinale
- specialization: specializzazioni post-laurea - (specializzazione MBA)
- mba_percent: percentuale dei voti in Master Business Administration
- status (TARGET): stato del posizionamento. Posizionato/Non posizionato
Caricamento dati:
Job_Placement_Data <- read.csv("Job_Placement_Data.csv")
Parte 2 : Domanda di ricerca
[modifica | modifica sorgente]Si vuole evidenziare che a prescindere dall'esperienza lavorativa, se le medie dei voti della scuola inferiore, superiore, laurea, test attitudinali, master del candidato sono alte, il candidato tende a trovare lavoro. Chi ha esperienza lavorativa ma voti scolastici bassi tende ad essere disoccupato. Inoltre non dipende dal tipo di studi (arte, commercio, scienze) se il candidato lavora oppure no. Per finire si vuole predire se un candidato troverà lavoro in base alle altre variabili.
Parte 3 : Esplorazione dati
[modifica | modifica sorgente]In chi è occupato la media di percentuale di voti nella scuola inferiore, superiore, università, master risulta di molto maggiore rispetto a chi non è occupato:
Job_Placement_Data %>%
group_by(status) %>%
summarise(media_scuola_inferiore=mean(ssc_percentage),
media_scuola_superiore=mean(hsc_percentage),
media_voti_laurea=mean(degree_percentage),
media_test_attitudinale=mean(emp_test_percentage),
media_master_mba=mean(mba_percent))
A tibble: 2 × 6
status media_scuola_inferiore media_scuola_superiore media_voti_laurea media_test_attitudinale media_master_mba
1 Not Placed 57.5 58.4 61.1 69.6 61.6 2 Placed 71.7 69.9 68.7 73.2 62.6
Come si vede dal seguente grafico e dal t test, chi ha esperienza lavorativa è in proporzione più occupato di chi non ce l'ha, infatti nel t test, essendo p_value<0,05, non vale l'ipotesi nulla al 95%, secondo cui la percentuale di chi è occupato sarebbe la stessa di chi non lo è:
Job_Placement_Data %>%
group_by(status,work_experience) %>%
summarise(totale=n(), .groups = "keep") %>%
ggplot(aes(status,totale, fill=work_experience))+
geom_bar(stat = "identity")
inference(work_experience, status, data=Job_Placement_Data,statistic = "proportion",method = "theoretical", alternative = "less", type = "ht", success = "Yes", null = 0)
Response variable: categorical (2 levels, success: Yes) Explanatory variable: categorical (2 levels) n_Not Placed = 67, p_hat_Not Placed = 0.1493 n_Placed = 148, p_hat_Placed = 0.4324 H0: p_Not Placed = p_Placed HA: p_Not Placed < p_Placed z = -4.0478 p_value = < 0.0001
Come si vede dalla seguente tabella la media delle percentuali di voti nella scuola inferiore, superiore, università e master risulta di molto maggiore in chi ha esperienza lavorativa ed è occupato rispetto a chi ha esperienza ma risulta non occupato:
Job_Placement_Data %>%
group_by(status, work_experience) %>%
summarise(media_scuola_inferiore=mean(ssc_percentage),
media_scuola_superiore=mean(hsc_percentage),
media_voti_laurea=mean(degree_percentage),
media_test_attitudinale=mean(emp_test_percentage),
media_master_mba=mean(mba_percent), .groups = "keep")
A tibble: 4 × 7 # Groups: status, work_experience [4] status work_experience media_scuola_inferiore media_scuola_superiore media_voti_laurea media_test_attitudin… media_master_mba 1 Not Placed No 58.1 58.1 61.3 70.4 61.4 2 Not Placed Yes 54.2 59.8 60.2 65.2 62.7 3 Placed No 71.2 70.0 68.7 72.4 61.7 4 Placed Yes 72.4 69.8 68.8 74.4 63.8
Come si vede dal seguente t test oltre che dalla precedente tabella, tra gli occupati la percentuale di voti alla scuola superiore di chi ha esperienza lavorativa è in media la stessa di chi non ha esperienza, infatti vale l'ipotesi nulla al 95%, essendo p_value>0,05 . Lo stesso vale per altre scuole: inferiore, università, master.
df_placed <- Job_Placement_Data %>%
filter(status=="Placed")
inference(hsc_percentage,work_experience, data=df_placed,statistic = "mean",method = "theoretical", alternative = "twosided", type = "ht", null = 0)
Response variable: numerical Explanatory variable: categorical (2 levels) n_No = 84, y_bar_No = 70.0248, s_No = 9.4334 n_Yes = 64, y_bar_Yes = 69.7977, s_Yes = 9.2636 H0: mu_No = mu_Yes HA: mu_No != mu_Yes t = 0.1466, df = 63 p_value = 0.8839
Non dipende dal tipo di studi (arte, commercio, scienze) se il candidato lavora oppure no infatti nel seguente test chi quadrato p_value>0,05 quindi le 2 variabili status e hsc_subject sono indipendenti:
inference(status,hsc_subject, data=Job_Placement_Data, statistic = "proportion",method = "theoretical", alternative = "greater", type = "ht", success = "Placed")
Response variable: categorical (2 levels) Explanatory variable: categorical (3 levels) Observed: y x Not Placed Placed Arts 5 6 Commerce 34 79 Science 28 63 Expected: y x Not Placed Placed Arts 3.427907 7.572093 Commerce 35.213953 77.786047 Science 28.358140 62.641860
H0: hsc_subject and status are independent HA: hsc_subject and status are dependent chi_sq = 1.1147, df = 2, p_value = 0.5727
Parte 4 : Modellizzazione e Previsione in Python
[modifica | modifica sorgente]import pandas as pd
# Read the data
data = pd.read_csv('Job_Placement_Data.csv')
from sklearn.model_selection import train_test_split
# Separo la variabile target dalle variabili predictors
y = data.status
X = data.drop(['status'], axis=1)
# Divido i dati in training (75%) e validation (25%) sets
X_train_full, X_valid_full, y_train, y_valid = train_test_split(X, y, train_size=0.75, test_size=0.25,random_state=0)
#
# Seleziono le colonne contenenti variabili categoriche
categorical_cols = [cname for cname in X_train_full.columns if X_train_full[cname].nunique() < 10 and
X_train_full[cname].dtype == "object"]
# Seleziono le colonne contenenti variabili numeriche
numerical_cols = [cname for cname in X_train_full.columns if X_train_full[cname].dtype in ['int64', 'float64']]
# Seleziono nel dataset tali colonne
my_cols = categorical_cols + numerical_cols
X_train = X_train_full[my_cols].copy()
X_valid = X_valid_full[my_cols].copy()
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
# Standardizzo le colonne numeriche
numerical_transformer = StandardScaler()
# Trasformo le colonne categoriche in numeriche e attribuisco un valore frequente ai NA
categorical_transformer = Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore')),
])
preprocessor = ColumnTransformer(
transformers=[
('num', numerical_transformer, numerical_cols),
('cat', categorical_transformer, categorical_cols)
])
Alleno sul training set vari algoritmi di machine learning. Quello con la migliore accuracy sul validation set (83,33%) è LinearDiscriminantAnalysis .
from sklearn.metrics import accuracy_score, log_loss
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC, LinearSVC, NuSVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier, GradientBoostingClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
classifiers = [
KNeighborsClassifier(),
SVC(kernel="rbf", C=0.025, probability=True),
NuSVC(probability=True),
DecisionTreeClassifier(),
RandomForestClassifier(),
AdaBoostClassifier(),
GradientBoostingClassifier(),
GaussianNB(),
LinearDiscriminantAnalysis()
]
for clf in classifiers:
my_pipeline = Pipeline(steps=[('preprocessor', preprocessor),
('model', clf)
])
my_pipeline.fit(X_train, y_train)
name = clf.__class__.__name__
print("="*30)
print(name)
print('****Results****')
train_predictions = my_pipeline.predict(X_valid)
acc = accuracy_score(y_valid, train_predictions)
print("Accuracy: {:.4%}".format(acc))
train_predictions = my_pipeline.predict_proba(X_valid)
ll = log_loss(y_valid, train_predictions)
print("Log Loss: {}".format(ll))
print("="*30)
============================== KNeighborsClassifier ****Results**** Accuracy: 74.0741% Log Loss: 4.71142932321887 ============================== SVC ****Results**** Accuracy: 68.5185% Log Loss: 0.5079557348761315 ============================== NuSVC ****Results**** Accuracy: 75.9259% Log Loss: 0.4639978645084237 ============================== DecisionTreeClassifier ****Results**** Accuracy: 68.5185% Log Loss: 10.873318494694104 ============================== RandomForestClassifier ****Results**** Accuracy: 74.0741% Log Loss: 0.4456363904734124 ============================== AdaBoostClassifier ****Results**** Accuracy: 79.6296% Log Loss: 0.5592596234218726 ============================== GradientBoostingClassifier ****Results**** Accuracy: 74.0741% Log Loss: 0.9540074689883228 ============================== GaussianNB ****Results**** Accuracy: 81.4815% Log Loss: 0.5448657681139126 ============================== LinearDiscriminantAnalysis ****Results**** Accuracy: 83.3333% Log Loss: 0.4406757975023656 ==============================