python数据分析个人学习读书笔记-目录索引

 

第3章 探索数据

本章会介绍一些技术,帮助你对一个银行营销电话的数据进行分类。你将学习以下主题:
·测试并比较模型
·朴素贝叶斯分类器
·将逻辑回归作为通用分类器使用
·将支持向量机用作分类引擎
·使用决策树进行分类
·使用随机森林预测订阅者
·使用神经网络对呼叫进行分类

3.1导论

本章中,我们会对一个银行的营销电话进行分类,看看一个呼叫会不会带来一个信用卡业务。本文引用《A Data-Driven Approach to Predict the Success of Bank Telemarketing》中的数据,这本书可在http://archive.ics.uci.edu/ml/datasets/Bank+Marketing上找到。
为了能在我们的模型中使用,我们转换了数据。数据字典在/Data/Chapter03/bank_contacts_data_dict.txt。


3.2测试并比较模型
独立安装 pandas
>pip install pandas
独立安装 scikit-learn
>pip install scikit-learn

pandas让计算你所用模型的性能指标变得极其容易。我们使用下面的代码衡量模型的能力(Codes文件夹根目录下的helper.py文件):

 1 import sklearn.metrics as mt    
 2 
 3 def printModelSummary(actual, predicted):
 4     '''
 5         Method to print out model summaries
 6     '''
 7     print('Overall accuracy of the model is {0:.2f} percent'\
 8         .format(
 9             (actual == predicted).sum() / \
10             len(actual) * 100))
11     print('Classification report: \n', 
12         mt.classification_report(actual, predicted))
13     print('Confusion matrix: \n', 
14         mt.confusion_matrix(actual, predicted))
15     print('ROC: ', mt.roc_auc_score(actual, predicted))
16     

 原理
首先,我们从scikit-learn导入了metrics模块。然后,我们输出模型总体上的精确度。这是统计我们的模型与实际分类一致的次数((actual==predicted).sum()),再除以测试样本的规模(len(actual)*100)得到的。这告诉了我们总体上成功的比例。如果独立变量的分布不对称,那么这个维度不能用来评估你的模型。
.confusion_matrix方法以一种很清晰的方式衡量我们的模型——矩阵的每一行代表着模型弄错(或预测对)的次数:

/*
Consusion matrix:
{[10154 1816]
[559,946]}
*/

第一行,很明显一共是10154+1816=11970的实际观测值,其属于0这一类。其中,10154是正确预测的数目(我们把这种情况称作true negative,因为这代表着电话并没有带来信用卡业务),1816是错误预测的数目(我们把这种情况称作false positive,这类电话被我们的模型当成了“带来了信用卡业务”,实际上并没有)。

第二行展示了模型成功预测产出的次数:559次错误(称作false negative,电话带来了信用卡业务,而模型认为没有),946次正确(称作true positive,电话带来了信用卡业务,与模型的结论一致)。
这些数值可用于计算一些指标。使用.classification_report(...)方法生成这些指标:


《数据分析实战-托马兹.卓巴斯》读书笔记第3章-从朴素贝叶斯分类器到复杂的神经网络、随机树森林

 
精确率(Precision)衡量的是,当样本不是正类时,模型不将样本预测为正类的能力。这是true positive(946)与所有预测为正类的数量(1816+946)的比值:这里是0.34,相当低。也可以为负类计算相对应的值:10154/(10154+559)=0.95。总体的精确率是个体精确率的加权平均,权重就是支持度。支持度(Support)是样本中各分类的实际数目。
召回率(Recall)可被看作模型找出所有正类的能力。这是真阳性对真阳性与假阴性之和的比值:946/(946+559)=0.63。同样地,可以用真阴性比上真阴性和假阳性之和,得到类别0的召回率。总体的召回率是各类别召回率的加权平均,权重是支持度。
综合评价指标(F1-score)是精确率和召回率的调和平均。即精确率和召回率乘积的两倍比上它们的和。用这一个指标来衡量模型表现的好坏。
用于评估模型表现的最后一个指标是ROC曲线(Receiver Operating Characteristic)。ROC曲线将模型的表现可视化(对分类的比例不敏感)。换句话说,这条曲线相当于以更多假阳性的代价换取更多真阳性的权衡。我们对ROC曲线下方的面积更感兴趣。一般认为0.9到1的模型是优秀的,而0.5和0.6这种的则没什么价值——这种模型和抛硬币做决定没什么差别。

在helper.py文件中,我们放了一些后续章节常用的辅助过程。使用最多的应该就是timeit(...)装饰器了。这个装饰器可用来测量程序的运行时间:

def timeit(method):
    '''
    A decorator to time how long it takes to estimate the models
        一个用于估算模块所需时间的装饰器
    '''

    def timed(*args, **kw):
        start = time.time()
        result = method(*args, **kw)
        end = time.time()

        print('The method {0} took {1:2.2f} sec to run.' \
              .format(method.__name__, end-start))
        return result

    return timed

这个装饰器返回的是timed(...)方法,这个方法测量的是一个方法执行过程的结束与开始的时间戳之差。要使用一个装饰器,我们将@timeit(或者@hlp.timeit)放在要测量的函数前面。timeit(...)方法唯一的参数,就是传递给timed(...)这个内部方法的method。timed(...)方法启动计时器,执行传递进来的函数,再打印出用了多久。
Python中的函数,也是可以传递的对象,和其他对象(比如int)没什么差别。所以,我们可以将方法作为参数传给另一个函数,并在内部使用。
关于(Python 3.7的)装饰器,可参考http://thecodeship.com/patterns/guide-to-python-function-decorators/
参考

强烈推荐Scikit文档中关于分类器各种指标的部分:
http://scikit-learn.org/stable/modules/model_evaluation.html

 

3.3朴素贝叶斯分类器

独立安装 pandas
>pip install pandas
独立安装 scikit-learn
>pip install scikit-learn

朴素贝叶斯分类器是最简单的分类技术之一。其理论基础是贝叶斯定理,在一个事件发生的情况下,求另一事件发生的概率:
P(A|B)=P(B|A)P(A)/P(B)

也就是说,我们有电话及通话方的各种特征(B),要计算电话带来信用卡业务的概率(A)。这就等价于计算:观测到的申请信用卡的频率P(A),乘以过去同意办理信用卡的通话方与电话具有这些特征的频率P(B|A),比上数据集中这些通话方与电话的频率P(B)。
本节示例需要装好pandas和scikit-learn。我们还要使用helper.py文件,所以你需要NumPy和time模块。
helper.py文件放在上一级目录,我们需要将上一层目录加到Python的环境变量中,Python会到这些路径下寻找代码:

# this is needed to load helper from the parent folder
import sys
sys.path.append('..')

# the rest of the imports
import helper as hlp
import pandas as pd
import sklearn.naive_bayes as nb

使用pandas构造朴素贝叶斯分类器只花两行代码。但到那一步之前得做点长一些的准备(classification_naiveBayes.py文件):

 1 # the file name of the dataset
 2 r_filename = '../../Data/Chapter03/bank_contacts.csv'
 3 
 4 
 5 # the file name of the dataset
 6 r_filename = '../../Data/Chapter03/bank_contacts.csv'
 7 
 8 # read the data
 9 csv_read = pd.read_csv(r_filename)
10 
11 # split the data into training(训练集) and testing(测试集)
12 train_x, train_y, \
13 test_x,  test_y, \
14 labels = hlp.split_data(
15     csv_read, y = 'credit_application')
16 
17 # train the model 训练模型
18 classifier = fitNaiveBayes((train_x, train_y))
19 
20 # classify the unseen data
21 predicted = classifier.predict(test_x)
22 
23 # print out the results
24 hlp.printModelSummary(test_y, predicted)
25 
26 @hlp.timeit
27 def fitNaiveBayes(data):
28     '''
29     Build the Naive Bayes classifier
30         构造朴素贝叶斯分类器
31     '''
32     # create the classifier object 构造一个分类 器对象
33     naiveBayes_classifier = nb.GaussianNB()
34 
35     # fit the model 拟合模型
36     return naiveBayes_classifier.fit(data[0], data[1])

说明:

我们先从CSV文件读取数据,这一步大家应该很熟悉了(参见本书1.2节)。接着将数据拆成训练集和测试集,维持自变量(x)和因变量(y)的分离(参见本书2.8节)。
helper.py脚本的.split_data(...)方法将数据集拆成两个子集:默认情况下,2/3的数据用于训练,1/3的数据用于测试。这个方法是前一章方法略微复杂些的变体。有两个必需的参数(按顺序)是:data和y(因变量)。data参数应是pandas的DataFrame类型,y应传这个DataFrame中某列的名字。你可以用x参数传入一个列名的列表,作为指定的自变量(默认是选取除y外的所有列)(本章后面会详细讲这块)。你也可以给test_size参数传入一个0到1之间的数,以指定测试数据占的比例。
拆分完数据集,我们就可以构造分类器了。当前技巧和下一个技巧中,我们将用@hlp.timeit装饰器给不同的模型计时。
我们使用Scikit的.GaussianNB()方法构建朴素贝叶斯分类器。这个方法不用传参数。使用.fit(...)方法拟合模型;要传的第一个参数是自变量的集合,第二个参数是因变量的向量。一旦拟合,我们就向主程序返回分类器。模型就构建成功。
下面我们要测试模型。.predict(...)方法处理test_x数据集,将样本分为两个桶:一个是带来信用卡申请的电话,一个是没带来申请的电话。
Scikit中不同模型遵循同样的命名模式;这样用起来就很方便。后续用到的其他模型都有.fit(...)和.predict(...)方法,这样不用修改代码,也能很方便地测试不同的模型。
我们用之前介绍的printModelSummary(...)方法测试模型的表现(参考本书3.2节)。fitNaiveBayes(...)在平均情况下,(在我的机器上)花费0.03秒。
在你的机器上,程序运行的时间很可能不同。我们只将这个时间用作与后续介绍的方法进行比较的基准(你也该如此)。

 《数据分析实战-托马兹.卓巴斯》读书笔记第3章-从朴素贝叶斯分类器到复杂的神经网络、随机树森林

朴素贝叶斯在很多机器学习的应用中都有运用。比如,如何分类文本:http://sebastianraschka.com/Articles/2014_naive_bayes_1.html

 3.4将逻辑回归作为通用分类器使用

独立安装 pandas
独立安装 StatsModels
>pip install StatsModels

/*
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Installing collected packages: patsy, StatsModels
Successfully installed StatsModels-0.10.2 patsy-0.5.1
FINISHED
 */


逻辑回归可能是第二广泛的回归模型(排在线性回归之后)。不过它也可用于解决分类问题。
要实践本技巧,你需要装好pandas和StatsModels。如果你使用的是Anaconda发行版Python,那么这两个模块都已预装。我们引入StatsModels的两个部分:

import statsmodels.api as sm
import statsmodels.genmod.families.links as fm

前一个允许我们选取模型,后一个允许我们指定链接函数。
类似前一招的模式,我们先导入需要的模块,读入数据,拆分数据集。然后调用fitLogisticRegression(...)方法来预测模型(classification_logistic.py文件):

@hlp.timeit
def fitLogisticRegression(data):
    '''
        Build the logistic regression classifier
        构建逻辑回归分类器
    '''
    # create the classifier object 创建分类器对象
    logistic_classifier = sm.GLM(data[1], data[0],
        family=sm.families.Binomial(link=fm.logit))

    # fit the data拟合数据
    return logistic_classifier.fit()


StatsModels模块提供了.GLM(...)方法。GLM代表广义线性模型(Generalized Linear Model)。广义线性模型是一族模型,可为其他分布生成一个线性回归(误差项的正态性假设之下)。模型可以表述为:
《数据分析实战-托马兹.卓巴斯》读书笔记第3章-从朴素贝叶斯分类器到复杂的神经网络、随机树森林

这里g是一个链接函数,Xβ是线性等式的集合,E(Y)是因变量的期望(把它看成一个非正态分布的平均值)。GLM用链接函数将模型与响应变量的分布关联起来。
这里有所有链接函数的列表:http://statsmodels.sourceforge.net/devel/glm.html#links
StatsModels的.GLM(...)方法允许我们指定很多分布。在我们的例子中,应用了二项分布变量,这种变量只有两种取值:1代表带来信用卡申请的电话,0代表没带来信用卡申请的电话。这样我们就可以应用.families.Binomial(...)方法。实际上,二项分布族默认的链接函数就是logit,所以我们其实不用显式指定;我们这样做,只是为了在你要用其他链接函数时,知道怎么做。
StatsModels中实现的所有模型族列表:http://statsmodels.sourceforge.net/devel/glm.html#families
我们更熟悉的也许是sigmoid函数,logit函数是其反函数(参见下图):
《数据分析实战-托马兹.卓巴斯》读书笔记第3章-从朴素贝叶斯分类器到复杂的神经网络、随机树森林
如你所见,逻辑回归的输出只能在0和1之间变化,我们可以将其作为电话转化为信用卡申请的概率;一旦高于50%,我们就认为更有可能带来信用卡申请,将其归为1,否则就归为0。下面的代码可以获得这个效果:

# classify the unseen data 对隐藏的数据分类
predicted = classifier.predict(test_x)

# assign the class指定类别
predicted = [1 if elem > 0.5 else 0 for elem in predicted]

# print out the results打印结果
hlp.printModelSummary(test_y, predicted)

我们使用列表表达式将最终的分类赋给测试数据集。然后,我们用.printModel Summary(...)方法列出模型的性能表现。逻辑回归分类器的表现要比朴素贝叶斯的好,但这是建立在更高的计算代价之上的。
《数据分析实战-托马兹.卓巴斯》读书笔记第3章-从朴素贝叶斯分类器到复杂的神经网络、随机树森林

与朴素贝叶斯分类器相比,我们付出了高估false positive的代价,得到的是更好的归类true positive的能力。
StatsModels的GLM分类器允许我们打印出关于回归的更详细的结果,以及系数值和它们的统计表现。在分类器上调用的.summary()方法会打印类似下图(缩略版)的结果:

   Generalized Linear Model Regression Results                  
==============================================================================
Dep. Variable:     credit_application   No. Observations:                27753
Model:                            GLM   Df Residuals:                    27701
Model Family:                Binomial   Df Model:                           51
Link Function:                  logit   Scale:                          1.0000
Method:                          IRLS   Log-Likelihood:                    nan
Date:                Sun, 15 Mar 2020   Deviance:                          nan
Time:                        16:56:57   Pearson chi2:                 1.90e+19
No. Iterations:                   100                                         
Covariance Type:            nonrobust                                         
================================================================================================
                                   coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------------------------
n_age                        -1.937e+13   4.09e+06  -4.74e+06      0.000   -1.94e+13   -1.94e+13
n_duration                    1.091e+16   7.63e+06   1.43e+09      0.000    1.09e+16    1.09e+16
n_pdays                      -8.708e+14   7.45e+06  -1.17e+08      0.000   -8.71e+14   -8.71e+14
n_previous                   -6.625e+12   1.39e+07  -4.76e+05      0.000   -6.63e+12   -6.63e+12
n_emp_var_rate               -3.034e+15   1.91e+07  -1.59e+08      0.000   -3.03e+15   -3.03e+15
n_cons_price_idx              7.766e+15    1.7e+07   4.57e+08      0.000    7.77e+15    7.77e+15
n_cons_conf_idx               2.743e+15   5.39e+06   5.09e+08      0.000    2.74e+15    2.74e+15
n_euribor3m                  -7.989e+15   1.43e+07  -5.57e+08      0.000   -7.99e+15   -7.99e+15
n_nr_employed                 9.976e+15   2.09e+07   4.76e+08      0.000    9.98e+15    9.98e+15
job_admin                    -3.148e+14   1.23e+06  -2.56e+08      0.000   -3.15e+14   -3.15e+14
job_blue_collar              -3.598e+14   1.34e+06  -2.68e+08      0.000    -3.6e+14    -3.6e+14
job_entrepreneur             -3.638e+14   2.19e+06  -1.66e+08      0.000   -3.64e+14   -3.64e+14
job_housemaid                -3.058e+14    2.5e+06  -1.22e+08      0.000   -3.06e+14   -3.06e+14
job_management               -3.439e+14   1.74e+06  -1.98e+08      0.000   -3.44e+14   -3.44e+14
job_retired                  -2.012e+14   2.29e+06  -8.78e+07      0.000   -2.01e+14   -2.01e+14
job_self_employed            -3.907e+14    2.2e+06  -1.78e+08      0.000   -3.91e+14   -3.91e+14
job_services                 -4.108e+14   1.58e+06   -2.6e+08      0.000   -4.11e+14   -4.11e+14
job_student                  -2.723e+14   2.86e+06  -9.53e+07      0.000   -2.72e+14   -2.72e+14
job_technician               -2.846e+14   1.41e+06  -2.01e+08      0.000   -2.85e+14   -2.85e+14
job_unemployed               -2.482e+14   2.47e+06  -1.01e+08      0.000   -2.48e+14   -2.48e+14
job_unknown                  -4.352e+14   4.24e+06  -1.03e+08      0.000   -4.35e+14   -4.35e+14
marital_divorced             -9.426e+14   2.92e+06  -3.23e+08      0.000   -9.43e+14   -9.43e+14
marital_married              -9.485e+14   2.78e+06  -3.42e+08      0.000   -9.48e+14   -9.48e+14
marital_single                -9.31e+14   2.81e+06  -3.32e+08      0.000   -9.31e+14   -9.31e+14
marital_unknown              -1.109e+15   7.48e+06  -1.48e+08      0.000   -1.11e+15   -1.11e+15
edu_basic_4y                 -3.349e+14   2.62e+06  -1.28e+08      0.000   -3.35e+14   -3.35e+14
edu_basic_6y                 -2.782e+14   2.78e+06     -1e+08      0.000   -2.78e+14   -2.78e+14
edu_basic_9y                 -3.374e+14   2.52e+06  -1.34e+08      0.000   -3.37e+14   -3.37e+14
edu_high_school              -2.794e+14   2.47e+06  -1.13e+08      0.000   -2.79e+14   -2.79e+14
edu_illiterate               -1.898e+15   1.59e+07  -1.19e+08      0.000    -1.9e+15    -1.9e+15
edu_professional_course      -3.051e+14   2.59e+06  -1.18e+08      0.000   -3.05e+14   -3.05e+14
edu_university_degree        -2.503e+14   2.46e+06  -1.02e+08      0.000    -2.5e+14    -2.5e+14
edu_unknown                  -2.477e+14   2.92e+06  -8.47e+07      0.000   -2.48e+14   -2.48e+14
default_unknown              -1.301e+14   1.07e+06  -1.22e+08      0.000    -1.3e+14    -1.3e+14
default_yes                  -9.129e+14   4.75e+07  -1.92e+07      0.000   -9.13e+14   -9.13e+14
housing_unknown               1.694e+13   1.34e+06   1.26e+07      0.000    1.69e+13    1.69e+13
housing_yes                  -3.679e+13   8.24e+05  -4.47e+07      0.000   -3.68e+13   -3.68e+13
loan_unknown                  1.694e+13   1.34e+06   1.26e+07      0.000    1.69e+13    1.69e+13
loan_yes                     -1.265e+13   1.13e+06  -1.12e+07      0.000   -1.27e+13   -1.27e+13
contact_cellular              -1.92e+15   3.79e+06  -5.07e+08      0.000   -1.92e+15   -1.92e+15
contact_telephone            -2.011e+15    4.2e+06  -4.79e+08      0.000   -2.01e+15   -2.01e+15
prev_ctc_outcome_failure     -9.593e+14   4.53e+06  -2.12e+08      0.000   -9.59e+14   -9.59e+14
prev_ctc_outcome_nonexistent -7.454e+14   4.15e+06  -1.79e+08      0.000   -7.45e+14   -7.45e+14
prev_ctc_outcome_success     -2.226e+15   4.54e+06   -4.9e+08      0.000   -2.23e+15   -2.23e+15
month_apr                    -9.509e+13   2.48e+06  -3.83e+07      0.000   -9.51e+13   -9.51e+13
month_aug                     3.182e+14   2.51e+06   1.27e+08      0.000    3.18e+14    3.18e+14
month_dec                    -1.189e+15   5.67e+06   -2.1e+08      0.000   -1.19e+15   -1.19e+15
month_jul                    -4.792e+14   2.27e+06  -2.12e+08      0.000   -4.79e+14   -4.79e+14
month_jun                    -2.196e+15   4.82e+06  -4.56e+08      0.000    -2.2e+15    -2.2e+15
month_mar                    -9.509e+14   3.41e+06  -2.79e+08      0.000   -9.51e+14   -9.51e+14
month_may                    -4.898e+14    1.5e+06  -3.26e+08      0.000    -4.9e+14    -4.9e+14
month_nov                     4.175e+14   1.96e+06   2.13e+08      0.000    4.17e+14    4.17e+14
month_oct                     2.752e+14   3.11e+06   8.84e+07      0.000    2.75e+14    2.75e+14
month_sep                     4.585e+14    3.8e+06   1.21e+08      0.000    4.58e+14    4.58e+14
dow_fri                      -8.033e+14    1.8e+06  -4.45e+08      0.000   -8.03e+14   -8.03e+14
dow_mon                      -8.761e+14   1.74e+06  -5.02e+08      0.000   -8.76e+14   -8.76e+14
dow_thu                       -7.73e+14   1.78e+06  -4.34e+08      0.000   -7.73e+14   -7.73e+14
dow_tue                      -7.526e+14   1.74e+06  -4.33e+08      0.000   -7.53e+14   -7.53e+14
dow_wed                       -7.26e+14   1.75e+06  -4.14e+08      0.000   -7.26e+14   -7.26e+14
================================================================================================
View Code

相关文章:

  • 2022-01-12
  • 2021-06-22
  • 2021-10-20
  • 2021-11-01
  • 2022-01-28
  • 2021-06-18
  • 2022-12-23
  • 2021-08-12
猜你喜欢
  • 2021-09-07
  • 2021-07-22
  • 2021-10-15
  • 2021-06-24
  • 2021-12-08
  • 2021-08-14
相关资源
相似解决方案