为慈善机构寻找捐助者

 

 

 

 

机器学习纳米学位

监督学习

项目2: 为CharityML寻找捐献者

 

欢迎来到机器学习工程师纳米学位的第二个项目!在此文件中,有些示例代码已经提供给你,但你还须要实现更多的功能让项目成功运行。除非有明确要求,你无须修改任何已给出的代码。以'练习'开始的标题表示接下来的代码部分中有你必需要实现的功能。每一部分都会有详细的指导,须要实现的部分也会在注释中以'TODO'标出。请仔细阅读全部的提示!javascript

除了实现代码外,你还必须回答一些与项目和你的实现有关的问题。每个须要你回答的问题都会以'问题 X'为标题。请仔细阅读每一个问题,而且在问题后的'回答'文字框中写出完整的答案。咱们将根据你对问题的回答和撰写代码所实现的功能来对你提交的项目进行评分。css

提示:Code 和 Markdown 区域可经过Shift + Enter快捷键运行。此外,Markdown能够经过双击进入编辑模式。html

 

开始

在这个项目中,你将使用1994年美国人口普查收集的数据,选用几个监督学习算法以准确地建模被调查者的收入。而后,你将根据初步结果从中选择出最佳的候选算法,并进一步优化该算法以最好地建模这些数据。你的目标是创建一个可以准确地预测被调查者年收入是否超过50000美圆的模型。这种类型的任务会出如今那些依赖于捐款而存在的非营利性组织。了解人群的收入状况能够帮助一个非营利性的机构更好地了解他们要多大的捐赠,或是否他们应该接触这些人。虽然咱们很难直接从公开的资源中推断出一我的的通常收入阶层,可是咱们能够(也正是咱们将要作的)从其余的一些公开的可得到的资源中得到一些特征从而推断出该值。html5

这个项目的数据集来自UCI机器学习知识库。这个数据集是由Ron Kohavi和Barry Becker在发表文章_"Scaling Up the Accuracy of Naive-Bayes Classifiers: A Decision-Tree Hybrid"_以后捐赠的,你能够在Ron Kohavi提供的在线版本中找到这个文章。咱们在这里探索的数据集相比于原有的数据集有一些小小的改变,好比说移除了特征'fnlwgt' 以及一些遗失的或者是格式不正确的记录。java

 

探索数据

运行下面的代码单元以载入须要的Python库并导入人口普查数据。注意数据集的最后一列'income'将是咱们须要预测的列(表示被调查者的年收入会大于或者是最多50,000美圆),人口普查数据中的每一列都将是关于被调查者的特征。python

In [2]:
# 检查你的Python版本
from sys import version_info
if version_info.major != 2 and version_info.minor != 7:
    raise Exception('请使用Python 2.7来完成此项目')
In [6]:
# 为这个项目导入须要的库
import numpy as np
import pandas as pd
from time import time
from IPython.display import display # 容许为DataFrame使用display()

# 导入附加的可视化代码visuals.py
import visuals as vs

# 为notebook提供更加漂亮的可视化
%matplotlib inline

# 导入人口普查数据
data = pd.read_csv("census.csv")

# 成功 - 显示第一条记录
display(data.head(n=10))
 
 
  age workclass education_level education-num marital-status occupation relationship race sex capital-gain capital-loss hours-per-week native-country income
0 39 State-gov Bachelors 13.0 Never-married Adm-clerical Not-in-family White Male 2174.0 0.0 40.0 United-States <=50K
1 50 Self-emp-not-inc Bachelors 13.0 Married-civ-spouse Exec-managerial Husband White Male 0.0 0.0 13.0 United-States <=50K
2 38 Private HS-grad 9.0 Divorced Handlers-cleaners Not-in-family White Male 0.0 0.0 40.0 United-States <=50K
3 53 Private 11th 7.0 Married-civ-spouse Handlers-cleaners Husband Black Male 0.0 0.0 40.0 United-States <=50K
4 28 Private Bachelors 13.0 Married-civ-spouse Prof-specialty Wife Black Female 0.0 0.0 40.0 Cuba <=50K
5 37 Private Masters 14.0 Married-civ-spouse Exec-managerial Wife White Female 0.0 0.0 40.0 United-States <=50K
6 49 Private 9th 5.0 Married-spouse-absent Other-service Not-in-family Black Female 0.0 0.0 16.0 Jamaica <=50K
7 52 Self-emp-not-inc HS-grad 9.0 Married-civ-spouse Exec-managerial Husband White Male 0.0 0.0 45.0 United-States >50K
8 31 Private Masters 14.0 Never-married Prof-specialty Not-in-family White Female 14084.0 0.0 50.0 United-States >50K
9 42 Private Bachelors 13.0 Married-civ-spouse Exec-managerial Husband White Male 5178.0 0.0 40.0 United-States >50K
 

练习:数据探索

首先咱们对数据集进行一个粗略的探索,咱们将看看每个类别里会有多少被调查者?而且告诉咱们这些里面多大比例是年收入大于50,000美圆的。在下面的代码单元中,你将须要计算如下量:jquery

  • 总的记录数量,'n_records'
  • 年收入大于50,000美圆的人数,'n_greater_50k'.
  • 年收入最多为50,000美圆的人数 'n_at_most_50k'.
  • 年收入大于50,000美圆的人所占的比例, 'greater_percent'.

提示: 您可能须要查看上面的生成的表,以了解'income'条目的格式是什么样的。linux

In [12]:
# TODO:总的记录数
n_records = len(data)

# TODO:被调查者的收入大于$50,000的人数
n_greater_50k = len(data[data.income == '>50K'])

# TODO:被调查者的收入最多为$50,000的人数
n_at_most_50k = len(data[data.income == '<=50K'])

# TODO:被调查者收入大于$50,000所占的比例
greater_percent = float(n_greater_50k)/n_records*100

# 打印结果
print "Total number of records: {}".format(n_records)
print "Individuals making more than $50,000: {}".format(n_greater_50k)
print "Individuals making at most $50,000: {}".format(n_at_most_50k)
print "Percentage of individuals making more than $50,000: {:.2f}%".format(greater_percent)
 
Total number of records: 45222
Individuals making more than $50,000: 11208
Individuals making at most $50,000: 34014
Percentage of individuals making more than $50,000: 24.78%
 

准备数据

在数据可以被做为输入提供给机器学习算法以前,它常常须要被清洗,格式化,和从新组织 - 这一般被叫作预处理。幸运的是,对于这个数据集,没有咱们必须处理的无效或丢失的条目,然而,因为某一些特征存在的特性咱们必须进行必定的调整。这个预处理均可以极大地帮助咱们提高几乎全部的学习算法的结果和预测能力。android

得到特征和标签

income 列是咱们须要的标签,记录一我的的年收入是否高于50K。 所以咱们应该把他从数据中剥离出来,单独存放。css3

In [13]:
# 将数据切分红特征和对应的标签
income_raw = data['income']
features_raw = data.drop('income', axis = 1)
 

转换倾斜的连续特征

一个数据集有时可能包含至少一个靠近某个数字的特征,但有时也会有一些相对来讲存在极大值或者极小值的不平凡分布的的特征。算法对这种分布的数据会十分敏感,而且若是这种数据没有可以很好地规一化处理会使得算法表现不佳。在人口普查数据集的两个特征符合这个描述:'capital-gain''capital-loss'

运行下面的代码单元以建立一个关于这两个特征的条形图。请注意当前的值的范围和它们是如何分布的。

In [14]:
# 可视化 'capital-gain'和'capital-loss' 两个特征
vs.distribution(features_raw)
 
 

对于高度倾斜分布的特征如'capital-gain''capital-loss',常见的作法是对数据施加一个对数转换,将数据转换成对数,这样很是大和很是小的值不会对学习算法产生负面的影响。而且使用对数变换显著下降了因为异常值所形成的数据范围异常。可是在应用这个变换时必须当心:由于0的对数是没有定义的,因此咱们必须先将数据处理成一个比0稍微大一点的数以成功完成对数转换。

运行下面的代码单元来执行数据的转换和可视化结果。再次,注意值的范围和它们是如何分布的。

In [15]:
# 对于倾斜的数据使用Log转换
skewed = ['capital-gain', 'capital-loss']
features_raw[skewed] = data[skewed].apply(lambda x: np.log(x + 1))

# 可视化对数转换后 'capital-gain'和'capital-loss' 两个特征
vs.distribution(features_raw, transformed = True)
 
 

规一化数字特征

除了对于高度倾斜的特征施加转换,对数值特征施加一些形式的缩放一般会是一个好的习惯。在数据上面施加一个缩放并不会改变数据分布的形式(好比上面说的'capital-gain' or 'capital-loss');可是,规一化保证了每个特征在使用监督学习器的时候可以被平等的对待。注意一旦使用了缩放,观察数据的原始形式再也不具备它原本的意义了,就像下面的例子展现的。

运行下面的代码单元来规一化每个数字特征。咱们将使用sklearn.preprocessing.MinMaxScaler来完成这个任务。

In [16]:
from sklearn.preprocessing import MinMaxScaler

# 初始化一个 scaler,并将它施加到特征上
scaler = MinMaxScaler()
numerical = ['age', 'education-num', 'capital-gain', 'capital-loss', 'hours-per-week']
features_raw[numerical] = scaler.fit_transform(data[numerical])

# 显示一个通过缩放的样例记录
display(features_raw.head(n = 1))
 
 
  age workclass education_level education-num marital-status occupation relationship race sex capital-gain capital-loss hours-per-week native-country
0 0.30137 State-gov Bachelors 0.8 Never-married Adm-clerical Not-in-family White Male 0.02174 0.0 0.397959 United-States
 

练习:数据预处理

从上面的数据探索中的表中,咱们能够看到有几个属性的每一条记录都是非数字的。一般状况下,学习算法指望输入是数字的,这要求非数字的特征(称为类别变量)被转换。转换类别变量的一种流行的方法是使用独热编码方案。独热编码为每个非数字特征的每个可能的类别建立一个_“虚拟”_变量。例如,假设someFeature有三个可能的取值AB或者C,。咱们将把这个特征编码成someFeature_A, someFeature_BsomeFeature_C.

特征X   特征X_A 特征X_B 特征X_C
B   0 1 0
C ----> 独热编码 ----> 0 0 1
A   1 0 0

此外,对于非数字的特征,咱们须要将非数字的标签'income'转换成数值以保证学习算法可以正常工做。由于这个标签只有两种可能的类别("<=50K"和">50K"),咱们没必要要使用独热编码,能够直接将他们编码分别成两个类01,在下面的代码单元中你将实现如下功能:

  • 使用pandas.get_dummies()'features_raw'数据来施加一个独热编码。
  • 将目标标签'income_raw'转换成数字项。
    • 将"<=50K"转换成0;将">50K"转换成1
In [18]:
# TODO:使用pandas.get_dummies()对'features_raw'数据进行独热编码
features = pd.get_dummies(features_raw)

# TODO:将'income_raw'编码成数字值
from sklearn import preprocessing
income = pd.Series(preprocessing.LabelEncoder().fit_transform(income_raw))

# 打印通过独热编码以后的特征数量
encoded = list(features.columns)
print "{} total features after one-hot encoding.".format(len(encoded))

# 移除下面一行的注释以观察编码的特征名字
#print encoded
 
103 total features after one-hot encoding.
 

混洗和切分数据

如今全部的 类别变量 已被转换成数值特征,并且全部的数值特征已被规一化。和咱们通常状况下作的同样,咱们如今将数据(包括特征和它们的标签)切分红训练和测试集。其中80%的数据将用于训练和20%的数据用于测试。而后再进一步把训练数据分为训练集和验证集,用来选择和优化模型。

运行下面的代码单元来完成切分。

In [19]:
# 导入 train_test_split
from sklearn.model_selection import train_test_split

# 将'features'和'income'数据切分红训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(features, income, test_size = 0.2, random_state = 0,
                                                    stratify = income)
# 将'X_train'和'y_train'进一步切分为训练集和验证集
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=0,
                                                    stratify = y_train)

# 显示切分的结果
print "Training set has {} samples.".format(X_train.shape[0])
print "Validation set has {} samples.".format(X_val.shape[0])
print "Testing set has {} samples.".format(X_test.shape[0])
 
Training set has 28941 samples.
Validation set has 7236 samples.
Testing set has 9045 samples.
 

评价模型性能

在这一部分中,咱们将尝试四种不一样的算法,并肯定哪个可以最好地建模数据。四种算法包含一个天真的预测器 和三个你选择的监督学习器。

 

评价方法和朴素的预测器

CharityML经过他们的研究人员知道被调查者的年收入大于\$50,000最有可能向他们捐款。由于这个缘由*CharityML*对于准确预测谁可以得到\$50,000以上收入尤为有兴趣。这样看起来使用准确率做为评价模型的标准是合适的。另外,把没有收入大于\$50,000的人识别成年收入大于\$50,000对于CharityML来讲是有害的,由于他想要找到的是有意愿捐款的用户。这样,咱们指望的模型具备准确预测那些可以年收入大于\$50,000的能力比模型去查全这些被调查者更重要。咱们可以使用F-beta score做为评价指标,这样可以同时考虑查准率和查全率:

$$ F_{\beta} = (1 + \beta^2) \cdot \frac{precision \cdot recall}{\left( \beta^2 \cdot precision \right) + recall} $$

尤为是,当 $\beta = 0.5$ 的时候更多的强调查准率,这叫作F$_{0.5}$ score (或者为了简单叫作F-score)。

 

问题 1 - 天真的预测器的性能

经过查看收入超过和不超过 \$50,000 的人数,咱们能发现多数被调查者年收入没有超过 \$50,000。若是咱们简单地预测说“这我的的收入没有超过 \$50,000”,咱们就能够获得一个 准确率超过 50% 的预测。这样咱们甚至不用看数据就能作到一个准确率超过 50%。这样一个预测被称做是天真的。一般对数据使用一个天真的预测器是十分重要的,这样可以帮助创建一个模型表现是否好的基准。 使用下面的代码单元计算天真的预测器的相关性能。将你的计算结果赋值给'accuracy', ‘precision’, ‘recall’'fscore',这些值会在后面被使用,请注意这里不能使用scikit-learn,你须要根据公式本身实现相关计算。

若是咱们选择一个不管什么状况都预测被调查者年收入大于 \$50,000 的模型,那么这个模型在验证集上的准确率,查准率,查全率和 F-score是多少?

In [29]:
#不能使用scikit-learn,你须要根据公式本身实现相关计算。

# 假阳性FP
FP = float(len(y_val[y_val == 0]))
# 真阳性TP
TP = float(len(y_val[y_val == 1]))
# 假阴性
FN = 0

#TODO: 计算准确率
accuracy = TP/len(y_val)

# TODO: 计算查准率 Precision
precision = TP / (TP+FP)

# TODO: 计算查全率 Recall
recall = TP / (TP+FN)

# TODO: 使用上面的公式,设置beta=0.5,计算F-score
fscore = (1+0.5**2) * ( (precision*recall) / (0.5**2*precision + recall) )

# 打印结果
print "Naive Predictor on validation data: \n\
    Accuracy score: {:.4f} \n\
    Precision: {:.4f} \n\
    Recall: {:.4f} \n\
    F-score: {:.4f}".format(accuracy, precision, recall, fscore)
 
Naive Predictor on validation data: 
     Accuracy score: 0.2478 
     Precision: 0.2478 
     Recall: 1.0000 
     F-score: 0.2917
 

监督学习模型

问题 2 - 模型应用

你可以在 scikit-learn 中选择如下监督学习模型

  • 高斯朴素贝叶斯 (GaussianNB)
  • 决策树 (DecisionTree)
  • 集成方法 (Bagging, AdaBoost, Random Forest, Gradient Boosting)
  • K近邻 (K Nearest Neighbors)
  • 随机梯度降低分类器 (SGDC)
  • 支撑向量机 (SVM)
  • Logistic回归(LogisticRegression)

从上面的监督学习模型中选择三个适合咱们这个问题的模型,并回答相应问题。

 

模型1

模型名称

回答:k近邻

描述一个该模型在真实世界的一个应用场景。(你须要为此作点研究,并给出你的引用出处)

回答: 使用k近邻分类海伦的约会对象,将其分为3类

参考文章:http://www.javashuo.com/article/p-yuwdaqgq-ba.html

这个模型的优点是什么?他什么状况下表现最好?

回答: 1.简单,容易理解,精度高,对异常数据不敏感。 2.目标变量是数值型且有限

这个模型的缺点是什么?什么条件下它表现不好?

回答: 1.计算复杂度高,空间复杂度高,样本不平衡 2.数值很大时

根据咱们当前数据集的特色,为何这个模型适合这个问题。

回答: 1.数值可能存在异常值,k近邻能够下降对异常值的敏感程度 2.二分类问题,k值能够选为奇数 3.数据量不是很大

 

模型2

模型名称

回答:集成方法(Random Forest)

描述一个该模型在真实世界的一个应用场景。(你须要为此作点研究,并给出你的引用出处)

回答:手写体数字识别

网址:http://www.javashuo.com/article/p-rjfuhvgz-bc.html

这个模型的优点是什么?他什么状况下表现最好?

回答: 1.能够处理高维数据,能够不用进行特征筛选,很是容易进行分布式处理,实现起来很是高效

2.可以评估各个特征在分类问题上的重要性

这个模型的缺点是什么?什么条件下它表现不好?

回答: 1.树越多,随机森林的表现才会越稳定。实际应用中树很少可能致使不稳定。

2.不平衡数据集

根据咱们当前数据集的特色,为何这个模型适合这个问题。

回答:数据维度较高,处理起来很合适

 

模型3

模型名称

回答:决策树

描述一个该模型在真实世界的一个应用场景。(你须要为此作点研究,并给出你的引用出处)

回答: 鸢尾花分类

参考地址:http://blog.csdn.net/rongrongyaofeiqi/article/details/52872957

这个模型的优点是什么?他什么状况下表现最好?

回答: 1.理解和解释起来简单,且决策树模型能够想象,可以处理多输出的问题。

2.可以生成清晰的基于特征(feature)选择不一样预测结果的树状结构

这个模型的缺点是什么?什么条件下它表现不好?

回答: 1.决策树的结果多是不稳定

2.人为的改变一些特征,使分类器错误

根据咱们当前数据集的特色,为何这个模型适合这个问题。

回答:

1.数据量不是很大 2.能够选择特征条件进行分类

 

练习 - 建立一个训练和预测的流水线

为了正确评估你选择的每个模型的性能,建立一个可以帮助你快速有效地使用不一样大小的训练集并在验证集上作预测的训练和验证的流水线是十分重要的。 你在这里实现的功能将会在接下来的部分中被用到。在下面的代码单元中,你将实现如下功能:

  • sklearn.metrics中导入fbeta_scoreaccuracy_score
  • 用训练集拟合学习器,并记录训练时间。
  • 对训练集的前300个数据点和验证集进行预测并记录预测时间。
  • 计算预测训练集的前300个数据点的准确率和F-score。
  • 计算预测验证集的准确率和F-score。
In [23]:
# TODO:从sklearn中导入两个评价指标 - fbeta_score和accuracy_score
from sklearn.metrics import fbeta_score, accuracy_score

def train_predict(learner, sample_size, X_train, y_train, X_val, y_val): 
    '''
    inputs:
       - learner: the learning algorithm to be trained and predicted on
       - sample_size: the size of samples (number) to be drawn from training set
       - X_train: features training set
       - y_train: income training set
       - X_val: features validation set
       - y_val: income validation set
    '''
    
    results = {}
    
    # TODO:使用sample_size大小的训练数据来拟合学习器
    # TODO: Fit the learner to the training data using slicing with 'sample_size'
    start = time() # 得到程序开始时间
    learner = learner.fit(X_train[:sample_size],y_train[:sample_size])
    end = time() # 得到程序结束时间
    
    # TODO:计算训练时间
    results['train_time'] = end - start
    
    # TODO: 获得在验证集上的预测值
    #       而后获得对前300个训练数据的预测结果
    start = time() # 得到程序开始时间
    predictions_val = learner.predict(X_val)
    predictions_train = learner.predict(X_train[:300])
    end = time() # 得到程序结束时间
    
    # TODO:计算预测用时
    results['pred_time'] = end - start
            
    # TODO:计算在最前面的300个训练数据的准确率
    results['acc_train'] = accuracy_score(y_train[:300],predictions_train)
        
    # TODO:计算在验证上的准确率
    results['acc_val'] = accuracy_score(y_val,predictions_val)
    
    # TODO:计算在最前面300个训练数据上的F-score
    results['f_train'] = fbeta_score(y_train[:300],predictions_train, beta=0.5)
        
    # TODO:计算验证集上的F-score
    results['f_val'] = fbeta_score(y_val,predictions_val, beta=0.5)
       
    # 成功
    print "{} trained on {} samples.".format(learner.__class__.__name__, sample_size)
        
    # 返回结果
    return results
 

练习:初始模型的评估

在下面的代码单元中,您将须要实现如下功能:

  • 导入你在前面讨论的三个监督学习模型。
  • 初始化三个模型并存储在'clf_A''clf_B''clf_C'中。
    • 使用模型的默认参数值,在接下来的部分中你将须要对某一个模型的参数进行调整。
    • 设置random_state (若是有这个参数)。
  • 计算1%, 10%, 100%的训练数据分别对应多少个数据点,并将这些值存储在'samples_1', 'samples_10', 'samples_100'

注意:取决于你选择的算法,下面实现的代码可能须要一些时间来运行!

In [51]:
# TODO:从sklearn中导入三个监督学习模型
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
#from sklearn.svm import SVC
#from sklearn.naive_bayes import GaussianNB
from sklearn import tree
#from sklearn import linear_model
#from sklearn.linear_model import LogisticRegression
#from sklearn.ensemble import BaggingClassifier

# TODO:初始化三个模型
clf_A = KNeighborsClassifier(n_neighbors=3)
clf_B = RandomForestClassifier(random_state=2)
clf_C = tree.DecisionTreeClassifier()
#clf_C = GaussianNB()
#clf_C = SVC(kernel='linear')
#clf_C = linear_model.SGDClassifier()


# TODO:计算1%, 10%, 100%的训练数据分别对应多少点
samples_1 = int( len(X_train)*0.01 )
samples_10 = int( len(X_train)*0.1 )
samples_100 = len(X_train)

# 收集学习器的结果
results = {}
for clf in [clf_A, clf_B, clf_C]:
    clf_name = clf.__class__.__name__
    results[clf_name] = {}
    for i, samples in enumerate([samples_1, samples_10, samples_100]):
        results[clf_name][i] = train_predict(clf, samples, X_train, y_train, X_val, y_val)

# 对选择的三个模型获得的评价结果进行可视化
vs.evaluate(results, accuracy, fscore)
 
KNeighborsClassifier trained on 289 samples.
KNeighborsClassifier trained on 2894 samples.
KNeighborsClassifier trained on 28941 samples.
RandomForestClassifier trained on 289 samples.
RandomForestClassifier trained on 2894 samples.
RandomForestClassifier trained on 28941 samples.
DecisionTreeClassifier trained on 289 samples.
DecisionTreeClassifier trained on 2894 samples.
DecisionTreeClassifier trained on 28941 samples.
 
 

提升效果

在这最后一节中,您将从三个有监督的学习模型中选择 最好的 模型来使用学生数据。你将在整个训练集(X_trainy_train)上使用网格搜索优化至少调节一个参数以得到一个比没有调节以前更好的 F-score。

 

问题 3 - 选择最佳的模型

基于你前面作的评价,用一到两段话向 CharityML 解释这三个模型中哪个对于判断被调查者的年收入大于 \$50,000 是最合适的。
提示:你的答案应该包括评价指标,预测/训练时间,以及该算法是否适合这里的数据。

 

回答:

1.从准确度上上看,DecisionTree在1%和100%训练集上表现最好,DecisionTree和RandomForest在10%训练集上表现同样好,RandomForest在全部的验证集表现最好

2.从F-score上看,RandomForest在1%训练集上和全部的验证集表现最好,DecisionTree和RandomForest在10%训练集上表现同样好

3.从训练时间上来看,KNeighbors最多,RandomForest中间,DecisionTree最少

4.从预测时间上来看,KNeighbors明显多与其余两种算法

5.综上所述RandomForest综合表现较好,所需时间少分类准,虽然DecisionTree在训练集上表现好,可是验证集上表现差,说明有过拟合。因此RandomForest最合适。

 

问题 4 - 用通俗的话解释模型

用一到两段话,向 CharityML 用外行也听得懂的话来解释最终模型是如何工做的。你须要解释所选模型的主要特色。例如,这个模型是怎样被训练的,它又是如何作出预测的。避免使用高级的数学或技术术语,不要使用公式或特定的算法名词。

 

回答: 1.训练:对全部数据找到最大程度区分当前数据的特征,而后按照此特征的条件进行数据分割,对分割的数据重复此步骤,直到全部特征判断完。这样的判断构成决策树。

2.因为单个决策树,依赖分类参数选择严重,因此重复1对样本进行随机有放回的抽样产生多个决策树,这些决策树合并起来就是随机森林

 

练习:模型调优

调节选择的模型的参数。使用网格搜索(GridSearchCV)来至少调整模型的重要参数(至少调整一个),这个参数至少需尝试3个不一样的值。你要使用整个训练集来完成这个过程。在接下来的代码单元中,你须要实现如下功能:

  • 导入sklearn.model_selection.GridSearchCVsklearn.metrics.make_scorer.
  • 初始化你选择的分类器,并将其存储在clf中。
    • 设置random_state (若是有这个参数)。
  • 建立一个对于这个模型你但愿调整参数的字典。
    • 例如: parameters = {'parameter' : [list of values]}。
    • 注意: 若是你的学习器有 max_features 参数,请不要调节它!
  • 使用make_scorer来建立一个fbeta_score评分对象(设置$\beta = 0.5$)。
  • 在分类器clf上用'scorer'做为评价函数运行网格搜索,并将结果存储在grid_obj中。
  • 用训练集(X_train, y_train)训练grid search object,并将结果存储在grid_fit中。

注意: 取决于你选择的参数列表,下面实现的代码可能须要花一些时间运行!

In [35]:
# TODO:导入'GridSearchCV', 'make_scorer'和其余一些须要的库
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import fbeta_score,make_scorer
# TODO:初始化分类器
clf = RandomForestClassifier(random_state=2)

# TODO:建立你但愿调节的参数列表
parameters = {'n_estimators':[1,12,55,100]}

# TODO:建立一个fbeta_score打分对象
scorer = make_scorer(fbeta_score, beta=0.5)

# TODO:在分类器上使用网格搜索,使用'scorer'做为评价函数
grid_obj = GridSearchCV(clf, parameters, scorer)

# TODO:用训练数据拟合网格搜索对象并找到最佳参数
grid_obj = grid_obj.fit(X_train, y_train)

# 获得estimator
best_clf = grid_obj.best_estimator_

# 使用没有调优的模型作预测
predictions = (clf.fit(X_train, y_train)).predict(X_val)
# 使用调优的模型作预测
best_predictions = best_clf.predict(X_val)

# 汇报调参前和调参后的分数
print "Unoptimized model\n------"
print "Accuracy score on validation data: {:.4f}".format(accuracy_score(y_val, predictions))
print "F-score on validation data: {:.4f}".format(fbeta_score(y_val, predictions, beta = 0.5))
print "\nOptimized Model\n------"
print "Final accuracy score on the validation data: {:.4f}".format(accuracy_score(y_val, best_predictions))
print "Final F-score on the validation data: {:.4f}".format(fbeta_score(y_val, best_predictions, beta = 0.5))
 
Unoptimized model
------
Accuracy score on validation data: 0.8401
F-score on validation data: 0.6844

Optimized Model
------
Final accuracy score on the validation data: 0.8467
Final F-score on the validation data: 0.6967
 

问题 5 - 最终模型评估

你的最优模型在测试数据上的准确率和 F-score 是多少?这些分数比没有优化的模型好仍是差?你优化的结果相比于你在问题 1中获得的天真预测器怎么样?
注意:请在下面的表格中填写你的结果,而后在答案框中提供讨论。

 

结果:

评价指标 天真预测器 未优化的模型 优化的模型
准确率 0.2478 0.8401 0.8467
F-score 0.2917 0.6844 0.6967
 

回答: 1.未优化的模型和优化的模型都比天真预测器好不少。 2.优化的模型比未优化的模型表现好。

 

特征的重要性

在数据上(好比咱们这里使用的人口普查的数据)使用监督学习算法的一个重要的任务是决定哪些特征可以提供最强的预测能力。专一于少许的有效特征和标签之间的关系,咱们可以更加简单地理解这些现象,这在不少状况下都是十分有用的。在这个项目的情境下这表示咱们但愿选择一小部分特征,这些特征可以在预测被调查者是否年收入大于\$50,000这个问题上有很强的预测能力。

选择一个有 'feature_importance_' 属性的scikit学习分类器(例如 AdaBoost,随机森林)。'feature_importance_' 属性是对特征的重要性排序的函数。在下一个代码单元中用这个分类器拟合训练集数据并使用这个属性来决定人口普查数据中最重要的5个特征。

 

问题 6 - 观察特征相关性

探索数据的时候,它显示在这我的口普查数据集中每一条记录咱们有十三个可用的特征。
在这十三个记录中,你认为哪五个特征对于预测是最重要的,选择每一个特征的理由是什么?你会怎样对他们排序?

 

回答:

  • 特征1:age,年龄越大,积累越高,收入越高
  • 特征2:education_level,教育程度越高理论上收入越高
  • 特征3:occupation,职业领域,不一样的职业领域,收入水平不同
  • 特征4:relationship,家庭状况,家庭总数入也有影响
  • 特征5:workclass,劳动类型,不一样的类型对输入也不一样

age>workclass>occupation>education_level>relationship

 

练习 - 提取特征重要性

选择一个scikit-learn中有feature_importance_属性的监督学习分类器,这个属性是一个在作预测的时候根据所选择的算法来对特征重要性进行排序的功能。

在下面的代码单元中,你将要实现如下功能:

  • 若是这个模型和你前面使用的三个模型不同的话从sklearn中导入一个监督学习模型。
  • 在整个训练集上训练一个监督学习模型。
  • 使用模型中的 'feature_importances_'提取特征的重要性。
In [36]:
# TODO:导入一个有'feature_importances_'的监督学习模型

# TODO:在训练集上训练一个监督学习模型
model = best_clf

# TODO: 提取特征重要性
importances = model.feature_importances_

# 绘图
vs.feature_plot(importances, X_train, y_train)
 
 

问题 7 - 提取特征重要性

观察上面建立的展现五个用于预测被调查者年收入是否大于\$50,000最相关的特征的可视化图像。

这五个特征的权重加起来是否超过了0.5?
这五个特征和你在问题 6中讨论的特征比较怎么样?
若是说你的答案和这里的相近,那么这个可视化怎样佐证了你的想法?
若是你的选择不相近,那么为何你以为这些特征更加相关?

 

回答:

1.权重之和超过了0.5

2.不一致

3.因为github上对这些特征没有解释,hours-per-week,capital-gain,marital-status,因此未考虑到。

 

特征选择

若是咱们只是用可用特征的一个子集的话模型表现会怎么样?经过使用更少的特征来训练,在评价指标的角度来看咱们的指望是训练和预测的时间会更少。从上面的可视化来看,咱们能够看到前五个最重要的特征贡献了数据中全部特征中超过一半的重要性。这提示咱们能够尝试去减少特征空间,简化模型须要学习的信息。下面代码单元将使用你前面发现的优化模型,并只使用五个最重要的特征在相同的训练集上训练模型。

In [37]:
# 导入克隆模型的功能
from sklearn.base import clone

# 减少特征空间
X_train_reduced = X_train[X_train.columns.values[(np.argsort(importances)[::-1])[:5]]]
X_val_reduced = X_val[X_val.columns.values[(np.argsort(importances)[::-1])[:5]]]

# 在前面的网格搜索的基础上训练一个“最好的”模型
clf_on_reduced = (clone(best_clf)).fit(X_train_reduced, y_train)

# 作一个新的预测
reduced_predictions = clf_on_reduced.predict(X_val_reduced)

# 对于每个版本的数据汇报最终模型的分数
print "Final Model trained on full data\n------"
print "Accuracy on validation data: {:.4f}".format(accuracy_score(y_val, best_predictions))
print "F-score on validation data: {:.4f}".format(fbeta_score(y_val, best_predictions, beta = 0.5))
print "\nFinal Model trained on reduced data\n------"
print "Accuracy on validation data: {:.4f}".format(accuracy_score(y_val, reduced_predictions))
print "F-score on validation data: {:.4f}".format(fbeta_score(y_val, reduced_predictions, beta = 0.5))
 
Final Model trained on full data
------
Accuracy on validation data: 0.8467
F-score on validation data: 0.6967

Final Model trained on reduced data
------
Accuracy on validation data: 0.8307
F-score on validation data: 0.6619
 

问题 8 - 特征选择的影响

最终模型在只是用五个特征的数据上和使用全部的特征数据上的 F-score 和准确率相比怎么样?
若是训练时间是一个要考虑的因素,你会考虑使用部分特征的数据做为你的训练集吗?

 

回答:

1.部分特征比全部特征F-score和准确率低。

2.会,若数据量比较大,特征比较多,从训练时间上考虑会选择部分特征训练

 

问题 9 - 在测试集上测试你的模型

终于到了测试的时候,记住,测试集只能用一次。

使用你最有信心的模型,在测试集上测试,计算出准确率和 F-score。 简述你选择这个模型的缘由,并分析测试结果

In [40]:
#TODO test your model on testing data and report accuracy and F score
res = best_clf.predict(X_test)
from sklearn.metrics import fbeta_score,accuracy_score
print accuracy_score(y_true=y_test,y_pred=res)
print fbeta_score(y_true=y_test,y_pred=res,beta=0.5)
 
0.840132669983
0.682483889865
 

1.随机森林模型主要在于训练时间短,准确率较高,不容易过拟合

2.预测结果还有很大提高空间

 

欢迎扫码关注,或搜索大数据与知识图谱,按期分享大数据与知识图谱相关知识点:

相关文章
相关标签/搜索