本文较长,全是干货,建议收藏后作为长期的学习指南。
不过这篇指南只是从宏观上指引了大家的学习步骤以及通过哪些资源学习,我们今天接着详细谈谈怎样依靠Python从零开始成为一名数据分析师,期间会以一个借贷数据集为例,分享利用Python进行数据分析所需的基础知识和工具,相信能为你借助Python迅速成为数据分析师提供一些帮助。
内容目录
1. 用于数据分析的Python基本知识
- 为何学习Python用于数据分析?
- 怎样安装Python?
- 用Python做一些简单的项目
2. Python库和数据结构
- Python数据结构
- Python迭代和条件构造
- 用于数据分析的Python库
3. 利用Python和Pandas进行探索性数据分析
- Pandas的Series和Dataframe入门简介
- 以借贷数据集为例完成数据分析项目
4. 用Python的Pandas进行数据再加工
- 如何推定缺失值
- 如何应对极值
5. 用Python创建预测模型,根据数据做预测
- 逻辑回归模型
- 决策树模型
- 随机森林模型
注:本文原作者为数据科学家Kunal Jain,其毕业于印度最顶尖的IT院校印度理工学院,从事数据科学领域已逾10年,在英国和印度等多家大型跨国公司担任资深数据分析师。
大概几年前,在SAS领域工作了5年后,我(作者Kunal Jain——译者注)决定走出我的舒适区,励志成为一名数据科学家。在多方寻找能助我成为数据科学家的学习工具后,我最终决定选择Python。
我一直都很喜欢写代码,这是我内心的热爱。
我花了大概一周的时间学习了Python的基础知识,然后不仅我自己深入掌握了这门语言,还帮助了其他人也学习了Python。最初Python是一种通用语言,但是随着这些年的发展和强大的社区支持,Python涌现了很多用于数据分析和预测建模的程序库。
由于很多人尚不知道如何将Python用于数据科学以及缺少相关的资源,我决定写这篇教程,帮更多人更快的学习Python。在教程中,我也会教大家如何用Python进行数据分析,最终熟练掌握,为己所用。
1. Python用于数据分析的基本知识
为何学习Python用于数据分析?
近年来,Python被很多人选择用于数据分析,我将它和SAS、R语言做了一番比较,觉得以下是你学习Python用于数据分析的好处:
- 开源——免费安装和使用
- 很强大的在线社区支持
- 非常容易学习(没任何编程基础也能很快上手)
- 能成为数据科学和部署基于数据分析产品的通用语言
当然也存在一些缺点:
它是一门解释性语言而非编译语言,因此会花费更多的CPU时间。不过考虑到我们能大幅节约编程学习时间(因为很容易学),两者相抵,这算不上是什么大缺点。
怎样安装Python?
安装Python有2种方法:
1.你可以从Python的项目网站(https://www.python.org/downloads/)直接下载,安装你需要的各个组件和库。
2.你也可以下载和安装程序包,里面内置了预先安装的库。我建议下载Anaconda。另一个选择是Enthought Canopy Express。第二种方法提供无忧安装,所以我建议初学者选这种方法。这种方法的缺点就是你必须等待整个包升级完毕,哪怕你只是对某个库的最新版感兴趣。
选择开发环境
一旦安装好Python,选择开发环境时也有多种选项。这里是3个最常见的选项:
- 基于终端和Shell
- IDLE(默认环境)
- iPython notebook——相当于R语言中的Markdown
虽然应该根据自己的需要选择正确的环境,但我个人更喜欢iPython notebook一些。
它提供了很多很好的功能供你在写代码时写文档,你还可以选择以代码块的方式运行代码(而不是逐行运行)。
本文的整篇教程我们都会使用iPython环境。
热身:运行你的第一个Python项目
你可以首先用Python写一个简单的计算器:
需要注意的一些事情:
- 根据所用操作系统,你可以在你的terminal/cmd上编写“ipython notebook”启动ipython notebook。
- 你可以在名称上简单点击就可以命名一个iPython notebook——例如上面截图中的UntitledO。
- 界面中In [*] 表示输入,Out[*]表示输出。
- 如果你想在后面插入一行额外行,可以通过按“shift+Enter”或“ALT+Enter”执行代码。
在我们深入解决问题前,先后退一步了解一下Python的基础知识。我们知道数据结构、迭代和条件结构是任何编程语言的关键。在Python中,这些信息包括列表,字符串,元组,字典,for循环,while循环,if-else等等。我们看看其中一些。
2. Python 库和数据结构
Python 数据结构
下面是Python中用到的一些数据结构。你应该对它们非常熟悉,以便后面能正确使用它们。
列表——列表是Python中最为通用的数据结构之一。在方括号内写一列常见的逗号分隔的值就能简单定义一个列表。列表可能包含不同类型的数据项,但通常数据项都属相同的类型。
Python列表是可变的,列表中的单个元素可以改变。
下面是在Python中定义一个列表并获取列表的示例:
字符串——使用单引号(‘),双引号(“)或三引号(“ ‘)定义字符串。以三引号结尾的字符串可以横跨多个代码行,在docstrings(Python中注释函数的一种方法)中使用非常频繁。\被用作转义字符。注意Python字符串是不可变的,所以你不能更改字符串内容。
元组——元组由若干被逗号分隔的值表示。元组是不可变的,输出被圆括号括起,因此要正确处理嵌套元组。此外,虽然元素是不可变的,如果有需要,它们也能包含可变数据。而由于元组不可变的特点,它们在处理方面要快于列表。所以,如果你的列表无法改变,就应该使用元组而非列表。
字典——字典是一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key=>value 对用冒号 : 分割,每个键值对之间用逗号 , 分割,整个字典包括在花括号 {} 中。一对花括号就能创建一个空字典:{}。
Python迭代和条件结构
和大多数语言一样,Python也有for循环,是Python迭代中应用最广泛的一种方法。它的语法比较简单:
for i in [Python Iterable]:
expression(i)
这里的“Python iterable”可以是个列表,元组或其它高级的数据结构,我们在下一部分会讲到。我们先看一个简单的例子,确定一个数字的阶乘。
fact=1
for i in range(1,N+1):
fact *= i
至于条件语句,它们是用于根据一定条件来执行代码片段。最常用的结构是if-else,语法如下:
if [condition]:
__execution if true__
else:
__execution if false__
例如,如果我们想打印数字N是偶数还是奇数,代码这样写就可以了:
if N%2 == 0:
print 'Even'
else:
print 'Odd'
现在你已经熟悉了Python的基本知识点,下面我们更近一步。如果你有以下一些任务,该怎么办:
- 相乘2个矩阵
- 求解一元二次方程的根
- 绘出条形图和直方图
- 创建统计模型
- 获取网页
如果你试图从头开始写代码完成它们,那这任务量简直是噩梦一般的大,肯定没两天你就坚持不下去了。不过不用太担心,幸好有很多预定义的Python库,我们在代码中可以直接导入它们,让我们的任务更轻松容易。
例如,拿我们上面所举的阶乘例子来说,我们只需一步即可:
math.factorial(N)
当然我们需要导入math库来解决这个问题。我们在下部分就讲解一些程序库。
Python库
在这部分,我们会认识一些实用的Python库。很显然第一步是学习怎么将它们导入到我们的环境中,有好几种方法:
import math as m
from math import *
在第一种方法中,我们为库math定义了一个别名m,我们现在可以通过用alias m.factorial()来引用math库来使用它内部的多种函数(比如factorial)。
在第二种方法中,我们导入了math中的整个名字空间,也就是说可以无需引用math直接使用factorial()。
小提示:谷歌建议大家使用第一种导入库的方法,因为这样你能知道函数来自哪里。
下面是一系列的程序库,不管是你做任何数据分析工作都会用到它们,所以务必熟练掌握:
- Numpy:Python语言的一个扩充程序库。支持高级大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
- SciPy:构建于NumPy之上,提供了一个用于在Python中进行科学计算的工具集,如数值计算的算法和一些功能函数,可以方便的处理数据。
- Matplotlib:一个 Python 的 2D绘图库,它以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形。通过 Matplotlib,开发者可以仅需要几行代码,便可以生成绘图,直方图,功率谱,条形图,错误图,散点图等。
- Pandas:基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
- Scikit Learn:用Python开发的机器学习库,其中包含大量机器学习算法、数据集,是数据挖掘方便的工具。
- Statsmodels:一个包含统计模型、统计测试和统计数据挖掘python模块。对每一个模型都会生成一个对应的统计结果。统计结果会和现有的统计包进行对比来保证其正确性。
- Seaborn:用于统计数据可视化的一款Python可视化工具。依靠它,你可以用Python绘出非常美观、直观和吸引人的图形。是从事数据分析和挖掘工作的利器。
- Bokeh:一款交互式可视化Python包,能够在浏览器上创建交互式图形、数据面板和数据应用。
- Blaze:能够扩展Numpy和Pandas处理分布式和流媒体数据集的能力。可以用于从包括Bcolz,MongoDB,SQLAIchemy,Apache Spark PyTables等多维数据源中获取数据。和Bokeh一起使用时,Blaze能够作为一种非常强大数据,帮我们绘制大量数据的可视化图。
- Scrapy:用于Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
- SymPy:用于符号计算的Python库,包括了积分,微分方程等各种数学运算方法,为python提供了强大的数学运算支持。
- Requests:是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库。它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTTP 测试需求。
还有其他一些可能会用到的库:
- os用于操作系统和文件操作
- Networkx和igraph用于基于数据操作的图形
- Regular expressions用于发现文本数据中的模式
- BeautifulSoup用于爬取网络数据。
以上这些所有程序库在学习初期不必全部掌握,视自己需求学习即可,但是像Numpy,Pandas这样的数据挖掘和分析工具,必须熟悉使用。
到了这里我们已经学习了Python基础知识和一些程序库,下面我们深入了解一下如何用Python解决问题。没错,用Python创建预测模型!在这个过程中,我们会用到一些强大的程序库,也会涉及更高层次的Python数据结构。主要有3个阶段:
- 数据探索——探索我们手中数据的更多信息
- 数据再加工——清洗数据,处理数据,让数据更适合统计建模
- 预测建模——运行算法,从数据中获取有趣有意义的结果
3. 使用Python和Pandas对数据进行探索性分析
为了进一步挖掘我们的数据,我们要用到Pandas。
Pandas是Python中一款最实用的数据分析库。下面我们会用Pandas从Analytic Vidhya大赛数据中读取数据集,对所得数据进行探索性分析,并创建简单的分类算法解决这个问题。
在我们加载数据之前,先理解Pandas中两个关键的数据结构——Series和dataframes 。
Series和Dataframes简介
Series可以理解为一个1维的标签或索引数组,你可以通过series中单个元素的标签获取它们。
Dataframe和Excel表很像,我们有列名指代列,也有行,使用行号就能获取它。不过在dataframe中,列名和行号都是列和行索引。
Series和dataframe组成了Python库Pandas的核心数据模式。首先Pandas会将数据集读取为dataframe格式,然后就能很容易地应用各种各样的操作,比如分组、聚集等等。
如果你对Pandas不是很熟悉,可以查看这篇10分钟Pandas入门教程:
https://www.pypandas.cn/docs/getting_started/10min.html
练习数据集——借贷预测问题
我们从这里(https://datahack.analyticsvidhya.com/contest/practice-problem-loan-prediction-iii/)下载数据,下面是变量描述:
我们开始探索数据。
首先,在你的terminal或Windows命令行输入以下内容,启动Pylab模式下的iPython界面:
ipython notebook --pylab=inline
这会在Pylab环境中打开ipython notebook,其中内置了一些很有用的库。而且,你能在行内绘制数据,从而使其非常适合交互式数据分析。可以输入以下代码,检查环境是否正确加载:
plot(arange(5))
我当前在Linux上工作,已将数据保存在如下位置:
/home/kunal/Downloads/Loan_Prediction/train.csv
导入程序库和数据集:
我们本教程会用到如下程序库:
- Numpy
- Matplotlib
- Pandas
请注意,因为使用Pylab环境,你无需导入matplotlib和Numpy。我将它们保留在了代码中,以防你在其它环境下使用本代码。
导入库以后,我们用函数read_csv()读取数据集。到这个阶段为止代码如下所示:
import pandas as pd
import numpy as np
import matplotlib as plt
df = pd.read_csv("/home/kunal/Downloads/Loan_Prediction/train.csv") #Reading the dataset in a dataframe using Pandas
快速数据探索
读取数据集后,我们就可以用函数head()查看顶部几行。
df.head(10)
应该会打印10行。你也可以通过打印数据集查看更多行。接着,你通过使用describe()函数查看数值字段的总结。
df.describe()
describe()函数可以在其输出中展示计数、平均值、标准方差、最小值、最大值等。
通过查看describe()函数的输出,我们可以发现如下信息:
LoanAmount有22个缺失值
Loan_Amount_Term有14个缺失值
Credit_History有50个缺失值
我们还可以看到84%的客户有credit_history。怎么来的?Credit_History字段的平均值为0.84.
Applicantlncome分布似乎和预期一致,Coapplicantlncome也是如此。
注意我们通过将平均值和中位数比较,也能看到数据中可能出现了偏差。
对于非数字值(比如Property_Area,Credit_History等),我们可以查看频率分布以理解它们是否合理。可以通过如下命令打印频率表:
df['Property_Area'].value_counts()
同样,我们也能查看Credit_History的特殊值。注意dfname[‘column_name’]是一个基本的索引技巧用以获取dataframe的具体列。它也可以是列的列表。
分布分析:
现在我们已经了解了基本的数据特征,接着来学习多种变量的分布。我们先从数值变量开始,即Applicantlncome和LoanAmount。
我们先用如下命令绘制Applicantlncome的直方图:
df['ApplicantIncome'].hist(bins=50)
这里我们观察到有少数极值,这也是为何我们需要用50个bins来清楚地描绘分布情况。
接着,我们查看箱型图来理解数据的分布。用如下命令可以绘制箱型图:
df.boxplot(column='ApplicantIncome')
这确认了数据中有很多异常值,从中也反映出社会上收入差距很大,这或许是因为人们的受教育水平不同。我们通过Education将他们进行分离:
df.boxplot(column='ApplicantIncome', by = 'Education')
我们可以看到受过高等教育的群体和未受过高等教育的群体的平均收入并未有显著差异。但受过高等教育的群体中高收入者更多,有些收入非常之高,成为数据中的异常值。
现在,我们用以下命令查看LoanAmount的直方图和箱型图:
df['LoanAmount'].hist(bins=50)
df.boxplot(column='LoanAmount')
我们再次发现了一些极端值。很明显,Applicantlncome和LoanAmount需要一些数据再加工。LoanAmount中包含缺失值和不少极值,而Applicantlncome中的极值要少一些,需要我们更深入的理解。我们会在接下来的部分解决这个任务。
分类变量分析
现在我们理解了Applicantlncome和Loanlncome的数据分布,接着探索更详细的分类变量信息。我们会用到Excel类型的数据透视表和交叉表,例如,我们可以查看根据信用记录获取贷款的几率。使用透视表可以获取结果:
注意:这里我们将借贷状态编写为1表示“是”,0表示“否”。所以平均值表示获取贷款的概率。
temp1 = df['Credit_History'].value_counts(ascending=True)
temp2 = df.pivot_table(values='Loan_Status',index=['Credit_History'],aggfunc=lambda x: x.map({'Y':1,'N':0}).mean())
print 'Frequency Table for Credit History:'
print temp1
print '\nProbility of getting loan for each Credit History class:'
print temp2
现在我们看看用Python生成相同数据洞察所需的步骤,我们可以观察得到的和Excel表一样的pivot_table。我们可以用matplotlib库以如下代码绘制出条形图:
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,4))
ax1 = fig.add_subplot(121)
ax1.set_xlabel('Credit_History')
ax1.set_ylabel('Count of Applicants')
ax1.set_title("Applicants by Credit_History")
temp1.plot(kind='bar')
ax2 = fig.add_subplot(122)
temp2.plot(kind = 'bar')
ax2.set_xlabel('Credit_History')
ax2.set_ylabel('Probability of getting loan')
ax2.set_title("Probability of getting loan by credit history")
图表显示如果申请人具有正当有效的信用记录,获取贷款的几率会增加8倍。我们也可以按照Married(婚否),Self-Employed(是否受雇于他人),Property_Area(财产状况)等绘制相似的图表。
另外,我们也可以将这两个图叠加在一起:
temp3 = pd.crosstab(df['Credit_History'], df['Loan_Status'])
temp3.plot(kind='bar', stacked=True, color=['red','blue'], grid=False)
还可以将性别因素添加进来:
如果你看得不是很明白,其实我们这里是创建了两个基本的分类算法。一个基于信用记录,另一个基于两个分类变量(包括性别)。
刚刚我们展示了如何用Python和Pandas进行探索性数据分析。接着我们进一步探索Applicantlncome和LoanStatus变量,进行数据再加工,并创建一个数据集应用多种多样的建模技巧。强烈建议你应用另一个数据集和类似问题,根据我们刚才的教程实际练习一番。
4. 利用Pandas和Python进行数据再加工
到了这个进度,一定要认真学习了,准备好上手练习。
数据再加工——“需求翻新”
在我们探索数据时,发现数据集中存在一些问题,需要加以解决以便后面用来搭建性能良好的模型。那么解决有问题数据的任务就被称为“数据再加工”(data munging)。下面是我们已经注意到的问题:
某些变量中存在缺失值,我们应根据缺失值数量和变量的预期重要性明智地预估这些值。
在查看数据的分布状况时,我们发现ApplicantIncome和LoanAmount似乎在两边都包含极值。虽然出现这些极端情况也能说得通,但是我们必须恰当地处理这些异常数据。
除了数值字段存在的这些问题外,我们还应该查看非数值字段,也就是Gender,Property_Area,Married,Education和Dependents等等,看看它们是否包含有用信息。
检查数据集中的缺失值
我们查看所有变量中的缺失值,因为大部分模型无法应对缺失值,即便它们能够应对,也帮不上忙。所以我们检查一下数据集中的空值。
df.apply(lambda x: sum(x.isnull()),axis=0)
如果值为空,这行命令应该能告诉我们每列中的缺失值数量。
虽然缺失值的数量并不是很多,但是很多变量中存在缺失值,那么我们应该将它们预估出来并进行相加。关于更多更详细的缺失值推定方法,可以查看这篇文章:
https://www.analyticsvidhya.com/blog/2016/01/guide-data-exploration/
注意:记住缺失值并非一直都是空值。比如,如果Loan_Amount_Term为0,你觉得说得通吗?或者你会将它当做缺失值吗?假设你就是这么认为,而且答案正确,那么我们应该检查那些不切实际的值。
如何填补LoanAmount的缺失值?
填补缺失值有很多种方法,最简单的一种就是用平均值取代,用如下代码可以实现:
df['LoanAmount'].fillna(df['LoanAmount'].mean(), inplace=True)
另一种方式就是创建一个监督学习模型,根据其它变量预测LoanAmount的数量,然后再结合其它变量来预测缺失值。
由于我们这里的目标是数据再加工的操作步骤,所以我会采取一种介乎这两者之间的方法。我们需要做个重要的假设:不管申请人是否受过良好教育,或者是否受雇于人,都能预期获得较大数额的贷款。
首先,我们查看箱型图,看看是否存在一定的趋势:
我们看到每组申请人的贷款额度的中位数出现了一些变化,可以用来推定缺失值。但是首先,我们必须确保Self_Employed和Education特征中全都没有缺失值。
我们之前说过,Self_Employed有一些缺失值,我们看一下频率表格:
由于~86%的值为“否”,因此推定缺失值也为“否”要靠谱一些,用如下代码可以完成:
df['Self_Employed'].fillna('No',inplace=True)
现在,我们会创建一个数据透视表,得到Self_Employed和Education特征下所有唯一值的中位数。接着,我们定义一个函数,返回这些单元格的值,然后用函数来填充LoanAmount的缺失值:
table = df.pivot_table(values='LoanAmount', index='Self_Employed' ,columns='Education', aggfunc=np.median)
# 定义函数以返回 pivot_table的值
def fage(x):
return table.loc[x['Self_Employed'],x['Education']]
# 替换缺失值
df['LoanAmount'].fillna(df[df['LoanAmount'].isnull()].apply(fage, axis=1), inplace=True)
以上就是我们推定LoanAmount中缺失值的方法。
如何应对LoanAmount和Applicantlncome数据分布中的极值?
咱们首先分析LoanAmount。由于极值在实际情况中是可能存在的,也就是说有些人可能会由于特定需求申请数额非常高的贷款,所以我们不将它们看作异常值,而是尝试对数转换来抵消它们的影响:
df['LoanAmount_log'] = np.log(df['LoanAmount'])
df['LoanAmount_log'].hist(bins=20)
我们再次查看直方图:
现在数据的分布看起来更接近正常情况了,极值的影响力也被大幅减弱。
现在看Applicantlncome。直觉告诉我们有些申请人会收入较低,但能作为很合格的共同申请人,也就是两个或两个以上的人共同申请一笔贷款。所以将共同申请人的收入合并为总收入,然后进行对数转换,会是个不错的方法。
df['TotalIncome'] = df['ApplicantIncome'] + df['CoapplicantIncome']
df['TotalIncome_log'] = np.log(df['TotalIncome'])
df['LoanAmount_log'].hist(bins=20)
现在我们看到数据的分布状况比之前好多了。你可以自己试着推定Gender,Married,Dependents,Loan_Amount_Term和Credit_History这些特征下的缺失值。另外我也建议大家多考虑一下从数据中可以挖掘出的其它一些信息。例如,可以为LoanAmount/Totallncome创建一个列,因为从中我们可以知道申请人有多大程度会归还贷款。
下面我们查看如何创建预测模型。
5. 用Python创建预测模型
在经过一番努力,将数据预处理后,我们现在用Python根据我们的数据集创建一个预测模型。在Python中,Skicit-learn是最常用的创建预测模型的库。
由于Sklearn需要所有的输入必须为数值型,所以我们应将全部分类变量转换为数值变量。用如下代码可以完成:
from sklearn.preprocessing import LabelEncoder
var_mod = ['Gender','Married','Dependents','Education','Self_Employed','Property_Area','Loan_Status']
le = LabelEncoder()
for i in var_mod:
df[i] = le.fit_transform(df[i])
df.dtypes
接着,我们导入所需的模块。然后我们会定义一个通用分类函数,它会将模型作为输入,确定准确率和交叉验证率。由于本文只是入门文章,这里不再深入讲解代码,关于如何用通过交叉验证来优化模型性能:
#Import models from scikit learn module:
from sklearn.linear_model import LogisticRegression
from sklearn.cross_validation import KFold #For K-fold cross validation
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier, export_graphviz
from sklearn import metrics
#创建分类模型和获取重要性的通用函数:
def classification_model(model, data, predictors, outcome):
# 拟合模型:
model.fit(data[predictors],data[outcome])
# 用数据集做出预测:
predictions = model.predict(data[predictors])
# 打印准确度
accuracy = metrics.accuracy_score(predictions,data[outcome])
print "Accuracy : %s" % "{0:.3%}".format(accuracy)
# 以5折执行K折交叉验证
kf = KFold(data.shape[0], n_folds=5)
error = []
for train, test in kf:
# 过滤训练数据
train_predictors = (data[predictors].iloc[train,:])
# 我们用于训练算法的目标值
train_target = data[outcome].iloc[train]
# 用目标值和预测因子训练算法
model.fit(train_predictors, train_target)
#记录每次运行交叉验证的误差值
error.append(model.score(data[predictors].iloc[test,:], data[outcome].iloc[test]))
print "Cross-Validation Score : %s" % "{0:.3%}".format(np.mean(error))
# 再次拟合模型,以便被外部函数引用
model.fit(data[predictors],data[outcome])
逻辑回归
我们创建我们的第一个逻辑回归模型。一种方法就是将所有变量输入模型中,但这样可能会造成过拟合,模型无法很好泛化。
我们可以做出一些直观的假设解决问题,如果是以下情况,申请人获取贷款的几率会更高:
- 申请人有信用记录(我们前面解释过这种情况)
- 申请人的收入很高,或作为共同申请人时的收入很高
- 申请人有较高的受教育程度
- 在城区有固定资产且有较高的升值前景
我们根据“Credit_History”创建我们的第一个预测模型。
outcome_var = 'Loan_Status'
model = LogisticRegression()
predictor_var = ['Credit_History']
classification_model(model, df,predictor_var,outcome_var)
准确度:80.945% 交叉验证得分:80.946%
#We can try different combination of variables:
predictor_var = ['Credit_History','Education','Married','Self_Employed','Property_Area']
classification_model(model, df,predictor_var,outcome_var)
准确度:80.945% 交叉验证得分:80.946%
通常我们预期增加变量后准确度能增加,但这很有挑战性。不够重要的变量对准确度和交叉验证得分影响并不大。Credit_History处于主导地位。现在我们有两个选择:
- 特征工程:挖取新信息,尝试预测。这一步就留给你做吧。
- 选择更好的建模方法。
决策树
决策树是另一种创建预测模型的方法,而且众所周知它能得到比逻辑回归模型更高的准确度。
model = DecisionTreeClassifier()
predictor_var = ['Credit_History','Gender','Married','Education']
classification_model(model, df,predictor_var,outcome_var)
准确度:81.930% 交叉验证得分:76.656%
这里模型基于分类变量无法产生影响,因为Credit_History处于主导地位。我们尝试一些数值变量。
# 我们可以尝试不同的变量组合
predictor_var = ['Credit_History','Loan_Amount_Term','LoanAmount_log']
classification_model(model, df,predictor_var,outcome_var)
准确度:92.345% 交叉验证得分:71.009%
这里我们观察到虽然随着变量增多准确度也增加了,但交叉验证误差也下降了。这是因为模型出现了过拟合的结果。我们尝试一种更复杂的算法,看看是否有帮助。
随机森林
随机森林是另一种解决分类问题的算法。详细了解随机森林可以参看这篇文章:
https://www.kuxai.com/post/107
随机森林的一个优点就是我们可以让它处理所有特征,它会返回一个特征重要性矩阵,能够用于选择特征。
model = RandomForestClassifier(n_estimators=100)
predictor_var = ['Gender', 'Married', 'Dependents', 'Education',
'Self_Employed', 'Loan_Amount_Term', 'Credit_History', 'Property_Area',
'LoanAmount_log','TotalIncome_log']
classification_model(model, df,predictor_var,outcome_var)
准确度:100.00% 交叉验证得分:78.179%
这里我们看到模型在训练集上的准确度达到了100%,这种属于过拟合的极端情况,可以通过以下两种方法解决:
- 减少预测因子的数量
- 调试模型参数
这两种方式我们都尝试一下。首先我们看看特征重要性矩阵,选出最重要的特征。
# 用特征重要性创建一个series:
Featimp = pd.Series(model.feature_importances_, index=predictor_var).sort_values(ascending=False)
print featimp
我们使用重要性最高的5个变量创建模型。同样,我们也会略微调整随机森林模型的参数:
model = RandomForestClassifier(n_estimators=25, min_samples_split=25, max_depth=7, max_features=1)
predictor_var = ['TotalIncome_log','LoanAmount_log','Credit_History','Dependents','Property_Area']
classification_model(model, df,predictor_var,outcome_var)
准确度:82.899% 交叉验证得分:81.461%
注意,虽然准确度下降了,但交叉验证得分也得到了优化,显示模型能够很好的泛化。记住随机森林模型并非可重复,由于随机性的缘故,每次运行得到的结果会略有不同。但是输出大体保持稳定。
你可能也注意到,虽然调试了随机森林模型中的基本函数,但我们得到的交叉验证得分只是略微好于第一个逻辑回归模型的结果。从中我们也可以得到一些有趣的发现:
- 使用更复杂的模型并不能保证得到更好的结果
- 在没有理解概念前,避免使用非常复杂的建模技巧。贸然使用会造成模型过拟合。
- 特征工程是解决问题的重要手段,每个人都可以使用Xgboost模型,但还是要依靠你能否增强特征以更好的匹配模型。
结语
希望本文能帮你入门如何借助从事数据科学工作,高效成长为一名数据分析师。通过学习以上内容,不仅能让你了解基本的数据分析方法,也能学习如何应用其中一些复杂的方法。
Python真的是一种很棒的工具,因为易于学习,有大量的程序库支持,故而成为数据科学领域越来越受欢迎的编程语言。
所以建议学好Python,相信你最终能轻松应对任何数据科学项目,包括读取、分析和可视化数据,并根据数据做出预测。