prateekiiest/titanic_survival_exploration

View on GitHub
titanic_survival_exploration-checkpoint.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Machine Learning Engineer Nanodegree\n",
    "## Introduction and Foundations\n",
    "## Project 0: Titanic Survival Exploration\n",
    "\n",
    "In 1912, the ship RMS Titanic struck an iceberg on its maiden voyage and sank, resulting in the deaths of most of its passengers and crew. In this introductory project, we will explore a subset of the RMS Titanic passenger manifest to determine which features best predict whether someone survived or did not survive. To complete this project, you will need to implement several conditional predictions and answer the questions below. Your project submission will be evaluated based on the completion of the code and your responses to the questions.\n",
    "> **Tip:** Quoted sections like this will provide helpful instructions on how to navigate and use an iPython notebook. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Getting Started\n",
    "To begin working with the RMS Titanic passenger data, we'll first need to `import` the functionality we need, and load our data into a `pandas` DataFrame.  \n",
    "Run the code cell below to load our data and display the first few entries (passengers) for examination using the `.head()` function.\n",
    "> **Tip:** You can run a code cell by clicking on the cell and using the keyboard shortcut **Shift + Enter** or **Shift + Return**. Alternatively, a code cell can be executed using the **Play** button in the hotbar after selecting it. Markdown cells (text cells like this one) can be edited by double-clicking, and saved using these same shortcuts. [Markdown](http://daringfireball.net/projects/markdown/syntax) allows you to write easy-to-read plain text that can be converted to HTML."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "# RMS Titanic data visualization code \n",
    "from titanic_visualizations import survival_stats\n",
    "from IPython.display import display\n",
    "%matplotlib inline\n",
    "\n",
    "# Load the dataset\n",
    "in_file = 'titanic_data.csv'\n",
    "full_data = pd.read_csv(in_file)\n",
    "\n",
    "# Print the first few entries of the RMS Titanic data\n",
    "display(full_data.head())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "From a sample of the RMS Titanic data, we can see the various features present for each passenger on the ship:\n",
    "- **Survived**: Outcome of survival (0 = No; 1 = Yes)\n",
    "- **Pclass**: Socio-economic class (1 = Upper class; 2 = Middle class; 3 = Lower class)\n",
    "- **Name**: Name of passenger\n",
    "- **Sex**: Sex of the passenger\n",
    "- **Age**: Age of the passenger (Some entries contain `NaN`)\n",
    "- **SibSp**: Number of siblings and spouses of the passenger aboard\n",
    "- **Parch**: Number of parents and children of the passenger aboard\n",
    "- **Ticket**: Ticket number of the passenger\n",
    "- **Fare**: Fare paid by the passenger\n",
    "- **Cabin** Cabin number of the passenger (Some entries contain `NaN`)\n",
    "- **Embarked**: Port of embarkation of the passenger (C = Cherbourg; Q = Queenstown; S = Southampton)\n",
    "\n",
    "Since we're interested in the outcome of survival for each passenger or crew member, we can remove the **Survived** feature from this dataset and store it as its own separate variable `outcomes`. We will use these outcomes as our prediction targets.  \n",
    "Run the code cell below to remove **Survived** as a feature of the dataset and store it in `outcomes`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Store the 'Survived' feature in a new variable and remove it from the dataset\n",
    "outcomes = full_data['Survived']\n",
    "data = full_data.drop('Survived', axis = 1)\n",
    "\n",
    "# Show the new dataset with 'Survived' removed\n",
    "display(data.head())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The very same sample of the RMS Titanic data now shows the **Survived** feature removed from the DataFrame. Note that `data` (the passenger data) and `outcomes` (the outcomes of survival) are now *paired*. That means for any passenger `data.loc[i]`, they have the survival outcome `outcome[i]`.\n",
    "\n",
    "To measure the performance of our predictions, we need a metric to score our predictions against the true outcomes of survival. Since we are interested in how *accurate* our predictions are, we will calculate the proportion of passengers where our prediction of their survival is correct. Run the code cell below to create our `accuracy_score` function and test a prediction on the first five passengers.  \n",
    "\n",
    "**Think:** *Out of the first five passengers, if we predict that all of them survived, what would you expect the accuracy of our predictions to be?*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def accuracy_score(truth, pred):\n",
    "    \"\"\" Returns accuracy score for input truth and predictions. \"\"\"\n",
    "    \n",
    "    # Ensure that the number of predictions matches number of outcomes\n",
    "    if len(truth) == len(pred): \n",
    "        \n",
    "        # Calculate and return the accuracy as a percent\n",
    "        return \"Predictions have an accuracy of {:.2f}%.\".format((truth == pred).mean()*100)\n",
    "    \n",
    "    else:\n",
    "        return \"Number of predictions does not match number of outcomes!\"\n",
    "    \n",
    "# Test the 'accuracy_score' function\n",
    "predictions = pd.Series(np.ones(5, dtype = int))\n",
    "print accuracy_score(outcomes[:5], predictions)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **Tip:** If you save an iPython Notebook, the output from running code blocks will also be saved. However, the state of your workspace will be reset once a new session is started. Make sure that you run all of the code blocks from your previous session to reestablish variables and functions before picking up where you last left off.\n",
    "\n",
    "# Making Predictions\n",
    "\n",
    "If we were asked to make a prediction about any passenger aboard the RMS Titanic whom we knew nothing about, then the best prediction we could make would be that they did not survive. This is because we can assume that a majority of the passengers (more than 50%) did not survive the ship sinking.  \n",
    "The `predictions_0` function below will always predict that a passenger did not survive."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def predictions_0(data):\n",
    "    \"\"\" Model with no features. Always predicts a passenger did not survive. \"\"\"\n",
    "\n",
    "    predictions = []\n",
    "    for _, passenger in data.iterrows():\n",
    "        \n",
    "        # Predict the survival of 'passenger'\n",
    "        predictions.append(0)\n",
    "    \n",
    "    # Return our predictions\n",
    "    return pd.Series(predictions)\n",
    "\n",
    "# Make the predictions\n",
    "predictions = predictions_0(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 1\n",
    "*Using the RMS Titanic data, how accurate would a prediction be that none of the passengers survived?*  \n",
    "**Hint:** Run the code cell below to see the accuracy of this prediction."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "print accuracy_score(outcomes, predictions)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Answer:** *Replace this text with the prediction accuracy you found above.*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***\n",
    "Let's take a look at whether the feature **Sex** has any indication of survival rates among passengers using the `survival_stats` function. This function is defined in the `titanic_visualizations.py` Python script included with this project. The first two parameters passed to the function are the RMS Titanic data and passenger survival outcomes, respectively. The third parameter indicates which feature we want to plot survival statistics across.  \n",
    "Run the code cell below to plot the survival outcomes of passengers based on their sex."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "survival_stats(data, outcomes, 'Sex')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Examining the survival statistics, a large majority of males did not survive the ship sinking. However, a majority of females *did* survive the ship sinking. Let's build on our previous prediction: If a passenger was female, then we will predict that they survived. Otherwise, we will predict the passenger did not survive.  \n",
    "Fill in the missing code below so that the function will make this prediction.  \n",
    "**Hint:** You can access the values of each feature for a passenger like a dictionary. For example, `passenger['Sex']` is the sex of the passenger."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def predictions_1(data):\n",
    "    \"\"\" Model with one feature: \n",
    "            - Predict a passenger survived if they are female. \"\"\"\n",
    "    \n",
    "    predictions = []\n",
    "    for _, passenger in data.iterrows():\n",
    "        \n",
    "        # Remove the 'pass' statement below \n",
    "        # and write your prediction conditions here\n",
    "        pass\n",
    "    \n",
    "    # Return our predictions\n",
    "    return pd.Series(predictions)\n",
    "\n",
    "# Make the predictions\n",
    "predictions = predictions_1(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 2\n",
    "*How accurate would a prediction be that all female passengers survived and the remaining passengers did not survive?*  \n",
    "**Hint:** Run the code cell below to see the accuracy of this prediction."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "print accuracy_score(outcomes, predictions)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Answer**: *Replace this text with the prediction accuracy you found above.*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***\n",
    "Using just the **Sex** feature for each passenger, we are able to increase the accuracy of our predictions by a significant margin. Now, let's consider using an additional feature to see if we can further improve our predictions. For example, consider all of the male passengers aboard the RMS Titanic: Can we find a subset of those passengers that had a higher rate of survival? Let's start by looking at the **Age** of each male, by again using the `survival_stats` function. This time, we'll use a fourth parameter to filter out the data so that only passengers with the **Sex** 'male' will be included.  \n",
    "Run the code cell below to plot the survival outcomes of male passengers based on their age."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "survival_stats(data, outcomes, 'Age', [\"Sex == 'male'\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "Examining the survival statistics, the majority of males younger than 10 survived the ship sinking, whereas most males age 10 or older *did not survive* the ship sinking. Let's continue to build on our previous prediction: If a passenger was female, then we will predict they survive. If a passenger was male and younger than 10, then we will also predict they survive. Otherwise, we will predict they do not survive.  \n",
    "Fill in the missing code below so that the function will make this prediction.  \n",
    "**Hint:** You can start your implementation of this function using the prediction code you wrote earlier from `predictions_1`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def predictions_2(data):\n",
    "    \"\"\" Model with two features: \n",
    "            - Predict a passenger survived if they are female.\n",
    "            - Predict a passenger survived if they are male and younger than 10. \"\"\"\n",
    "    \n",
    "    predictions = []\n",
    "    for _, passenger in data.iterrows():\n",
    "        \n",
    "        # Remove the 'pass' statement below \n",
    "        # and write your prediction conditions here\n",
    "        pass\n",
    "    \n",
    "    # Return our predictions\n",
    "    return pd.Series(predictions)\n",
    "\n",
    "# Make the predictions\n",
    "predictions = predictions_2(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 3\n",
    "*How accurate would a prediction be that all female passengers and all male passengers younger than 10 survived?*  \n",
    "**Hint:** Run the code cell below to see the accuracy of this prediction."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "print accuracy_score(outcomes, predictions)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Answer**: *Replace this text with the prediction accuracy you found above.*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "***\n",
    "Adding the feature **Age** as a condition in conjunction with **Sex** improves the accuracy by a small margin more than with simply using the feature **Sex** alone. Now it's your turn: Find a series of features and conditions to split the data on to obtain an outcome prediction accuracy of at least 80%. This may require multiple features and multiple levels of conditional statements to succeed. You can use the same feature multiple times with different conditions.   \n",
    "**Pclass**, **Sex**, **Age**, **SibSp**, and **Parch** are some suggested features to try.\n",
    "\n",
    "Use the `survival_stats` function below to to examine various survival statistics.  \n",
    "**Hint:** To use mulitple filter conditions, put each condition in the list passed as the last argument. Example: `[\"Sex == 'male'\", \"Age < 18\"]`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "survival_stats(data, outcomes, 'Age', [\"Sex == 'male'\", \"Age < 18\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After exploring the survival statistics visualization, fill in the missing code below so that the function will make your prediction.  \n",
    "Make sure to keep track of the various features and conditions you tried before arriving at your final prediction model.  \n",
    "**Hint:** You can start your implementation of this function using the prediction code you wrote earlier from `predictions_2`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def predictions_3(data):\n",
    "    \"\"\" Model with multiple features. Makes a prediction with an accuracy of at least 80%. \"\"\"\n",
    "    \n",
    "    predictions = []\n",
    "    for _, passenger in data.iterrows():\n",
    "        \n",
    "        # Remove the 'pass' statement below \n",
    "        # and write your prediction conditions here\n",
    "        pass\n",
    "    \n",
    "    # Return our predictions\n",
    "    return pd.Series(predictions)\n",
    "\n",
    "# Make the predictions\n",
    "predictions = predictions_3(data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Question 4\n",
    "*Describe the steps you took to implement the final prediction model so that it got an accuracy of at least 80%. What features did you look at? Were certain features more informative than others? Which conditions did you use to split the survival outcomes in the data? How accurate are your predictions?*  \n",
    "**Hint:** Run the code cell below to see the accuracy of your predictions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "print accuracy_score(outcomes, predictions)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Answer**: *Replace this text with your answer to the question above.*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Conclusion\n",
    "\n",
    "After several iterations of exploring and conditioning on the data, you have built a useful algorithm for predicting the survival of each passenger aboard the RMS Titanic. The technique applied in this project is a manual implementation of a simple machine learning model, the *decision tree*. A decision tree splits a set of data into smaller and smaller groups (called *nodes*), by one feature at a time. Each time a subset of the data is split, our predictions become more accurate if each of the resulting subgroups are more homogeneous (contain similar labels) than before. The advantage of having a computer do things for us is that it will be more exhaustive and more precise than our manual exploration above. [This link](http://www.r2d3.us/visual-intro-to-machine-learning-part-1/) provides another introduction into machine learning using a decision tree.\n",
    "\n",
    "A decision tree is just one of many models that come from *supervised learning*. In supervised learning, we attempt to use features of the data to predict or model things with objective outcome labels. That is to say, each of our data points has a known outcome value, such as a categorical, discrete label like `'Survived'`, or a numerical, continuous value like predicting the price of a house.\n",
    "\n",
    "### Question 5\n",
    "*Think of a real-world scenario where supervised learning could be applied. What would be the outcome variable that you are trying to predict? Name two features about the data used in this scenario that might be helpful for making the predictions.*  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "**Answer**: *Replace this text with your answer to the question above.*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> **Note**: Once you have completed all of the code implementations and successfully answered each question above, you may finalize your work by exporting the iPython Notebook as an HTML document. You can do this by using the menu above and navigating to  \n",
    "**File -> Download as -> HTML (.html)**. Include the finished document along with this notebook as your submission."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [Root]",
   "language": "python",
   "name": "Python [Root]"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}