"En 1972-1974, à Whickham, une ville du nord-est de l'Angleterre, située à environ 6,5 kilomètres au sud ouest de Newcastle upon Tyne, un sondage d'un sixième des électeurs a été effectué afin d'éclairer des travaux sur les maladies thyroïdiennes et cardiaques (Tunbridge et al. 1977). Une suite de cette étude a été menée vingt ans plus tard (Vanderpump et al. 1995). Certains des résultats avaient trait au tabagisme et à savoir si les individus étaient toujours en vie lors de la seconde étude. Par simplicité, nous nous restreindrons aux femmes et parmi celles-ci aux 1314 qui ont été catégorisées comme \"fumant actuellement\" ou \"n'ayant jamais fumé\". Il y avait relativement peu de femmes dans le sondage initial ayant fumé mais ayant arrêté depuis (162) et très peu pour lesquelles l'information n'était pas disponible (18). La survie à 20 ans a été déterminée pour l'ensemble des femmes du premier sondage.\n",
"\n",
"L'ensemble de ces données est disponible dans le fichier 'SmokingNotSmokingWomen_InputData.csv'. \n",
"Pour info, sur chaque ligne du fichier 'SmokingNotSmokingWomen_InputData.csv', on trouve (Smoker,Status,Age) :\n",
"si la personne fume ou non, si elle est vivante ou décédée au moment de la seconde étude, et quel était son âge lors du premier sondage."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## I - Chargement des données et controle si leur contenu est valide + extraction de quelques informations générales :"
"\u001b[0;32m<ipython-input-8-b10f7dd111ab>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mOriginalInputData\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mOriginalInputData\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0misnull\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0many\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: name 'OriginalInputData' is not defined"
"On voit que, sur 1314 femmes, il y a 945 specimens du type 'Alive' ; \n",
"donc on peut en déduire qu'il y a 1314-945=369 femmes decedees, qu'elles aient été fumeuses ou non"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## II - Calculons dans chaque groupe (fumeuses, non fumeuses) le taux de mortalité (le rapport entre le nombre de femmes décédées dans un groupe avec le nombre total de femmes dans ce groupe)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# selection des lignes du DataFrame Fumeuse_ou_non en fonction de la valeur 'Yes' dans la colonne descriptive 'Smoker':\n",
"A partir de maintenant, on va prendre en compte une variable qui n'a pas été explicitée jusqu'ici et qui introduit la confusion en influencant le résultat final : il s’agit de l’âge des personnes qui joue lui-aussi sur la mortalité.\n",
"Pour ce faire, on va répéter les opérations précédentes mais en opérant par tranches d'age ; \n",
"on en choisit 4 : [18:34] ; ]34:54] ; ]54:64] ; >64 ans ."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## III - Pour chaque groupe (fumeuses , non fumeuses), le taux de mortalité est maintenant évalué par tranches d'age"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print (\"On reprend l'analyse en opérant dans la 1ere tranche d'age [AgeMin:34] ans :\")"
" 'Mortalité en %': [Fumeuses_TrA4_TxMortalite, NonFumeuses_TrA4_TxMortalite]\n",
" }\n",
"Resume4 = pd.DataFrame(table4, columns=[\"Dans la tranche d'age ]64:89]\", 'Nb_Vivantes','Nb_Mortes','Mortalité en %'])\n",
"print (Resume4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Resumons la partie III à l'aide des tableaux 1 à 4, et à l'aide d'un graphe en barres dont la hauteur reflete des taux de mortalité pour chacun des groupes"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print (Resume1)\n",
"print (Resume2)\n",
"print (Resume3)\n",
"print (Resume4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Construire la série des valeurs pour la hauteur des barres :\n",
"plt.title(\"Taux de mortalité (en %) par tranche d'age\", fontdict=None, loc='center', pad=None, color='orange')\n",
"plt.show()"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"Les tableaux 'ResumeX' et le graphique montrant le taux de mortalité par tranche d'age permet de conclure que le tabac constitue un facteur de mortalité ."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## IV - Prolongement de l'activité avec une regression logistique "
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"Afin d'éviter un biais induit par des regroupements en tranches d'âges arbitraires et non régulières, on peut essayer de réaliser d'autres analyse (par exemple, une régression logistique). \n",
"Le but est d'analyser ''la corrrélation'' entre les 2 variables 'Mortalité' et 'Age' pour étudier la probabilité de décès en fonction de l'âge, et ceci selon que l'on considère le groupe des fumeuses ou des non fumeuses. \n",
"\n",
"Avertissements : \n",
"* la régression logistique porte assez mal son nom , car il ne s’agit pas à proprement parler d’une régression au sens classique du terme (on essaye pas d’expliquer une variable quantitative mais de classer des individus dans deux catégories). \n",
"* par ailleurs, la fonction LogisticRegression de Scikit Learn ne fournit pas les valeurs p-value et les intervalles de confiance pour les coefficients du modele, meme si cela est theoriquement possible de les avoir si la regression est appliquée sans penalisation ; il faut privilégier l'utilisation de la fonction de la librairie \"statsmodels\"."
"taille1Colonne = OriginalInputData['Smoker'].shape[0] # devrait etre egal à 1314\n",
"for i in range(taille1Colonne) :\n",
" if OriginalInputData.loc[i,'Status'] == \"Alive\" : \n",
" Y.loc[i] = 1\n",
" else :\n",
" Y.loc[i] = 0"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Y.head(5) # pour vérifier son contenu converti"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print (\"verif : somme des valeurs dans la colonne Status = \",Y.sum())"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"Avertissement : \n",
"* SciKit-Learn décide par défaut d’appliquer une régularisation sur le modèle. \n",
"* Dans le modèle que l'on va utiliser, on n'applique pas de pénalité et on prend un solver du type Newton qui est le plus classique pour la régression logistique.\n",
"* Pour comprendre les coefficients du modèle, SciKit-Learn stocke les informations dans .coef_, \n",
" il faut les afficher de manière plus agréable dans un DataFrame avec la constante du modèle ; \n",
" mais leur interprétation n'est pas évidente"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### * Appliquons le modele de Regression Logistique de 'scikit learn' sur l'ensemble des 2 groupes Fumeuses et Non Fumeuses :"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Rappel : la variable 'Smoker' represente ici A LA FOIS les fumeuses et non-fumeuses !!\n",
"if Y.sum() == 0 : # on verifie que Y contient plus de 1 classe\n",
" print (\"Probleme : la somme Y.sum() = \",Y.sum(),\" devrait être différente de 0 !\")\n",
" print (\" les valeurs de Y ne composent qu'une seule classe !\")\n",
"else : # La regression logistique peut être effectuée :\n",
"Commençons par rappeler que le même modele de régression logistique (de base mais très classique, sans inclure d'interception avec une constante, issu des librairies \"scikit learn\" d'une part \"statmodels\" d'autre part) a été utilisé pour les 3 types de groupes, en considérant tous ensemble les différents ages (afin de s'affranchir d'un biais induit par des regroupements en tranches d'âges arbitraires et non régulières) ; et que le score reflète la capacité de ce modèle de régression logistique à prédire la mortalité en fonction de l'age.\n",
" \n",
"De façon différente mais cohérente avec l'utilisation du modele de Regression Logistique issu de la librairie \"scikit learn\", les performances dans l'optimization (fit) du modele de Regression Logistique issu de la librairie \"statmodels\" terminée avec succes sont rappelées ci-dessous pour les 2 groupes traités séparemment :\n",
" * Fumeuses : en 7 itérations : valeur de la fonction = 0.412727 , coef de corrl avec Age = -0.0890 , std err = 0.009\n",
" * NonFumeuses : en 3 itérations : valeur de la fonction = 0.687904 , coef de corrl avec Age = -0.1073 , std err = 0.008\n",
"(remarque : les coefficients de corrélation entre les variables 'Age' et 'Status' sont normalement négatifs car ils reflètent le fait de tendances opposées: l'augmentation de l'age est corrélée avec la diminution des chances d'être en vie : pour l'intensité de la corrélation, il faut donc considérer la valeur absolue de ce coefficient). \n",
"\n",
"D'ailleurs, les scores 'TRAINING r_score' (cf la partie V) qui refletent les performances dans l'optimization (fit) du modele de Regression Linéaire confirment les observations et interpretations faites avec les essais de Regression Logistique.\n",
"\n",
"On observe que le score du modèle (autrement dit, la probabilité de décès en fonction de l'âge) pour le groupe des femmes non fumeuses est plus élevé que le score pour le groupe des fumeuses ; \n",
"Ceci s'interprete par le fait que, par-rapport aux femmes non fumeuses, les fumeuses ont une probalité plus grande de mourir en raison d'un autre facteur que l'age ; étant donné que dans cette étude , ne sont pris en compte que 2 facteurs explicatifs de la mortalité: le tabagisme et l'age, ces régressions logistiques permettent de conclure sur la nocivité du tabagisme d'une part. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## V - Prolongement avec un essai de Regression Linéaire séparemment sur les 2 groupes"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Creation d'une fonction qui pourra etre appelée plusieurs fois : \n",
"def buildLinearRegressionModel(X, Y):\n",
" # step_2 = build a LinearRegression model on the subset of TRAINING data , and show its performance-score :\n",
" from sklearn.linear_model import LinearRegression\n",
"Sans donner d'explication sur la mise en oeuvre de cet autre modèle qui est appliqué à l'identique aux 2 groupes de femmes,\n",
"ni sur la qualité toute relative des scores obtenus, \n",
"on retrouve l'observation faite précédemment avec la regression logistique : à savoir, la probabilité de décès en fonction de l'âge pour le groupe des femmes non fumeuses est plus élevée que cette probabilité pour le groupe des fumeuses."