Titanic - Correction

Last updated: October 8th, 20192019-10-08Project preview

Comprendre la donnée - Partie 1 : Traitement de données et data visualisation

In [2]:
import pandas as pa
import numpy as np

On importe les données

On commence par importer nos données. Elles se trouvent aux URLs suivantes.

In [3]:
df = pa.read_csv('https://gitlab.com/jwheat/titanic/raw/master/passengers.csv')
su = pa.read_csv('https://gitlab.com/jwheat/titanic/raw/master/survivors.csv')

Ensuite, je remarque que les deux jeux de données ont un champs en commun : PassengerId. Je peux donc les rejoindre en faisant un merge.

In [4]:
df = df.merge(su, on="PassengerId")

Premier coup d'oeil

Affichons les premières lignes

In [5]:
df.head()
Out[5]:
PassengerId Pclass Name Gender Age Fare Ticket Cabin Embarked Parch SibSp Survived
0 1 3 Braund, Mr. Owen Harris male 22.0 7.2500 A/5 21171 NaN S 0 1 0
1 2 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 71.2833 PC 17599 C85 C 0 1 1
2 3 3 Heikkinen, Miss. Laina female 26.0 7.9250 STON/O2. 3101282 NaN S 0 0 1
3 4 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 53.1000 113803 C123 S 0 1 1
4 5 3 Allen, Mr. William Henry male 35.0 8.0500 373450 NaN S 0 0 0

Combien de lignes ?

In [6]:
df.shape[0]
Out[6]:
891

Combien de colonnes ?

In [7]:
df.shape[1]
Out[7]:
12

Est-ce que nos données sont intègres ?

In [8]:
df["PassengerId"].isnull().sum()
Out[8]:
0
In [9]:
df["Pclass"].isnull().sum()
Out[9]:
0
In [10]:
df["Name"].isnull().sum()
Out[10]:
0
In [11]:
df["Gender"].isnull().sum()
Out[11]:
0
In [12]:
df["Age"].isnull().sum()
Out[12]:
177
In [13]:
df["SibSp"].isnull().sum()
Out[13]:
0
In [14]:
df["Parch"].isnull().sum()
Out[14]:
0
In [15]:
df["Ticket"].isnull().sum()
Out[15]:
0
In [16]:
df["Survived"].isnull().sum()
Out[16]:
0
In [17]:
df["Fare"].isnull().sum()
Out[17]:
0
In [18]:
df["Cabin"].isnull().sum()
Out[18]:
687
In [19]:
df["Embarked"].isnull().sum()
Out[19]:
2
In [20]:
df["Gender"].unique()
Out[20]:
array(['male', 'female', 'Male', 'Female'], dtype=object)
In [21]:
df["Pclass"].unique()
Out[21]:
array([ 3,  1,  2, -1])
In [22]:
df["Survived"].unique()
Out[22]:
array([0, 1])

Correction des données

In [23]:
# correction du gender
df = df.replace("Male", "male")
df = df.replace("Female", "female")
In [24]:
# correction des classes
df = df.query("Pclass != -1")
In [25]:
# correction de l'age
age_moyen = df["Age"].mean()
df["Age"] = df["Age"].fillna(age_moyen)
In [26]:
# correction de la cabine (on supprime la colonne)
df = df.drop(["Cabin"], axis=1)

Analyse

On importe les librairies utiles pour faire de la dataviz.

In [27]:
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

Analyse Univariée

In [28]:
sns.countplot(data=df, x="Gender")
Out[28]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c236f5710>
In [29]:
sns.countplot(data=df, x="Pclass")
Out[29]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c2829a410>
In [30]:
sns.countplot(data=df, x="Survived")
Out[30]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c27f8dd90>
In [31]:
sns.boxplot(
    data=df,
    x="Age"
)
Out[31]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c233ef490>

On voit qu'il y a des points qui "écrasent" notre graphique : ce sont des outliers. On peut rajouer showfliers=False pour les masquer et mieux voir les autres données.

In [32]:
sns.boxplot(
    data=df,
    x="Age",
    showfliers=False
)
Out[32]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c236f58d0>
In [33]:
sns.boxplot(
    data=df,
    x="Fare",
    showfliers=False
)
Out[33]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c236f5750>

Analyse bivariée

In [34]:
sns.countplot(data=df, x="Gender", hue="Survived")
Out[34]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c232d9850>
In [35]:
sns.countplot(data=df, x="Pclass", hue="Survived")
Out[35]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c23364d90>
In [36]:
sns.countplot(data=df, x="Pclass", hue="Gender")
Out[36]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c22b86290>
In [37]:
sns.boxplot(
    data=df,
    x="Gender",
    y="Age",
    showfliers=False
)
Out[37]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c2829a0d0>
In [38]:
sns.boxplot(
    data=df,
    x="Pclass",
    y="Age",
    showfliers=False
)
Out[38]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c22b0b810>
In [39]:
sns.boxplot(
    data=df,
    x="Pclass",
    y="Fare",
    showfliers=False
)
Out[39]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c22f66fd0>
In [40]:
sns.lmplot(
    data=df,
    x="Fare",
    y="Age"
)
/home/nbuser/anaconda2_501/lib/python2.7/site-packages/scipy/stats/stats.py:1713: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
  return np.add.reduce(sorted[indexer] * weights, axis=axis) / sumval
Out[40]:
<seaborn.axisgrid.FacetGrid at 0x7f5c2272a650>

Recherche de corrélations

Pour calculer les corrélations, on a besoin de passer le genre (qui est en texte) en nombre, afin que l'algorithme les comprenne.

In [41]:
# Correlation
# correction du gender
df.loc[df['Gender'] == "male", "Gender"] = 0
df.loc[df['Gender'] == "female", "Gender"] = 1
In [42]:
corr = df.corr(method='pearson', min_periods=0)
plt.figure(figsize=(10, 10))

sns.heatmap(corr, 
            linewidths=0.01,
            square=True,
            annot=True,
            cmap='RdBu',
            linecolor="white",
            center=0)
Out[42]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f5c22f46110>

On voit des corrélations entre Survived et Gender, Pclass et Fare, car les coefficients de corrélation sont significatifs (entre 0.26 et 0.55)

PCA : Analyse en composante principale

In [43]:
df.columns
dfp = df[["Pclass", "Gender", "Age", "SibSp", "Parch", "Fare"]]

dfp.head()
Out[43]:
Pclass Gender Age SibSp Parch Fare
0 3 0 22.0 1 0 7.2500
1 1 1 38.0 1 0 71.2833
2 3 1 26.0 0 0 7.9250
3 1 1 35.0 1 0 53.1000
4 3 0 35.0 0 0 8.0500
In [44]:
from sklearn.decomposition import PCA
In [45]:
pca = PCA(n_components=6)
principalComponents = pca.fit_transform(dfp)
In [46]:
print pca.explained_variance_ratio_
print pca.explained_variance_ratio_.cumsum()
[9.35945336e-01 6.31653252e-02 4.76587203e-04 1.77806219e-04
 1.59721092e-04 7.52244813e-05]
[0.93594534 0.99911066 0.99958725 0.99976505 0.99992478 1.        ]

On peut lire que la première composante créée par la PCA résume 93% de l'information du dataset. En regardant le tableau ci-dessous, cette composante est composée essentiellement du prix du ticket.

In [47]:
cov = pa.DataFrame(pca.components_)
cov.columns = dfp.columns
cov[cov < 0.01] = np.nan
cov
Out[47]:
Pclass Gender Age SibSp Parch Fare
0 NaN NaN 0.025400 NaN NaN 0.999621
1 NaN NaN 0.999191 NaN NaN NaN
2 0.126614 0.052541 0.027066 0.899557 0.413830 NaN
3 0.122935 0.185567 NaN NaN 0.874630 NaN
4 0.973282 NaN 0.014171 NaN NaN NaN
5 NaN NaN NaN NaN 0.214623 NaN
Notebooks AI
Notebooks AI Profile20060