In [1]:
# d'après le challenge Kaggle : https://www.kaggle.com/c/titanic

Données

data : Train : Matrix(n1,m) colonne = [ID, survécu, Class, Age, N_fs, N_pe, tarif, port, genre] ID Identifiant du passager survécu Si le passager à survécu (0 = non, 1 = oui) Class Passenger Class (1 = 1st; 2 = 2nd; 3 = 3rd) Age Age ('Nan' remplacé par l'age median) N_fs Nombre de freres, soeurs, epouse et mari à bord N_pe Nombre de parents enfants à bords Tarif tarif du passager ('Nan' rempl.acé par tarif median) port Port d'embarquement (0 = Cherbourg; 1 = Queenstown; 2 = Southampton) genre Genre du passager (0 = femme, 1 = homme)Test : Matrix(n2,m-1) colonne = [ID, Class, Age, N_fs, N_pe, tarif, port, genre]
In [2]:
#load train & test
import pandas
train = pandas.read_csv('train.csv').values
test = pandas.read_csv('test.csv').values

X = train[:,2:] # 891 x 7
y = train[:,1] # 891 x 1

X_test = test[:,1:] # 418 x 7

Classification

In [46]:
import numpy as np # import la librairie numpy (calcul scientifique)
import matplotlib.pyplot as plt # librairie pour afficher les graphs.
%matplotlib inline  
In [47]:
from sklearn import tree
In [ ]:
 
Exercices : a) Determiner en fonction du genre quelle proportion de personnes ont survécu. (i.e. proba(Survivre | femme)) De même avec la classe (1er classe étant la plus chère) et le port de départ. Quel est le facteur qui semble le plus informatif ? b) Calculer la quantité d'information donnée par genre = 0 (femme) c) Calculer la quantité d'information donnée par le genre. de même pour la classe et le port d'embarquation. Quel est le facteur qui apporte le plus d'information ? d) Entrainer un arbre de decision sur ces données, l'attribut 'feature_importances_' de tree.DecisionTreeClassifier() doone t'il les même résultats ?
In [22]:
survivants = np.zeros(2)
total = np.zeros(2)
for i in range(X.shape[0]):
    genre = train[i,8]
    surv = y[i]
    total[genre] += 1
    if surv == 1:
        survivants[genre] += 1
        
ratio_hf = survivants / total
print('Femmes ayant survecut:', np.round(ratio_hf[0],2),\
      '%.\n Hommes ayant survecut : ', np.round(ratio_hf[1],2),'%')
Femmes ayant survecut: 0.74 %.
 Hommes ayant survecut :  0.19 %
In [27]:
survivants = np.zeros(3)
total = np.zeros(3)
for i in range(X.shape[0]):
    classe = train[i,2]
    surv = y[i]
    total[classe-1] += 1
    if surv == 1:
        survivants[classe-1] += 1
        
ratio_classe = survivants / total
print('1er classe ayant survecut : {}% \n 2eme classe ayant survecut : {}% \n 3eme classe ayant\
survecut : {}% \n '.format(np.round(ratio_classe[0],2),np.round(ratio_classe[1],2),np.round(ratio_classe[2],2)))
1er classe ayant survecut : 0.63% 
 2eme classe ayant survecut : 0.47% 
 3eme classe ayantsurvecut : 0.24% 
 
In [31]:
survivants = np.zeros(3)
total = np.zeros(3)
for i in range(X.shape[0]):
    port = train[i,7]
    surv = y[i]
    total[port-1] += 1
    if surv == 1:
        survivants[port-1] += 1
        
ratio_port = np.round(survivants / total,2)
print('Ratio de survivants par port : \n\
Port 1 :', ratio_port[0], '%. \nPort  2: ', ratio_port[1], '%\nPort  3: ', ratio_port[2],'%')
Ratio de survivants par port : 
Port 1 : 0.39 %. 
Port  2:  0.34 %
Port  3:  0.55 %
b) Calculer la quantité d'information donnée par genre = 0 (femme)
In [50]:
print("I = -p * log(p) - (1-p) * log(1- p) \n \
avec p = Proba(survivre | genre = femme) \n\
(Rappel : un faible I est plus informatif qu'un I élevé.)")
I = -p * log(p) - (1-p) * log(1- p) 
 avec p = Proba(survivre | genre = femme) 
(Rappel : un faible I est plus informatif qu'un I élevé.)
In [43]:
def entropy(p):
    if p == 0 or p ==1 :
        return 0
    else:
        return - p*np.log(p) - (1-p)*np.log(1-p)
    
p = np.arange(0,1,0.01)
plt.plot(x,list(map(entropy,p)))

plt.title('fonction entropy')
plt.xlabel('p')
plt.ylabel('incertitude')
Out[43]:
<matplotlib.text.Text at 0x7f0b4511bd30>
In [9]:
I_femme = entropy(ratio_hf[0])
print('I_femme =', I_femme)
I_femme 0.570914192248
c) Calculer la quantité d'information donnée par le genre.
In [42]:
print("I_genre = proba(femme) * I(genre=femme) + proba(homme) * I(genre=homme)")
I_genre = proba(femme) * I(genre=femme) + proba(homme) * I(genre=homme)
In [33]:
genre = train[:,8]
proba_homme = np.sum(genre) / len(genre)
proba_femme = (len(genre) - np.sum(genre)) / len(genre)

I_genre = proba_homme * entropy(ratio_hf[1]) + proba_femme * entropy(ratio_hf[0])
print('Information donnée par le genre : I_genre =', I_genre)
Information donnée par le genre : I_genre = 0.515041484275
In [34]:
classe = train[:,2]
proba_classe1 = list(classe==1).count(True) / len(classe)
proba_classe2 = list(classe==2).count(True) / len(classe)
proba_classe3 = list(classe==3).count(True) / len(classe)

ratio_classe
I_classe = proba_classe1 * entropy(ratio_classe[0]) + \
            proba_classe2 * entropy(ratio_classe[1]) + \
            proba_classe3 * entropy(ratio_classe[2])

print('Information donnée par la classe : I_classe =' , I_classe)
Information donnée par la classe : I_classe = 0.607804720836
In [35]:
port = train[:,7]
proba_port1 = list(port==0).count(True) / len(port)
proba_port2 = list(port==1).count(True) / len(port)
proba_port3 = list(port==2).count(True) / len(port)

ratio_port
I_port = proba_port1 * entropy(ratio_port[0]) + \
            proba_port2 * entropy(ratio_port[1]) + \
            proba_port3 * entropy(ratio_port[2])

print('Information donnée par le port : I_port =', I_port)
Information donnée par le port : I_port = 0.680411991074
In [44]:
print("Bilan : \n Le genre a une quantite d'information plus faible, il est donc le facteur le plus discriminant")
Bilan : 
 Le genre a une quantite d'information plus faible, il est donc le facteur le plus discriminant
In [45]:
DT = tree.DecisionTreeClassifier()
DT.fit(X,y)
print('type - importance (higher is better)')
print('')
for type,imp in zip(['Class', 'Age', 'N_fs', 'N_pe', 'tarif', 'port', 'genre'],DT.feature_importances_):
    print(type,'-',imp)
    
print("\n On retrouve que le genre est un des facteurs les plus discriminant (avec l'age et le tarif des billets).\
\n Ici le port d'embarquement ne donnes presque aucune information.")
type - importance (higher is better)

Class - 0.107689904025
Age - 0.248930328039
N_fs - 0.0462099461317
N_pe - 0.0230868307888
tarif - 0.248064702502
port - 0.0151373431989
genre - 0.310880945315

 On retrouve que le genre est un des facteurs les plus discriminant (avec l'age et le tarif des billets).
 Ici le port d'embarquement ne donnes presque aucune information.
In [ ]:
 
In [ ]:
 

Submission for Kaggle

In [48]:
# make a submission for kaggle
def make_submission(output):
    
    test = pandas.read_csv('test.csv').values
    test_id = np.asarray(test[:,0],dtype = int)
    output = np.asarray(output,dtype = int)

    import csv
    predictions_file = open("my_submission.csv", "w")
    open_file_object = csv.writer(predictions_file)
    open_file_object.writerow(["PassengerId","Survived"])
    open_file_object.writerows(zip(test_id, output))
    predictions_file.close()
    
    print('submission save as "my_submission.csv"')
In [49]:
clf = tree.DecisionTreeRegressor()
clf.fit(X,y)
output = clf.predict(X_test)
make_submission(output)
submission save as "my_submission.csv"
In [255]:
clf = sklearn.ensemble.RandomForestClassifier()
clf.fit(X,y)
output = clf.predict(X_test)
make_submission(output)
submission save as "my_submission.csv"