<jupyter_start><jupyter_text><jupyter_code># https://www.kaggle.com/c/titanic/data
!mkdir /root/.kaggle
!mv kaggle.json /root/.kaggle/kaggle.json
!chmod 600 /root/.kaggle/kaggle.json
!kaggle competitions download -c titanic
!unzip titanic.zip
!pip install category_encoders
!pip install optuna
import pandas as pd
import numpy as np

import plotly.express as px
from plotly.subplots import make_subplots
import plotly.graph_objects as go

from sklearn.model_selection import train_test_split, cross_val_score, cross_validate, StratifiedKFold
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import make_scorer, f1_score, recall_score, precision_score, confusion_matrix, ConfusionMatrixDisplay, accuracy_score
from sklearn.impute import KNNImputer, SimpleImputer
from sklearn.preprocessing import StandardScaler, OrdinalEncoder
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.compose import ColumnTransformer

from category_encoders import TargetEncoder

import optuna<jupyter_output><empty_output><jupyter_text>Caricamento dati<jupyter_code>df = pd.read_csv(r'train.csv', index_col='PassengerId')
df.head()
df_test = pd.read_csv(r'test.csv', index_col='PassengerId')
df_test
df.info()
df.describe()
fig = make_subplots(rows=len(df.columns)//2+1, cols=2, subplot_titles=df.columns)
for i, column in enumerate(df.columns):
    fig.add_trace(go.Histogram(x=df[column]),
              row=i//2+1, col=i%2+1)
    
fig.update_layout(height=1600, showlegend=False)

fig.show()
df.groupby(df['Survived']).size()<jupyter_output><empty_output><jupyter_text>Train-test split<jupyter_code>df_train, df_test = train_test_split(df, test_size=0.2, stratify=df['Survived'], random_state=1)<jupyter_output><empty_output><jupyter_text>Three features: Pclass, Age, Sex<jupyter_code>X_train = df_train.loc[:, ['Pclass', 'Age', 'Sex']]
X_test = df_test.loc[:, ['Pclass', 'Age', 'Sex']]

y_train = df_train['Survived']
y_test = df_test['Survived']
X_train.info()
px.histogram(df, x='Age')
px.histogram(df, x='Age', facet_row='Pclass', histnorm='percent', category_orders={'Pclass': [1, 2, 3]})
df.groupby('Pclass').size()
df.groupby('Pclass')['Age'].median()
class AgeImputer(BaseEstimator, TransformerMixin):
    def fit(self, X, y=None):
        self.median_ages = X.groupby('Pclass')['Age'].median()
        return self

    def transform(self, X, y=None):
        X_copy = X.copy()
        for p_class in X_copy['Pclass'].unique():
            X_copy.loc[(X_copy['Pclass']==p_class) & X_copy['Age'].isna(), 'Age'] = self.median_ages[p_class]

        return X_copy
df_test.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
Int64Index: 179 entries, 233 to 230
Data columns (total 11 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   Survived  179 non-null    int64  
 1   Pclass    179 non-null    int64  
 2   Name      179 non-null    object 
 3   Sex       179 non-null    object 
 4   Age       141 non-null    float64
 5   SibSp     179 non-null    int64  
 6   Parch     179 non-null    int64  
 7   Ticket    179 non-null    object 
 8   Fare      179 non-null    float64
 9   Cabin     27 non-null     object 
 10  Embarked  179 non-null    object 
dtypes: float64(2), int64(4), object(5)
memory usage: 16.8+ KB<jupyter_text>Model selection<jupyter_code>study = optuna.create_study(storage='sqlite:///storage.db', study_name='random_forest', direction='maximize')
def get_objective_function(X_train, y_train):
    def objective_function(trial):
        pipeline = Pipeline(
            [('age_imputer', AgeImputer()),
             ('sex_encoder', ColumnTransformer(
                 [('sex_encoder_ordinal', OrdinalEncoder(), ['Sex'])],
                 remainder='passthrough')),
            ('random_forest', RandomForestClassifier())]
        )

        params = {
            'random_forest__n_estimators': trial.suggest_int('random_forest__n_estimators', 10, 1_000, log=False),
            'random_forest__criterion': trial.suggest_categorical('random_forest__criterion', ['gini', 'entropy']),
            'random_forest__max_features': trial.suggest_categorical('random_forest__max_features', ['auto', 'sqrt', 'log2']),
            'random_forest__min_impurity_decrease': trial.suggest_loguniform('random_forest__min_impurity_decrease', 1e-6, 1e-4)
        }

        pipeline.set_params(**params)

        scores = cross_val_score(pipeline, X_train, y_train, scoring=make_scorer(accuracy_score), cv=StratifiedKFold(n_splits=5, random_state=1, shuffle=True))

        return np.mean(scores)
    
    return objective_function
study.optimize(get_objective_function(X_train, y_train), n_trials=100)
optuna.visualization.plot_optimization_history(study)
optuna.visualization.plot_slice(study)
optuna.visualization.plot_parallel_coordinate(study)<jupyter_output><empty_output><jupyter_text>Test<jupyter_code>study.best_value
study.best_params
pipeline = Pipeline(
    [   
        ('age_imputer', AgeImputer()),
        ('sex_encoder', ColumnTransformer(
                [('sex_encoder_ordinal', OrdinalEncoder(), ['Sex'])],
                remainder='passthrough')),
        ('random_forest', RandomForestClassifier())
    ]
)
pipeline.set_params(**study.best_params)
pipeline.fit(X_train, y_train)
y_test_hat = pipeline.predict(X_test)
accuracy_score(y_test, y_test_hat)
cv_results = cross_validate(pipeline, X_train, y_train, scoring=make_scorer(accuracy_score))
cv_results
np.std(cv_results['test_score'])<jupyter_output><empty_output><jupyter_text>Feature engineering  Cabin<jupyter_code>df['Cabin'].count(), df['Cabin'].size
df[df['Pclass']==1]['Cabin'].unique()
df[df['Pclass']==2]['Cabin'].unique()
df[df['Pclass']==3]['Cabin'].unique()
df.groupby('Pclass').count()
pd.options.display.max_rows = 200
df.groupby('Cabin')['Survived'].agg(lambda x: x.sum() / x.size).sort_values()
import math
import re
def cabin_transform(cabin_col):
    cabins_encoded = []
    keys = []
    for key, cabin in cabin_col.iteritems():
        match = re.match(r'([A-Z])(\d+)', str(cabin))
        if match:
            character = match.group(1)
            number = int(match.group(2))
        else:
            character, number = None, math.nan

        cabin_encoded = dict(Cabin_char=character, Cabin_number=number, Cabin_isodd=number%2)
        cabins_encoded.append(cabin_encoded)
        keys.append(key)

    return pd.DataFrame(cabins_encoded, index=keys)

cabin_transform(df['Cabin'])
df = pd.concat([df, cabin_transform(df['Cabin'])], axis=1)
df<jupyter_output><empty_output><jupyter_text>Name<jupyter_code>def get_name_features(record):
    match = re.match(r'([a-zA-Z\'\- ]+[a-zA-Z]) *, *([a-zA-Z ]+[a-zA-Z])\. *([a-zA-Z ]+[a-zA-Z])? *(:?\(([a-zA-Z ]+[a-zA-Z])\) *)?', record.Name)
    # return {key: match.group(i) for i, key in zip([1, 2, 3, 5], ['Nome_Cognome', 'Nome_Titolo', 'None_Nome', 'Nome_Nubile'])}
    return tuple(match.group(i) for i in [1, 2, 3, 5])
df[['Name_Cognome', 'Name_Titolo', 'Name_Nome', 'Name_Nubile']] = df['Name'].to_frame().apply(func=get_name_features, result_type='expand', axis=1)
df.groupby('Name_Titolo').size().sort_values(ascending=False)<jupyter_output><empty_output><jupyter_text>Compagni<jupyter_code>df['Dimensione_gruppo'] = df['Parch'] + df['SibSp'] + 1<jupyter_output><empty_output><jupyter_text>Fare<jupyter_code>df.assign(Embarked_filled=df['Embarked'].fillna(value='U')).Embarked_filled.unique()
df['Fare_unitary'] = df['Fare'] / df['Dimensione_gruppo']
px.scatter(data_frame=df, x='Dimensione_gruppo', y='Fare', facet_row='Pclass', height=1000, trendline='ols', range_y=[0, 200])
px.scatter(data_frame=df, x='Dimensione_gruppo', y='Fare_unitary', facet_row='Pclass', height=1000, trendline='ols', range_y=[0, 200])
df.groupby(['Embarked', 'Pclass'])['Fare_unitary'].agg(['mean', 'std'])<jupyter_output><empty_output><jupyter_text>Correlazione feature-target<jupyter_code># Age

age_df = df.groupby(by=pd.qcut(df['Age'], q=90, duplicates='drop')).aggregate(
                    survive_prob=pd.NamedAgg(column='Survived', aggfunc=lambda x: x.sum() / x.count()),
                    size=pd.NamedAgg(column='Survived', aggfunc='size')).reset_index()

age_df['Age'].apply(lambda x: f'({x.left}, {x.right})')

px.bar(x=age_df['Age'].apply(lambda x: f'({x.left}, {x.right})'), y=age_df['survive_prob'])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15683008091385053, 'fraction_numerical': 0.01832460732984293, 'mean_word_length': 4.906535488404779, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 45, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '631682', 'license': 'MIT', 'n_tokens_mistral': 3245, 'n_tokens_neox': 3050, 'n_words': 493, 'path': 'titanic master.ipynb', 'repo_name': 'March-08/Best-README-Template', 'size': '8404'}