我在SAS工作了5年多之后,决定走出舒适区。作为一名数据科学家,我在寻找其他好用的工具,幸运的是,没过多久,我发现了Python。
一直以来,我喜欢敲代码。事实证明,有了Python,敲代码变得更为容易。
我花了一周时间来学习Python的基础知识,从那时起,我不仅深入钻研Python,而且还帮助许多其他人学习这门语言。起初,Python是门通用语言,多年来,随着社区的大力支持,现在有了数据分析及预测建模库。
由于缺少Python数据科学资源,我决定创建本教程,旨在帮助大家快速入门。在本教程中,我们将讨论如何使用Python来进行数据分析,在实践中总结方法。
Python数据分析基础
为什么要学习使用Python来进行数据分析?
使用Python来进行数据分析的原因有很多,过去一段时间通过对比SAS和R,有以下几点理由:
- 开源免费
- 强大社区支持
- 易学
- 成为数据科学和web产品分析的通用语言
诚然,它还有很多缺点:
Python是一种解释语言而不是编译语言,因此占用更多的CPU时间。然而,由于节省了程序员时间(易学),Python仍然是一个不错的选择。
Python 2.7与3.4版本的比较
这是Python中最受争议的话题之一,作为初学者,你绕不开这个问题。其实选择哪个版本都没有对错,完全取决于你的需要和实际使用场景。我会尝试给大家一些指引,帮助大家做出明智的选择。
为什么选择Python 2.7?
社区支持,这是早期需要的,Python 2版本在2000年下半年发布,超过15年的使用了。
第三方库支持,虽然许多库提供3.X的支持,但仍然有大量库只能在2.X版本上运行。如果你打算将Python用于特定的场景,如网页开发,高度依赖外部模块,你可能选择2.7版本会更好。
3.X版本的一些功能向后兼容,可以使用2.7版本。
为什么选择Python 3.4?
简洁快速,Python开发人员已经修复了一些自身的Bug,为其发展打下更坚实的基础。最初这些可能与你不是很相关,终将是很重要的。
未来趋势,2.7版本是2.X系列的最后一个版本,最终大家都必须转到3.X版本。Python 3已经发布了5年的稳定版本,并将持续推进。
没有明确显示到底谁好,但我认为最重要的是大家应该专注于将Python当作一门语言来学习。版本之间的转换是一个时间的问题。迟点,继续关注Python 2.X与3.X比较的文章。
如何安装Python?
有两种安装Python的方法:
你可以直接在官网上下载Python,并安装所需要的组件和库。
或者,你可以下载安装预装库的软件包,我建议你下载Anaconda,另外可以是Canopy Express。
第二种方法免去安装其他库的麻烦,因此我会推荐给初学者。如果你对单个库的最新版本感兴趣,你必须等到整个软件包的更新。除非你在做前沿的统计研究,否则应该没有什么影响。
选择开发环境
一旦安装了Python,就有各种各样的开发环境,以下是常见的3种:
- Terminal / Shell
- IDLE (默认)
- iPython notebook(类似R中的markdown)
正确的开发环境取决于你的需要,我个人更喜欢iPython Notebook。它有很多好的功能,编写代码时提供了文档记录功能,可以选择运行代码块(而不是逐行执行)。
我们将使用iPython开发环境完成本教程。
预热:运行你的第一个Python程序
你可以使用Python作为简单的计算器开始
提醒几点
你可以在terminal / cmd上输入“ipython notebook”来启动iPython Notebook,这取决于你正在使用的操作系统。
可以通过点击“UntitledO”来重命名。
界面显示In [*]表示输入,Out[*]表示输出。
执行当前代码块按快捷键“Shift + Enter”,运行当前块并插入额外的块按快捷键“ALT + Enter”。
在深入解决问题之前,让我们回顾一下,了解Python的基础知识。 我们知道数据结构、迭代和条件结构构成任何语言的关键。 在Python中,这些包括列表,字符串,元组,字典,for循环,while循环,if-else等。我们来看看其中的一些。
Python库及数据结构
Python数据结构
以下是一些在Python中使用的数据结构。你应该熟悉它们,以便适当使用它们。
Lists – 列表是Python中最常用的数据结构之一。 可以通过在方括号中写入逗号分隔值的序列来简单地定义列表。列表可以包含不同类型的项,但通常这些项都具有相同的类型。 Python列表是可变的,可以更改列表的各个元素。
下面是一个快速定义一个列表然后访问它的例子:
Strings – 字符串可以简单地通过使用单个(’),双(“)或三个(’’’)的逗号来定义。 用三引号(’’’)括起来的字符串允许跨行,并且在文档字符串中经常使用(Python的记录函数的方法)。 “\”用作转义字符。 请注意,Python字符串是不可变的,因此不能更改字符串的一部分。
Tuples – 一个元组用逗号分隔的值来表示。元组是不可变的,输出被圆括号包围,以便嵌套元组被正确处理。 此外,即使元组是不可变的,如果需要,可以保存可变数据。
由于元组是不可变的,不能改变,与列表相比,它的处理速度更快。 因此,如果你的列表不太可能更改,应该使用元组,而不是列表。
Dictionary – 字典是一组无序的键:值对,要求键是唯一的(在一个字典内)。一对大括号创建一个空字典:{}。
Python迭代和条件构造
像大多数语言一样,Python也有一个FOR循环,它是最广泛使用的迭代方法。它有一个简单的语法:
- 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 ture__
- else:
- __execution if false__
例如,如果我们要打印数字N是偶数还是奇数:
- if N%2 == 0:
- print 'Even'
- else:
- print 'Odd'
现在,你已经熟悉Python的基础知识了,我们进一步了解一下,如果必须执行以下任务,该怎么办?
1.两个矩阵相乘
2.找到二次方程的根
3.绘制条形图和直方图
4.网页访问
如果你尝试从头开始编写代码,那将成为一场恶梦,你将在Python上不会坚持超过2天!但是不用担心, 幸运的是,有许多预定义的库,我们可以直接导入到我们的代码中,使我们的编程工作变得容易。
例如,考虑我们刚刚看到的阶乘例子。完成只需一个步骤:
- math.factorial(N)
当然,我们需要导入math库。我们来研究一下各种库。
Python库
通过了解一些有用的库,将在我们学习Python的过程中领先一步。第一步显然是学会将它们导入我们的环境中。在Python中有以下几种方法:
- import math as m
- from math import *
在第一种方式中,我们定义了一个别名为m的math库。现在我们可以使用别名m.factorial()引用它,从math库(例如阶乘)中使用各种函数。
第二种方式,导入了math库的整个名称空间,即可以直接使用factorial()而不引用math。
提示:Google建议你使用第一种导入库方式,因为你将知道函数来自哪里。
以下是库列表,任何科学计算和数据分析会用到:
- NumPy:代表的是Numerical Python。NumPy最强大的功能是n维数组。该库还包含基本的线性代数函数,傅里叶变换,随机数函数和与其他底层语言(如Fortran,C和C ++)集成的工具。
- SciPy:代表的是Scientific Python。SciPy建立在NumPy基础上。它是离散傅里叶变换,线性代数,优化和稀疏矩阵等多种高级科学和工程模块最有用的库之一。
- Matplotlib:用于绘制各种各样的图形,从直方图到线图、热力图。你可以使用ipython notebook中的Pylab功能(ipython notebook -pylab = inline)在线使用这些绘图功能。如果忽略内联选项,pylab将ipython环境转换为与Matlab非常相似的环境。还可以使用Latex命令在图像添加数学符号。
- Pandas:用于结构化数据的运算和操作。广泛用于数据整理和预处理。相较而言,Pandas被添加到Python时间不久,其有助于提高Python在数据科学社区的使用。
- Scikit:用于机器学习。该库建立在NumPy,SciPy和matplotlib基础上,包含许多有效的机器学习和统计建模工具,例如分类,回归,聚类和降维。
- Statsmodels:用于统计建模。Statsmodels是一个Python中提供用户探索数据、估计统计模型和执行统计测试的模组。可用于不同类型数据的描述性统计,统计测试,绘图功能和结果统计。
- Seaborn:用于数据可视化。Seaborn是一个用于在Python中制作有吸引力和翔实的统计图形库。它是基于matplotlib。Seaborn旨在使可视化成为探索和理解数据的核心组成。
- Bokeh:用于在现代网络浏览器上创建交互式图表,仪表盘和数据应用程序。它赋予用户以D3.js的风格生成优雅简洁的图形。此外,它具有超大型或流式数据集的高性能交互能力。
- Blaze:将Numpy和Pandas的能力扩展到分布式和流式传输数据集。它可以用于从众多来源(包括Bcolz,MongoDB,SQLAlchemy,Apache Spark,PyTables等)访问数据。与Bokeh一起,Blaze可以作为在巨型数据块上创建有效可视化和仪表盘的强大的工具。
- Scrapy:用于网络爬虫。它是获取特定模式数据的非常有用的框架。它从网站首页url开始,然后挖掘网站内的网页内容来收集信息。
- SymPy:用于符号计算。它具有从基本算术符号到微积分,代数,离散数学和量子物理学的广泛能力。另一个有用的功能是将计算结果格式化为LaTeX代码。
- Requests:用于web访问。它类似于标准python库urllib2,但是代码更容易。你会发现与urllib2的微妙差异,但是对于初学者来说,Requests可能更方便。
你可能需要的额外的库:
- os用于操作系统和文件操作
- networkx和igraph为基于图的数据操作
- regular expressions用于在文本中查找特定模式的数据
- BeautifulSoup用于网络爬虫。它不如Scrapy,因为它只是单个网页中提取信息。
既然我们熟悉Python基础知识和库,那么我们可以通过Python深入解决问题。做预测模型过程中,我们会使用到一些功能强大的库,也会遇到不同的数据结构。我们将带你进入三个关键阶段:
- 数据探索 – 详细了解我们的数据
- 数据清洗 – 清理数据,使其更适合统计建模
- 预测建模 – 运行实际算法并获得结果
使用pandas进行数据探索
为了进一步探索我们的数据,给你介绍另一个动物(好像Python还不够!)- Pandas
Pandas是Python中最有好用的数据分析库之一(我知道这些名字听起来很奇怪,先这样!)促使越来越多数据科学界人士使用Python。现在我们将使用pandas从Analytics Vidhya比赛中读取数据集,进行探索性分析,并构建我们的第一个基础分类算法来解决这个问题。
在数据加载之前,先了解Pandas中2个关键数据结构 – Series和DataFrames。
Series及DataFrame介绍
Series可以理解为1维标签/索引数组。你可以通过这些标签访问series的各个元素。
Dataframe类似于Excel工作簿,列名称引用列,使用行号访问行。本质区别在于dataframes中列名称和行号称为列和行索引。
Series和DataFrames构成了Pandas在Python中的核心数据模型。数据集首先被读入Dataframes,然后各种操作(例如分组、聚合等)可以非常容易地应用于其列。
应用案例 – 贷款预测问题
以下是变量的描述:
变量 | 描述 |
Loan_ID | 贷款ID |
Gender | 男/女 |
Married | 已婚(Y/N) |
Dependents | 赡养人数 |
Education | 教育程度(Graduate/Under Graduate) |
Self_Employed | 自雇人士(Y/N) |
ApplicantIncome | 申报收入 |
CoapplicantIncome | 综合收入 |
LoanAmount | 贷款金额 |
Loan_Amount_Term | 贷款月数 |
Credit_History | 信用记录 |
Property_Area | 房产位置(Urban/Semi Urban/Rural) |
Loan_Status | 贷款批准状态(Y/N) |
开始数据探索
首先,在terminal/ Windows命令提示符下键入以下命令,以Inline 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") #使用Pandas读入数据集转换成dataframe
快速数据探索
读取数据集后,可以使用head()函数查看前几行
- df.head(10)
这样输出了10行,或者,也可以打印查看更多行数据集。
接下来,可以使用describe()函数来查看数值字段的摘要
- df.describe()
describe()函数将在其输出中提供计数、平均值、标准偏差(std)、最小值、四分位数和最大值。
这里有几个发现,你可以通过看看describe()函数的输出来绘制:
1.LoanAmount有(614 – 592)22个缺失值。
2.Loan_Amount_Term有(614 – 600)14个缺失值。
3.Credit_History有(614 – 564)50个缺失值。
4.我们也可以看到,约84%的申请人有信用记录,怎么样?Credit_History字段的平均值为0.84(记住,Credit_History对于具有信用记录的用户而言为1,否则为0)
5.申请人收入分布似乎符合预期。与CoapplicantIncome相同。
请注意,我们可以通过比较平均值与中位数来了解数据中可能的偏差。
对于非数值(例如Property_Area,Credit_History等),我们可以查看频率分布来了解它们是否有意义。频率表可以通过以下命令打印输出:
- df['Property_Area'].value_counts()
同样,我们可以看看信用历史的独特价值。请注意,dfname [‘column_name’]是一种基本的索引方法来访问dataframe的特定列。它也可以是一个列名的列表。
分布分析
现在我们熟悉基本的数据特征,我们来研究各种变量的分布。从数字变量ApplicantIncome和LoanAmount开始。
首先使用以下命令绘制ApplicantIncome的直方图:
- df['ApplicantIncome'].hist(bins=50)
在这里我们观察到很少极端值。这也是为什么需要50个箱子来明确分配分配的原因。
接下来,我们来看一下箱线图来了解分布。箱线图可以通过以下方式绘制:
- df.boxplot(column='ApplicantIncome')
这证实了许多异常值/极端值的存在。这可归因于社会的收入差距。部分原因可能是由于我们研究了不同教育水平的人。通过教育变量将其分离开:
- df.boxplot(column='ApplicantIncome', by = 'Education')
我们可以看到大学学历和非大学学历的平均收入之间没有实质性差异。但是,高学历中高收入人数更多,这似乎是离群值。
现在,我们来看看变量LoanAmount的直方图和boxplot,使用以下命令:
- df['LoanAmount'].hist(bins=50)
- df.boxplot(column='LoanAmount')
再次,有一些离群值。显然,ApplicantIncome和LoanAmount都需要一定量的数据清洗。 LoanAmount有缺失值和离群值,同时,ApplicantIncome有一些离群值,接下来我们将分几个部分,做更深入的了解。
分类变量的分析
现在我们了解ApplicantIncome和LoanIncome的分布,为了更详细地理解分类变量,我们将使用Excel的透视表和交叉表。例如,我们来看根据信用记录获得贷款的机会,这可以在MS Excel中使用数据透视表来实现:
注意:这里的贷款状态重编码了,1代表是,0代表否,平均值表示贷款的概率。
现在我们将看看使用Python生成类似洞察所需的步骤。
- 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
现在可以看到,我们得到一个类似MS Excel一样的透视表,这可以使用“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倍。你可以通过已婚,自雇,居住地区等绘制相似的图表。
或者,这两个图也可以通过将它们组合在堆叠图表中来进行可视化:
- temp3 = pd.crosstab(df['Credit_History'], df['Loan_Status'])
- temp3.plot(kind='bar', stacked=True, color=['red','blue'], grid=False)
还可以添加性别(类似于Excel中的数据透视表):
如果你还没有意识到,我们在这里创建了两个基本的分类算法,一个基于信用记录,另一个基于2分类变量(包括性别)。你可以快速编码,以便在AV Datahacks上创建你的第一次提交版本。
我们看到如何在Python中使用pandas进行探索性数据分析,希望你对pandas(熊猫)的爱将会增加,pandas库为你的数据集分析提供一些帮助。
接下来,我们进一步探讨ApplicantIncome和LoanStatus变量,执行数据运算并创建一个数据集以应用各种建模技术。强烈建议再选择一个数据集和问题,阅读一个独立的例子,然后再做进一步分析。
python数据清洗:Pandas
对于从事数据分析的人来说,下面这些是你必须要做的。
数据清洗 – 重构数据
在数据探索时,为了构建一个好的模型,需要先解决掉数据集中发现了的一些问题。这个过程通常称为“数据清洗”。针对以下问题,我们看到:
1.变量缺失值。我们应该根据缺失值的数量和变量的预期重要性明智地估计这些值。
2.在分析这些分布的同时,我们看到变量ApplicantIncome和LoanAmount似乎都包含了离群值。虽然他们可能会有直观的意义,但应该得到适当的处理。
除了这些数值型的数据问题之外,我们还应该关注非数值型数据,如性别、区域、已婚、教育程度和赡养人数,用以挖掘任何有用的信息。
检查数据集中的缺失值
一起看看所有变量中的缺失值,因为大多数模型不能使用含缺失值的数据,缺失值填补很重要。所以,我们检查数据集中的null / NaN的数量。
- df.apply(lambda x: sum(x.isnull()),axis=0)
如果值为null则isnull()返回1,那么该命令计算出每个列中缺失值的数量。
虽然缺失值数量不是很多,但是大多变量都有缺失值,需要估算并填补缺失值。
注意:缺失值可能并不总是NaN。例如,如果Loan_Amount_Term为0,那么是否有意义,或者是否是缺失值?我想你的答案是缺失值,你是对的。所以我们应该检查数据是否有实际意义。
如何填补LoanAmount中的缺失值?
有许多方法来填补贷款额度的缺失值,最简单的是用均值替换,可以通过以下代码来完成:
- df['LoanAmount'].fillna(df['LoanAmount'].mean(), inplace=True)
另外也可以是建立一个监督学习模型,以其他变量如年龄等为基础预测贷款额度。
既然现在是数据清洗的步骤,我宁愿采取介于两者之间的一种方法。一个关键的假设是,一个人教育程度或者个体经营户与否,可以结合起来给出一个很好的贷款额度的估计。
首先,我们来看一下箱线图,看看是否存在趋势规律:
因此,我们看到每个组的贷款额中位数有一些变化,可以用来作估算值。但是,我们必须先确保Self_Employed和Education变量中的每一个都不应该有缺少值。
如前所述,Self_Eployee有一些缺失的值。看看频率表:
大约86%的值为“No”,将缺失值估计为“No”是安全的,因为正确的概率会更高。可以使用以下代码完成:
- df['Self_Employed'].fillna('No',inplace=True)
现在,我们将创建一个数据透视表,它提供了贷款额度中位数按Self_Eployed和Education交叉分组。接下来,我们定义一个函数,它返回这些单元格的值并应用它来填补贷款金额的缺失值:
- table = df.pivot_table(values='LoanAmount', index='Self_Employed' ,columns='Education', aggfunc=np.median)
- # Define function to return value of this pivot_table
- def fage(x):
- return table.loc[x['Self_Employed'],x['Education']]
- # Replace missing values
- df['LoanAmount'].fillna(df[df['LoanAmount'].isnull()].apply(fage, axis=1), inplace=True)
这样为你提供一个很好的方式来估算贷款额度的缺失值。
如何处理LoanAmount和ApplicantIncome分布中的极端值?
我们首先分析LoanAmount。 极端值可能有实际意义的,有些人可能因为特殊需要才申请高额贷款,所以不用把它们视为离群值,我们来尝试用对数变换来消除它们的影响:
- df['LoanAmount_log'] = np.log(df['LoanAmount'])
- df['LoanAmount_log'].hist(bins=20)
再次查看直方图:
现在分布看起来更加接近正态分布,极端值的影响已经显示减弱。
对于变量ApplicantIncome,一个可能的直觉是,一些申请人申报收入较低,但是综合收入高也获得支持。所以把申报收入作为总收入结合在一起是一个好主意,并采取同样的对数变换。
- df['TotalIncome'] = df['ApplicantIncome'] + df['CoapplicantIncome']
- df['TotalIncome_log'] = np.log(df['TotalIncome'])
- df['LoanAmount_log'].hist(bins=20)
现在我们看到分布比以前好多了。我会把性别、已婚、赡养者、贷款月数、信用历史等缺失值的估算留给大家完成。此外,我鼓励大家考虑可能从数据中发掘附加信息,例如,创建列LoanAmount / TotalIncome可能是有道理的,因为它给出了申请人如何适应偿还贷款的想法。
接下来,我们将看看创建预测模型。
在Python中构建一个预测模型
现在,我们已经有对建模有用的数据,现在我们来看看python代码,在我们的数据集上创建一个预测模型。Skicit-Learn(sklearn)是Python中最常用的机器学习库,我们将会借助它来建模。
既然,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
- #Generic function for making a classification model and accessing performance:
- def classification_model(model, data, predictors, outcome):
- #Fit the model:
- model.fit(data[predictors],data[outcome])
- #Make predictions on training set:
- predictions = model.predict(data[predictors])
- #Print accuracy
- accuracy = metrics.accuracy_score(predictions,data[outcome])
- print "Accuracy : %s" % "{0:.3%}".format(accuracy)
- #Perform k-fold cross-validation with 5 folds
- kf = KFold(data.shape[0], n_folds=5)
- error = []
- for train, test in kf:
- # Filter training data
- train_predictors = (data[predictors].iloc[train,:])
- # The target we're using to train the algorithm.
- train_target = data[outcome].iloc[train]
- # Training the algorithm using the predictors and target.
- model.fit(train_predictors, train_target)
- #Record error from each cross-validation run
- error.append(model.score(data[predictors].iloc[test,:],data[outcome].iloc[test]))
- print "Cross-Validation Score : %s" % "{0:.3%}".format(np.mean(error))
- #Fit the model again so that it can be refered outside the function:
- model.fit(data[predictors],data[outcome])
逻辑回归
我们来做第一个逻辑回归模型。一种方法是将所有变量都放入模型中,但这可能会导致过拟合。 简单来说,模型采用所有变量,有可能理解数据的特定的复杂关系,并不能很好地推广。
我们可以很容易地做出一些直观的假设,获得贷款的机会会更高:
1.具有信用记录的申请人
2.具有较高申请收入和综合收入的申请人
3.高等教育水平的申请人
4.具有高增长前景的城市地产
我们用’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%
一般来说,我们期望通过增加变量数量来提高准确度,但这是一个更具挑战性的案例,准确度和交叉验证得分不受重要性较小的变量的影响。信用历史是主导模式。我们现在有两个选择:
1.特征工程:挖掘新信息,并尝试预测。这个留给大家去发挥创造力。
2.更好的建模技术。接下来我们来探讨一下。
决策树
决策树是构建预测模型的另一种方法,通常比逻辑回归模型具有更高的精度。
- model = DecisionTreeClassifier()
- predictor_var = ['Credit_History','Gender','Married','Education']
- classification_model(model, df,predictor_var,outcome_var)
准确度:81.930%,交叉验证得分:76.656%
这里,基于分类变量的模型不会受信用历史产生影响。我们来尝试几个数值型变量:
- #We can try different combination of variables:
- predictor_var = ['Credit_History','Loan_Amount_Term','LoanAmount_log']
- classification_model(model, df,predictor_var,outcome_var)
准确度:92.345%交叉验证得分:71.009%
在这里我们观察到,添加变量后模型准确度上升,交叉验证错误率下降。这是模型数据过拟合的结果。我们尝试一个更复杂的算法,看看是否有帮助。
随机森林
随机森林是解决分类问题的另一种算法。
随机森林的一个优点是我们可以将所有特征放在一起,并返回一个可用于选择的特征重要性矩阵。
- 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.000%交叉验证得分:78.179%
训练集的准确度是100%,这是过拟合的最终结果,可以通过两种方式解决:
1.减少预测数量
2.调整模型参数
我们来试试这两种方法,首先我们看到特征重要性矩阵,我们将从中筛选最重要的特征变量。
- #Create a series with feature importances:
- 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%
虽然准确度降低,但交叉验证分数在提高,表明该模型的适用性很好。记住,随机森林模型不是完全可复用的。不同的变量运行结果会有变化,但输出尽量保持正确。
你会注意到,即使在对随机森林进行了一些基本的参数调整之后,我们交叉验证的精度只比原始逻辑回归模型略好一些。这个案例给了我们一些非常有趣、特别的学习体验:
1.使用更复杂的模型不能保证更好的预测结果。
2.避免使用复杂的建模技术作为黑盒子而不了解基本概念。这样做会增加过拟合趋势,从而降低模型解释力。
3.特征工程是成功的关键。大家可以使用Xgboost模型,但真正的艺术和创造力在于增强特征能力以更好地适应模型。
你准备好迎接挑战吗?借助贷款预测问题开始数据科学之旅。
结束教程
我希望本教程将帮助你在使用Python开展数据科学分析时能最大限度地提高效率。我相信,这不仅给你提供一个基本的数据分析方法的引导,而且还向你展示了如何实现一些更先进的编程技术。
Python真的是一个强大的工具,并且日益成为数据科学家中流行的编程语言。原因在于Python很容易学习,与其他数据库和工具(如Spark和Hadoop)集成很好。最主要还是因为Python具有很强的计算能力和强大的数据分析库。
学习利用Python来完成任何数据科学项目的完整过程包括阅读、分析、可视化和结果预测。