import numpy as np
import pandas as pd

# RMS Titanic data visualization code 
# 数据可视化代码
from titanic_visualizations import survival_stats
from IPython.display import display
%matplotlib inline

# Load the dataset 
# 加载数据集
in_file = 'titanic_data.csv'
full_data = pd.read_csv(in_file)

# Print the first few entries of the RMS Titanic data 
# 显示数据列表中的前几项乘客数据
display(full_data.head())

"""
Explanation: 机器学习工程师纳米学位
入门
项目 0: 预测泰坦尼克号乘客生还率
1912年，泰坦尼克号在第一次航行中就与冰山相撞沉没，导致了大部分乘客和船员身亡。在这个入门项目中，我们将探索部分泰坦尼克号旅客名单，来确定哪些特征可以最好地预测一个人是否会生还。为了完成这个项目，你将需要实现几个基于条件的预测并回答下面的问题。我们将根据代码的完成度和对问题的解答来对你提交的项目的进行评估。 

提示：这样的文字将会指导你如何使用 iPython Notebook 来完成项目。

点击这里查看本文件的英文版本。
开始
当我们开始处理泰坦尼克号乘客数据时，会先导入我们需要的功能模块以及将数据加载到 pandas DataFrame。运行下面区域中的代码加载数据，并使用 .head() 函数显示前几项乘客数据。 

提示：你可以通过单击代码区域，然后使用键盘快捷键 Shift+Enter 或 Shift+ Return 来运行代码。或者在选择代码后使用播放（run cell）按钮执行代码。像这样的 MarkDown 文本可以通过双击编辑，并使用这些相同的快捷键保存。Markdown 允许你编写易读的纯文本并且可以转换为 HTML。
End of explanation
"""


# Store the 'Survived' feature in a new variable and remove it from the dataset 
# 从数据集中移除 'Survived' 这个特征，并将它存储在一个新的变量中。
outcomes = full_data['Survived']
data = full_data.drop('Survived', axis = 1)

# Show the new dataset with 'Survived' removed
# 显示已移除 'Survived' 特征的数据集
display(data.head())

"""
Explanation: 从泰坦尼克号的数据样本中，我们可以看到船上每位旅客的特征

Survived：是否存活（0代表否，1代表是）
Pclass：社会阶级（1代表上层阶级，2代表中层阶级，3代表底层阶级）
Name：船上乘客的名字
Sex：船上乘客的性别
Age:船上乘客的年龄（可能存在 NaN）
SibSp：乘客在船上的兄弟姐妹和配偶的数量
Parch：乘客在船上的父母以及小孩的数量
Ticket：乘客船票的编号
Fare：乘客为船票支付的费用
Cabin：乘客所在船舱的编号（可能存在 NaN）
Embarked：乘客上船的港口（C 代表从 Cherbourg 登船，Q 代表从 Queenstown 登船，S 代表从 Southampton 登船）

因为我们感兴趣的是每个乘客或船员是否在事故中活了下来。可以将 Survived 这一特征从这个数据集移除，并且用一个单独的变量 outcomes 来存储。它也做为我们要预测的目标。
运行该代码，从数据集中移除 Survived 这个特征，并将它存储在变量 outcomes 中。
End of explanation
"""


def accuracy_score(truth, pred):
    """ Returns accuracy score for input truth and predictions. """
    
    # Ensure that the number of predictions matches number of outcomes
    # 确保预测的数量与结果的数量一致
    if len(truth) == len(pred): 
        
        # Calculate and return the accuracy as a percent
        # 计算预测准确率（百分比）
        return "Predictions have an accuracy of {:.2f}%.".format((truth == pred).mean()*100)
    
    else:
        return "Number of predictions does not match number of outcomes!"
    
# Test the 'accuracy_score' function
# 测试 'accuracy_score' 函数
predictions = pd.Series(np.ones(5, dtype = int))
print accuracy_score(outcomes[:5], predictions)

"""
Explanation: 这个例子展示了如何将泰坦尼克号的 Survived 数据从 DataFrame 移除。注意到 data（乘客数据）和 outcomes （是否存活）现在已经匹配好。这意味着对于任何乘客的 data.loc[i] 都有对应的存活的结果 outcome[i]。
为了验证我们预测的结果，我们需要一个标准来给我们的预测打分。因为我们最感兴趣的是我们预测的准确率，既正确预测乘客存活的比例。运行下面的代码来创建我们的 accuracy_score 函数以对前五名乘客的预测来做测试。
思考题：从第六个乘客算起，如果我们预测他们全部都存活，你觉得我们预测的准确率是多少？
End of explanation
"""


def predictions_0(data):
    """ Model with no features. Always predicts a passenger did not survive. """

    predictions = []
    for _, passenger in data.iterrows():
        
        # Predict the survival of 'passenger'
        # 预测 'passenger' 的生还率
        predictions.append(0)
    
    # Return our predictions
    # 返回预测结果
    return pd.Series(predictions)

# Make the predictions
# 进行预测
predictions = predictions_0(data)

"""
Explanation: 提示：如果你保存 iPython Notebook，代码运行的输出也将被保存。但是，一旦你重新打开项目，你的工作区将会被重置。请确保每次都从上次离开的地方运行代码来重新生成变量和函数。

预测
如果我们要预测泰坦尼克号上的乘客是否存活，但是我们又对他们一无所知，那么最好的预测就是船上的人无一幸免。这是因为，我们可以假定当船沉没的时候大多数乘客都遇难了。下面的 predictions_0 函数就预测船上的乘客全部遇难。
End of explanation
"""


print accuracy_score(outcomes, predictions)

"""
Explanation: 问题1
对比真实的泰坦尼克号的数据，如果我们做一个所有乘客都没有存活的预测，你认为这个预测的准确率能达到多少？
提示：运行下面的代码来查看预测的准确率。
End of explanation
"""


survival_stats(data, outcomes, 'Sex')

"""
Explanation: 回答: Predictions have an accuracy of 61.62%.

我们可以使用 survival_stats 函数来看看 Sex 这一特征对乘客的存活率有多大影响。这个函数定义在名为 titanic_visualizations.py 的 Python 脚本文件中，我们的项目提供了这个文件。传递给函数的前两个参数分别是泰坦尼克号的乘客数据和乘客的 生还结果。第三个参数表明我们会依据哪个特征来绘制图形。
运行下面的代码绘制出依据乘客性别计算存活率的柱形图。
End of explanation
"""


def predictions_1(data):
    """ Model with one feature: 
            - Predict a passenger survived if they are female. """
    
    predictions = []
    for _, passenger in data.iterrows():
        
        # Remove the 'pass' statement below 
        # 移除下方的 'pass' 声明
        # and write your prediction conditions here
        # 输入你自己的预测条件
        if passenger['Sex'] == 'male':
            predictions.append(0)
        else:
            predictions.append(1)
            
    # Return our predictions
    # 返回预测结果
    return pd.Series(predictions)

# Make the predictions
# 进行预测
predictions = predictions_1(data)

"""
Explanation: 观察泰坦尼克号上乘客存活的数据统计，我们可以发现大部分男性乘客在船沉没的时候都遇难了。相反的，大部分女性乘客都在事故中生还。让我们在先前推断的基础上继续创建：如果乘客是男性，那么我们就预测他们遇难；如果乘客是女性，那么我们预测他们在事故中活了下来。
将下面的代码补充完整，让函数可以进行正确预测。  
提示：您可以用访问 dictionary（字典）的方法来访问船上乘客的每个特征对应的值。例如， passenger['Sex'] 返回乘客的性别。
End of explanation
"""


print accuracy_score(outcomes, predictions)

"""
Explanation: 问题2
当我们预测船上女性乘客全部存活，而剩下的人全部遇难，那么我们预测的准确率会达到多少？
提示：运行下面的代码来查看我们预测的准确率。
End of explanation
"""


survival_stats(data, outcomes, 'Age', ["Sex == 'male'"])

"""
Explanation: 回答: Predictions have an accuracy of 78.68%.

仅仅使用乘客性别（Sex）这一特征，我们预测的准确性就有了明显的提高。现在再看一下使用额外的特征能否更进一步提升我们的预测准确度。例如，综合考虑所有在泰坦尼克号上的男性乘客：我们是否找到这些乘客中的一个子集，他们的存活概率较高。让我们再次使用 survival_stats 函数来看看每位男性乘客的年龄（Age）。这一次，我们将使用第四个参数来限定柱形图中只有男性乘客。
运行下面这段代码，把男性基于年龄的生存结果绘制出来。
End of explanation
"""


def predictions_2(data):
    """ Model with two features: 
            - Predict a passenger survived if they are female.
            - Predict a passenger survived if they are male and younger than 10. """
    
    predictions = []
    for _, passenger in data.iterrows():
        
        # Remove the 'pass' statement below 
        # 移除下方的 'pass' 声明
        # and write your prediction conditions here
        # 输入你自己的预测条件
        if passenger['Sex'] == 'male':
            if  passenger['Age'] > 10:
                predictions.append(0)
            else:
                predictions.append(1)
        else:
            predictions.append(1)
        
    
    # Return our predictions
    # 返回预测结果
    return pd.Series(predictions)

# Make the predictions
# 进行预测
predictions = predictions_2(data)

"""
Explanation: 仔细观察泰坦尼克号存活的数据统计，在船沉没的时候，大部分小于10岁的男孩都活着，而大多数10岁以上的男性都随着船的沉没而遇难。让我们继续在先前预测的基础上构建：如果乘客是女性，那么我们就预测她们全部存活；如果乘客是男性并且小于10岁，我们也会预测他们全部存活；所有其它我们就预测他们都没有幸存。  
将下面缺失的代码补充完整，让我们的函数可以实现预测。
提示: 您可以用之前 predictions_1 的代码作为开始来修改代码，实现新的预测函数。
End of explanation
"""


print accuracy_score(outcomes, predictions)

"""
Explanation: 问题3
当预测所有女性以及小于10岁的男性都存活的时候，预测的准确率会达到多少？
提示：运行下面的代码来查看预测的准确率。
End of explanation
"""


survival_stats(data, outcomes, 'Age', ["Sex == 'male'", "Age < 18"])

"""
Explanation: 回答: Predictions have an accuracy of 68.91%.

添加年龄（Age）特征与性别（Sex）的结合比单独使用性别（Sex）也提高了不少准确度。现在该你来做预测了：找到一系列的特征和条件来对数据进行划分，使得预测结果提高到80%以上。这可能需要多个特性和多个层次的条件语句才会成功。你可以在不同的条件下多次使用相同的特征。Pclass，Sex，Age，SibSp 和 Parch 是建议尝试使用的特征。   
使用 survival_stats 函数来观测泰坦尼克号上乘客存活的数据统计。
提示: 要使用多个过滤条件，把每一个条件放在一个列表里作为最后一个参数传递进去。例如: ["Sex == 'male'", "Age &lt; 18"]
End of explanation
"""


def predictions_3(data):
    """ Model with multiple features. Makes a prediction with an accuracy of at least 80%. """
    
    predictions = []
    for _, passenger in data.iterrows():
        
        # Remove the 'pass' statement below 
        # and write your prediction conditions here
        
        if passenger['Sex'] == 'male':
            if  passenger['Pclass'] > 2:
                predictions.append(0)
            elif passenger['Age'] > 10:
                predictions.append(0)
            elif passenger['Parch'] < 1:
                predictions.append(0)
            else:
                predictions.append(1)
        elif passenger['Parch'] > 3:
            predictions.append(0)
        else:
            predictions.append(1)
    # Return our predictions
    return pd.Series(predictions)

# Make the predictions
predictions = predictions_3(data)

"""
Explanation: 当查看和研究了图形化的泰坦尼克号上乘客的数据统计后，请补全下面这段代码中缺失的部分，使得函数可以返回你的预测。 
在到达最终的预测模型前请确保记录你尝试过的各种特征和条件。 
提示: 您可以用之前 predictions_2 的代码作为开始来修改代码，实现新的预测函数。
End of explanation
"""


print accuracy_score(outcomes, predictions)

"""
Explanation: 结论
请描述你实现80%准确度的预测模型所经历的步骤。您观察过哪些特征？某些特性是否比其他特征更有帮助？你用了什么条件来预测生还结果？你最终的预测的准确率是多少？
提示:运行下面的代码来查看你的预测准确度。
End of explanation
"""


