<filename>pygraal_livrable_1_dataviz.py
# -*- coding: utf-8 -*-
"""PyGraal_Livrable_1_DATAVIZ.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1VOdSSm0I_kGabrDsl7aFbr2HO6UOupVa

# Analyse des techniques et outils utilisés par les professionnels de la Data

Cette analyse repose sur un sondage contenant 20 036 réponses obtenues auprès de participants provenants de 171 pays différents.

Les participants ont dû répondre à une série d'une trentaine de questions.
Quelques unes sont d'ordre personnel (Age, genre...) ou bien en rapport avec leur poste et entreprise actuels.
Cepndant, l'essentiel concerne avant tout les outils utilisés dans le domaine de la Data Science (Langage de programmation, bibliothèque de Datavisualisaton...) ainsi que le rapport à l'utilisation de Machine Learning.

Ce sondage comprend à la fois des questions à choix unique et également à choix multiple.

A noter également que certaines questions étaient accessibles en fonction de réponses précédentes.

A partir de ce sondage, nous souhaitons établir des ensembles de compétences et outils correspondant aux divers postes monde de la Data, afin de construire dans un second temps un système de recommandation de poste permettant au demandeur de viser exactement le poste correspondant le plus à ses appétences.

# ANALYSE EXPLORATOIRE
"""

# Commented out IPython magic to ensure Python compatibility.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# %matplotlib inline
import seaborn as sns
sns.set_theme()

from google.colab import drive
drive.mount('/content/drive')

import warnings
warnings.filterwarnings ('ignore')

data = pd.read_csv('/content/drive/MyDrive/Data/kaggle_survey_2020_responses.csv')

df = data.copy()

print (df.shape)
df.head()

"""La visualisation du DataFrame nous permet de constater que pour les questions à choix multiples, chaque choix est une colonne avec deux valeurs possibles (Nan ou Valeur).

Ainsi nous pourrons traiter par la suite distinctement les questions à choix unique et les questions à choix multiple.

De plus, nous constatons que les différents postes en Data Science se trouve dans la colonne Q5.

Q5 correspond donc à notre variable cible pour la suite de l'étude.
"""

df.dtypes.value_counts()

"""# Il n'y a que des valeurs catégorielles, un encodage sera nécessaire pour la création d'un modèle de Machine Learning.

## Analyse et Nettoyage des Doublons et Valeurs Manquantes
"""

#Visualisation/Suppression des doublons
print("Il y a",df.duplicated().sum(), 'doublons.')
#14 doublons
df = df.drop_duplicates()

#La première colonne (temps de réponse au questionnaire) n'est pas pertinente pour l'étude.
df.drop(['Time from Start to Finish (seconds)'], axis=1, inplace=True)

#Recherche des Nans dans la variable cible
print("Il y a",df['Q5'].isna().sum(),"valeurs manquantes sur cette valeur.")

#Suppression des Nans sur cette valeur
df.dropna(subset=['Q5'], inplace=True)

#Vérif modification du nbre de lignes 20037 - 14 -745
print (df.shape)
df.head()

"""La première ligne du DataFrame n'est pas une entrée mais correspond à l'intitulé des différentes questions.
Cette entrée n'est donc pas à exploiter dans le DataFrame, mais elle reste intéressante pour la compréhension du jeu de données.
"""

#Création d'une base de données Questions à partir de la 1ère ligne de df
Questions = df.iloc[0:1,:].transpose()
Questions = Questions.set_axis(['Questions'], axis=1, inplace=False)
Questions



#Suppression de la première ligne:
df.drop(0,axis=0,inplace=True)

#Vérif modification du nbre de lignes 19278 - 1
print (df.shape)
df.head()

#Analyse des NaNs par % par colonne:
(df.isna().sum() / df.shape[0]).sort_values(ascending=False)

"""Cela nous permet de constater des taux conséquents de NaNs.

Toutefois, pour rappel, certaines questions sont à choix multiples, par conséquent le phénomène s'explique en partie et pour ce type précis de questions les Nans seront à interpréter mais surtout pas à supprimer ou à remplacer par un mode.

Il paraît donc nécessaire de distinguer les questions à choix mutliple des questions à choix unique.

Un moyen simple de les distinguer est de s'appuyer sur le nombre de valeurs contenues dans chaque colonne.
Les choix multiples ont été éclatés en colonne, contenant ainsi soit le choix retenu, soit une valeur manquante.

Par conséquent les questions à choix multiples ne contiennent que deux valeurs.

## Traitement des questions à choix unique
"""

#Récupération des valeurs uniques pour chaque col
def col_u(df):
    for i in df:
        print(f'{i :-<20} {df[i].unique()}')
col_u(df)

#Recherche des colonnes avec + de 2 valeurs
#quest_u regroupe les colonnes des questions choix unique
#quest_u regroupe les colonnes des questions choix multiple
quest_u =[]
quest_m =[]
for i in df:
  if len(df[i].unique())>2:
    quest_u.append(i)
  else:
    quest_m.append(i)
print("Liste des questions à choix unique\n", quest_u)
print("\n\n")
print("Liste des questions à choix multiple\n", quest_m)

"""Nous pouvons à présent observer la présence ou non de valeurs manquantes sur les colonnes de questions à choix unique."""

(df[['Q1', 'Q2', 'Q3', 'Q4', 'Q5', 'Q6', 'Q8', 'Q11', 'Q13', 'Q15', 'Q20', 'Q21', 'Q22', 'Q24', 'Q25', 'Q30', 'Q32', 'Q38']].isna().sum() / df.shape[0]).sort_values(ascending=False)

"""Nous remplaçons les valeurs manquantes par le mode de chaque colonne."""

quest_u =[]
for i in df:
    if len(df[i].unique())>2:
        quest_u.append(i)
print(quest_u)

#Remplacement des Nans des colonnes choix unique par le mode des colonnes
for col in quest_u:
  df[col].fillna(df[col].mode()[0], inplace=True)

df[quest_u].isna().sum()

"""## Traitement des questions à choix multiples

Les questions à choix multiples sont plus difficiles à interpréter de par la manière dont elles ont été intégrées dans la base de données. Pour chaque question, un nombre de colonnes équivalent au nombre de réponses proposées a été créé. Pour chaque réponse, chaque colonne est remplie de la valeur de la réponse si le répondant a sélectionné ce choix et de Nan sinon. Il ne faut pas supprimer les valeurs manquantes sur ces colonnes car elles ont une utilité de compréhension.

Afin de pouvoir les utiliser et les analyser ultérieurement, il est cependant nécessaire de les encoder de manière binaire : 1 en cas de réponse positive, 0 si la valeur est manquante.

Dans un souci de flexibilité et de lisibilité, les différentes questions à choix multiples seront regroupées au sein de mini dataframes contenant en colonnes chacune des options proposées pour répondre à la question.
"""

#création de sub dataframes répliquant les intervalles créés pour les questions
#dfQ7 à dfQ35B contiennent toutes les questions à multiples réponses

dfQ7=df.iloc[:,6:19]       #correspond aux réponses de la question 7, ie Q7
dfQ9=df.iloc[:,20:32]      #Q9
dfQ10=df.iloc[:,32:46]     #Q10
dfQ12=df.iloc[:,47:51]     #Q12
dfQ14=df.iloc[:,52:64]     #Q14
dfQ16=df.iloc[:,65:81]     #Q16
dfQ17=df.iloc[:,81:93]     #Q17
dfQ18=df.iloc[:,93:100]    #Q18
dfQ19=df.iloc[:,100:106]   #Q19
dfQ23=df.iloc[:,109:117]   #Q23
dfQ26A=df.iloc[:,119:131]  #Q26A
dfQ27A=df.iloc[:,131:143]  #Q27A
dfQ28A=df.iloc[:,143:154]  #Q28A
dfQ29A=df.iloc[:,154:172]  #Q29A
dfQ31A=df.iloc[:,173:188]  #Q31A
dfQ33A=df.iloc[:,189:197]  #Q33A
dfQ34A=df.iloc[:,197:209]  #Q34A
dfQ35A=df.iloc[:,209:220]  #Q35A
dfQ36=df.iloc[:,220:230]   #Q36
dfQ37=df.iloc[:,230:242]   #Q37
dfQ39=df.iloc[:,243:255]   #Q39
dfQ26B=df.iloc[:,255:267]  #Q26B
dfQ27B=df.iloc[:,267:279]  #Q27B
dfQ28B=df.iloc[:,279:290]  #Q28B
dfQ29B=df.iloc[:,290:308]  #Q29B
dfQ31B=df.iloc[:,308:323]  #Q31B
dfQ33B=df.iloc[:,323:331]  #Q33B
dfQ34B=df.iloc[:,331:343]  #Q34B
dfQ35B=df.iloc[:,343:354]  #Q35B

"""Une vérification rapide nous montre que dfQ7 intègre toutes les informations relatives à la question 7."""

dfQ35B.head().transpose()

"""Toutefois le libellé des colonnes est peu parlant. Nous allons donc les renommer en utilisant chaque choix comme nouveau titre.
L'encodage se fera ensuite à partir du nouveau titre. Ce procédé permet aussi de supprimer tout risque de labélisation incorrecte, vu qu'il est très difficile de répérer à l'oeil nu le nombre d'espaces présents dans des cellules textes. 
"""

# les codes ci-dessous ont été dupliqués autant de fois que nécessaire

labels_dfQ7=[]
new_labels_dfQ7=[]

for i in dfQ7:
        labels_dfQ7.append(dfQ7[i].value_counts().index[0])

dfQ7 = dfQ7.set_axis(labels_dfQ7, axis=1, inplace=False)

for code in labels_dfQ7:
        dfQ7[code] = dfQ7[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ7.append('Q7:'+code)

dfQ7 = dfQ7.set_axis(new_labels_dfQ7, axis=1, inplace=False)

labels_dfQ9=[]
new_labels_dfQ9=[]

for i in dfQ9:
        labels_dfQ9.append(dfQ9[i].value_counts().index[0])

dfQ9 = dfQ9.set_axis(labels_dfQ9, axis=1, inplace=False)

for code in labels_dfQ9:
        dfQ9[code] = dfQ9[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ9.append('Q9:'+code)

dfQ9 = dfQ9.set_axis(new_labels_dfQ9, axis=1, inplace=False)

labels_dfQ10=[]
new_labels_dfQ10=[]

for i in dfQ10:
        labels_dfQ10.append(dfQ10[i].value_counts().index[0])

dfQ10 = dfQ10.set_axis(labels_dfQ10, axis=1, inplace=False)

for code in labels_dfQ10:
        dfQ10[code] = dfQ10[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ10.append('Q10:'+code)

dfQ10 = dfQ10.set_axis(new_labels_dfQ10, axis=1, inplace=False)

labels_dfQ12=[]
new_labels_dfQ12=[]

for i in dfQ12:
        labels_dfQ12.append(dfQ12[i].value_counts().index[0])


dfQ12 = dfQ12.set_axis(labels_dfQ12, axis=1, inplace=False)

for code in labels_dfQ12:
        dfQ12[code] = dfQ12[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ12.append('Q12:'+code)

dfQ12 = dfQ12.set_axis(new_labels_dfQ12, axis=1, inplace=False)

labels_dfQ14=[]
new_labels_dfQ14=[]

for i in dfQ14:
        labels_dfQ14.append(dfQ14[i].value_counts().index[0])


dfQ14 = dfQ14.set_axis(labels_dfQ14, axis=1, inplace=False)

for code in labels_dfQ14:
        dfQ14[code] = dfQ14[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ14.append('Q14:'+code)

dfQ14 = dfQ14.set_axis(new_labels_dfQ14, axis=1, inplace=False)

labels_dfQ16=[]
new_labels_dfQ16=[]

for i in dfQ16:
        labels_dfQ16.append(dfQ16[i].value_counts().index[0])


dfQ16 = dfQ16.set_axis(labels_dfQ16, axis=1, inplace=False)

for code in labels_dfQ16:
        dfQ16[code] = dfQ16[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ16.append('Q16:'+code)

dfQ16 = dfQ16.set_axis(new_labels_dfQ16, axis=1, inplace=False)

labels_dfQ17=[]
new_labels_dfQ17=[]

for i in dfQ17:
        labels_dfQ17.append(dfQ17[i].value_counts().index[0])

dfQ17 = dfQ17.set_axis(labels_dfQ17, axis=1, inplace=False)

for code in labels_dfQ17:
        dfQ17[code] = dfQ17[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ17.append('Q17:'+code)

dfQ17 = dfQ17.set_axis(new_labels_dfQ17, axis=1, inplace=False)

labels_dfQ18=[]
new_labels_dfQ18=[]

for i in dfQ18:
        labels_dfQ18.append(dfQ18[i].value_counts().index[0])

dfQ18 = dfQ18.set_axis(labels_dfQ18, axis=1, inplace=False)

for code in labels_dfQ18:
        dfQ18[code] = dfQ18[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ18.append('Q18:'+code)

dfQ18 = dfQ18.set_axis(new_labels_dfQ18, axis=1, inplace=False)

labels_dfQ19=[]
new_labels_dfQ19=[]

for i in dfQ19:
        labels_dfQ19.append(dfQ19[i].value_counts().index[0])

dfQ19 = dfQ19.set_axis(labels_dfQ19, axis=1, inplace=False)

for code in labels_dfQ19:
        dfQ19[code] = dfQ19[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ19.append('Q19:'+code)

dfQ19 = dfQ19.set_axis(new_labels_dfQ19, axis=1, inplace=False)

labels_dfQ23=[]
new_labels_dfQ23=[]

for i in dfQ23:
        labels_dfQ23.append(dfQ23[i].value_counts().index[0])

dfQ23 = dfQ23.set_axis(labels_dfQ23, axis=1, inplace=False)

for code in labels_dfQ23:
        dfQ23[code] = dfQ23[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ23.append('Q23:'+code)

dfQ23 = dfQ23.set_axis(new_labels_dfQ23, axis=1, inplace=False)

labels_dfQ26A=[]
new_labels_dfQ26A=[]

for i in dfQ26A:
        labels_dfQ26A.append(dfQ26A[i].value_counts().index[0])

dfQ26A = dfQ26A.set_axis(labels_dfQ26A, axis=1, inplace=False)

for code in labels_dfQ26A:
        dfQ26A[code] = dfQ26A[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ26A.append('Q26A:'+code)

dfQ26A = dfQ26A.set_axis(new_labels_dfQ26A, axis=1, inplace=False)

labels_dfQ27A=[]
new_labels_dfQ27A=[]

for i in dfQ27A:
        labels_dfQ27A.append(dfQ27A[i].value_counts().index[0])
        
dfQ27A = dfQ27A.set_axis(labels_dfQ27A, axis=1, inplace=False)

for code in labels_dfQ27A:
        dfQ27A[code] = dfQ27A[code].replace(to_replace = [np.nan,code],value= [0,1])

labels_dfQ27A[10]='None'
dfQ27A = dfQ27A.set_axis(labels_dfQ27A, axis=1, inplace=False)

for code in labels_dfQ27A:
        new_labels_dfQ27A.append('Q27A:'+code)

dfQ27A = dfQ27A.set_axis(new_labels_dfQ27A, axis=1, inplace=False)

labels_dfQ28A=[]
new_labels_dfQ28A=[]

for i in dfQ28A:
        labels_dfQ28A.append(dfQ28A[i].value_counts().index[0])

dfQ28A = dfQ28A.set_axis(labels_dfQ28A, axis=1, inplace=False)

for code in labels_dfQ28A:
        dfQ28A[code] = dfQ28A[code].replace(to_replace = [np.nan,code],value= [0,1])

labels_dfQ28A[9]='None'
dfQ28A = dfQ28A.set_axis(labels_dfQ28A, axis=1, inplace=False)

for code in labels_dfQ28A:
        new_labels_dfQ28A.append('Q28A:'+code)

dfQ28A = dfQ28A.set_axis(new_labels_dfQ28A, axis=1, inplace=False)

labels_dfQ29A=[]
new_labels_dfQ29A=[]

for i in dfQ29A:
        labels_dfQ29A.append(dfQ29A[i].value_counts().index[0])

dfQ29A = dfQ29A.set_axis(labels_dfQ29A, axis=1, inplace=False)

for code in labels_dfQ29A:
        dfQ29A[code] = dfQ29A[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ29A.append('Q29A:'+code)

dfQ29A = dfQ29A.set_axis(new_labels_dfQ29A, axis=1, inplace=False)

labels_dfQ31A=[]
new_labels_dfQ31A=[]

for i in dfQ31A:
        labels_dfQ31A.append(dfQ31A[i].value_counts().index[0])

dfQ31A = dfQ31A.set_axis(labels_dfQ31A, axis=1, inplace=False)

for code in labels_dfQ31A:
        dfQ31A[code] = dfQ31A[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ31A.append('Q31A:'+code)

dfQ31A = dfQ31A.set_axis(new_labels_dfQ31A, axis=1, inplace=False)

labels_dfQ33A=[]
new_labels_dfQ33A=[]

for i in dfQ33A:
        labels_dfQ33A.append(dfQ33A[i].value_counts().index[0])

dfQ33A = dfQ33A.set_axis(labels_dfQ33A, axis=1, inplace=False)

for code in labels_dfQ33A:
        dfQ33A[code] = dfQ33A[code].replace(to_replace = [np.nan,code],value= [0,1])
        
labels_dfQ33A[6]='None'
dfQ33A = dfQ33A.set_axis(labels_dfQ33A, axis=1, inplace=False)             

for code in labels_dfQ33A:
        new_labels_dfQ33A.append('Q33A:'+code)

dfQ33A = dfQ33A.set_axis(new_labels_dfQ33A, axis=1, inplace=False)

labels_dfQ34A=[]
new_labels_dfQ34A=[]

for i in dfQ34A:
        labels_dfQ34A.append(dfQ34A[i].value_counts().index[0])

dfQ34A = dfQ34A.set_axis(labels_dfQ34A, axis=1, inplace=False)

for code in labels_dfQ34A:
        dfQ34A[code] = dfQ34A[code].replace(to_replace = [np.nan,code],value= [0,1])
        
labels_dfQ34A[10]='None'
dfQ34A = dfQ34A.set_axis(labels_dfQ34A, axis=1, inplace=False)          
        
for code in labels_dfQ34A:
        new_labels_dfQ34A.append('Q34A:'+code)

dfQ34A = dfQ34A.set_axis(new_labels_dfQ34A, axis=1, inplace=False)

labels_dfQ35A=[]
new_labels_dfQ35A=[]

for i in dfQ35A:
        labels_dfQ35A.append(dfQ35A[i].value_counts().index[0])

dfQ35A = dfQ35A.set_axis(labels_dfQ35A, axis=1, inplace=False)

for code in labels_dfQ35A:
        dfQ35A[code] = dfQ35A[code].replace(to_replace = [np.nan,code],value= [0,1])
        
labels_dfQ35A[9]='None'
dfQ35A = dfQ35A.set_axis(labels_dfQ35A, axis=1, inplace=False)    
        
for code in labels_dfQ35A:
        new_labels_dfQ35A.append('Q35A:'+code)

dfQ35A = dfQ35A.set_axis(new_labels_dfQ35A, axis=1, inplace=False)

labels_dfQ36=[]
new_labels_dfQ36=[]

for i in dfQ36:
        labels_dfQ36.append(dfQ36[i].value_counts().index[0])

dfQ36 = dfQ36.set_axis(labels_dfQ36, axis=1, inplace=False)

for code in labels_dfQ36:
        dfQ36[code] = dfQ36[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ36.append('Q36:'+code)

dfQ36 = dfQ36.set_axis(new_labels_dfQ36, axis=1, inplace=False)

labels_dfQ37=[]
new_labels_dfQ37=[]

for i in dfQ37:
        labels_dfQ37.append(dfQ37[i].value_counts().index[0])

dfQ37 = dfQ37.set_axis(labels_dfQ37, axis=1, inplace=False)

for code in labels_dfQ37:
        dfQ37[code] = dfQ37[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ37.append('Q37:'+code)

dfQ37 = dfQ37.set_axis(new_labels_dfQ37, axis=1, inplace=False)

labels_dfQ39=[]
new_labels_dfQ39=[]

for i in dfQ39:
        labels_dfQ39.append(dfQ39[i].value_counts().index[0])

dfQ39 = dfQ39.set_axis(labels_dfQ39, axis=1, inplace=False)

for code in labels_dfQ39:
        dfQ39[code] = dfQ39[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ39.append('Q39:'+code)

dfQ39 = dfQ39.set_axis(new_labels_dfQ39, axis=1, inplace=False)

labels_dfQ26B=[]
new_labels_dfQ26B=[]

for i in dfQ26B:
        labels_dfQ26B.append(dfQ26B[i].value_counts().index[0])

dfQ26B = dfQ26B.set_axis(labels_dfQ26B, axis=1, inplace=False)

for code in labels_dfQ26B:
        dfQ26B[code] = dfQ26B[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ26B.append('Q26B:'+code)

dfQ26B = dfQ26B.set_axis(new_labels_dfQ26B, axis=1, inplace=False)

labels_dfQ27B=[]
new_labels_dfQ27B=[]

for i in dfQ27B:
        labels_dfQ27B.append(dfQ27B[i].value_counts().index[0])

dfQ27B = dfQ27B.set_axis(labels_dfQ27B, axis=1, inplace=False)

for code in labels_dfQ27B:
        dfQ27B[code] = dfQ27B[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ27B.append('Q27B:'+code)

dfQ27B = dfQ27B.set_axis(new_labels_dfQ27B, axis=1, inplace=False)

labels_dfQ28B=[]
new_labels_dfQ28B=[]

for i in dfQ28B:
        labels_dfQ28B.append(dfQ28B[i].value_counts().index[0])

dfQ28B = dfQ28B.set_axis(labels_dfQ28B, axis=1, inplace=False)

for code in labels_dfQ28B:
        dfQ28B[code] = dfQ28B[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ28B.append('Q28B:'+code)

dfQ28B = dfQ28B.set_axis(new_labels_dfQ28B, axis=1, inplace=False)

labels_dfQ29B=[]
new_labels_dfQ29B=[]

for i in dfQ29B:
        labels_dfQ29B.append(dfQ29B[i].value_counts().index[0])

dfQ29B = dfQ29B.set_axis(labels_dfQ29B, axis=1, inplace=False)

for code in labels_dfQ29B:
        dfQ29B[code] = dfQ29B[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ29B.append('Q29B:'+code)

dfQ29B = dfQ29B.set_axis(new_labels_dfQ29B, axis=1, inplace=False)

labels_dfQ31B=[]
new_labels_dfQ31B=[]

for i in dfQ31B:
        labels_dfQ31B.append(dfQ31B[i].value_counts().index[0])

dfQ31B = dfQ31B.set_axis(labels_dfQ31B, axis=1, inplace=False)

for code in labels_dfQ31B:
        dfQ31B[code] = dfQ31B[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ31B.append('Q31B:'+code)

dfQ31B = dfQ31B.set_axis(new_labels_dfQ31B, axis=1, inplace=False)

labels_dfQ33B=[]
new_labels_dfQ33B=[]

for i in dfQ33B:
        labels_dfQ33B.append(dfQ33B[i].value_counts().index[0])

dfQ33B = dfQ33B.set_axis(labels_dfQ33B, axis=1, inplace=False)

for code in labels_dfQ33B:
        dfQ33B[code] = dfQ33B[code].replace(to_replace = [np.nan,code],value= [0,1])

dfQ33B = dfQ33B.set_axis(labels_dfQ33B, axis=1, inplace=False)

for code in labels_dfQ33B:
        new_labels_dfQ33B.append('Q33B:'+code)

dfQ33B = dfQ33B.set_axis(new_labels_dfQ33B, axis=1, inplace=False)

labels_dfQ34B=[]
new_labels_dfQ34B=[]

for i in dfQ34B:
        labels_dfQ34B.append(dfQ34B[i].value_counts().index[0])

dfQ34B = dfQ34B.set_axis(labels_dfQ34B, axis=1, inplace=False)

for code in labels_dfQ34B:
        dfQ34B[code] = dfQ34B[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ34B.append('Q34B:'+code)

dfQ34B = dfQ34B.set_axis(new_labels_dfQ34B, axis=1, inplace=False)

labels_dfQ35B=[]
new_labels_dfQ35B=[]

for i in dfQ35B:
        labels_dfQ35B.append(dfQ35B[i].value_counts().index[0])

dfQ35B = dfQ35B.set_axis(labels_dfQ35B, axis=1, inplace=False)

for code in labels_dfQ35B:
        dfQ35B[code] = dfQ35B[code].replace(to_replace = [np.nan,code],value= [0,1])
        
labels_dfQ33B[5]='Automation of full ML pipelines (e.g. Google AutoML, H20 Driverless AI)'
dfQ33B = dfQ33B.set_axis(labels_dfQ33B, axis=1, inplace=False)   
        
for code in labels_dfQ35B:
        new_labels_dfQ35B.append('Q35B:'+code)

dfQ35B = dfQ35B.set_axis(new_labels_dfQ35B, axis=1, inplace=False)



"""Le nettoyage ayant été réalisé, nous pouvons désormais émettre des hypothèses à rejeter ou non à l'aide de Data Visualization.

# DATA VISUALIZATION

## Hypothèse 1 : Le Domaine de la Data regroupe 4/5 métiers
"""

#Visualisation des différents postes en DataScience (valeur cible)
plt.figure (figsize=(10,10))
plt.pie(df['Q5'].value_counts(),
        autopct = lambda x: str(round(x, 2)) + '%',
        labels=df['Q5'].value_counts().index,
        explode = [0.1,0,0,0.1,0.1,0,0,0,0,0,0,0,0],
        pctdistance=0.7,
        shadow =True,
        colors = ['#00ff7f', '#dddddd', '#81d8d0','#ff4040', '#ccff00', 
                  '#ffff66', '#ff7f50', '#a0db8e', '#c0d6e4', '#ffc0cb', '#ffa500', '#808080' , '#6897bb'])
plt.title("Distribution du panel de répondants par poste",fontsize=15, fontweight='bold');

"""Cette première visualisation nous permet tout d'abord de rejeter notre hypothèse, car une dizaine de métiers sont représentés ici, dans le domaine de la Data.

Par ailleurs, nous constatons également trois catégories qui ne correspondent pas à des métiers et donc pas à des outils et compétences associés.

Il y a de fait un risque de biais conséquent sur la construction d'un modèle cherchant à prédire un métier sur une base d'outils et compétences techniques.

Afin de lever ce biais, nous excluons ces trois catégories "Non Professionnelles" pour la suite de l'analyse notre DataFrame .
"""

#Validation du df "Professionnel" qui servira pour le reste de l'analyse

df_pro = df[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]

df_pro.shape

plt.figure (figsize=(10,10))
plt.pie(df_pro['Q5'].value_counts(),
        autopct = lambda x: str(round(x, 2)) + '%',
        labels=df_pro['Q5'].value_counts().index,
        pctdistance=0.7,
        shadow =True,
        colors = ['#dddddd', '#81d8d0','#ffff66', '#ff7f50',
                  '#a0db8e', '#c0d6e4', '#ffc0cb', '#ffa500', '#808080' , '#6897bb'])
plt.title("Distribution du panel de répondants par poste hors étudiant/autres/sans emploi",fontsize=15, fontweight='bold');

"""## Hypothèse 2 : Le domaine de la Data resterait masculinisé"""

#Visualisation de la répartition des Genres (Question 2)
fig = plt.figure(figsize=(10,5))

sns.countplot(df_pro['Q2'], palette = "Set2")
plt.title('Distribution des Genres',fontsize=12, fontweight='bold');

"""Nous constatons un déséquilibre flagrant, notre hypothèse ne peut donc être rejetée.
Il apparaît toutefois intéressant de pousser l'analyse sur la répartition au sein des différents types de poste.

Pour simplifier la visualisation, nous garderons seulement les valeurs 'Woman' et 'Man'.
"""

#Filtre du df sur les valeurs 'Woman' et 'Man
df_sx = df_pro[(df_pro['Q2'] == 'Man')|(df_pro['Q2'] == 'Woman')]

#Création d'une colonne pour comptage
df_sx['COUNTER'] = 1

rep_gnd = df_sx.groupby(['Q2','Q5'])['COUNTER'].sum()
rep_gnd_pct = rep_gnd.groupby(level=0).apply(lambda x: 100 * x / float(x.sum())).reset_index()

plt.figure(figsize=(30,30))
g=sns.catplot(y='Q5', x='COUNTER', hue='Q2', data=rep_gnd_pct, kind='bar', palette="Set2", legend=False)
g.set_xticklabels(rotation=90)
plt.ylabel('POSTES')
plt.xlabel('POURCENTAGE')
plt.title('Répartition des postes par Genre',fontsize=15, fontweight='bold')
plt.legend(title='Genre');

"""Nous constatons que les femmes sont proportionnellement plus nombreuses en Data Analysts et au même niveau en Data Scientists. Par contre elles sont sous-représentées en Machine Learning Engineers et en Product Managers.

## Hypothèse 3 : Le domaine de la Data semble concerner un public de moins de 40 ans
"""

#Représentation de la distribution du panel de répondants par tranche d'âge
plt.figure(figsize=(10,10))
g = sns.countplot(y= df_pro['Q1'], order = ['18-21','22-24','25-29','30-34', '35-39', '40-44', '45-49', '50-54','55-59', '60-69','70+'])
plt.xlabel('Nombre de participants')
plt.ylabel("Tranches d'âge")
plt.title("Distribution des participants par tranche d'âge", fontsize=12, fontweight = 'bold');

"""Nous constatons que la majorité des postes en Data est occupée par des moins de 40 ans.

## Hypothèse 4 : les "outils" les plus utilisés dans les métiers de la Data sont-ils ceux enseignés par DataScientest?

Afin d'illustrer de la manière la plus synthétique notre hypothèse, nous n'avons retenu que quatre questions portant respectivement sur l'utilsation quotidienne des :

        Langages de programmation (question 7)
        IDE (question 9)
        DataViz (question 14)
        Outils de Machine Learning (question 16)

Tous ces éléments sont abordés via des questions à choix multiples, où plusieurs réponses sont possibles. Les catégories représentées ci-dessous ne seront donc pas nécessairement disjointes.

De plus, notre base d'étude se restreignant désormais uniquement aux professionnels, il est nécessaire d'ajuster les bases de données des questions 7, 9, 14 et 16 aux individus concernés.
"""

dfQ7_pro = dfQ7[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ9_pro = dfQ9[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ14_pro = dfQ14[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ16_pro = dfQ16[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]

"""Nous travaillons bien désormais sur un groupe de 10,717 individus."""

dfQ7_pro.info()

plt.figure(figsize=(10,30))

plt.subplot(4,1,1)
dfQ7_pro.sum().sort_values().plot(kind = 'barh')
plt.title("Q7: What programming languages do you use on a regular basis?",fontsize=12, fontweight = 'bold')
plt.xlabel('Responses')

plt.subplot(4,1,2)
dfQ9_pro.sum().sort_values().plot(kind = 'barh',color='green')
plt.title("Q9: Which of the following integrated development environments (IDE's) do you use on a regular basis?",fontsize=12, fontweight = 'bold')
plt.xlabel('Responses')

plt.subplot(4,1,3)
dfQ14_pro.sum().sort_values().plot(kind = 'barh',color='orange')
plt.title("Q14: What data visualization libraries or tools do you use on a regular basis?",fontsize=12, fontweight = 'bold')
plt.xlabel('Responses')

plt.subplot(4,1,4)
dfQ16_pro.sum().sort_values().plot(kind = 'barh',color='purple')
plt.title("Q16: Which of the following machine learning frameworks do you use on a regular basis?",fontsize=12, fontweight = 'bold')
plt.xlabel('Responses')

plt.show()

"""Python est de loin le langage de programmation le plus populaire dans les métiers de la data. Jupyter Notebook est l'IDE privilégié, bien que d'autres IDE soient aussi utilisés.
Quand on parle de data visualization, Matplotlib et Seaborn se détachent clairement des autres outils à disposition.
Enfin le Machine Learning se fait majoritairement via Scikit-learn, même si TensorFlow et Keras ont aussi un certain succés.

Le contenu de formation de DataScientest semble refléter de façon assez correcte, les outils actuellement utilisés par les professionnels de la data.

## Hypothèse 5 : Big Data = Big Company?
Le Machine Learning n'est-il utilisé que dans les grandes entreprises?
"""

df_taille = df_pro[['Q20', 'Q22']]

df_taille['COUNTER'] = 1

rep1 = df_taille.groupby(['Q20','Q22'])['COUNTER'].sum()
rep2 = rep1.groupby(level=0).apply(lambda x: 100 * x / float(x.sum())).reset_index()

plt.figure(figsize=(20,13))

g=sns.catplot(x = 'Q20', y = 'COUNTER', hue = 'Q22', data = rep2, order = ['0-49 employees', '50-249 employees', '250-999 employees', '1000-9,999 employees', '10,000 or more employees'], kind = 'point')
g.set_xticklabels(rotation=45)
plt.xlabel('Company size')
plt.ylabel('Count ratio')
plt.title("Répartition de l'utilisation de ML en fonction de la taille de l'entreprise", fontsize=15, fontweight='bold');

"""On voit clairement que plus la taille de l'entreprise est grande, plus les modèles de ML sont non seulement en production depuis plus de 2 ans, mais aussi entrés dans la culture d'entreprise.

On constate toutefois que le ML est en cours de développement quelle que soit la taille de l'entreprise.

Donc nous rejetons notre hypothèse.

# Reconstitution du DataFrame à partir des divers sub DataFrames créés pour encoder les colonnes de questions à choix multiples

NB: Après consultation de la méthodologie du sondage, il apparait que les questions 30 et 32 n'ont été posées qu'à certaines personnes, en fonction des réponses aux questions précédentes, d'où le ratio de NaN conséquent traité au préalable.

Nous décidons de ne pas garder ces deux colonnes.

De plus, la Question 33_B nécessitant un traitement particulier mais n'étant pas nécessaire pour le livrable suivant, la colonne coresspondante n'est pas non plus retenue.
"""

#initialisation d'une base temporaire à partir des 6 premières colonnes
df_pro_temp = df_pro.iloc[:,0:6]

#rajout des questions à réponses uniques
df_pro_temp['Q8'] = df_pro['Q8']
df_pro_temp['Q11'] = df_pro['Q11']
df_pro_temp['Q13'] = df_pro['Q13']
df_pro_temp['Q15'] = df_pro['Q15']
df_pro_temp['Q20'] = df_pro['Q20']
df_pro_temp['Q21'] = df_pro['Q21']
df_pro_temp['Q22'] = df_pro['Q22']
df_pro_temp['Q24'] = df_pro['Q24']
df_pro_temp['Q25'] = df_pro['Q25']
df_pro_temp['Q38'] = df_pro['Q38']

#Filtre des divers subDataFrames sur les catégories "Professionnelles" de répondants 
dfQ10_pro = dfQ10[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ12_pro = dfQ12[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ17_pro = dfQ17[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ18_pro = dfQ18[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ19_pro = dfQ19[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ23_pro = dfQ23[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]

dfQ26A_pro = dfQ26A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ27A_pro = dfQ27A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ28A_pro = dfQ28A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ29A_pro = dfQ29A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ31A_pro = dfQ31A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ33A_pro = dfQ33A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ34A_pro = dfQ34A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ35A_pro = dfQ35A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]

dfQ36_pro = dfQ36[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ37_pro = dfQ37[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ39_pro = dfQ39[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]

dfQ26B_pro = dfQ26B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ27B_pro = dfQ27B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ28B_pro = dfQ28B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ29B_pro = dfQ29B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ31B_pro = dfQ31B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ33B_pro = dfQ33B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ34B_pro = dfQ34B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ35B_pro = dfQ35B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]


#rajout des questions à réponses multiples
df_pro_temp = df_pro_temp.join(dfQ7_pro)
df_pro_temp = df_pro_temp.join(dfQ9_pro)

df_pro_temp = df_pro_temp.join(dfQ10_pro)
df_pro_temp = df_pro_temp.join(dfQ12_pro)

df_pro_temp = df_pro_temp.join(dfQ14_pro)
df_pro_temp = df_pro_temp.join(dfQ16_pro)

df_pro_temp = df_pro_temp.join(dfQ17_pro)
df_pro_temp = df_pro_temp.join(dfQ18_pro)
df_pro_temp = df_pro_temp.join(dfQ19_pro)
df_pro_temp = df_pro_temp.join(dfQ23_pro)

df_pro_temp = df_pro_temp.join(dfQ26A_pro)
df_pro_temp = df_pro_temp.join(dfQ27A_pro)
df_pro_temp = df_pro_temp.join(dfQ28A_pro)
df_pro_temp = df_pro_temp.join(dfQ29A_pro)
df_pro_temp = df_pro_temp.join(dfQ31A_pro)
df_pro_temp = df_pro_temp.join(dfQ33A_pro)
df_pro_temp = df_pro_temp.join(dfQ34A_pro)
df_pro_temp = df_pro_temp.join(dfQ35A_pro)

df_pro_temp = df_pro_temp.join(dfQ36_pro)
df_pro_temp = df_pro_temp.join(dfQ37_pro)
df_pro_temp = df_pro_temp.join(dfQ39_pro)

df_pro_temp = df_pro_temp.join(dfQ26B_pro)
df_pro_temp = df_pro_temp.join(dfQ27B_pro)
df_pro_temp = df_pro_temp.join(dfQ28B_pro)
df_pro_temp = df_pro_temp.join(dfQ29B_pro)
df_pro_temp = df_pro_temp.join(dfQ31B_pro)
df_pro_temp = df_pro_temp.join(dfQ33B_pro)
df_pro_temp = df_pro_temp.join(dfQ34B_pro)
df_pro_temp = df_pro_temp.join(dfQ35B_pro)

df_pro_temp.head(3).transpose()
#df_pro_temp.shape

df_pro = df_pro_temp

df_pro.shape

#df_pro.to_csv('/content/drive/MyDrive/Data/df_pro.csv')
<filename>pygraal_livrable_1_dataviz.py
# -*- coding: utf-8 -*-
"""PyGraal_Livrable_1_DATAVIZ.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1VOdSSm0I_kGabrDsl7aFbr2HO6UOupVa

# Analyse des techniques et outils utilisés par les professionnels de la Data

Cette analyse repose sur un sondage contenant 20 036 réponses obtenues auprès de participants provenants de 171 pays différents.

Les participants ont dû répondre à une série d'une trentaine de questions.
Quelques unes sont d'ordre personnel (Age, genre...) ou bien en rapport avec leur poste et entreprise actuels.
Cepndant, l'essentiel concerne avant tout les outils utilisés dans le domaine de la Data Science (Langage de programmation, bibliothèque de Datavisualisaton...) ainsi que le rapport à l'utilisation de Machine Learning.

Ce sondage comprend à la fois des questions à choix unique et également à choix multiple.

A noter également que certaines questions étaient accessibles en fonction de réponses précédentes.

A partir de ce sondage, nous souhaitons établir des ensembles de compétences et outils correspondant aux divers postes monde de la Data, afin de construire dans un second temps un système de recommandation de poste permettant au demandeur de viser exactement le poste correspondant le plus à ses appétences.

# ANALYSE EXPLORATOIRE
"""

# Commented out IPython magic to ensure Python compatibility.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# %matplotlib inline
import seaborn as sns
sns.set_theme()

from google.colab import drive
drive.mount('/content/drive')

import warnings
warnings.filterwarnings ('ignore')

data = pd.read_csv('/content/drive/MyDrive/Data/kaggle_survey_2020_responses.csv')

df = data.copy()

print (df.shape)
df.head()

"""La visualisation du DataFrame nous permet de constater que pour les questions à choix multiples, chaque choix est une colonne avec deux valeurs possibles (Nan ou Valeur).

Ainsi nous pourrons traiter par la suite distinctement les questions à choix unique et les questions à choix multiple.

De plus, nous constatons que les différents postes en Data Science se trouve dans la colonne Q5.

Q5 correspond donc à notre variable cible pour la suite de l'étude.
"""

df.dtypes.value_counts()

"""# Il n'y a que des valeurs catégorielles, un encodage sera nécessaire pour la création d'un modèle de Machine Learning.

## Analyse et Nettoyage des Doublons et Valeurs Manquantes
"""

#Visualisation/Suppression des doublons
print("Il y a",df.duplicated().sum(), 'doublons.')
#14 doublons
df = df.drop_duplicates()

#La première colonne (temps de réponse au questionnaire) n'est pas pertinente pour l'étude.
df.drop(['Time from Start to Finish (seconds)'], axis=1, inplace=True)

#Recherche des Nans dans la variable cible
print("Il y a",df['Q5'].isna().sum(),"valeurs manquantes sur cette valeur.")

#Suppression des Nans sur cette valeur
df.dropna(subset=['Q5'], inplace=True)

#Vérif modification du nbre de lignes 20037 - 14 -745
print (df.shape)
df.head()

"""La première ligne du DataFrame n'est pas une entrée mais correspond à l'intitulé des différentes questions.
Cette entrée n'est donc pas à exploiter dans le DataFrame, mais elle reste intéressante pour la compréhension du jeu de données.
"""

#Création d'une base de données Questions à partir de la 1ère ligne de df
Questions = df.iloc[0:1,:].transpose()
Questions = Questions.set_axis(['Questions'], axis=1, inplace=False)
Questions



#Suppression de la première ligne:
df.drop(0,axis=0,inplace=True)

#Vérif modification du nbre de lignes 19278 - 1
print (df.shape)
df.head()

#Analyse des NaNs par % par colonne:
(df.isna().sum() / df.shape[0]).sort_values(ascending=False)

"""Cela nous permet de constater des taux conséquents de NaNs.

Toutefois, pour rappel, certaines questions sont à choix multiples, par conséquent le phénomène s'explique en partie et pour ce type précis de questions les Nans seront à interpréter mais surtout pas à supprimer ou à remplacer par un mode.

Il paraît donc nécessaire de distinguer les questions à choix mutliple des questions à choix unique.

Un moyen simple de les distinguer est de s'appuyer sur le nombre de valeurs contenues dans chaque colonne.
Les choix multiples ont été éclatés en colonne, contenant ainsi soit le choix retenu, soit une valeur manquante.

Par conséquent les questions à choix multiples ne contiennent que deux valeurs.

## Traitement des questions à choix unique
"""

#Récupération des valeurs uniques pour chaque col
def col_u(df):
    for i in df:
        print(f'{i :-<20} {df[i].unique()}')
col_u(df)

#Recherche des colonnes avec + de 2 valeurs
#quest_u regroupe les colonnes des questions choix unique
#quest_u regroupe les colonnes des questions choix multiple
quest_u =[]
quest_m =[]
for i in df:
  if len(df[i].unique())>2:
    quest_u.append(i)
  else:
    quest_m.append(i)
print("Liste des questions à choix unique\n", quest_u)
print("\n\n")
print("Liste des questions à choix multiple\n", quest_m)

"""Nous pouvons à présent observer la présence ou non de valeurs manquantes sur les colonnes de questions à choix unique."""

(df[['Q1', 'Q2', 'Q3', 'Q4', 'Q5', 'Q6', 'Q8', 'Q11', 'Q13', 'Q15', 'Q20', 'Q21', 'Q22', 'Q24', 'Q25', 'Q30', 'Q32', 'Q38']].isna().sum() / df.shape[0]).sort_values(ascending=False)

"""Nous remplaçons les valeurs manquantes par le mode de chaque colonne."""

quest_u =[]
for i in df:
    if len(df[i].unique())>2:
        quest_u.append(i)
print(quest_u)

#Remplacement des Nans des colonnes choix unique par le mode des colonnes
for col in quest_u:
  df[col].fillna(df[col].mode()[0], inplace=True)

df[quest_u].isna().sum()

"""## Traitement des questions à choix multiples

Les questions à choix multiples sont plus difficiles à interpréter de par la manière dont elles ont été intégrées dans la base de données. Pour chaque question, un nombre de colonnes équivalent au nombre de réponses proposées a été créé. Pour chaque réponse, chaque colonne est remplie de la valeur de la réponse si le répondant a sélectionné ce choix et de Nan sinon. Il ne faut pas supprimer les valeurs manquantes sur ces colonnes car elles ont une utilité de compréhension.

Afin de pouvoir les utiliser et les analyser ultérieurement, il est cependant nécessaire de les encoder de manière binaire : 1 en cas de réponse positive, 0 si la valeur est manquante.

Dans un souci de flexibilité et de lisibilité, les différentes questions à choix multiples seront regroupées au sein de mini dataframes contenant en colonnes chacune des options proposées pour répondre à la question.
"""

#création de sub dataframes répliquant les intervalles créés pour les questions
#dfQ7 à dfQ35B contiennent toutes les questions à multiples réponses

dfQ7=df.iloc[:,6:19]       #correspond aux réponses de la question 7, ie Q7
dfQ9=df.iloc[:,20:32]      #Q9
dfQ10=df.iloc[:,32:46]     #Q10
dfQ12=df.iloc[:,47:51]     #Q12
dfQ14=df.iloc[:,52:64]     #Q14
dfQ16=df.iloc[:,65:81]     #Q16
dfQ17=df.iloc[:,81:93]     #Q17
dfQ18=df.iloc[:,93:100]    #Q18
dfQ19=df.iloc[:,100:106]   #Q19
dfQ23=df.iloc[:,109:117]   #Q23
dfQ26A=df.iloc[:,119:131]  #Q26A
dfQ27A=df.iloc[:,131:143]  #Q27A
dfQ28A=df.iloc[:,143:154]  #Q28A
dfQ29A=df.iloc[:,154:172]  #Q29A
dfQ31A=df.iloc[:,173:188]  #Q31A
dfQ33A=df.iloc[:,189:197]  #Q33A
dfQ34A=df.iloc[:,197:209]  #Q34A
dfQ35A=df.iloc[:,209:220]  #Q35A
dfQ36=df.iloc[:,220:230]   #Q36
dfQ37=df.iloc[:,230:242]   #Q37
dfQ39=df.iloc[:,243:255]   #Q39
dfQ26B=df.iloc[:,255:267]  #Q26B
dfQ27B=df.iloc[:,267:279]  #Q27B
dfQ28B=df.iloc[:,279:290]  #Q28B
dfQ29B=df.iloc[:,290:308]  #Q29B
dfQ31B=df.iloc[:,308:323]  #Q31B
dfQ33B=df.iloc[:,323:331]  #Q33B
dfQ34B=df.iloc[:,331:343]  #Q34B
dfQ35B=df.iloc[:,343:354]  #Q35B

"""Une vérification rapide nous montre que dfQ7 intègre toutes les informations relatives à la question 7."""

dfQ35B.head().transpose()

"""Toutefois le libellé des colonnes est peu parlant. Nous allons donc les renommer en utilisant chaque choix comme nouveau titre.
L'encodage se fera ensuite à partir du nouveau titre. Ce procédé permet aussi de supprimer tout risque de labélisation incorrecte, vu qu'il est très difficile de répérer à l'oeil nu le nombre d'espaces présents dans des cellules textes. 
"""

# les codes ci-dessous ont été dupliqués autant de fois que nécessaire

labels_dfQ7=[]
new_labels_dfQ7=[]

for i in dfQ7:
        labels_dfQ7.append(dfQ7[i].value_counts().index[0])

dfQ7 = dfQ7.set_axis(labels_dfQ7, axis=1, inplace=False)

for code in labels_dfQ7:
        dfQ7[code] = dfQ7[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ7.append('Q7:'+code)

dfQ7 = dfQ7.set_axis(new_labels_dfQ7, axis=1, inplace=False)

labels_dfQ9=[]
new_labels_dfQ9=[]

for i in dfQ9:
        labels_dfQ9.append(dfQ9[i].value_counts().index[0])

dfQ9 = dfQ9.set_axis(labels_dfQ9, axis=1, inplace=False)

for code in labels_dfQ9:
        dfQ9[code] = dfQ9[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ9.append('Q9:'+code)

dfQ9 = dfQ9.set_axis(new_labels_dfQ9, axis=1, inplace=False)

labels_dfQ10=[]
new_labels_dfQ10=[]

for i in dfQ10:
        labels_dfQ10.append(dfQ10[i].value_counts().index[0])

dfQ10 = dfQ10.set_axis(labels_dfQ10, axis=1, inplace=False)

for code in labels_dfQ10:
        dfQ10[code] = dfQ10[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ10.append('Q10:'+code)

dfQ10 = dfQ10.set_axis(new_labels_dfQ10, axis=1, inplace=False)

labels_dfQ12=[]
new_labels_dfQ12=[]

for i in dfQ12:
        labels_dfQ12.append(dfQ12[i].value_counts().index[0])


dfQ12 = dfQ12.set_axis(labels_dfQ12, axis=1, inplace=False)

for code in labels_dfQ12:
        dfQ12[code] = dfQ12[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ12.append('Q12:'+code)

dfQ12 = dfQ12.set_axis(new_labels_dfQ12, axis=1, inplace=False)

labels_dfQ14=[]
new_labels_dfQ14=[]

for i in dfQ14:
        labels_dfQ14.append(dfQ14[i].value_counts().index[0])


dfQ14 = dfQ14.set_axis(labels_dfQ14, axis=1, inplace=False)

for code in labels_dfQ14:
        dfQ14[code] = dfQ14[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ14.append('Q14:'+code)

dfQ14 = dfQ14.set_axis(new_labels_dfQ14, axis=1, inplace=False)

labels_dfQ16=[]
new_labels_dfQ16=[]

for i in dfQ16:
        labels_dfQ16.append(dfQ16[i].value_counts().index[0])


dfQ16 = dfQ16.set_axis(labels_dfQ16, axis=1, inplace=False)

for code in labels_dfQ16:
        dfQ16[code] = dfQ16[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ16.append('Q16:'+code)

dfQ16 = dfQ16.set_axis(new_labels_dfQ16, axis=1, inplace=False)

labels_dfQ17=[]
new_labels_dfQ17=[]

for i in dfQ17:
        labels_dfQ17.append(dfQ17[i].value_counts().index[0])

dfQ17 = dfQ17.set_axis(labels_dfQ17, axis=1, inplace=False)

for code in labels_dfQ17:
        dfQ17[code] = dfQ17[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ17.append('Q17:'+code)

dfQ17 = dfQ17.set_axis(new_labels_dfQ17, axis=1, inplace=False)

labels_dfQ18=[]
new_labels_dfQ18=[]

for i in dfQ18:
        labels_dfQ18.append(dfQ18[i].value_counts().index[0])

dfQ18 = dfQ18.set_axis(labels_dfQ18, axis=1, inplace=False)

for code in labels_dfQ18:
        dfQ18[code] = dfQ18[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ18.append('Q18:'+code)

dfQ18 = dfQ18.set_axis(new_labels_dfQ18, axis=1, inplace=False)

labels_dfQ19=[]
new_labels_dfQ19=[]

for i in dfQ19:
        labels_dfQ19.append(dfQ19[i].value_counts().index[0])

dfQ19 = dfQ19.set_axis(labels_dfQ19, axis=1, inplace=False)

for code in labels_dfQ19:
        dfQ19[code] = dfQ19[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ19.append('Q19:'+code)

dfQ19 = dfQ19.set_axis(new_labels_dfQ19, axis=1, inplace=False)

labels_dfQ23=[]
new_labels_dfQ23=[]

for i in dfQ23:
        labels_dfQ23.append(dfQ23[i].value_counts().index[0])

dfQ23 = dfQ23.set_axis(labels_dfQ23, axis=1, inplace=False)

for code in labels_dfQ23:
        dfQ23[code] = dfQ23[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ23.append('Q23:'+code)

dfQ23 = dfQ23.set_axis(new_labels_dfQ23, axis=1, inplace=False)

labels_dfQ26A=[]
new_labels_dfQ26A=[]

for i in dfQ26A:
        labels_dfQ26A.append(dfQ26A[i].value_counts().index[0])

dfQ26A = dfQ26A.set_axis(labels_dfQ26A, axis=1, inplace=False)

for code in labels_dfQ26A:
        dfQ26A[code] = dfQ26A[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ26A.append('Q26A:'+code)

dfQ26A = dfQ26A.set_axis(new_labels_dfQ26A, axis=1, inplace=False)

labels_dfQ27A=[]
new_labels_dfQ27A=[]

for i in dfQ27A:
        labels_dfQ27A.append(dfQ27A[i].value_counts().index[0])
        
dfQ27A = dfQ27A.set_axis(labels_dfQ27A, axis=1, inplace=False)

for code in labels_dfQ27A:
        dfQ27A[code] = dfQ27A[code].replace(to_replace = [np.nan,code],value= [0,1])

labels_dfQ27A[10]='None'
dfQ27A = dfQ27A.set_axis(labels_dfQ27A, axis=1, inplace=False)

for code in labels_dfQ27A:
        new_labels_dfQ27A.append('Q27A:'+code)

dfQ27A = dfQ27A.set_axis(new_labels_dfQ27A, axis=1, inplace=False)

labels_dfQ28A=[]
new_labels_dfQ28A=[]

for i in dfQ28A:
        labels_dfQ28A.append(dfQ28A[i].value_counts().index[0])

dfQ28A = dfQ28A.set_axis(labels_dfQ28A, axis=1, inplace=False)

for code in labels_dfQ28A:
        dfQ28A[code] = dfQ28A[code].replace(to_replace = [np.nan,code],value= [0,1])

labels_dfQ28A[9]='None'
dfQ28A = dfQ28A.set_axis(labels_dfQ28A, axis=1, inplace=False)

for code in labels_dfQ28A:
        new_labels_dfQ28A.append('Q28A:'+code)

dfQ28A = dfQ28A.set_axis(new_labels_dfQ28A, axis=1, inplace=False)

labels_dfQ29A=[]
new_labels_dfQ29A=[]

for i in dfQ29A:
        labels_dfQ29A.append(dfQ29A[i].value_counts().index[0])

dfQ29A = dfQ29A.set_axis(labels_dfQ29A, axis=1, inplace=False)

for code in labels_dfQ29A:
        dfQ29A[code] = dfQ29A[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ29A.append('Q29A:'+code)

dfQ29A = dfQ29A.set_axis(new_labels_dfQ29A, axis=1, inplace=False)

labels_dfQ31A=[]
new_labels_dfQ31A=[]

for i in dfQ31A:
        labels_dfQ31A.append(dfQ31A[i].value_counts().index[0])

dfQ31A = dfQ31A.set_axis(labels_dfQ31A, axis=1, inplace=False)

for code in labels_dfQ31A:
        dfQ31A[code] = dfQ31A[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ31A.append('Q31A:'+code)

dfQ31A = dfQ31A.set_axis(new_labels_dfQ31A, axis=1, inplace=False)

labels_dfQ33A=[]
new_labels_dfQ33A=[]

for i in dfQ33A:
        labels_dfQ33A.append(dfQ33A[i].value_counts().index[0])

dfQ33A = dfQ33A.set_axis(labels_dfQ33A, axis=1, inplace=False)

for code in labels_dfQ33A:
        dfQ33A[code] = dfQ33A[code].replace(to_replace = [np.nan,code],value= [0,1])
        
labels_dfQ33A[6]='None'
dfQ33A = dfQ33A.set_axis(labels_dfQ33A, axis=1, inplace=False)             

for code in labels_dfQ33A:
        new_labels_dfQ33A.append('Q33A:'+code)

dfQ33A = dfQ33A.set_axis(new_labels_dfQ33A, axis=1, inplace=False)

labels_dfQ34A=[]
new_labels_dfQ34A=[]

for i in dfQ34A:
        labels_dfQ34A.append(dfQ34A[i].value_counts().index[0])

dfQ34A = dfQ34A.set_axis(labels_dfQ34A, axis=1, inplace=False)

for code in labels_dfQ34A:
        dfQ34A[code] = dfQ34A[code].replace(to_replace = [np.nan,code],value= [0,1])
        
labels_dfQ34A[10]='None'
dfQ34A = dfQ34A.set_axis(labels_dfQ34A, axis=1, inplace=False)          
        
for code in labels_dfQ34A:
        new_labels_dfQ34A.append('Q34A:'+code)

dfQ34A = dfQ34A.set_axis(new_labels_dfQ34A, axis=1, inplace=False)

labels_dfQ35A=[]
new_labels_dfQ35A=[]

for i in dfQ35A:
        labels_dfQ35A.append(dfQ35A[i].value_counts().index[0])

dfQ35A = dfQ35A.set_axis(labels_dfQ35A, axis=1, inplace=False)

for code in labels_dfQ35A:
        dfQ35A[code] = dfQ35A[code].replace(to_replace = [np.nan,code],value= [0,1])
        
labels_dfQ35A[9]='None'
dfQ35A = dfQ35A.set_axis(labels_dfQ35A, axis=1, inplace=False)    
        
for code in labels_dfQ35A:
        new_labels_dfQ35A.append('Q35A:'+code)

dfQ35A = dfQ35A.set_axis(new_labels_dfQ35A, axis=1, inplace=False)

labels_dfQ36=[]
new_labels_dfQ36=[]

for i in dfQ36:
        labels_dfQ36.append(dfQ36[i].value_counts().index[0])

dfQ36 = dfQ36.set_axis(labels_dfQ36, axis=1, inplace=False)

for code in labels_dfQ36:
        dfQ36[code] = dfQ36[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ36.append('Q36:'+code)

dfQ36 = dfQ36.set_axis(new_labels_dfQ36, axis=1, inplace=False)

labels_dfQ37=[]
new_labels_dfQ37=[]

for i in dfQ37:
        labels_dfQ37.append(dfQ37[i].value_counts().index[0])

dfQ37 = dfQ37.set_axis(labels_dfQ37, axis=1, inplace=False)

for code in labels_dfQ37:
        dfQ37[code] = dfQ37[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ37.append('Q37:'+code)

dfQ37 = dfQ37.set_axis(new_labels_dfQ37, axis=1, inplace=False)

labels_dfQ39=[]
new_labels_dfQ39=[]

for i in dfQ39:
        labels_dfQ39.append(dfQ39[i].value_counts().index[0])

dfQ39 = dfQ39.set_axis(labels_dfQ39, axis=1, inplace=False)

for code in labels_dfQ39:
        dfQ39[code] = dfQ39[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ39.append('Q39:'+code)

dfQ39 = dfQ39.set_axis(new_labels_dfQ39, axis=1, inplace=False)

labels_dfQ26B=[]
new_labels_dfQ26B=[]

for i in dfQ26B:
        labels_dfQ26B.append(dfQ26B[i].value_counts().index[0])

dfQ26B = dfQ26B.set_axis(labels_dfQ26B, axis=1, inplace=False)

for code in labels_dfQ26B:
        dfQ26B[code] = dfQ26B[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ26B.append('Q26B:'+code)

dfQ26B = dfQ26B.set_axis(new_labels_dfQ26B, axis=1, inplace=False)

labels_dfQ27B=[]
new_labels_dfQ27B=[]

for i in dfQ27B:
        labels_dfQ27B.append(dfQ27B[i].value_counts().index[0])

dfQ27B = dfQ27B.set_axis(labels_dfQ27B, axis=1, inplace=False)

for code in labels_dfQ27B:
        dfQ27B[code] = dfQ27B[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ27B.append('Q27B:'+code)

dfQ27B = dfQ27B.set_axis(new_labels_dfQ27B, axis=1, inplace=False)

labels_dfQ28B=[]
new_labels_dfQ28B=[]

for i in dfQ28B:
        labels_dfQ28B.append(dfQ28B[i].value_counts().index[0])

dfQ28B = dfQ28B.set_axis(labels_dfQ28B, axis=1, inplace=False)

for code in labels_dfQ28B:
        dfQ28B[code] = dfQ28B[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ28B.append('Q28B:'+code)

dfQ28B = dfQ28B.set_axis(new_labels_dfQ28B, axis=1, inplace=False)

labels_dfQ29B=[]
new_labels_dfQ29B=[]

for i in dfQ29B:
        labels_dfQ29B.append(dfQ29B[i].value_counts().index[0])

dfQ29B = dfQ29B.set_axis(labels_dfQ29B, axis=1, inplace=False)

for code in labels_dfQ29B:
        dfQ29B[code] = dfQ29B[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ29B.append('Q29B:'+code)

dfQ29B = dfQ29B.set_axis(new_labels_dfQ29B, axis=1, inplace=False)

labels_dfQ31B=[]
new_labels_dfQ31B=[]

for i in dfQ31B:
        labels_dfQ31B.append(dfQ31B[i].value_counts().index[0])

dfQ31B = dfQ31B.set_axis(labels_dfQ31B, axis=1, inplace=False)

for code in labels_dfQ31B:
        dfQ31B[code] = dfQ31B[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ31B.append('Q31B:'+code)

dfQ31B = dfQ31B.set_axis(new_labels_dfQ31B, axis=1, inplace=False)

labels_dfQ33B=[]
new_labels_dfQ33B=[]

for i in dfQ33B:
        labels_dfQ33B.append(dfQ33B[i].value_counts().index[0])

dfQ33B = dfQ33B.set_axis(labels_dfQ33B, axis=1, inplace=False)

for code in labels_dfQ33B:
        dfQ33B[code] = dfQ33B[code].replace(to_replace = [np.nan,code],value= [0,1])

dfQ33B = dfQ33B.set_axis(labels_dfQ33B, axis=1, inplace=False)

for code in labels_dfQ33B:
        new_labels_dfQ33B.append('Q33B:'+code)

dfQ33B = dfQ33B.set_axis(new_labels_dfQ33B, axis=1, inplace=False)

labels_dfQ34B=[]
new_labels_dfQ34B=[]

for i in dfQ34B:
        labels_dfQ34B.append(dfQ34B[i].value_counts().index[0])

dfQ34B = dfQ34B.set_axis(labels_dfQ34B, axis=1, inplace=False)

for code in labels_dfQ34B:
        dfQ34B[code] = dfQ34B[code].replace(to_replace = [np.nan,code],value= [0,1])
        new_labels_dfQ34B.append('Q34B:'+code)

dfQ34B = dfQ34B.set_axis(new_labels_dfQ34B, axis=1, inplace=False)

labels_dfQ35B=[]
new_labels_dfQ35B=[]

for i in dfQ35B:
        labels_dfQ35B.append(dfQ35B[i].value_counts().index[0])

dfQ35B = dfQ35B.set_axis(labels_dfQ35B, axis=1, inplace=False)

for code in labels_dfQ35B:
        dfQ35B[code] = dfQ35B[code].replace(to_replace = [np.nan,code],value= [0,1])
        
labels_dfQ33B[5]='Automation of full ML pipelines (e.g. Google AutoML, H20 Driverless AI)'
dfQ33B = dfQ33B.set_axis(labels_dfQ33B, axis=1, inplace=False)   
        
for code in labels_dfQ35B:
        new_labels_dfQ35B.append('Q35B:'+code)

dfQ35B = dfQ35B.set_axis(new_labels_dfQ35B, axis=1, inplace=False)



"""Le nettoyage ayant été réalisé, nous pouvons désormais émettre des hypothèses à rejeter ou non à l'aide de Data Visualization.

# DATA VISUALIZATION

## Hypothèse 1 : Le Domaine de la Data regroupe 4/5 métiers
"""

#Visualisation des différents postes en DataScience (valeur cible)
plt.figure (figsize=(10,10))
plt.pie(df['Q5'].value_counts(),
        autopct = lambda x: str(round(x, 2)) + '%',
        labels=df['Q5'].value_counts().index,
        explode = [0.1,0,0,0.1,0.1,0,0,0,0,0,0,0,0],
        pctdistance=0.7,
        shadow =True,
        colors = ['#00ff7f', '#dddddd', '#81d8d0','#ff4040', '#ccff00', 
                  '#ffff66', '#ff7f50', '#a0db8e', '#c0d6e4', '#ffc0cb', '#ffa500', '#808080' , '#6897bb'])
plt.title("Distribution du panel de répondants par poste",fontsize=15, fontweight='bold');

"""Cette première visualisation nous permet tout d'abord de rejeter notre hypothèse, car une dizaine de métiers sont représentés ici, dans le domaine de la Data.

Par ailleurs, nous constatons également trois catégories qui ne correspondent pas à des métiers et donc pas à des outils et compétences associés.

Il y a de fait un risque de biais conséquent sur la construction d'un modèle cherchant à prédire un métier sur une base d'outils et compétences techniques.

Afin de lever ce biais, nous excluons ces trois catégories "Non Professionnelles" pour la suite de l'analyse notre DataFrame .
"""

#Validation du df "Professionnel" qui servira pour le reste de l'analyse

df_pro = df[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]

df_pro.shape

plt.figure (figsize=(10,10))
plt.pie(df_pro['Q5'].value_counts(),
        autopct = lambda x: str(round(x, 2)) + '%',
        labels=df_pro['Q5'].value_counts().index,
        pctdistance=0.7,
        shadow =True,
        colors = ['#dddddd', '#81d8d0','#ffff66', '#ff7f50',
                  '#a0db8e', '#c0d6e4', '#ffc0cb', '#ffa500', '#808080' , '#6897bb'])
plt.title("Distribution du panel de répondants par poste hors étudiant/autres/sans emploi",fontsize=15, fontweight='bold');

"""## Hypothèse 2 : Le domaine de la Data resterait masculinisé"""

#Visualisation de la répartition des Genres (Question 2)
fig = plt.figure(figsize=(10,5))

sns.countplot(df_pro['Q2'], palette = "Set2")
plt.title('Distribution des Genres',fontsize=12, fontweight='bold');

"""Nous constatons un déséquilibre flagrant, notre hypothèse ne peut donc être rejetée.
Il apparaît toutefois intéressant de pousser l'analyse sur la répartition au sein des différents types de poste.

Pour simplifier la visualisation, nous garderons seulement les valeurs 'Woman' et 'Man'.
"""

#Filtre du df sur les valeurs 'Woman' et 'Man
df_sx = df_pro[(df_pro['Q2'] == 'Man')|(df_pro['Q2'] == 'Woman')]

#Création d'une colonne pour comptage
df_sx['COUNTER'] = 1

rep_gnd = df_sx.groupby(['Q2','Q5'])['COUNTER'].sum()
rep_gnd_pct = rep_gnd.groupby(level=0).apply(lambda x: 100 * x / float(x.sum())).reset_index()

plt.figure(figsize=(30,30))
g=sns.catplot(y='Q5', x='COUNTER', hue='Q2', data=rep_gnd_pct, kind='bar', palette="Set2", legend=False)
g.set_xticklabels(rotation=90)
plt.ylabel('POSTES')
plt.xlabel('POURCENTAGE')
plt.title('Répartition des postes par Genre',fontsize=15, fontweight='bold')
plt.legend(title='Genre');

"""Nous constatons que les femmes sont proportionnellement plus nombreuses en Data Analysts et au même niveau en Data Scientists. Par contre elles sont sous-représentées en Machine Learning Engineers et en Product Managers.

## Hypothèse 3 : Le domaine de la Data semble concerner un public de moins de 40 ans
"""

#Représentation de la distribution du panel de répondants par tranche d'âge
plt.figure(figsize=(10,10))
g = sns.countplot(y= df_pro['Q1'], order = ['18-21','22-24','25-29','30-34', '35-39', '40-44', '45-49', '50-54','55-59', '60-69','70+'])
plt.xlabel('Nombre de participants')
plt.ylabel("Tranches d'âge")
plt.title("Distribution des participants par tranche d'âge", fontsize=12, fontweight = 'bold');

"""Nous constatons que la majorité des postes en Data est occupée par des moins de 40 ans.

## Hypothèse 4 : les "outils" les plus utilisés dans les métiers de la Data sont-ils ceux enseignés par DataScientest?

Afin d'illustrer de la manière la plus synthétique notre hypothèse, nous n'avons retenu que quatre questions portant respectivement sur l'utilsation quotidienne des :

        Langages de programmation (question 7)
        IDE (question 9)
        DataViz (question 14)
        Outils de Machine Learning (question 16)

Tous ces éléments sont abordés via des questions à choix multiples, où plusieurs réponses sont possibles. Les catégories représentées ci-dessous ne seront donc pas nécessairement disjointes.

De plus, notre base d'étude se restreignant désormais uniquement aux professionnels, il est nécessaire d'ajuster les bases de données des questions 7, 9, 14 et 16 aux individus concernés.
"""

dfQ7_pro = dfQ7[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ9_pro = dfQ9[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ14_pro = dfQ14[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ16_pro = dfQ16[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]

"""Nous travaillons bien désormais sur un groupe de 10,717 individus."""

dfQ7_pro.info()

plt.figure(figsize=(10,30))

plt.subplot(4,1,1)
dfQ7_pro.sum().sort_values().plot(kind = 'barh')
plt.title("Q7: What programming languages do you use on a regular basis?",fontsize=12, fontweight = 'bold')
plt.xlabel('Responses')

plt.subplot(4,1,2)
dfQ9_pro.sum().sort_values().plot(kind = 'barh',color='green')
plt.title("Q9: Which of the following integrated development environments (IDE's) do you use on a regular basis?",fontsize=12, fontweight = 'bold')
plt.xlabel('Responses')

plt.subplot(4,1,3)
dfQ14_pro.sum().sort_values().plot(kind = 'barh',color='orange')
plt.title("Q14: What data visualization libraries or tools do you use on a regular basis?",fontsize=12, fontweight = 'bold')
plt.xlabel('Responses')

plt.subplot(4,1,4)
dfQ16_pro.sum().sort_values().plot(kind = 'barh',color='purple')
plt.title("Q16: Which of the following machine learning frameworks do you use on a regular basis?",fontsize=12, fontweight = 'bold')
plt.xlabel('Responses')

plt.show()

"""Python est de loin le langage de programmation le plus populaire dans les métiers de la data. Jupyter Notebook est l'IDE privilégié, bien que d'autres IDE soient aussi utilisés.
Quand on parle de data visualization, Matplotlib et Seaborn se détachent clairement des autres outils à disposition.
Enfin le Machine Learning se fait majoritairement via Scikit-learn, même si TensorFlow et Keras ont aussi un certain succés.

Le contenu de formation de DataScientest semble refléter de façon assez correcte, les outils actuellement utilisés par les professionnels de la data.

## Hypothèse 5 : Big Data = Big Company?
Le Machine Learning n'est-il utilisé que dans les grandes entreprises?
"""

df_taille = df_pro[['Q20', 'Q22']]

df_taille['COUNTER'] = 1

rep1 = df_taille.groupby(['Q20','Q22'])['COUNTER'].sum()
rep2 = rep1.groupby(level=0).apply(lambda x: 100 * x / float(x.sum())).reset_index()

plt.figure(figsize=(20,13))

g=sns.catplot(x = 'Q20', y = 'COUNTER', hue = 'Q22', data = rep2, order = ['0-49 employees', '50-249 employees', '250-999 employees', '1000-9,999 employees', '10,000 or more employees'], kind = 'point')
g.set_xticklabels(rotation=45)
plt.xlabel('Company size')
plt.ylabel('Count ratio')
plt.title("Répartition de l'utilisation de ML en fonction de la taille de l'entreprise", fontsize=15, fontweight='bold');

"""On voit clairement que plus la taille de l'entreprise est grande, plus les modèles de ML sont non seulement en production depuis plus de 2 ans, mais aussi entrés dans la culture d'entreprise.

On constate toutefois que le ML est en cours de développement quelle que soit la taille de l'entreprise.

Donc nous rejetons notre hypothèse.

# Reconstitution du DataFrame à partir des divers sub DataFrames créés pour encoder les colonnes de questions à choix multiples

NB: Après consultation de la méthodologie du sondage, il apparait que les questions 30 et 32 n'ont été posées qu'à certaines personnes, en fonction des réponses aux questions précédentes, d'où le ratio de NaN conséquent traité au préalable.

Nous décidons de ne pas garder ces deux colonnes.

De plus, la Question 33_B nécessitant un traitement particulier mais n'étant pas nécessaire pour le livrable suivant, la colonne coresspondante n'est pas non plus retenue.
"""

#initialisation d'une base temporaire à partir des 6 premières colonnes
df_pro_temp = df_pro.iloc[:,0:6]

#rajout des questions à réponses uniques
df_pro_temp['Q8'] = df_pro['Q8']
df_pro_temp['Q11'] = df_pro['Q11']
df_pro_temp['Q13'] = df_pro['Q13']
df_pro_temp['Q15'] = df_pro['Q15']
df_pro_temp['Q20'] = df_pro['Q20']
df_pro_temp['Q21'] = df_pro['Q21']
df_pro_temp['Q22'] = df_pro['Q22']
df_pro_temp['Q24'] = df_pro['Q24']
df_pro_temp['Q25'] = df_pro['Q25']
df_pro_temp['Q38'] = df_pro['Q38']

#Filtre des divers subDataFrames sur les catégories "Professionnelles" de répondants 
dfQ10_pro = dfQ10[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ12_pro = dfQ12[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ17_pro = dfQ17[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ18_pro = dfQ18[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ19_pro = dfQ19[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ23_pro = dfQ23[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]

dfQ26A_pro = dfQ26A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ27A_pro = dfQ27A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ28A_pro = dfQ28A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ29A_pro = dfQ29A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ31A_pro = dfQ31A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ33A_pro = dfQ33A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ34A_pro = dfQ34A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ35A_pro = dfQ35A[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]

dfQ36_pro = dfQ36[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ37_pro = dfQ37[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ39_pro = dfQ39[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]

dfQ26B_pro = dfQ26B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ27B_pro = dfQ27B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ28B_pro = dfQ28B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ29B_pro = dfQ29B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ31B_pro = dfQ31B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ33B_pro = dfQ33B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ34B_pro = dfQ34B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]
dfQ35B_pro = dfQ35B[(df['Q5'] != 'Student')&(df['Q5'] != 'Other')&(df['Q5'] != 'Currently not employed')]


#rajout des questions à réponses multiples
df_pro_temp = df_pro_temp.join(dfQ7_pro)
df_pro_temp = df_pro_temp.join(dfQ9_pro)

df_pro_temp = df_pro_temp.join(dfQ10_pro)
df_pro_temp = df_pro_temp.join(dfQ12_pro)

df_pro_temp = df_pro_temp.join(dfQ14_pro)
df_pro_temp = df_pro_temp.join(dfQ16_pro)

df_pro_temp = df_pro_temp.join(dfQ17_pro)
df_pro_temp = df_pro_temp.join(dfQ18_pro)
df_pro_temp = df_pro_temp.join(dfQ19_pro)
df_pro_temp = df_pro_temp.join(dfQ23_pro)

df_pro_temp = df_pro_temp.join(dfQ26A_pro)
df_pro_temp = df_pro_temp.join(dfQ27A_pro)
df_pro_temp = df_pro_temp.join(dfQ28A_pro)
df_pro_temp = df_pro_temp.join(dfQ29A_pro)
df_pro_temp = df_pro_temp.join(dfQ31A_pro)
df_pro_temp = df_pro_temp.join(dfQ33A_pro)
df_pro_temp = df_pro_temp.join(dfQ34A_pro)
df_pro_temp = df_pro_temp.join(dfQ35A_pro)

df_pro_temp = df_pro_temp.join(dfQ36_pro)
df_pro_temp = df_pro_temp.join(dfQ37_pro)
df_pro_temp = df_pro_temp.join(dfQ39_pro)

df_pro_temp = df_pro_temp.join(dfQ26B_pro)
df_pro_temp = df_pro_temp.join(dfQ27B_pro)
df_pro_temp = df_pro_temp.join(dfQ28B_pro)
df_pro_temp = df_pro_temp.join(dfQ29B_pro)
df_pro_temp = df_pro_temp.join(dfQ31B_pro)
df_pro_temp = df_pro_temp.join(dfQ33B_pro)
df_pro_temp = df_pro_temp.join(dfQ34B_pro)
df_pro_temp = df_pro_temp.join(dfQ35B_pro)

df_pro_temp.head(3).transpose()
#df_pro_temp.shape

df_pro = df_pro_temp

df_pro.shape

#df_pro.to_csv('/content/drive/MyDrive/Data/df_pro.csv')
# -*- coding: utf-8 -*- PyGraal_Livrable_1_DATAVIZ.ipynb  Automatically generated by Colaboratory.  Original file is located at     https://colab.research.google.com/drive/1VOdSSm0I_kGabrDsl7aFbr2HO6UOupVa  # Analyse des techniques et outils utilisés par les professionnels de la Data  Cette analyse repose sur un sondage contenant 20 036 réponses obtenues auprès de participants provenants de 171 pays différents.  Les participants ont dû répondre à une série d'une trentaine de questions. Quelques unes sont d'ordre personnel (Age, genre...) ou bien en rapport avec leur poste et entreprise actuels. Cepndant, l'essentiel concerne avant tout les outils utilisés dans le domaine de la Data Science (Langage de programmation, bibliothèque de Datavisualisaton...) ainsi que le rapport à l'utilisation de Machine Learning.  Ce sondage comprend à la fois des questions à choix unique et également à choix multiple.  A noter également que certaines questions étaient accessibles en fonction de réponses précédentes.  A partir de ce sondage, nous souhaitons établir des ensembles de compétences et outils correspondant aux divers postes monde de la Data, afin de construire dans un second temps un système de recommandation de poste permettant au demandeur de viser exactement le poste correspondant le plus à ses appétences.  # ANALYSE EXPLORATOIRE # Commented out IPython magic to ensure Python compatibility. # %matplotlib inline La visualisation du DataFrame nous permet de constater que pour les questions à choix multiples, chaque choix est une colonne avec deux valeurs possibles (Nan ou Valeur).  Ainsi nous pourrons traiter par la suite distinctement les questions à choix unique et les questions à choix multiple.  De plus, nous constatons que les différents postes en Data Science se trouve dans la colonne Q5.  Q5 correspond donc à notre variable cible pour la suite de l'étude. # Il n'y a que des valeurs catégorielles, un encodage sera nécessaire pour la création d'un modèle de Machine Learning.  ## Analyse et Nettoyage des Doublons et Valeurs Manquantes #Visualisation/Suppression des doublons #14 doublons #La première colonne (temps de réponse au questionnaire) n'est pas pertinente pour l'étude. #Recherche des Nans dans la variable cible #Suppression des Nans sur cette valeur #Vérif modification du nbre de lignes 20037 - 14 -745 La première ligne du DataFrame n'est pas une entrée mais correspond à l'intitulé des différentes questions. Cette entrée n'est donc pas à exploiter dans le DataFrame, mais elle reste intéressante pour la compréhension du jeu de données. #Création d'une base de données Questions à partir de la 1ère ligne de df #Suppression de la première ligne: #Vérif modification du nbre de lignes 19278 - 1 #Analyse des NaNs par % par colonne: Cela nous permet de constater des taux conséquents de NaNs.  Toutefois, pour rappel, certaines questions sont à choix multiples, par conséquent le phénomène s'explique en partie et pour ce type précis de questions les Nans seront à interpréter mais surtout pas à supprimer ou à remplacer par un mode.  Il paraît donc nécessaire de distinguer les questions à choix mutliple des questions à choix unique.  Un moyen simple de les distinguer est de s'appuyer sur le nombre de valeurs contenues dans chaque colonne. Les choix multiples ont été éclatés en colonne, contenant ainsi soit le choix retenu, soit une valeur manquante.  Par conséquent les questions à choix multiples ne contiennent que deux valeurs.  ## Traitement des questions à choix unique #Récupération des valeurs uniques pour chaque col #Recherche des colonnes avec + de 2 valeurs #quest_u regroupe les colonnes des questions choix unique #quest_u regroupe les colonnes des questions choix multiple Nous pouvons à présent observer la présence ou non de valeurs manquantes sur les colonnes de questions à choix unique. Nous remplaçons les valeurs manquantes par le mode de chaque colonne. #Remplacement des Nans des colonnes choix unique par le mode des colonnes ## Traitement des questions à choix multiples  Les questions à choix multiples sont plus difficiles à interpréter de par la manière dont elles ont été intégrées dans la base de données. Pour chaque question, un nombre de colonnes équivalent au nombre de réponses proposées a été créé. Pour chaque réponse, chaque colonne est remplie de la valeur de la réponse si le répondant a sélectionné ce choix et de Nan sinon. Il ne faut pas supprimer les valeurs manquantes sur ces colonnes car elles ont une utilité de compréhension.  Afin de pouvoir les utiliser et les analyser ultérieurement, il est cependant nécessaire de les encoder de manière binaire : 1 en cas de réponse positive, 0 si la valeur est manquante.  Dans un souci de flexibilité et de lisibilité, les différentes questions à choix multiples seront regroupées au sein de mini dataframes contenant en colonnes chacune des options proposées pour répondre à la question. #création de sub dataframes répliquant les intervalles créés pour les questions #dfQ7 à dfQ35B contiennent toutes les questions à multiples réponses #correspond aux réponses de la question 7, ie Q7 #Q9 #Q10 #Q12 #Q14 #Q16 #Q17 #Q18 #Q19 #Q23 #Q26A #Q27A #Q28A #Q29A #Q31A #Q33A #Q34A #Q35A #Q36 #Q37 #Q39 #Q26B #Q27B #Q28B #Q29B #Q31B #Q33B #Q34B #Q35B Une vérification rapide nous montre que dfQ7 intègre toutes les informations relatives à la question 7. Toutefois le libellé des colonnes est peu parlant. Nous allons donc les renommer en utilisant chaque choix comme nouveau titre. L'encodage se fera ensuite à partir du nouveau titre. Ce procédé permet aussi de supprimer tout risque de labélisation incorrecte, vu qu'il est très difficile de répérer à l'oeil nu le nombre d'espaces présents dans des cellules textes. # les codes ci-dessous ont été dupliqués autant de fois que nécessaire Le nettoyage ayant été réalisé, nous pouvons désormais émettre des hypothèses à rejeter ou non à l'aide de Data Visualization.  # DATA VISUALIZATION  ## Hypothèse 1 : Le Domaine de la Data regroupe 4/5 métiers #Visualisation des différents postes en DataScience (valeur cible) Cette première visualisation nous permet tout d'abord de rejeter notre hypothèse, car une dizaine de métiers sont représentés ici, dans le domaine de la Data.  Par ailleurs, nous constatons également trois catégories qui ne correspondent pas à des métiers et donc pas à des outils et compétences associés.  Il y a de fait un risque de biais conséquent sur la construction d'un modèle cherchant à prédire un métier sur une base d'outils et compétences techniques.  Afin de lever ce biais, nous excluons ces trois catégories "Non Professionnelles" pour la suite de l'analyse notre DataFrame . #Validation du df "Professionnel" qui servira pour le reste de l'analyse ## Hypothèse 2 : Le domaine de la Data resterait masculinisé #Visualisation de la répartition des Genres (Question 2) Nous constatons un déséquilibre flagrant, notre hypothèse ne peut donc être rejetée. Il apparaît toutefois intéressant de pousser l'analyse sur la répartition au sein des différents types de poste.  Pour simplifier la visualisation, nous garderons seulement les valeurs 'Woman' et 'Man'. #Filtre du df sur les valeurs 'Woman' et 'Man #Création d'une colonne pour comptage Nous constatons que les femmes sont proportionnellement plus nombreuses en Data Analysts et au même niveau en Data Scientists. Par contre elles sont sous-représentées en Machine Learning Engineers et en Product Managers.  ## Hypothèse 3 : Le domaine de la Data semble concerner un public de moins de 40 ans #Représentation de la distribution du panel de répondants par tranche d'âge Nous constatons que la majorité des postes en Data est occupée par des moins de 40 ans.  ## Hypothèse 4 : les "outils" les plus utilisés dans les métiers de la Data sont-ils ceux enseignés par DataScientest?  Afin d'illustrer de la manière la plus synthétique notre hypothèse, nous n'avons retenu que quatre questions portant respectivement sur l'utilsation quotidienne des :          Langages de programmation (question 7)         IDE (question 9)         DataViz (question 14)         Outils de Machine Learning (question 16)  Tous ces éléments sont abordés via des questions à choix multiples, où plusieurs réponses sont possibles. Les catégories représentées ci-dessous ne seront donc pas nécessairement disjointes.  De plus, notre base d'étude se restreignant désormais uniquement aux professionnels, il est nécessaire d'ajuster les bases de données des questions 7, 9, 14 et 16 aux individus concernés. Nous travaillons bien désormais sur un groupe de 10,717 individus. Python est de loin le langage de programmation le plus populaire dans les métiers de la data. Jupyter Notebook est l'IDE privilégié, bien que d'autres IDE soient aussi utilisés. Quand on parle de data visualization, Matplotlib et Seaborn se détachent clairement des autres outils à disposition. Enfin le Machine Learning se fait majoritairement via Scikit-learn, même si TensorFlow et Keras ont aussi un certain succés.  Le contenu de formation de DataScientest semble refléter de façon assez correcte, les outils actuellement utilisés par les professionnels de la data.  ## Hypothèse 5 : Big Data = Big Company? Le Machine Learning n'est-il utilisé que dans les grandes entreprises? On voit clairement que plus la taille de l'entreprise est grande, plus les modèles de ML sont non seulement en production depuis plus de 2 ans, mais aussi entrés dans la culture d'entreprise.  On constate toutefois que le ML est en cours de développement quelle que soit la taille de l'entreprise.  Donc nous rejetons notre hypothèse.  # Reconstitution du DataFrame à partir des divers sub DataFrames créés pour encoder les colonnes de questions à choix multiples  NB: Après consultation de la méthodologie du sondage, il apparait que les questions 30 et 32 n'ont été posées qu'à certaines personnes, en fonction des réponses aux questions précédentes, d'où le ratio de NaN conséquent traité au préalable.  Nous décidons de ne pas garder ces deux colonnes.  De plus, la Question 33_B nécessitant un traitement particulier mais n'étant pas nécessaire pour le livrable suivant, la colonne coresspondante n'est pas non plus retenue. #initialisation d'une base temporaire à partir des 6 premières colonnes #rajout des questions à réponses uniques #Filtre des divers subDataFrames sur les catégories "Professionnelles" de répondants #rajout des questions à réponses multiples #df_pro_temp.shape #df_pro.to_csv('/content/drive/MyDrive/Data/df_pro.csv')