Recrutement sur les campus : un problème de classification avec régression logistique

Recrutement sur les campus : un problème de classification avec régression logistique

Nœud source: 1996810

Introduction

Dans ce projet, nous nous concentrerons sur les données de l'Inde. Et notre objectif est de créer un modèle prédictif, comme la régression logistique, etc. afin que lorsque nous donnons les caractéristiques d'un candidat, le modèle puisse prédire s'il recrutera.

La jeu de données tourne autour de la saison de placement d'une école de commerce en Inde. L'ensemble de données contient divers facteurs sur les candidats, tels que l'expérience professionnelle, le pourcentage d'examens, etc. Enfin, il contient l'état du recrutement et les détails de la rémunération.

Problème de science des données avec régression logistique

Le recrutement sur les campus est une stratégie de recherche, d'engagement et d'embauche de jeunes talents pour des stages et des postes de niveau débutant. Cela implique souvent de travailler avec des centres de services de carrière universitaires et d'assister à des salons de l'emploi pour rencontrer en personne des étudiants et des diplômés récents.

Cet article a été publié dans le cadre du Blogathon sur la science des données.

Table des matières

  1. Étapes impliquées dans la résolution du problème
  2. Préparer les données
  3. Construire un modèle de régression logistique
  4. Résultats du modèle de régression logistique
  5. Conclusion

Étapes impliquées dans la résolution du problème

Dans cet article, nous allons importer cet ensemble de données, le nettoyer, puis le préparer pour créer un modèle de régression logistique. Nos objectifs ici sont les suivants :

Tout d'abord, nous allons préparer notre ensemble de données pour classification binaire. Maintenant, qu'est-ce que je veux dire ? lorsque nous essayons de prédire une valeur continue, comme le prix d'un appartement, cela peut être n'importe quel nombre entre zéro et plusieurs millions de dollars. Nous appelons cela un problème de régression.

Mais dans ce projet, les choses sont un peu différentes. Au lieu de prédire une valeur continue, nous avons des groupes ou des classes discrets que nous essayons de prédire entre eux. C'est donc ce qu'on appelle un problème de classification, et parce que dans notre projet, nous n'aurons que deux groupes entre lesquels nous essaierons de choisir, cela en fait une classification binaire.

Le deuxième objectif est de créer un modèle de régression logistique pour prédire le recrutement. Et notre troisième objectif est d'expliquer les prédictions de notre modèle en utilisant le rapport de cotes.

Maintenant, en ce qui concerne le flux de travail d'apprentissage automatique, les étapes que nous suivrons et certaines des nouvelles choses, nous apprendrons en cours de route. Ainsi, dans la phase d'importation, nous préparerons nos données pour qu'elles fonctionnent avec une cible binaire. Dans la phase d'exploration, nous examinerons l'équilibre des classes. Donc, fondamentalement, quelle proportion de candidats était troisième et quelles proportions ne l'étaient pas ? et dans la phase d'encodage des fonctionnalités, nous effectuerons l'encodage de nos fonctionnalités catégorielles. Dans la partie fractionnée, nous ferons un fractionnement de test de train aléatoire.

Pour la phase de construction du modèle, tout d'abord, nous définirons notre base de référence, et comme nous utiliserons des scores de précision, nous parlerons davantage de ce qu'est un score de précision et de la manière de construire une base de référence lorsque c'est la métrique qui nous intéresse. Deuxièmement, nous ferons une régression logistique. Et puis last but not least, nous aurons la phase d'évaluation. Nous nous concentrerons à nouveau sur le score de précision. Enfin, pour communiquer les résultats, nous nous pencherons sur l'odds ratio.

Enfin, avant de plonger dans le travail, présentons-nous aux bibliothèques que nous utiliserons pour lancer le projet. Tout d'abord, nous allons importer nos données dans le bloc-notes Google Colabe dans la bibliothèque io. Ensuite, comme nous utiliserons un modèle de régression logistique, nous l'importerons depuis scikit-learn. Après cela, également de scikit-apprendre, nous importerons nos métriques de performance, le score de précision et le train-test-split.

Nous utiliserons matplotlib et seaborn pour notre visualisation, et NumPy  sera juste pour peu de maths.
Nous avons besoin pandas pour manipuler nos données, labelencoder pour encoder nos variables catégorielles, et standard scaler pour normaliser les données. Ce seront les bibliothèques dont nous avons besoin.

Passons à la préparation des données.

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

Préparer les données

L’

Pour commencer notre préparation des données, commençons notre travail important. Tout d'abord, nous chargeons notre fichier de données, puis nous devons les placer dans 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()
Ensemble de données pour la régression logistique

Nous pouvons voir notre belle DataFrame, et nous avons 215 enregistrements et 15 colonnes qui incluent l'attribut `status`, notre cible. Ceci est la description de toutes les fonctionnalités.

Régression logistique

Explorer

Nous avons maintenant toutes ces fonctionnalités que nous allons explorer. Alors commençons notre l'analyse exploratoire des données. Tout d'abord, examinons les informations de cette base de données et voyons si nous devrons en conserver ou si nous devrons peut-être les supprimer.

# 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

Maintenant, lorsque nous examinons les informations `df`, nous recherchons deux ou trois choses, nous avons 215 lignes dans notre base de données, et la question que nous voulons nous poser est la suivante : y a-t-il des données manquantes ? Et si nous regardons ici, il semble que nous n'ayons pas de données manquantes à l'exception de la colonne des salaires, comme prévu, en raison de candidats qui n'ont pas été embauchés.

Une autre préoccupation pour nous ici est la suivante: y a-t-il des fonctionnalités qui fuient qui donneraient des informations à notre modèle qu'il n'aurait pas s'il était déployé dans le monde réel ? N'oubliez pas que nous voulons que notre modèle prédise si un candidat sera placé ou non, et nous voulons que notre modèle fasse ces prédictions avant que le recrutement ne se produise. Nous ne voulons donc donner aucune information sur ces candidats après le recrutement.

Donc, il est assez clair que cette fonction "salaire" donne des informations sur le salaire offert par l'entreprise. Et parce que ce salaire est pour ceux qui sont acceptés, cette fonctionnalité ici constitue une fuite, et nous devons la laisser tomber.

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

La deuxième chose que je veux examiner, ce sont les types de données pour ces différentes fonctionnalités. Donc, en regardant ces types de données, nous avons huit caractéristiques catégorielles avec notre cible et sept caractéristiques numériques, et tout est correct. Donc, maintenant que nous avons ces idées, prenons le temps de les explorer plus en profondeur.

Nous savons que notre cible a deux classes. Nous avons placé des candidats et non des candidats placés. La question est, quelle est la proportion relative de ces deux classes ? Sont-ils à peu près au même équilibre ? Ou l'un est-il beaucoup plus que l'autre ? C'est quelque chose que vous devez prendre en compte lorsque vous faites des problèmes de classification. C'est donc une étape importante dans notre EDA.

# Plot class balance
df["status"].value_counts(normalize=True).plot( kind="bar", xlabel="Class", ylabel="Relative Frequency", title="Class Balance"
);
Déséquilibre de classe pour la régression logistique

Notre classe positive 'placé' compte pour plus de 65% de nos observations, et notre classe négative 'non placé' est d'environ 30%. Maintenant, si elles étaient super déséquilibrées, comme si c'était plutôt 80 ou même plus que ça, je dirais que ce sont des classes déséquilibrées. Et nous devrons faire du travail pour nous assurer que notre modèle fonctionnera de la bonne manière. Mais c'est un bon équilibre.

Faisons une autre visualisation pour remarquer la connexion entre nos fonctionnalités et la cible. Commençons par les caractéristiques numériques.

Tout d'abord, nous verrons la distribution individuelle des caractéristiques à l'aide d'un diagramme de distribution, et nous verrons également la relation entre les caractéristiques numériques et notre cible à l'aide d'un diagramme en boîte.

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]);
"Régression logistique

Dans la première colonne de notre graphique, nous pouvons voir que toutes les distributions suivent une distribution normale, et la plupart des performances éducatives du candidat se situent entre 60 et 80 %.

Dans la deuxième colonne, nous avons un double box plot avec la classe "Placed" à droite, puis la classe "Not Placed" à gauche. Pour les fonctionnalités 'etest_p' et 'mba_p', il n'y a pas beaucoup de différence entre ces deux distributions du point de vue de la création de modèles. Il y a un chevauchement important dans la distribution sur les classes, donc ces caractéristiques ne seraient pas un bon prédicteur de notre cible. Quant au reste des fonctionnalités, elles sont suffisamment distinctes pour les considérer comme de bons prédicteurs potentiels de notre cible. Passons aux caractéristiques catégorielles. Et pour les explorer, nous utiliserons un count plot.

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")
"Régression logistique

En regardant l'intrigue, nous voyons que nous avons plus de candidats masculins que de femmes. Et la plupart de nos candidats n'ont aucune expérience de travail, mais ces candidats ont été embauchés plus que ceux qui en avaient. Nous avons des candidats qui ont fait du commerce comme cours «hsc», et ainsi qu'un premier cycle, les candidats ayant une formation scientifique sont les deuxièmes les plus élevés dans les deux cas.

Une petite note sur les modèles de régression logistique, bien qu'ils soient destinés à la classification, ils sont dans le même groupe que d'autres modèles linéaires comme la régression linéaire, et pour cette raison, puisqu'ils sont tous les deux des modèles linéaires. Nous devons également nous préoccuper de la question de la multicolinéarité. Nous devons donc créer une matrice de corrélation, puis nous devons la tracer dans une carte thermique. Nous ne voulons pas examiner toutes les caractéristiques ici, nous voulons examiner uniquement les caractéristiques numériques et nous ne voulons pas inclure notre cible. Car si notre cible correspond à certaines de nos fonctionnalités, c'est très bien.

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 de corrélation

Voici le bleu clair, qui signifie peu ou pas de corrélation, et le bleu foncé, avec lequel nous avons une corrélation plus élevée. Nous voulons donc être à l'affût de ces bleus foncés. Nous pouvons voir une ligne bleu foncé, une ligne diagonale descendant au milieu de cette parcelle. Ce sont les caractéristiques qui sont corrélées avec elles-mêmes. Et puis, on voit des carrés sombres. Cela signifie que nous avons un tas de corrélations entre les fonctionnalités.

À la dernière étape de notre EDA, nous devons vérifier la cardinalité élevée-basse dans les caractéristiques catégorielles. La cardinalité fait référence au nombre de valeurs uniques dans une variable catégorielle. Une cardinalité élevée signifie que les entités catégorielles ont un grand nombre de valeurs uniques. Il n'y a pas de nombre exact de valeurs uniques qui confèrent à une fonctionnalité une cardinalité élevée. Mais si la valeur de la caractéristique catégorique est unique pour presque toutes les observations, elle peut généralement être supprimée.

# 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

Je ne vois aucune colonne où le nombre de valeurs uniques est un ou quelque chose de très élevé. Mais je pense qu'il y a une colonne de type catégoriel qui nous manque ici. Et la raison en est qu'il n'est pas encodé en tant qu'objet mais en tant qu'entier. La colonne 'sl_no' n'est pas un entier dans le sens que nous connaissons. Ces candidats sont classés dans un certain ordre. Juste une étiquette de nom unique, et le nom est comme une catégorie, n'est-ce pas ? Il s'agit donc d'une variable catégorielle. Et il n'a aucune information, nous devons donc le supprimer.

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

Codage des fonctionnalités

Nous avons terminé notre analyse, et la prochaine chose que nous devons faire est d'encoder nos caractéristiques catégorielles, j'utiliserai le 'LabelEncoder'. L'encodage d'étiquette est une technique d'encodage populaire pour la gestion des variables catégorielles. Avec l'utilisation de cette technique, chaque étiquette se voit attribuer un entier unique basé sur l'ordre alphabétique.

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()
sortie de code

Diviser

Nous avons importé et nettoyé nos données. Nous avons fait un peu d'analyse exploratoire des données, et maintenant nous devons diviser nos données. Nous avons deux types de fractionnement : fractionnement vertical ou caractéristiques-cible et fractionnement horizontal ou ensembles de test de train. Commençons par le fractionnement vertical. Nous allons créer notre matrice de caractéristiques 'X' et notre vecteur cible 'y'. Notre cible est le « statut ». Nos caractéristiques devraient être toutes les colonnes qui restent dans le 'df.'

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

Les modèles fonctionnent généralement mieux lorsqu'ils ont des données normalisées pour s'entraîner, alors qu'est-ce que la normalisation ? Normalisation transforme les valeurs de plusieurs variables en une plage similaire. Notre objectif est de normaliser nos variables. Ainsi, leurs plages de valeurs seront comprises entre 0 et 1. Faisons cela, et j'utiliserai le `StandardScaler.`

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

Passons maintenant aux ensembles de fractionnement horizontal ou de train-test. Nous devons diviser nos données (X et y) en ensembles d'apprentissage et de test à l'aide d'une répartition train-test aléatoire. notre ensemble de test devrait représenter 20 % de nos données totales. Et nous n'oublions pas de définir un random_state pour la reproductibilité.

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

Construire un modèle de régression logistique

Baseline

Nous devons donc maintenant commencer à construire notre modèle, et nous devrons commencer à commander pour définir notre base de référence. N'oubliez pas que le type de problème auquel nous sommes confrontés est un problème de classification et qu'il existe différentes métriques pour évaluer les modèles de classification. Celui sur lequel je veux me concentrer est le score de précision.

Maintenant, quel est le score de précision ? Le score de précision dans l'apprentissage automatique est une métrique d'évaluation qui mesure le nombre de prédictions correctes faites par un modèle par rapport au nombre total de prédictions faites. Nous le calculons en divisant le nombre de prédictions correctes par le nombre total de prédictions. Cela signifie donc que le score de précision se situe entre 0 et 1. Zéro n'est pas bon. C'est là que vous ne voulez pas être, et l'un est parfait. Alors gardons cela à l'esprit et rappelons-nous que la ligne de base est un modèle qui donne une prédiction encore et encore, quelle que soit l'observation, une seule supposition pour nous.

Dans notre cas, nous avons deux classes, placées ou non. Donc, si nous ne pouvions faire qu'une seule prédiction, quelle serait notre seule supposition ? Si vous avez dit la classe majoritaire. Je pense que c'est logique, non ? Si nous ne pouvons avoir qu'une seule prédiction, nous devrions probablement choisir celle avec les observations les plus élevées dans notre ensemble de données. Ainsi, notre ligne de base utilisera le pourcentage que la classe majoritaire apparaît dans les données d'entraînement. Si le modèle ne dépasse pas cette ligne de base, les caractéristiques n'ajoutent pas d'informations précieuses pour classer nos observations.

Nous pouvons utiliser la méthode "value_counts" avec l'argument "normalize = True" pour calculer la précision de la ligne de base :

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

Nous pouvons voir que notre précision de base est de 68 % ou 0.68 en tant que proportion. Donc, pour ajouter de la valeur utile, nous voulons dépasser ce nombre et nous rapprocher de un. C'est notre objectif, et maintenant commençons à construire notre modèle.

Répéter

Il est maintenant temps de construire notre modèle à l'aide de la régression logistique. Nous utiliserons la régression logistique, mais avant de le faire, parlons un peu de ce qu'est la régression logistique et de son fonctionnement, puis nous pourrons faire le codage. Et pour cela, nous avons ici une petite grille.

Le long de l'axe des x, disons que j'ai les p_degrees des candidats dans notre ensemble de données. Et au fur et à mesure que je me déplace de droite à gauche, les degrés deviennent de plus en plus hauts, puis le long de l'axe Y, j'ai les classes possibles pour le placement : zéro et un.

graphique pour la régression logistique

Donc, si nous devions tracer nos points de données, à quoi cela ressemblerait-il ? Notre analyse montre qu'un candidat ayant un "p_degree" élevé est plus susceptible d'être embauché. Donc, cela ressemblerait probablement à quelque chose comme ça, où le candidat avec un petit "p_degree" serait à zéro. Et le candidat avec un `p_degree` élevé serait debout à un.

p-degré pour la régression logistique

Disons maintenant que nous voulions faire une régression linéaire avec cela. Disons que nous voulions tracer une ligne.
Maintenant, si nous faisions cela, ce qui se passerait, c'est que cette ligne serait tracée de telle manière qu'elle essaierait d'être aussi proche que possible de tous les points. Et donc nous nous retrouverions probablement avec une ligne qui ressemblait à quelque chose comme ça. Serait-ce un bon modèle ?

répéter

Pas vraiment. Ce qui se passerait, quel que soit le p_degree du candidat, nous obtiendrions toujours une sorte de valeur. Et cela ne nous aidera pas parce que les chiffres, dans ce contexte, ne veulent rien dire. Ce problème de classification doit être égal à zéro ou à un. Donc, ça ne marchera pas comme ça.

D'un autre côté, comme il s'agit d'une ligne, que se passe-t-il si nous avons un candidat avec un p_degree très bas ? Eh bien, tout d'un coup, notre estimation est un nombre négatif. Et encore une fois, cela n'a aucun sens. Il n'y a pas de nombre négatif, ni besoin d'être zéro ou un. Et de la même manière, si nous avons un candidat avec un p_degree très élevé, je pourrais avoir un positif, quelque chose au-dessus de un. Et encore une fois, cela n'a aucun sens. Nous devons avoir un zéro ou un.

prédiction

Nous voyons donc ici de sérieuses limitations à l'utilisation de la régression linéaire pour la classification. Alors, que devons-nous faire ? Nous devons créer un modèle qui numéro un : ne descend pas en dessous de zéro ou au-dessus de un, il doit donc être lié entre zéro et un. Et le numéro deux, quel que soit le résultat de cette fonction, cette équation que nous créons, nous ne devrions peut-être pas la traiter comme la prédiction en soi mais comme une étape vers la réalisation de notre prédiction finale.

Maintenant, laissez-moi décortiquer ce que je viens de dire, et rappelons-nous que lorsque nous faisons nos modèles de régression linéaire, nous nous retrouvons avec cette équation linéaire, qui est la forme la plus simple. Et c'est cette équation ou fonction qui nous donne cette ligne droite.

img

Il existe un moyen de lier cette ligne entre 0 et 1. Et ce que nous pouvons faire, c'est prendre cette fonction que nous venons de créer et l'inclure dans une autre fonction, ce qu'on appelle une fonction sigmoïde.

fonction de régression logistique

Donc, je vais prendre l'équation linéaire que nous venons d'avoir, et je vais la réduire dans la fonction sigmoïde et la mettre comme exponentielle.

fonction de régression logistique

Ce qui se passe, c'est qu'au lieu d'obtenir une ligne droite, nous obtenons une ligne qui ressemble un peu à ceci. C'est coincé à un. Il entre et descend. Ensuite, il est bloqué à zéro.

régression logistique

Bon, c'est à quoi ressemble la ligne, et nous pouvons voir que nous avons résolu notre premier problème. Tout ce que nous obtiendrons de cette fonction sera compris entre 0 et 1. Dans la deuxième étape, nous ne traiterons pas tout ce qui sort de cette équation comme la prédiction ultime. Au lieu de cela, nous le traiterons comme une probabilité.

régression logistique

Qu'est ce que je veux dire? Cela signifie que lorsque je fais une prédiction, j'obtiendrai une valeur à virgule flottante entre 0 et 1. Et ce que je ferai, c'est la traiter comme la probabilité que ma prédiction appartienne à la classe positive.

J'obtiens donc une valeur à 0.9999. Je dirai que la probabilité que ce candidat appartienne à notre classe positive est de 99 %. Je suis donc presque sûr qu'il appartient à la classe positive. Inversement, s'il est en baisse au point 0.001 ou autre, je dirai que ce nombre est faible. La probabilité que cette observation particulière appartienne à la classe positive placée est presque nulle. Et donc, je vais dire qu'il appartient à la classe zéro.

Cela a donc du sens pour les nombres proches de un ou proches de zéro. Mais vous pourriez vous demander, qu'est-ce que je fais avec d'autres valeurs entre les deux ? La façon dont cela fonctionne est que nous mettons une ligne de coupure juste à 0.5, donc toute valeur que j'obtiens en dessous de cette ligne, je la mettrai à zéro, donc ma prédiction est non, et si elle est au-dessus de cette ligne, si elle est au-dessus du point cinq , je vais mettre ça dans la classe positive, ma prédiction est une.

p-degré

Donc, maintenant j'ai une fonction qui me donne une prédiction entre zéro et un, et je traite cela comme une probabilité. Et si cette probabilité est supérieure à 0.5 ou 50 %, je dis, d'accord, classe positive 50. Et si c'est en dessous de 1000%, je dis, c'est la classe négative, zéro. C'est ainsi que fonctionne la régression logistique. Et maintenant que nous comprenons cela, codons-le et adaptons-le. Je vais définir l'hyperparamètre 'max_iter' sur XNUMX. Ce paramètre fait référence au nombre maximum d'itérations pour que les solveurs convergent.

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

Évaluer

Il est maintenant temps de voir comment fonctionne notre modèle. Il est temps d'évaluer le modèle de régression logistique. Alors, rappelons-nous que cette fois, la mesure de performance qui nous intéresse est le score de précision, et nous voulons un score précis. Et nous voulons battre la ligne de base de 0.68. La précision du modèle peut être calculée à l'aide de la fonction precision_score. La fonction nécessite deux arguments, les vrais libellés et les libellés prédits.

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

Nous pouvons voir notre précision d'entraînement à 90%. Il bat la ligne de base. La précision de notre test était un peu inférieure à 88 %. Il a également battu la ligne de base et était très proche de la précision de notre entraînement. C'est donc une bonne nouvelle car cela signifie que notre modèle n'est pas trop adapté ou quoi que ce soit.

Résultats du modèle de régression logistique

Rappelez-vous qu'avec la régression logistique, nous nous retrouvons avec ces prédictions finales de zéro ou un. Mais sous cette prédiction, il y a une probabilité d'un nombre à virgule flottante entre zéro et un, et parfois il peut être utile de voir quelles sont ces estimations de probabilité. Regardons nos prédictions d'entraînement, et regardons les cinq premières. La méthode "prédire" prédit la cible d'une observation non étiquetée.

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

C'étaient donc les prédictions finales, mais quelles sont les probabilités derrière elles ? Pour les obtenir, nous devons créer un code légèrement différent. Au lieu d'utiliser la méthode `predict` avec notre modèle, j'utiliserai 'predict_proba' avec nos données d'entraînement.

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

Nous pouvons voir une sorte de liste imbriquée avec deux colonnes différentes. La colonne de gauche représente la probabilité qu'un candidat ne soit pas placé ou notre classe négative "Non placé". L'autre colonne représente la classe positive "Placed" ou la probabilité qu'un candidat soit placé. Nous nous concentrerons sur la deuxième colonne. Si nous regardons la première estimation de probabilité à droite, nous pouvons voir qu'il s'agit de 0.07. Donc, puisque c'est inférieur à 50 %, selon notre modèle, ma prédiction est nulle. Et pour les prédictions suivantes, nous pouvons voir que celles-ci sont toutes supérieures à 0.5, et c'est pourquoi notre modèle en a prédit un au final.

Maintenant, nous voulons extraire les noms et l'importance des fonctionnalités et les placer dans une série. Et parce que nous devons afficher l'importance des caractéristiques sous forme de rapports de cotes, nous devons faire juste une petite transformation mathématique en prenant l'exponentielle de notre importance.

# 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

Avant de discuter des rapports de cotes et de ce qu'ils sont, plaçons-les sur un graphique à barres horizontales. Utilisons des pandas pour faire le tracé, et rappelons-nous que nous chercherons les cinq plus grands coefficients. Et nous ne voulons pas utiliser tous les rapports de cotes. Nous voulons donc utiliser la queue.

# Horizontal bar chart, five largest coefficients
odds_ratios.tail().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("High Importance Features");
# Diagramme à barres horizontales, cinq plus grands coefficients odds_ratios.tail().plot(kind=

Maintenant, je veux que vous imaginiez une ligne verticale juste à 5, et je veux commencer par la regarder. Parlons de chacun d'eux individuellement ou seulement du premier couple. Commençons donc ici par le « ssc_p », qui fait référence au « pourcentage de l'enseignement secondaire – 10e année ». Et nous pouvons voir que l'odds ratio est à 30. Maintenant, qu'est-ce que cela signifie ? Cela signifie que si un candidat a un « ssc_p » élevé, ses chances de placement sont six fois supérieures à celles des autres candidats, toutes choses étant égales par ailleurs. Donc, une autre façon d'y penser est que lorsque le candidat a `ssc_p`, les chances de recrutement du candidat augmentent six fois.

Ainsi, tout rapport de cotes supérieur à cinq augmente les chances que les candidats soient placés. Et c'est pourquoi nous avons cette ligne verticale à cinq. Et ces cinq types de caractéristiques sont les caractéristiques les plus associées à un recrutement accru. Donc, c'est ce que notre rapport de cotes est. Maintenant, nous avons examiné les fonctionnalités les plus associées à une augmentation du recrutement. Regardons les caractéristiques qui y sont associées, la baisse du recrutement. Alors maintenant, il est temps de regarder les plus petits. Ainsi, au lieu de regarder la queue, nous allons la regarder.

odds_ratios.head().plot(kind="barh")
plt.xlabel("Odds Ratio")
plt.xlabel("Odds Ratio")
plt.ylabel("Feature")
plt.title("Low Importance Features");
caractéristique de faible importance

La première chose que nous devons voir ici est que notez que sur l'axe des x, tout est un ou en dessous. Maintenant, qu'est-ce que cela signifie? Jetons donc un coup d'œil à notre plus petit rapport de cotes ici. C'est mba_p qui fait référence au pourcentage MBA. Nous pouvons voir qu'il est prêt à environ 0.45. Maintenant, qu'est-ce que cela signifie? Eh bien, la différence entre 0.45 et 1 est de 0.55. D'accord? Et que signifie ce chiffre ? Les candidats titulaires d'un MBA sont moins susceptibles d'être recrutés de 55 %, toutes choses étant égales par ailleurs. D'accord? Cela a donc réduit les chances de recrutement d'un facteur de 0.55 ou 55 %. Et c'est vrai pour tout ici.

Conclusion

Alors qu'avons-nous appris ? Tout d'abord, dans la phase de préparation des données, nous avons appris que nous travaillions avec la classification, en particulier la classification binaire, en utilisant la régression logistique. En termes d'exploration des données, nous avons fait une tonne de choses, mais en termes de faits saillants, nous avons examiné l'équilibre des classes, n'est-ce pas ? La proportion de nos classes positives et négatives. Ensuite, nous divisons nos données.

Étant donné que la régression logistique est un modèle de classification, nous avons découvert une nouvelle mesure de performance, le score de précision. Maintenant, le score de précision va de 0 à 1. Zéro est mauvais et un est bon. Lors de l'itération, nous avons appris la régression logistique. C'est une manière magique, où vous pouvez prendre une équation linéaire, une ligne droite, et la mettre dans une autre fonction, une fonction sigmoïde et une fonction d'activation, et en tirer une estimation de probabilité et transformer cette estimation de probabilité en prédiction.

Enfin, nous avons appris le rapport de cotes et la façon dont nous pouvons interpréter les coefficients pour voir si une caractéristique donnée augmentera les chances que nous ayons recruté un candidat ou non.

Code source du projet : https://github.com/SawsanYusuf/Campus-Recruitment.git

Les médias présentés dans cet article n'appartiennent pas à Analytics Vidhya et sont utilisés à la discrétion de l'auteur. 

Horodatage:

Plus de Analytique Vidhya