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.
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é
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.
#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')
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')
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.
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)
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)
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.
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.
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