[PYTHON] L'histoire d'un technicien de haut niveau essayant de prédire la survie du Titanic


** Site auquel j'ai fait référence en faisant cette fois ** https://yolo-kiyoshi.com/2020/01/22/post-1588/ https://www.codexa.net/kaggle-titanic-beginner/ https://qiita.com/suzumi/items/8ce18bc90c942663d1e6


Pensées / biais

――Il semble difficile de survivre dans un environnement glacial. .. Les femmes et les enfants sur l'embarcation de sauvetage ont-ils bénéficié d'un traitement préférentiel?

――La personne à statut social élevé ne bénéficie-t-elle pas d'un traitement préférentiel?

Confirmation des données

Vérifier avec info () 2020-04-17 (2).png À partir d'informations (), vous pouvez voir que l'âge et la cabine sont manquants. image.png

Que faire des valeurs manquantes?

C'est comme ça quand je résume personnellement mon expérience de l'analyse de données depuis longtemps. Comment allez-vous, les gars?

image.png

Dans ce cas, l'âge avec une carence moyenne est moyen ou médian, et Cabin est une carence importante, il n'est donc pas utilisé. .. Je voudrais dire que cela est fait d'une manière facile à comprendre par d'autres personnes, alors faisons cette partie boueuse

Carence d'âge

En ce qui concerne le manque d'âge, je pense que l'important est le nom. Parmi eux, il y a des informations précieuses comme ce qu'on appelle un titre, hommes et femmes, adultes et enfants, mariés / célibataires s'il s'agit d'une femme, statut élevé, etc.

En particulier, c'est un navire qui est susceptible d'être utilisé par des personnes dans la trentaine en moyenne. La présence d'enfants et de personnes âgées dans des positions élevées réduit la précision de l'âge

Donc, tout d'abord, je vais extraire le titre.

in: #Afficher le nom
train_data['Name']

out:
0                                Braund, Mr. Owen Harris
1      Cumings, Mrs. John Bradley (Florence Briggs Th...
2                                 Heikkinen, Miss. Laina
3           Futrelle, Mrs. Jacques Heath (Lily May Peel)
4                               Allen, Mr. William Henry
                             ...                        
886                                Montvila, Rev. Juozas
887                         Graham, Miss. Margaret Edith
888             Johnston, Miss. Catherine Helen "Carrie"
889                                Behr, Mr. Karl Howell
890                                  Dooley, Mr. Patrick
Name: Name, Length: 891, dtype: object

Si vous regardez les données à vol d'oiseau, il y a un titre entre "," et "."

in: #Je veux extraire le titre du nom
#Test de train de fusion
train_data1 = train_data.copy()
test_data1 = test_data.copy()
train_data1['train_or_test'] = 'train' 
test_data1['train_or_test'] = 'test' 
test_data1['Survived'] = np.nan #Définissez la colonne Survived sur NaN pour les tests
all_data = pd.concat(
    [
        train_data1,
        test_data1
    ],
    sort=False,
    axis=0 #Former dans le sens de la colonne_data1、test_Combiner les données1
).reset_index(drop=True)
#all_Extraire le titre des données+Calculer l'âge moyen
honorific=all_data['honorific'] = all_data['Name'].map(lambda x: x.split(', ')[1].split('. ')[0])
Average_age=all_data['Age'].groupby(all_data['honorific']).agg(['count','mean','median','std'])
Average_age

Cela vous donnera un âge moyen pour chaque titre 2020-04-19 (2).png

Maintenant, entrons l'âge moyen à partir des titres des données manquantes en fonction de ces données.

in:Appliquer l'âge moyen de chaque titre à la valeur manquante
f = lambda x: x.fillna(x.mean())
age_complement = all_data.groupby('honorific').transform(f)
age_complement.info()


out:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1309 entries, 0 to 1308
Data columns (total 7 columns):
PassengerId    1309 non-null int64
Survived       1308 non-null float64
Pclass         1309 non-null int64
Age            1309 non-null float64
SibSp          1309 non-null int64
Parch          1309 non-null int64
Fare           1309 non-null float64
dtypes: float64(3), int64(4)
memory usage: 71.7 KB

Ceci complète la carence en âge. Mais pour une raison quelconque, la colonne a disparu Transférer à l'âge initial de all_data

del(all_data['Age']) #all_Supprimer l'âge des données
all_data['Age']=age_complement['Age'] #Créez une colonne Âge et mettez-y les données d'âge de la personne qui a complété la zone manquante

Ceci termine le traitement des valeurs manquantes dans les données d'âge.

Variations tarifaires qui m'inquiétaient lors de la manipulation des données

En regardant les données, j'étais inquiet de la variation du prix du tarif, donc ce n'est pas le prix par personne, mais le montant total du groupe est substitué,? J'ai pensé. Tarif / Je compterai le nombre de billets en double et je le retournerai au prix raisonnable par personne

in:# 1.Créer un tableau de type dictionnaire qui représente le nombre de tickets en double
double_check_dict = all_data['Ticket'].value_counts().to_dict()

# 2.Ajouter plusieurs colonnes à un DataFrame
all_data['double_check'] = all_data['Ticket'].apply(lambda x: double_check_dict[x] if x in double_check_dict else 0)
all_data['Fare']=all_data['Fare']/all_data['double_check']
all_data

2020-04-19 (5).png

Double_check est le nombre de billets en double, mais après tout, le prix du tarif monte en flèche là où il y a beaucoup de billets, donc divisez le tarif par le nombre de billets.

in:
all_data['Fare']=all_data['Fare']/all_data['double_check']
all_data

image.png

Avec cela, nous avons pu supprimer les variations de prix.

** Si les chambres Cabin sont désormais stratifiées par prix, pourquoi ne pas obtenir la plupart des chambres à partir de Fare? Je pense **

Pensez à la cabine

Nous décomposerons les données contenant les données Cabin.

in:
cabin_data=all_data.dropna() #Extraire uniquement ceux avec des données de cabine
cabin_data['Cabin_id'] = cabin_data['Cabin'].map(lambda x:x[0]) #Cabin_Mettez l'acronyme Cabin dans id
cabin_data['room']=cabin_data['Cabin'].map(lambda x:x.count(' '))+1
cabin_data.head(50) 

image.png

Demandez-vous si vous pouvez calculer le prix de la chambre séparément pour chaque classe P

Pour voir s'il y a une différence de prix dans le classement de chaque chambre, faites un tout, divisé par P_class 1 2 3 et pensez au prix de chaque chambre

cabin_data_1=cabin_data.query('Pclass == "1"')
cabin_data_2=cabin_data.query('Pclass == "2"')
cabin_data_3=cabin_data.query('Pclass == "3"')

Average_ageC=cabin_data['Fare'].groupby(cabin_data['Cabin_id']).agg(['count','mean','median','std','max','min'])
Average_ageC

Cliquez ici pour le prix global image.png

Average_ageC=cabin_data_1['Fare'].groupby(cabin_data_1['Cabin_id']).agg(['count','mean','median','std','max','min'])
Average_ageC

Pclass1 image.png

Average_ageC=cabin_data_2['Fare'].groupby(cabin_data_2['Cabin_id']).agg(['count','mean','median','std','max','min'])
Average_ageC

Pclass2 image.png

Average_ageC=cabin_data_3['Fare'].groupby(cabin_data_3['Cabin_id']).agg(['count','mean','median','std','max','min'])
Average_ageC

Pclass3 image.png

Cela ressemble à ceci quand vous le regardez grossièrement, mais par exemple, si les frais d'utilisation sont différents pour chaque pièce dans la même bande de classe, il est possible d'estimer la valeur manquante de Cabin, mais c'est presque la même et il semble qu'elle ne puisse pas être estimée exactement. Hmm, désolé image.png

Obtenez le nombre de membres de la famille de SibSp et Parch

all_data['famiry_size']=all_data['SibSp']+all_data['Parch']+1

Divisez le tarif en 11

Je l'ai divisé en 11 parties, mais j'ai l'impression que je peux encore creuser profondément ici.

#Tarif partagé
all_data['Fare_bin'] = pd.qcut(all_data.Fare, 11)#Tarif à tarif_Divisez en 11 comme bac

Diviser le sexe

sex_col = ['Sex']
le = LabelEncoder()
for col in sex_col:
    all_data[col] = le.fit_transform(all_data[col]) #Diviser Sex male famale en 0 et 1

Remplacez'Pclass ',' Embarked ',' honororific ',' Fare_bin ',' famiry_size ', par des variables catégorielles

cat_col = ['Pclass','Embarked','honorific','Fare_bin','famiry_size',]
all_data = pd.get_dummies(all_data, drop_first=True, columns=cat_col)#'Pclass','Embarked','honorific','Fare_bin','famiry_size'Est transformé en une variable fictive avec 0 et 1

C'est tout pour diviser chaque colonne.

Divisez all_data en données de train et de test

from sklearn.model_selection import train_test_split
 
train = all_data.query('train_or_test == "train"')#'train_or_extrait de test train
test = all_data.query('train_or_test == "test"')
#Définissez des variables cibles et des colonnes inutiles pour la formation
target_col = 'Survived'
drop_col = ['PassengerId','Survived', 'Name', 'Fare', 'Ticket', 'Cabin', 'train_or_test','Parch','SibSp','honorific_Jonkheer','honorific_Mme','honorific_Dona','honorific_Lady','honorific_Ms',]
#Contient uniquement les fonctionnalités requises pour l'apprentissage
train_feature = train.drop(columns=drop_col)
test_feature = test.drop(columns=drop_col)
train_tagert = train[target_col]
#Données de train fractionnées
X_train, X_test, y_train, y_test = train_test_split(
    train_feature, train_tagert, test_size=0.3, random_state=0, stratify=train_tagert)

Apprentissage

En tant que bibliothèque RandomForestClassifier SVC LogisticRegression CatBoostClassifier Utilisation

from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from catboost import CatBoostClassifier


rfc = RandomForestClassifier(random_state=0)
rfc.fit(X_train, y_train)
print('='*20)
print('RandomForestClassifier')
print(f'accuracy of train set: {rfc.score(X_train, y_train)}')
print(f'accuracy of test set: {rfc.score(X_test, y_test)}')


lr = LogisticRegression(random_state=0)
lr.fit(X_train, y_train)
print('='*20)
print('LogisticRegression')
print(f'accuracy of train set: {lr.score(X_train, y_train)}')
print(f'accuracy of train set: {lr.score(X_test, y_test)}')

svc = SVC(random_state=0)
svc.fit(X_train, y_train)
print('='*20)
print('SVC')
print(f'accuracy of train set: {svc.score(X_train, y_train)}')
print(f'accuracy of train set: {svc.score(X_test, y_test)}')


cat = CatBoostClassifier(random_state=0)
cat.fit(X_train, y_train)
print('='*20)
print('CAT')
print(f'accuracy of train set: {cat.score(X_train, y_train)}')
print(f'accuracy of train set: {cat.score(X_test, y_test)}')

Comme l'extérieur

RandomForestClassifier
accuracy of train set: 0.9678972712680578
accuracy of test set: 0.8246268656716418
LogisticRegression
accuracy of train set: 0.8426966292134831
accuracy of train set: 0.832089552238806
SVC
accuracy of train set: 0.8330658105939005
accuracy of train set: 0.8134328358208955
CAT
accuracy of train set: 0.9085072231139647
accuracy of train set: 0.8507462686567164

Ajuster les hyperparamètres avec les tests Oputuna et Kfold

RandomForestClassifier

from sklearn.model_selection import StratifiedKFold, cross_validate
import optuna

cv = 10
def objective(trial):
    
    param_grid_rfc = {
        "max_depth": trial.suggest_int("max_depth", 5, 15),
        "min_samples_leaf": trial.suggest_int("min_samples_leaf", 1, 5),
        'min_samples_split': trial.suggest_int("min_samples_split", 7, 15),
        "criterion": trial.suggest_categorical("criterion", ["gini", "entropy"]),
        'max_features': trial.suggest_int("max_features", 3, 10),
        "random_state": 0
    }
 
    model = RandomForestClassifier(**param_grid_rfc)
    
    # 5-Fold CV /Évaluez le modèle avec précision
    kf = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
    scores = cross_validate(model, X=X_train, y=y_train, cv=kf)
    #1 car il est minimisé.Soustrayez le score de 0
    return scores['test_score'].mean()
 
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)
print(study.best_params)
print(study.best_value)
rfc_best_param = study.best_params


SVC

import warnings
warnings.filterwarnings('ignore')

def objective(trial):
    
    param_grid_lr = {
        'C' : trial.suggest_int("C", 1, 100),
        "random_state": 0
    }

    model = LogisticRegression(**param_grid_lr)
    
    # 5-Fold CV /Évaluez le modèle avec précision
    kf = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
    scores = cross_validate(model, X=X_train, y=y_train, cv=kf)
    #1 car il est minimisé.Soustrayez le score de 0
    return scores['test_score'].mean()

study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)
print(study.best_params)
print(study.best_value)
lr_best_param = study.best_params 

LogisticRegression

import warnings
warnings.filterwarnings('ignore')

def objective(trial):
    
    param_grid_svc = {
        'C' : trial.suggest_int("C", 50, 200),
        'gamma': trial.suggest_loguniform("gamma", 1e-4, 1.0),
        "random_state": 0,
        'kernel': 'rbf'
    }

    model = SVC(**param_grid_svc)
    
    # 5-Fold CV /Évaluez le modèle avec précision
    kf = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
    scores = cross_validate(model, X=X_train, y=y_train, cv=kf)
    #1 car il est minimisé.Soustrayez le score de 0
    return scores['test_score'].mean()

study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100)
print(study.best_params)
print(study.best_value)
svc_best_param = study.best_params

CatBoostClassifier

from sklearn.model_selection import train_test_split
from catboost import Pool
import sklearn.metrics
X = train_feature
y = test_feature
categorical_features_indices = np.where(X.dtypes != np.float)[0]
def objective(trial):
    #Séparez les données d'entraînement et les données de test
    X_train, X_test, y_train, y_test = train_test_split(
    train_feature, train_tagert, test_size=0.35, random_state=0, stratify=train_tagert)
    train_pool = Pool(X_train, y_train, cat_features=categorical_features_indices)
    test_pool = Pool(X_test,y_test, cat_features=categorical_features_indices)

    #Spécification des paramètres
    params = {
        'iterations' : trial.suggest_int('iterations', 50, 300),                         
        'depth' : trial.suggest_int('depth', 4, 10),                                       
        'learning_rate' : trial.suggest_loguniform('learning_rate', 0.01, 0.3),               
        'random_strength' :trial.suggest_int('random_strength', 0, 100),                       
        'bagging_temperature' :trial.suggest_loguniform('bagging_temperature', 0.01, 100.00), 
        'od_type': trial.suggest_categorical('od_type', ['IncToDec', 'Iter']),
        'od_wait' :trial.suggest_int('od_wait', 10, 50)
    }

    #Apprentissage
    model = CatBoostClassifier(**params)
    # 5-Fold CV /Évaluez le modèle avec précision
    kf = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)
    scores = cross_validate(model, X=X_train, y=y_train, cv=kf)

    #1 car il est minimisé.Soustrayez le score de 0
    return scores['test_score'].mean()

if __name__ == '__main__':
    study = optuna.create_study()
    study.optimize(objective, n_trials=5)
    cat_best_param = study.best_params
    print(study.best_value)
    print(cat_best_param)


Vérifiez à nouveau la précision avec le paramètre ajusté

# 5-Fold CV /Évaluez le modèle avec précision
kf = StratifiedKFold(n_splits=5, shuffle=True, random_state=0)

rfc_best = RandomForestClassifier(**rfc_best_param)
print('RandomForestClassifier')
scores = cross_validate(rfc_best, X=train_feature, y=train_tagert, cv=kf)
print(f'mean:{scores["test_score"].mean()}, std:{scores["test_score"].std()}')

lr_best = LogisticRegression(**lr_best_param)
print('LogisticRegression')
scores = cross_validate(lr_best, X=train_feature, y=train_tagert, cv=kf)
print(f'mean:{scores["test_score"].mean()}, std:{scores["test_score"].std()}')

svc_best = SVC(**svc_best_param)
print('SVC')
scores = cross_validate(svc_best, X=train_feature, y=train_tagert, cv=kf)
print(f'mean:{scores["test_score"].mean()}, std:{scores["test_score"].std()}')

cat_best =CatBoostClassifier
print('CAT')
scores = cross_validate(cat, X=train_feature, y=train_tagert, cv=kf)
print(f'mean:{scores["test_score"].mean()}, std:{scores["test_score"].std()}')

Par conséquent

RandomForestClassifier
mean:0.827152263628423, std:0.029935476082608138
LogisticRegression
mean:0.8294309818436642, std:0.03568888547665349
SVC
mean:0.826034945192669, std:0.03392425879847107
CAT
mean:0.8249241166088076, std:0.030217830226771592

est devenu. LogisticRegression est le plus précis, mais il a également une valeur std élevée.

# RandomForest
rfc_best = RandomForestClassifier(**rfc_best_param)
rfc_best.fit(train_feature, train_tagert)

# LogisticRegression
lr_best = LogisticRegression(**lr_best_param)
lr_best.fit(train_feature, train_tagert)

# SVC
svc_best = SVC(**svc_best_param)
svc_best.fit(train_feature, train_tagert)

#CatBoostClassifier
cat_best = CatBoostClassifier(**cat_best_param)
cat_best.fit(train_feature, train_tagert)


#Prédire chacun
pred = {
    'rfc': rfc_best.predict(test_feature).astype(int),
    'lr': lr_best.predict(test_feature).astype(int),
    'svc': svc_best.predict(test_feature).astype(int),
    'cat': cat_best.predict(test_feature).astype(int)
}


#Sortie de fichier
for key, value in pred.items():
    pd.concat(
        [
            pd.DataFrame(test.PassengerId, columns=['PassengerId']).reset_index(drop=True),
            pd.DataFrame(value, columns=['Survived'])
       ],
        axis=1
    ).to_csv(f'output_{key}.csv', index=False)

résultat

Lorsqu'il a été soumis à Kaggle, SVC a donné les meilleurs résultats. image.png

Après cela, j'ai ajusté diverses colonnes et hyper paramètres, mais actuellement, ce score est le résultat le plus élevé. Je pense que cela changera en fonction de la façon d'appliquer le prétraitement, donc si vous trouvez une bonne méthode à l'avenir, nous la vérifierons tout en la faisant fonctionner.

Recommended Posts

L'histoire d'un technicien de haut niveau essayant de prédire la survie du Titanic
L'histoire d'essayer de reconnecter le client
Je ne trouve pas l'horloge tsc! ?? L'histoire d'essayer d'écrire un patch de noyau
L'histoire de l'exportation d'un programme
Une histoire dans laquelle l'algorithme est arrivé à une conclusion ridicule en essayant de résoudre correctement le problème du voyageur de commerce
L'histoire de la mise en place de MeCab dans Ubuntu 16.04
L'histoire d'un débutant en apprentissage profond essayant de classer les guitares avec CNN
L'histoire d'essayer deep3d et de perdre
L'histoire du traitement A du blackjack (python)
Essayez de résoudre un problème défini de mathématiques au lycée avec Python
L'histoire du changement de pep8 en pycodestyle
J'ai essayé l'histoire courante de l'utilisation du Deep Learning pour prédire la moyenne Nikkei
L'histoire de la tentative de pousser SSH_AUTH_SOCK obsolète avec LD_PRELOAD à l'écran
L'histoire de l'adresse IPv6 que je souhaite conserver au minimum
J'ai essayé de refactoriser le code de Python débutant (lycéen)
Histoire d'essayer d'utiliser Tensorboard avec Pytorch
J'ai essayé de prédire la survie du Titanic avec PyCaret
L'histoire d'essayer Sourcetrail × macOS × VS Code
L'histoire de la création d'un générateur d'icônes mel
Histoire de passer de Pipenv à la poésie
Une histoire qui a échoué lors de la tentative de suppression du suffixe d'une chaîne avec rstrip
L'histoire du serveur Web et du DAG d'Airflow, dont le chargement prend beaucoup de temps
Une histoire bloquée lors de la tentative de mise à niveau de la version Python avec GCE
Une histoire d'essais et d'erreurs essayant de créer un groupe d'utilisateurs dynamique dans Slack
L'histoire du passage de WoSign à Let's Encrypt pour un certificat SSL gratuit
Une histoire sur la tentative de contribuer à l'analyse COVID-19 avec l'offre gratuite d'AWS et l'échec
Une note de malentendu lors de la tentative de chargement de l'intégralité du module self-made avec Python3
Comment changer l'image générée de GAN en une image de haute qualité à votre goût
L'histoire du lancement d'un serveur Minecraft depuis Discord
Une histoire qui réduit l'effort de fonctionnement / maintenance
Un mémo pour comprendre visuellement l'axe des pandas.
L'histoire de la création d'un réseau neuronal de génération musicale
Étapes pour calculer la probabilité d'une distribution normale
Une histoire sur le changement du nom principal de BlueZ
Le problème Zip 4 Gbyte est une histoire du passé
Une histoire qui a analysé la livraison de Nico Nama.
L'histoire de vouloir acheter une aventure en forme de bague
L'histoire de l'utilisation de Circleci pour construire des roues Manylinux
Note Python: Le mystère de l'attribution d'une variable à une variable
Je suis à Singapour en ce moment Une histoire sur la création d'un LineBot et la volonté de faire un travail mémorable
De zéro connaissance de Python à la création d'IA en première année du collège
L'histoire de sys.path.append ()
L'histoire de la création d'un canal VIP dans le chatwork en interne
[Ubuntu] Comment supprimer tout le contenu du répertoire
L'histoire de l'introduction de Jedi (package de complétion automatique de python) dans emacs
L'histoire du champ de modèle Django disparaissant de la classe
J'ai fait une fonction pour vérifier le modèle de DCGAN
Une histoire sur la façon de traiter le problème CORS
L'histoire de la copie de données de S3 vers TeamDrive de Google
Comment trouver le coefficient de mise à l'échelle d'une ondelette bipolaire
Technologie qui prend en charge Jupyter: Tralets (histoire d'essayer de déchiffrer)
Après tout, l'histoire du retour de Linux à Windows
Une histoire sur la tentative d'implémentation de variables privées en Python.
L'histoire de la création d'une base de données à l'aide de l'API Google Analytics
L'histoire de la création d'un bot de boîte à questions avec discord.py
Y a-t-il un secret dans la fréquence des nombres de rapport de circonférence?
Comment connecter le contenu de la liste dans une chaîne de caractères