[PYTHON] Prédiction des survivants à l'aide du réseau neuronal titanesque de Kaggle [80,8%]

La dernière fois, j'ai essayé de prédire le taux de survie en utilisant xgboost en fonction de l'arbre de décision. Dernière fois: Prédiction de survie utilisant le boost xg titanesque de Kaggle [80,1%]

Cette fois, je vais essayer de prédire la survie du Titanic en utilisant ** Neural Network **, qui est souvent utilisé dans kaggle.

1. Acquisition des données et confirmation des valeurs manquantes

import pandas as pd
import numpy as np

train = pd.read_csv('/kaggle/input/titanic/train.csv')
test = pd.read_csv('/kaggle/input/titanic/test.csv')
#Combinez les données de train et les données de test en un seul
data = pd.concat([train,test]).reset_index(drop=True)
#Vérifiez le nombre de lignes contenant des valeurs manquantes
train.isnull().sum()
test.isnull().sum()

Le numéro de chaque valeur manquante est le suivant.

données de train données de test
PassengerId 0 0
Survived 0
Pclass 0 0
Name 0 0
Sex 0 0
Age 177 86
SibSp 0 0
Parch 0 0
Ticket 0 0
Fare 0 1
Cabin 687 327
Embarked 2 0

2. Compléter les valeurs manquantes et créer des fonctionnalités

2.1 Complément de tarif

La ligne manquante avait une ** Pclass de 3 ** et ** Embarked était S **. スクリーンショット 2020-10-01 12.01.00.png Compléter avec la médiane ** parmi ceux qui remplissent ces deux conditions **.

data['Fare'] = data['Fare'].fillna(data.query('Pclass==3 & Embarked=="S"')['Fare'].median())

2.2 Différence de vie et de mort entre les groupes Création de la «survie de la famille»

Titanic [0.82] - [0.83] Création de la quantité de fonctionnalités "Family_survival" introduite dans ce code. Je vais.

** La famille et les amis sont plus susceptibles d'agir ensemble à bord **, on peut donc dire que le fait qu'ils aient survécu ou non ** a tendance à avoir le même résultat au sein du groupe **.

Par conséquent, le regroupement est effectué par le prénom et le nom et le numéro de ticket, et la valeur est déterminée par le fait que les membres du groupe sont en vie ou non.

** En créant ce montant de caractéristiques, le taux de précision de la prédiction s'est amélioré d'environ 2% **, ce regroupement est donc assez efficace.

#Obtenez le nom de famille du nom'Last_name'Mettre en
data['Last_name'] = data['Name'].apply(lambda x: x.split(",")[0])

data['Family_survival'] = 0.5 #Valeur par défaut
#Last_Regroupement par nom et tarif
for grp, grp_df in data.groupby(['Last_name', 'Fare']):
                               
    if (len(grp_df) != 1):
        #(Même nom)Et(Le tarif est le même)Quand il y a deux personnes ou plus
        for index, row in grp_df.iterrows():
            smax = grp_df.drop(index)['Survived'].max()
            smin = grp_df.drop(index)['Survived'].min()
            passID = row['PassengerId']
            
            if (smax == 1.0):
                data.loc[data['PassengerId'] == passID, 'Family_survival'] = 1
            elif (smin == 0.0):
                data.loc[data['PassengerId'] == passID, 'Family_survival'] = 0
            #À propos des membres autres que vous dans le groupe
            #Même une personne est en vie → 1
            #Aucun survivant(Y compris NaN) → 0
            #Tout NaN → 0.5

#Regroupement par numéro de billet
for grp, grp_df in data.groupby('Ticket'):
    if (len(grp_df) != 1):
        #Lorsqu'il y a deux personnes ou plus avec le même numéro de billet
        #S'il y a même un survivant dans le groupe'Family_survival'À 1
        for ind, row in grp_df.iterrows():
            if (row['Family_survival'] == 0) | (row['Family_survival']== 0.5):
                smax = grp_df.drop(ind)['Survived'].max()
                smin = grp_df.drop(ind)['Survived'].min()
                passID = row['PassengerId']
                if (smax == 1.0):
                    data.loc[data['PassengerId'] == passID, 'Family_survival'] = 1
                elif (smin == 0.0):
                    data.loc[data['PassengerId'] == passID, 'Family_survival'] = 0

2.3 Création et classification de la quantité de caractéristiques 'Taille_famille' représentant le nombre de membres de la famille

En utilisant les valeurs de SibSp et Parch, nous allons créer une quantité caractéristique «Taille de la famille» qui indique le nombre de familles à bord du Titanic, et les classer en fonction du nombre de personnes.

#Family_Création de taille
data['Family_size'] = data['SibSp']+data['Parch']+1
#1, 2~4, 5~Divisez en trois
data['Family_size_bin'] = 0
data.loc[(data['Family_size']>=2) & (data['Family_size']<=4),'Family_size_bin'] = 1
data.loc[(data['Family_size']>=5) & (data['Family_size']<=7),'Family_size_bin'] = 2
data.loc[(data['Family_size']>=8),'Family_size_bin'] = 3

2.4 Création du titre du titre 'Titre'

Obtenez des titres tels que «Monsieur», «Miss» dans la colonne Nom. Incorporez quelques titres («Mme», «Mlle», etc.) dans des titres qui ont la même signification.

#Obtenez le titre du nom'Title'Mettre en
data['Title'] = data['Name'].map(lambda x: x.split(', ')[1].split('. ')[0])
#Intégrez quelques titres
data['Title'].replace(['Capt', 'Col', 'Major', 'Dr', 'Rev'], 'Officer', inplace=True)
data['Title'].replace(['Don', 'Sir',  'the Countess', 'Lady', 'Dona'], 'Royalty', inplace=True)
data['Title'].replace(['Mme', 'Ms'], 'Mrs', inplace=True)
data['Title'].replace(['Mlle'], 'Miss', inplace=True)
data['Title'].replace(['Jonkheer'], 'Master', inplace=True)

2.5 Complémentation et classification par âge

Utilisez ** l'âge moyen obtenu pour chaque titre du nom ** pour compléter la valeur manquante Age. Ensuite, il est divisé en trois catégories: ** enfants (0-18), adultes (18-60) et personnes âgées (60-) **.

#Complétez la valeur manquante de Age avec la valeur moyenne de chaque titre
title_list = data['Title'].unique().tolist()
for t in title_list:
    index = data[data['Title']==t].index.values.tolist()
    age = data.iloc[index]['Age'].mean()
    age = np.round(age,1)
    data.iloc[index,5] = data.iloc[index,5].fillna(age)

#Classification par âge
data['Age_bin'] = 0
data.loc[(data['Age']>18) & (data['Age']<=60),'Age_bin'] = 1
data.loc[(data['Age']>60),'Age_bin'] = 2

2.6 Standardisation du tarif et variable fictive du montant de la fonction

Étant donné que la différence d'échelle des variables est importante pour la valeur du tarif, ** normaliser ** (la valeur moyenne est 0, l'écart type est 1) afin que le réseau neuronal puisse être facilement appris.

Ensuite, la chaîne qui est une chaîne de caractères est transformée en une variable factice avec get_dummies. ** Pclass est une valeur numérique **, mais ** la taille de la valeur elle-même n'a aucune signification **, alors convertissons-la également en variable factice.

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
#Une version standardisée de Fare'Fare_std'Mettre en
data['Fare_std'] = sc.fit_transform(data[['Fare']])
#Convertir en variable factice
data['Sex'] = data['Sex'].map({'male':0, 'female':1})
data = pd.get_dummies(data=data, columns=['Title','Pclass','Family_survival'])

Enfin, supprimez les fonctionnalités inutiles.

data = data.drop(['PassengerId','Name','Age','SibSp','Parch','Ticket',
                     'Fare','Cabin','Embarked','Family_size','Last_name'], axis=1)

La trame de données ressemble à ceci.

Survived Sex Family_size_bin Age_bin Fare_std Title_Master Title_Miss Title_Mr Title_Mrs Title_Officer Title_Royalty Pclass_1 Pclass_2 Pclass_3 Family_survival_0.0 Family_survival_0.5 Family_survival_1.0
0 0.0 0 1 1 -0.503176 0 0 1 0 0 0 0 0 1 0 1 0
1 1.0 1 1 1 0.734809 0 0 0 1 0 0 1 0 0 0 1 0
2 1.0 1 0 1 -0.490126 0 1 0 0 0 0 0 0 1 0 1 0
3 1.0 1 1 1 0.383263 0 0 0 1 0 0 1 0 0 1 0 0
4 0.0 0 0 1 -0.487709 0 0 1 0 0 0 0 0 1 0 1 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1304 NaN 0 0 1 -0.487709 0 0 1 0 0 0 0 0 1 0 1 0
1305 NaN 1 0 1 1.462069 0 0 0 0 0 1 1 0 0 0 0 1
1306 NaN 0 0 1 -0.503176 0 0 1 0 0 0 0 0 1 0 1 0
1307 NaN 0 0 1 -0.487709 0 0 1 0 0 0 0 0 1 0 1 0
1308 NaN 0 1 0 -0.211081 1 0 0 0 0 0 0 0 1 0 0 1

1309 rows × 17 columns

Les données intégrées sont divisées en données de train et données de test, et le traitement des caractéristiques est terminé.

model_train = data[:891]
model_test = data[891:]

x_train = model_train.drop('Survived', axis=1)
y_train = pd.DataFrame(model_train['Survived'])
x_test = model_test.drop('Survived', axis=1)

3. Construction de modèles et prédiction

Maintenant que la trame de données est terminée, construisons un modèle du réseau neuronal et faisons des prédictions.

from keras.layers import Dense,Dropout
from keras.models import Sequential
from keras.callbacks import EarlyStopping
#Initialisation du modèle
model = Sequential()
#Construction de couches
model.add(Dense(12, activation='relu', input_dim=16))
model.add(Dropout(0.2))
model.add(Dense(8, activation='relu'))
model.add(Dense(5, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
#Construire un modèle
model.compile(optimizer = 'adam', loss='binary_crossentropy', metrics='acc')
#Voir la structure du modèle
model.summary()

スクリーンショット 2020-10-15 11.12.07.png Former en passant les données du train. Si vous définissez validation_split, ce sera facile car les données de validation seront divisées arbitrairement à partir des données du train.

log = model.fit(x_train, y_train, epochs=5000, batch_size=32,verbose=1,
                callbacks=[EarlyStopping(monitor='val_loss',min_delta=0,patience=100,verbose=1)],
                validation_split=0.3)

スクリーンショット 2020-10-15 11.20.07.png

Cela ressemble à ceci lorsque l'état d'avancement de l'apprentissage est affiché dans un graphique.

import matplotlib.pyplot as plt
plt.plot(log.history['loss'],label='loss')
plt.plot(log.history['val_loss'],label='val_loss')
plt.legend(frameon=False)
plt.xlabel('epochs')
plt.ylabel('crossentropy')
plt.show()

スクリーンショット 2020-10-15 11.11.03.png

Enfin, predict_classes est utilisé pour afficher la valeur prédite.

#Prédire s'il sera classé 0 ou 1
y_pred_cls = model.predict_classes(x_test)
#Créer un bloc de données pour kaggle
y_pred_cls = y_pred_cls.reshape(-1)
submission = pd.DataFrame({'PassengerId':test['PassengerId'], 'Survived':y_pred_cls})
submission.to_csv('titanic_nn.csv', index=False)

Le taux de réponse correcte de ce modèle de prédiction était de ** 80,8% **. Je ne sais pas si ce modèle créé est optimal car le réseau neuronal peut décider librement des paramètres et du nombre de couches du modèle, mais s'il dépasse 80%, c'est raisonnable. スクリーンショット 2020-10-15 12.58.37.png

Si vous avez des opinions ou des suggestions, nous vous serions reconnaissants de bien vouloir faire un commentaire ou une demande de modification.

Sites et livres auxquels j'ai fait référence

Titanic - Neural Networks [KERAS] - 81.8% Titanic [0.82] - [0.83] [Technologie d'analyse de données qui gagne avec Kaggle](https://www.amazon.co.jp/Kaggle%E3%81%A7%E5%8B%9D%E3%81%A4%E3%83%87%E3% 83% BC% E3% 82% BF% E5% 88% 86% E6% 9E% 90% E3% 81% AE% E6% 8A% 80% E8% A1% 93-% E9% 96% 80% E8% 84 % 87-% E5% A4% A7% E8% BC% 94-ebook / dp / B07YTDBC3Z) [Deep Learning from scratch-Theory et implémentation du deep learning appris avec Python](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3] % 82% 89% E4% BD% 9C% E3% 82% 8BApprentissage en profondeur-% E2% 80% 95Python% E3% 81% A7% E5% AD% A6% E3% 81% B6% E3% 83% 87% E3% 82% A3% E3% 83% BC% E3% 83% 97% E3% 83% A9% E3% 83% BC% E3% 83% 8B% E3% 83% B3% E3% 82% B0% E3% 81% AE% E7% 90% 86% E8% AB% 96% E3% 81% A8% E5% AE% 9F% E8% A3% 85-% E6% 96% 8E% E8% 97% A4-% E5% BA% B7% E6% AF% 85 / dp / 4873117585)

Recommended Posts

Prédiction des survivants à l'aide du réseau neuronal titanesque de Kaggle [80,8%]
Prédiction de survivant utilisant le boost de xg titanesque de Kaggle [80,1%]
Implémentation simple d'un réseau neuronal à l'aide de Chainer
Essayez d'utiliser TensorFlow-Part 2-Convolution Neural Network (MNIST)
Implémentation de réseaux neuronaux "flous" avec Chainer
Implémentation de réseau neuronal simple à l'aide de la préparation Chainer-Data-
Implémentation de réseau neuronal simple à l'aide de la description du modèle Chainer-
Implémentation simple d'un réseau de neurones à l'aide de Chainer ~ Définition d'un algorithme d'optimisation ~
Apprentissage par renforcement 10 Essayez d'utiliser un réseau neuronal formé.
Une autre méthode de conversion de style utilisant le réseau neuronal convolutif
Réseau neuronal paramétrique
Estimation de l'auteur à l'aide du réseau neuronal et de Doc2Vec (Aozora Bunko)
Modèle utilisant un réseau neuronal convolutif dans le traitement du langage naturel
Implémentation d'un réseau de neurones convolutifs utilisant uniquement Numpy
Implémenter un réseau neuronal convolutif
Implémenter le réseau neuronal à partir de zéro
Expérience de réseau de neurones pliable
Essayez le didacticiel Titanic de Kaggle
Apprentissage des classements à l'aide d'un réseau neuronal (implémentation RankNet par Chainer)
Prédiction de survie Titanic à l'aide de l'outil de gestion du flux de travail d'apprentissage automatique Kedro
Essayez de créer un réseau de neurones en Python sans utiliser de bibliothèque