[PYTHON] Prédire la présence ou l'absence d'infidélité par l'apprentissage automatique

introduction

J'ai essayé d'analyser les données à l'aide de python en référence à [[50 000 personnes dans le monde] Practical Python Data Science] d'Udemy (https://www.udemy.com/course/python-jp/) .. Les données utilisées cette fois sont des exemples de données contenues dans une bibliothèque appelée Statsmodels, qui est un article d'une enquête menée en 1974 pour demander s'il y a eu ou non une liaison avec une femme mariée.

Affairs dataset

Le but de ce temps est À l'aide d'échantillons de données, nous créerons un modèle qui prédit la présence ou l'absence d'infidélité par apprentissage automatique et prédirons quels attributs affectent le résultat.

*** Il n'y a pas d'autre intention dans le choix de ces données, et étant donné qu'il est possible que le mensonge dû à l'auto-déclaration soit inclus, nous ne considérons pas la crédibilité des données et les traitons comme des exemples de données jusqu'au dernier. *** ***

environnement: Pyhton3 scikit-learn version 0.21.2 (le cours Udemy et la version scikit-learn sont différents) jupyter notebook+Anaconda

** N'expliquez pas **: Environnement Syntaxe de base pour Python, Pandas, Numpy, matplotlib (d'autres seront expliqués dans les commentaires) Explication des connaissances mathématiques

** Explique **: Retour logistique Variables explicatives et objectives Préparation et visualisation des données Prétraitement des données Construction de modèles à l'aide de scikit-learn Résumé

Qu'est-ce que la régression logistique?

La régression logistique est une analyse de régression dans laquelle la variable objective (les données que vous souhaitez acquérir) converge vers une valeur comprise entre 0 et 1. Plus précisément, la valeur peut être convergée en utilisant la fonction sigmoïde. Il semble que ses caractéristiques soient utilisées pour la prédiction de probabilité et la classification binaire. Cette fois, j'ai utilisé la régression logistique car la présence ou l'absence d'infidélité est classée en deux valeurs, 1 et 0.

Préparation et visualisation des données

#Importation de bibliothèque requise
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import math

#seaborn est une bibliothèque qui permet de tracer des graphiques magnifiquement. Cela semble être populaire.
#set_Changez de style avec style. Cette fois, sélectionnez la grille blanche et sélectionnez avec du grain avec un fond blanc.
#Si c'est gênant.set()Soyez juste à la mode
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid')

#scikit-Importez les modules requis pour apprendre
#cross_la validation ne peut être utilisée qu'avec les anciennes versions
#2.À partir de 0 modèle_utiliser la sélection
from sklearn.linear_model import LogisticRegressin
from sklearn.model_selection import train_test_split

#Module utilisé lors de l'évaluation d'un modèle
from sklearn import metrics

#Importer pour utiliser des exemples de données statsmodels
#Il peut être nécessaire d'installer une installation autre qu'Anaconda
import statsmodels.api as sm

Maintenant que nous sommes prêts, jetons un œil à l'aperçu des données.

#Charger des exemples de données dans Pandas DataFrame
df = sm.datasets.fair.load_pandas().data

#Commençons par un aperçu des données
df.info()
#production
# RangeIndex: 6366 entries, 0 to 6365
# Data columns (total 9 columns):
# rate_marriage      6366 non-null float64
# age                6366 non-null float64
# yrs_married        6366 non-null float64
# children           6366 non-null float64
# religious          6366 non-null float64
# educ               6366 non-null float64
# occupation         6366 non-null float64
# occupation_husb    6366 non-null float64
# affairs            6366 non-null float64
# dtypes: float64(9)
# memory usage: 447.7 KB

#Ensuite, regardons les 5 premières lignes
df.head()
rate_
marriage
age yrs_married children religious educ occupation occupation_husb affairs
3 32 9.0 3 3 17 2 5 0.1111
3 27 13.0 3 1 14 3 4 3.2308
4 22 2.5 0 1 16 3 5 1.4000
4 37 16.5 4 3 16 5 5 0.7273
5 27 9.0 1 1 14 3 4 4.6667

Vous pouvez voir que le nombre de lignes est de 6366, le nombre de colonnes est composé de la variable objective affaires et des variables explicatives totalisant 9, et il n'y a pas de Null. Pour compléter le nom de la colonne

・ Rate_marriage: Auto-évaluation de la vie conjugale ・ Educ: Éducation ・ Enfants: nombre d'enfants ・ Religieux: religieux ・ Profession: Occupation ・ Occupation_husb: profession du mari Cependant, vous pouvez vérifier les détails sur le site Web statsmodels.

*** La variable objective *** fait référence à la variable que vous souhaitez prédire. Dans ce cas, «affaires», qui est une variable de la présence ou de l'absence de liaison, est cela. *** Les variables explicatives *** sont des variables utilisées pour prédire la variable objective. Cette fois, toutes les variables sauf les affaires.

Cette fois, nous devons définir la variable sur binaire parce que nous voulons vérifier l'affaire, mais la variable objective affaires est une valeur réelle continue. C'est parce que le contenu de la question est le moment où les affaires sont terminées. Nous ajoutons donc une nouvelle colonne Had_Affair pour stocker le résultat via une fonction qui convertit les nombres non nuls en 1.

#Eu si les affaires sont non nulles_affairs。
def affair_check(x):
    if x != 0:
        return 1
    else:
        return 0
#L'argument apply applique la fonction à la colonne spécifiée.
df['Had_Affair'] = df['affairs'].apply(affair_check)
#Sortez les 5 premières lignes
df.head()
rate_marriage age yrs_married children religious educ occupation occupation_
husb
affairs Had_Affair
3 32 9.0 3 3 17 2 5 0.1111 1
3 27 13.0 3 1 14 3 4 3.2308 1
4 22 2.5 0 1 16 3 5 1.4000 1
4 37 16.5 4 3 16 5 5 0.7273 1
5 27 9.0 1 1 14 3 4 4.6667 1

J'ai pu l'ajouter. Voyons maintenant les données et découvrons facilement quelles variables explicatives influencent. Regroupez par Had_Affair et calculez la moyenne de chaque colonne.

df.groupby('Had_Affair').mean()
Had_Affair rate_marriage age yrs_married children religious educ occupation occupation_husb affairs
0 4.330 28.39 7.989 1.239 2.505 14.32 3.405 3.834 0.000
1 3.647 30.54 11.152 1.729 2.262 13.97 3.464 3.885 2.187

Vous pouvez voir que la colonne avec "Had_Affair" dans la deuxième ligne a un long mariage et une faible auto-évaluation du mariage. Maintenant, visualisons la relation avec la durée du mariage avec un histogramme utilisant seaborn (comme un matplotlib à la mode).

#Agréger et visualiser les données à l'aide de la méthode countplot de seaborn, les arguments sont l'axe X, le DF cible, le nom de la colonne est Had_Classification binaire avec Affair, spécification de couleur
sns.countplot('yrs_married',data=df.sort_values('yrs_married'),hue='Had_Affair',palette='coolwarm')

ダウンロード (1).png

Il semble y avoir une relation entre le mariage et la présence ou l'absence de liaison. Ensuite, visualisons la durée du mariage et le taux de liaison.

#L'axe y du barplot génère la moyenne. Eu_Comme Affair est une valeur de 1 et 0, le rapport de 1 est calculé en calculant la moyenne.
sns.barplot(data=df, x='yrs_married', y='Had_Affair')

ダウンロード (3).png

Si la vie conjugale dépasse 9 ans, le taux d'avoir une liaison dépassera 40%. Il semble que vous puissiez faire des prédictions en regardant à l'avance d'autres données, mais nous passerons à l'étape suivante dans ce domaine.

Prétraitement des données

Maintenant que la visualisation est terminée, nous allons prétraiter les données. Plus précisément, afin de s'adapter au modèle d'apprentissage automatique, la variable explicative et la variable objectif sont séparées, les valeurs des données sont alignées et les valeurs manquantes sont traitées.

Maintenant, alignons les valeurs des données. Les chaînes de données «occupation» et «occupation_husb» qui indiquent les professions reçoivent des numéros uniquement pour des raisons de commodité afin de les catégoriser, de sorte que la taille des nombres n'a pas de sens. Il n'y a pas de redevances dans la profession.

Par conséquent, créez une nouvelle colonne pour les données catégorielles des professions par profession. Si l'enregistrement est applicable, les données sont organisées en les divisant en 2 valeurs, 1 sinon. C'est une tâche fastidieuse, mais c'est instantané avec la fonction de génération de variable factice de Pandas.

Puis, puisque la colonne profession n'est plus nécessaire, supprimez-la, affectez la variable objectif à Y, affectez la variable explicative à X et supprimez affaires, qui sont les données d'origine de la variable objectif.

Lors de la sortie, il s'agit d'une table, mais comme il y a trop de colonnes et qu'il est difficile de voir avec Qiita, elle est divisée en deux.

#Utilisez une fonction qui crée des variables factices pour les pandas. scikit-Il semble que ce soit aussi en apprentissage.
occ_dummies = pd.get_dummies(df['occupation'])
hus_occ_dummies = pd.get_dummies(df['occupation_husb'])

#Nommez le nom de la catégorie. Il est en fait plus facile de voir en utilisant le nom de colonne des données d'origine, mais j'ai abandonné parce que c'était gênant.
occ_dummies.columns = ['occ1','occ2','occ3','occ4','occ5','occ6']
hus_occ_dummies.columns = ['hocc1','hocc2','hocc3','hocc4','hocc5','hocc6']

#La colonne d'occurrence inutile et la variable objective «Had»_Supprimer "Affaire". Affaires aussi.
#Pour l'axe, 0 spécifie la ligne et 1 spécifie la colonne.
#drop méthode prend place en argument=Si vous n'entrez pas True, il ne sera pas supprimé du DataFrame d'origine.
X = df.drop(['occupation','occupation_husb','Had_Affair','affairs'],axis=1)

#Combinez les variables fictives dans le DataFrame de la variable explicative X.
dummies = pd.concat([occ_dummies,hus_occ_dummies],axis=1)
X = pd.concat([X,dummies],axis=1)

#Affectez la variable objectif à Y
Y = df.Had_Affair

#production
X.head()
rate_marriage age yrs_married children religious educ
3 32 9.0 3 3 17
3 27 13.0 3 1 14
4 22 2.5 0 1 16
4 37 16.5 4 3 16
5 27 9.0 1 1 14
occ1 occ2 occ3 occ4 occ5 occ6 hocc1 hocc2 hocc3 hocc4 hocc5 hocc6
0 1 0 0 0 0 0 0 0 0 1 0
0 0 1 0 0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0 0 0 1 0
0 0 1 0 0 0 0 0 0 1 0 0

Il semble que l'analyse ne soit pas possible s'il existe une forte corrélation entre les variables indépendantes. Je l'appelle ** colinéarité multiple **, mais je ne pouvais pas comprendre les détails même si je les ai recherchés sur Google, alors je vais l'examiner tout en étudiant les statistiques du mois prochain.

Pour le moment, celle qui présente une forte corrélation dans ces données est la colonne profession utilisant des variables fictives, il semble donc qu'elle puisse être traitée en supprimant une à une.

#Je peux gérer ça pour le moment
X = X.drop('occ1',axis=1)
X = X.drop('hocc1',axis=1)

Puisque la variable objectif Y est Series, changez-la en array, qui est un tableau principal, afin de s'adapter au modèle. Ceci termine le prétraitement des données.


type(Y)
Y = np.ravel(Y)

Construction de modèles à l'aide de scikit-learn

Créez un modèle de régression logistique à l'aide de scikit-learn.

#Créez une instance de la classe LogisticRegression.
log_model = LogisticRegression() 
#Créez un modèle en utilisant les données.
log_model.fit(X,Y)
#Vérifions l'exactitude du modèle.
log_model.score(X,Y)
#production
#0.7260446120012567

La précision de ce modèle est d'environ 73%. Est-ce raisonnable car cela entraîne le modèle et les paramètres sont les valeurs par défaut? Maintenant, affichons le coefficient de régression et explorons "Quelle variable contribue à la prédiction?"

#Créez un DataFrame pour stocker le nom de la variable et son coefficient.
#coef_Affiche le coefficient de régression.
coeff_df = DataFrame([X.columns, log_model.coef_[0]]).T
coeff_df
0 1
rate_marriage -0.72992
age -0.05343
yrs_married 0.10210
children 0.01495
religious -0.37498
educ 0.02590
occ2 0.27846
occ3 0.58384
occ4 0.35833
occ5 0.99972
occ6 0.31673
hocc2 0.48310
hocc3 0.65189
hocc4 0.42345
hocc5 0.44224
hocc6 0.39460

Vous pouvez voir le coefficient de régression lors de la création du modèle pour les variables explicatives. Si le coefficient de régression est positif, plus la valeur de cette variable est élevée, plus le risque d'infidélité est grand. S'il est négatif, c'est le contraire qui est vrai. D'après ce tableau, il semble que la possibilité d'infidélité diminue à mesure que l'auto-évaluation de la vie conjugale et la vision de la religion augmentent, et que la possibilité d'infidélité augmente à mesure que le nombre d'années après le mariage augmente. Il est également affiché par profession, mais comme la valeur de 1 est supprimée lors de la prise de mesures contre la colinéarité multiple, il semble préférable de la considérer comme un niveau de référence (au fait, il semble que ce soit une valeur assez élevée d'occ5. Puisque le métier est managérial, il peut s'agir d'une valeur intuitivement convaincante)

Résumé

Si vous souhaitez améliorer la précision, vous pouvez effectuer une normalisation et des essais et erreurs des paramètres. Cependant, compte tenu de la crédibilité des données, j'ai pensé qu'il serait plus apprenant d'analyser la relation aux résultats par attributs en examinant les coefficients de régression utilisés dans le modèle.

De côté

Publier la sortie du tableau par DataFrame sur Qiita a été très difficile et a pris environ 5 heures.

Au début, j'ai essayé de le convertir en table matplotlib et de le publier sous forme d'image, mais j'ai abandonné car les caractères d'index sont devenus petits et je ne savais pas comment le réparer. Ensuite, j'ai essayé d'utiliser une bibliothèque appelée pytablewriter qui convertit DataFrame en Markdown, mais comme ce n'est pas une bibliothèque distribuée par Anaconda, je n'ai pas eu d'autre choix que de l'installer avec PIP. L'erreur «impossible d'importer le nom» se produit dans la bibliothèque importée, vérifiez-la.

Si vous installez PIP dans l'environnement Anaconda, les bibliothèques peuvent entrer en collision et cela peut être gênant.

Oh! Je suis surpris! Si vous y réfléchissez, les versions de bibliothèques dépendantes peuvent être différentes pour Anaconda et PIP, ce qui risque de causer des problèmes. Je m'en fichais jusqu'à présent, alors quand je l'ai vérifié sur la liste Conda, il y avait d'innombrables Pypi, donc je ne l'ai pas vu. Je me demandais s'il y aurait des problèmes avec d'autres langues, comme le NPM et le fil, et quand j'ai demandé à l'ingénieur de mon ami, il a dit: "La bibliothèque est enregistrée au même endroit!", La vérité est donc dans le noir. La contre-mesure consiste donc à créer un autre environnement Anaconda ou à créer un autre environnement qui n'installe que PIP, mais je sélectionne ce dernier et installe la bibliothèque avec PIP à partir de zéro, mais installe Statsmodels avec PIP Dans certains cas, une erreur se produit (c'est plus facile avec Anaconda), et si quelque chose ne va pas, c'est résolu.

*** Je respecte les affiches qui créent rapidement des tableaux avec Markdown. Je voudrais savoir s'il y a un moyen. *** ***

Recommended Posts

Prédire la présence ou l'absence d'infidélité par l'apprentissage automatique
J'ai essayé de prédire la présence ou l'absence de neige par apprentissage automatique.
Prédire le sexe des utilisateurs de Twitter grâce à l'apprentissage automatique
Confirmé la différence de présence ou d'absence de traitement aléatoire lors de l'apprentissage par mini-lots avec chainer
Essayez de prédire le triplet de la course de bateaux en classant l'apprentissage
Mémo d'apprentissage Python pour l'apprentissage automatique par Chainer jusqu'à la fin du chapitre 2
Déterminez l'authenticité des articles publiés par machine learning (API Google Prediction).
Classification des images de guitare par apprentissage automatique Partie 1
À propos du contenu de développement de l'apprentissage automatique (exemple)
Analyse de l'utilisation de l'espace partagé par l'apprentissage automatique
[Français] scikit-learn 0.18 Introduction de l'apprentissage automatique par le didacticiel scikit-learn
Estimation raisonnable du prix de Mercari par apprentissage automatique
Classification des images de guitare par apprentissage automatique, partie 2
Essayez de prédire la valeur de la jauge de niveau d'eau par apprentissage automatique en utilisant les données ouvertes de Data City Sabae
Comment la référence du tableau python change en fonction de la présence ou de l'absence d'indices
Prédire les travaux de courte durée de Weekly Shonen Jump par apprentissage automatique (Partie 2: Apprentissage et évaluation)
J'ai essayé de prédire l'évolution de la quantité de neige pendant 2 ans par apprentissage automatique
Mise en place d'un modèle de prédiction des taux de change (taux dollar-yen) par machine learning
Prédire les travaux de courte durée de Weekly Shonen Jump par apprentissage automatique (Partie 1: Analyse des données)
Impressions d'avoir obtenu le nano-diplôme Udacity Machine Learning Engineer
À propos des tests dans la mise en œuvre de modèles d'apprentissage automatique
Résumé du flux de base de l'apprentissage automatique avec Python
Bilan du premier défi du machine learning avec Keras
rsync Le comportement change en fonction de la présence ou de l'absence de la barre oblique de la source de copie
Essayez d'évaluer les performances du modèle d'apprentissage automatique / de régression
Bases de l'apprentissage automatique (mémoire)
Le résultat de l'apprentissage automatique des ingénieurs Java avec Python www
Enquête sur l'utilisation du machine learning dans les services réels
Une méthode concrète pour prédire les courses de chevaux et simuler le taux de récupération par apprentissage automatique
Un exemple de mécanisme qui renvoie une prédiction par HTTP à partir du résultat de l'apprentissage automatique
Essayez d'évaluer les performances du modèle d'apprentissage automatique / de classification
Juger la victoire ou la défaite de Shadova par reconnaissance d'image
J'ai essayé de vérifier la classification yin et yang des membres hololive par apprentissage automatique
Comment augmenter le nombre d'images de jeux de données d'apprentissage automatique
[Apprentissage automatique] J'ai essayé de résumer la théorie d'Adaboost
Importance des ensembles de données d'apprentissage automatique
4 [/] Quatre arithmétiques par apprentissage automatique
Une histoire coincée avec l'installation de la bibliothèque de machine learning JAX
[Apprentissage automatique] Vérifiez les performances du classificateur à l'aide de données de caractères manuscrites
Effectuer une analyse morphologique dans l'environnement d'apprentissage automatique lancé par GCE
Comment utiliser l'apprentissage automatique pour le travail? 01_ Comprendre l'objectif de l'apprentissage automatique
Mémorandum of scraping & machine learning [technique de développement] par Python (chapitre 4)
Mémorandum of scraping & machine learning [technique de développement] par Python (chapitre 5)
Évaluer la précision du modèle d'apprentissage par test croisé de scikit learn
Résumé de l'apprentissage automatique par les débutants de Python
Apprentissage automatique ③ Résumé de l'arbre de décision
J'ai essayé d'appeler l'API de prédiction du modèle d'apprentissage automatique de WordPress
Prédiction des données en un clic pour le champ réalisée par apprentissage automatique entièrement automatique
Mémo d'apprentissage Python pour l'apprentissage automatique par Chainer Chapitre 13 Bases du réseau neuronal
Procédure d'apprentissage automatique de base: ③ Comparez et examinez la méthode de sélection de la quantité de caractéristiques
J'ai essayé l'histoire courante de l'utilisation du Deep Learning pour prédire la moyenne Nikkei
Algorithme d'apprentissage automatique (généralisation de la régression linéaire)
Prédire la demande de puissance avec l'apprentissage automatique, partie 2
Faire le contrôle d'un homme sandwich par l'apprentissage automatique ver4
[Mémo d'apprentissage] Bases de la classe par python
Enregistrez les étapes pour comprendre l'apprentissage automatique
Notes d'apprentissage depuis le début de Python 1
20 sélections recommandées en 2020 de livres d'introduction à l'apprentissage automatique
[Échec] Trouvez Maki Horikita par apprentissage automatique