{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# imports\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport re\n\nfrom tqdm import tqdm\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.impute import SimpleImputer\nfrom sklearn.model_selection import train_test_split","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Dictionary\n    Variable\tDefinition\tKey\n    survival\tSurvival\t0 = No, 1 = Yes\n    pclass\tTicket class\t1 = 1st, 2 = 2nd, 3 = 3rd\n    sex\tSex\t\n    Age\tAge in years\t\n    sibsp\t# of siblings / spouses aboard the Titanic\t\n    parch\t# of parents / children aboard the Titanic\t\n    ticket\tTicket number\t\n    fare\tPassenger fare\t\n    cabin\tCabin number\t\n    embarked\tPort of Embarkation\tC = Cherbourg, Q = Queenstown, S = Southampton\n    Variable Notes\n    pclass: A proxy for socio-economic status (SES)\n    1st = Upper\n    2nd = Middle\n    3rd = Lower\n\n    age: Age is fractional if less than 1. If the age is estimated, is it in the form of xx.5\n\n    sibsp: The dataset defines family relations in this way...\n    Sibling = brother, sister, stepbrother, stepsister\n    Spouse = husband, wife (mistresses and fiancés were ignored)\n\n    parch: The dataset defines family relations in this way...\n    Parent = mother, father\n    Child = daughter, son, stepdaughter, stepson\n    Some children travelled only with a nanny, therefore parch=0 for them.","metadata":{}},{"cell_type":"markdown","source":"## EDA","metadata":{}},{"cell_type":"code","source":"train, test = pd.read_csv(\"../input/titanic/train.csv\", index_col=0), pd.read_csv(\"../input/titanic/test.csv\", index_col=0)\ntrain.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Examine Missing Values","metadata":{}},{"cell_type":"code","source":"np.round(train.isnull().sum() / (train.isnull().sum() + train.notnull().sum()), 4) * 100","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.round(test.isnull().sum() / (test.isnull().sum() + test.notnull().sum()), 4) * 100","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Missing values from **Age** and **Cabin** in both the training and testing datasets. There are also a few values missing in the **Embarked** Column from the training dataset, and from the **Fare** column of the testing dataset.","metadata":{}},{"cell_type":"markdown","source":"## Distributions and Correlations","metadata":{}},{"cell_type":"code","source":"# Target (Survived) Class\n\ntrain['Survived'].value_counts().plot(kind='bar')\nplt.title('Not Survived (0) / Survived (1)')\nprint(train['Survived'].value_counts(normalize=True))\ntrain.corr().abs()['Survived'].sort_values(ascending=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Passenger Class\n\ntrain['Pclass'].value_counts().plot(kind='bar')\nplt.title('Passenger Class Distributions')\ntrain['Pclass'].value_counts(normalize=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.round(train.groupby('Pclass').mean(),2)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Sex\n\ntrain['Sex_enc'] = train['Sex'].apply(lambda x: 0 if x == 'male' else 1)\ntest['Sex_enc'] = test['Sex'].apply(lambda x: 0 if x == 'male' else 1)\ntrain['Sex_enc'].value_counts().plot(kind='bar')\nplt.title('Men (0) / Women (1)')\nprint(train['Sex_enc'].value_counts(normalize=True))\ntrain.corr().abs()['Sex_enc'].sort_values(ascending=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.groupby('Sex').mean()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Age\n\ntrain['Age'].hist()\nplt.vlines(\n    x=train['Age'].mean(),\n    ymin = 0,\n    ymax = 180,\n    label='mean',\n    colors='red'\n)\nplt.vlines(\n    x=train['Age'].median(),\n    ymin = 0,\n    ymax = 180,\n    label='median',\n    colors='black'\n)\nplt.title('Age')\nplt.legend()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.corr().abs()['Age'].sort_values(ascending=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.groupby(['Pclass', 'Sex'])['Age'].median().plot(kind='bar')\nplt.title('median ages of male/female passengers by class')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# fill in missing na values\n\ntrain['Age'] = train.groupby(['Pclass', 'Sex'])['Age'].apply(lambda x: x.fillna(x.median()))\ntest['Age'] = test.groupby(['Pclass', 'Sex'])['Age'].apply(lambda x: x.fillna(x.median()))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Survived vs Not Survived by Age\n\ntrain[train['Survived'] == 0]['Age'].hist(label = 'Died', alpha=0.75)\ntrain[train['Survived'] == 1]['Age'].hist(label='Survived', alpha=0.75)\nplt.legend()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Siblings and Spouses\n\ntrain['SibSp'].value_counts().plot(kind='bar')\nplt.title('Passenger Siblings + Spouses')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Parents and Children\n\ntrain['Parch'].value_counts().plot(kind='bar')\nplt.title('Passenger Parents + Children')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Fare\n\ntrain['Fare'].hist()\nplt.vlines(\n    x=train['Fare'].mean(),\n    ymin = 0,\n    ymax = 750,\n    label='mean',\n    colors='red'\n)\nplt.vlines(\n    x=train['Fare'].median(),\n    ymin = 0,\n    ymax = 750,\n    label='median',\n    colors='black'\n)\nplt.title('Fare')\nplt.legend()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train[train['Survived'] == 1]['Fare'].hist(alpha=0.75, label='Survived')\ntrain[train['Survived'] == 0]['Fare'].hist(alpha=0.75, label='Died')\nplt.title('Passenger Fare by Survival')\nplt.legend()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.corr().abs()['Fare'].sort_values(ascending=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Look at Average Fare Distribution for Pclass == 3\n\ntrain[train['Pclass'] == 3]['Fare'].hist()\nplt.vlines(\n    x=train[train['Pclass'] == 3]['Fare'].mean(),\n    ymin = 0,\n    ymax = 350,\n    label='mean',\n    colors='red'\n)\nplt.vlines(\n    x=train[train['Pclass'] == 3]['Fare'].median(),\n    ymin = 0,\n    ymax = 350,\n    label='median',\n    colors='black'\n)\nplt.title('Fare for Pclass = 3')\nplt.legend()\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Add median of training data for missing values\n\ntest['Fare'] = test.groupby('Pclass')['Fare'].apply(lambda x: x.fillna(x.median()))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Cabin\n\ntrain['Cabin'] = train['Cabin'].fillna(value='X')\ntest['Cabin'] = test['Cabin'].fillna(value='X')\ntrain['Deck'] = train['Cabin'].apply(lambda x: x[0])\ntest['Deck'] = test['Cabin'].apply(lambda x: x[0])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['Deck'].value_counts().sort_index()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test['Deck'].value_counts().sort_index()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# need to make sure values match in training and testing set\n\ntrain[train['Deck'] == 'T']","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The fare for the passenger in Deck T is 35.5, so I am going to see what other fares match up with what other decks","metadata":{}},{"cell_type":"code","source":"train.groupby('Deck')['Fare'].mean()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# setting T to A\n\ntrain.at[train[train['Deck'] == 'T'].index[0], 'Deck'] = 'A'","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['Deck'].value_counts()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.groupby('Deck')['Survived'].mean().plot(kind='bar')\nplt.title('Average Survival Rate by Deck')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Embarked\n\nimputer = SimpleImputer(strategy='most_frequent')\nencoder = LabelEncoder()\ntrain['Embarked_enc'] = imputer.fit_transform(train[['Embarked']])\ntrain['Embarked_enc'] = encoder.fit_transform(train[['Embarked_enc']])\ntrain['Embarked'].value_counts().plot(kind='bar')\ntrain['Embarked'].value_counts(dropna=False)\n\ntest['Embarked_enc'] = imputer.fit_transform(test[['Embarked']])\ntest['Embarked_enc'] = encoder.fit_transform(test[['Embarked_enc']])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Feature Engineering\nFirst thing to do is bin any continuous or categorical features.","metadata":{}},{"cell_type":"code","source":"# Age\n\ntrain['Age_Bin'] = pd.qcut(train['Age'], 12)\ntrain.groupby(['Age_Bin', 'Sex'])['Survived'].mean().plot(kind='bar')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['Age_Bin'].iloc[0]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Family Size = # Siblings + Spouses + Parents + Children + 1\n\ntrain['Family_Size'] = train['SibSp'] + train['Parch'] + 1\ntest['Family_Size'] = test['SibSp'] + test['Parch'] + 1","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.groupby('Family_Size')['Survived'].mean()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test['Family_Size'].value_counts().sort_index()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Group family \n\ndef family_size(x):\n      if x == 1:\n            return 'Alone'\n      elif x <= 2 and x < 5:\n            return 'Small'\n      elif x <=5 and x < 7:\n            return 'Medium'\n      else:\n            return 'Large'\n        \ntrain['Family_Grp_Size'] = train['Family_Size'].apply(lambda x: family_size(x))\ntest['Family_Grp_Size'] = test['Family_Size'].apply(lambda x: family_size(x))\ntrain['Family_Grp_Size_enc'] = encoder.fit_transform(train['Family_Grp_Size'])\ntest['Family_Grp_Size_enc'] = encoder.fit_transform(test['Family_Grp_Size'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['Family_Grp_Size'].value_counts()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.groupby('Family_Grp_Size')['Survived'].mean().plot(kind='bar')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Names\ntrain['Name'].sample(20)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Extract titles\n\nPATTERN = r\"([A-Za-z]*\\.)\"\ntrain['Title'] = train['Name'].apply(lambda x:re.findall(PATTERN, x)[0])\ntest['Title'] = test['Name'].apply(lambda x:re.findall(PATTERN, x)[0])\ntrain['Title'].value_counts()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test['Title'].value_counts()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# bin titles\ntitles = train['Title'].value_counts().index[:4]\ntrain['Title'] = train['Title'].apply(lambda x: x if x in titles else \"Other\")\ntest['Title'] = test['Title'].apply(lambda x: x if x in titles else \"Other\")\ntrain['Title_enc'] = encoder.fit_transform(train['Title'])\ntest['Title_enc'] = encoder.fit_transform(test['Title'])\ntrain['Title'].value_counts()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.groupby('Title')['Survived'].mean()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"features = ['Pclass', 'Sex_enc', 'Fare', 'Sex_enc', 'Embarked_enc', 'Age', 'Family_Grp_Size_enc', 'Title_enc']\nX = train[features]\ny = train['Survived']\nX_test = test[features]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.ensemble import RandomForestClassifier\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.model_selection import cross_val_score\nfrom sklearn.metrics import accuracy_score","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_learning_curves(model, X, y):\n    X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2)\n    train_errors, val_errors = [], []\n    for m in tqdm(range(10, len(X_train))):\n        model.fit(X_train[:m], y_train[:m])\n        y_train_predict = model.predict(X_train[:m])\n        y_val_predict = model.predict(X_val[:m])\n        train_errors.append(accuracy_score(y_train[:m], y_train_predict))\n        val_errors.append(accuracy_score(y_val[:m], y_val_predict))\n    plt.plot(train_errors, \"r-+\", linewidth=2, label='train')\n    plt.plot(val_errors, \"g-\", linewidth=3, label='val')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rf = RandomForestClassifier(n_estimators=100)\nplot_learning_curves(rf, X, y)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import StandardScaler\n\nlr = LogisticRegression()\nscaler = StandardScaler()\nX_scaled = scaler.fit_transform(X)\nplot_learning_curves(lr, X_scaled, y)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Submit Predictions","metadata":{}},{"cell_type":"code","source":"lr.fit(train[features], train['Survived'])\ny_pred = lr.predict(test[features])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame({'PassengerId':test.index.values, 'Survived':y_pred})\nsubmission.to_csv('submission.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}