独家 | 2种数据科学编程中的思维模式,了解一下(附代码)
作者:Srini Kadamati
翻译:梁傅淇
校对:丁楠雅
本文约2500字,建议阅读10分钟。
本文以具体的例子阐释了如何最优化原型思维模式及生产流思维模式的应用。
数据科学的完整流程一般包含以下几个组成部分:
数据收集
数据清洗
数据探索和可视化
统计或预测建模
虽然这些组成部分有助于我们理解数据科学的不同阶段,但对于编程工作流并无助益。
通常而言,在同一个文件中覆盖完整的流程将会导致Jupyter Notebook、脚本变成一团乱麻。此外,大多数的数据科学问题都要求我们在数据收集、数据清洗、数据探索、数据可视化和统计/预测建模中切换。
但是还存在更好的方法来组织我们的代码!在这篇博客中,我将介绍大多数人在做数据科学编程工作的时候切换的两套思维模式:原型思维模式和生产流思维模式。
原型思维模式强调 |
生产流思维模式强调 |
某部分代码的迭代速度 |
整体工作流程的迭代速度 |
更少的抽象 (直接修改代码和数据类型) |
更多的抽象 (修改参数) |
代码更松散 (模块化程度低) |
代码更结构化 (模块化程度高) |
帮助人们更了解代码和数据 |
帮助电脑更自动地运行代码 |
我个人使用JupyteLab来进行整个流程的操作(包括写原型代码和生产流代码)。我建议至少使用JupyteLab来写原型代码:
JupyteLab:
http://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html
借贷俱乐部数据
为了更好地理解原型和生产流两种思维模式,我们来处理一些真实的数据。我们将使用个人对个人的借贷网站——借贷俱乐部上面的借贷数据。跟银行不同,借贷俱乐部自身并不借钱,而是为贷款人提供一个市场以贷款给因不同的原因(比如维修、婚礼)需要借款的个人。
借贷俱乐部网站:
https://www.dataquest.io/blog/programming-best-practices-for-data-science/www.lendingclub.com
我们可以使用这个数据来建立一个模型,判断一个给定的贷款申请是否会成功。这篇博客中,我们不会深入到建立机器学习模型工作流。
借贷俱乐部提供关于成功的贷款(被借贷俱乐部和联合贷款人通过的贷款)和失败的贷款(被借贷俱乐部和联合贷款人拒绝的贷款,款项并没有转手)的详尽历史数据。打开他们的数据下载页,选择2007-2011年,并下载数据:
数据下载页:
https://www.lendingclub.com/info/download-data.action
原型思维模式
在原型思维模式中,我们比较关心快速迭代,并尝试了解数据中包含的特征和事实。创建一个Jupyter Notebook,并增加一个Cell来解释:
你为了更好地了解借贷俱乐部而做的所有调查
有关你下载的数据集的所有信息
首先,让我们将csv文件读入pandas:
import pandas as pd
loans_2007 = pd.read_csv('LoanStats3a.csv')
loans_2007.head(2)
我们得到两部分输出,首先是一条警告信息:
/home/srinify/anaconda3/envs/dq2/lib/python3.6/site-packages/IPython/core/interactiveshell.py:2785: DtypeWarning: Columns (0,1,2,3,4,7,13,18,24,25,27,28,29,30,31,32,34,36,37,38,39,40,41,42,43,44,46,47,49,50,51,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,123,124,125,126,127,128,129,130,131,132,133,134,135,136,142,143,144) have mixed types. Specify dtype option on import or set low_memory=False.
interactivity=interactivity, compiler=compiler, result=result)
然后是数据框的前5行,这里我们就不展示了(太长了)。
警告信息让我们了解到如果我们在使用pandas.read_csv()的时候将low_memory参数设为False的话,数据框里的每一列的类型将会被更好地记录。
第二个输出的问题就更大了,因为数据框记录数据的方式存在着问题。JupyterLab有一个内建的终端,所以我们可以打开终端并使用bash命令head来查看原始文件的头两行数据。
head -2 LoanStats3a.csv
原始的csv文件第二行包含了我们所期望的列名,看起来像是第一行数据导致了数据框的格式问题:
Notes offered by Prospectus
https://www.lendingclub.com/info/prospectus.action
增加一个Cell来说明你的观察,并增加一个code cell来处理观察到的问题。
import pandas as pd
loans_2007 = pd.read_csv('LoanStats3a.csv', skiprows=1, low_memory=False)
在借贷俱乐部下载页查看数据字典以了解哪些列没有包含对特征有用的信息。Desc和url列很明显就没有太大的用处。
loans_2007 = loans_2007.drop(['desc', 'url'],axis=1)
然后就是将超过一半以上都缺失值的列去掉,使用一个cell来探索哪一列符合这个标准,再使用另一个cell来删除这些列。
loans_2007.isnull().sum()/len(loans_2007)
loans_2007 = loans_2007.dropna(thresh=half_count, axis=1)
因为我们使用Jupyter Notebook来记录我们的想法和代码,所以实际上我们是依赖于环境(通过IPython内核)来记录状态的变化。这让我们能够自由地移动cell,重复运行同一段代码,等等。
通常而言,原型思维模式专注于:
可理解性
使用Markdown cell来记录我们的观察和假设
使用一小段代码来进行真实的逻辑操作
使用大量的可视化和计数
抽象最小化
大部分的代码都不在函数中(更为面向对象)
我们会花时间来探索数据并且写下我们采取哪些步骤来清洗数据,然后就切换到工作流模式,并且将代码写得更强壮一些。
生产流模式
在生产流模式,我们会专注于写代码来统一处理更多的情况。比如,我们想要可以清洗来自借贷俱乐部的所有数据集的代码,那么最好的办法就是概括我们的代码,并且将它转化为数据管道。数据管道是采用函数式编程
的原则来设计的,数据在函数中被修改,并在不同的函数之间传递:
函数式编程教程:
https://www.dataquest.io/blog/introduction-functional-programming-python/
这里是数据管道的第一个版本,使用一个单独的函数来封装数据清洗代码。
import pandas as pd
def import_clean(file_list):
frames = []
for file in file_list:
loans = pd.read_csv(file, skiprows=1, low_memory=False)
loans = loans.drop(['desc', 'url'], axis=1)
half_count = len(loans)/2
loans = loans.dropna(thresh=half_count, axis=1)
loans = loans.drop_duplicates()
# Drop first group of features
loans = loans.drop(["funded_amnt", "funded_amnt_inv", "grade", "sub_grade", "emp_title", "issue_d"], axis=1)
# Drop second group of features
loans = loans.drop(["zip_code", "out_prncp", "out_prncp_inv", "total_pymnt", "total_pymnt_inv", "total_rec_prncp"], axis=1)
# Drop third group of features
loans = loans.drop(["total_rec_int", "total_rec_late_fee", "recoveries", "collection_recovery_fee", "last_pymnt_d", "last_pymnt_amnt"], axis=1)
frames.append(loans)
return frames
frames = import_clean(['LoanStats3a.csv'])
在上面的代码中,我们将之前的代码抽象为一个函数。函数的输入是一个文件名的列表,输出是一个数据框的列表。
普遍来说,生产流思维模式专注于:
适合的抽象程度
代码应该被泛化以匹配的类似的数据源
代码不应该太过泛化以至于难以理解
管道稳定性
可依赖程度应该和代码运行的频率相匹配(每天?每周?每月?)
在不同的思维模式中切换
假设我们在运行函数处理所有来自借贷俱乐部的数据集的时候报错了,部分潜在的原因如下:
不同的文件当中列名存在差异
超过50%缺失值的列存在差异
数据框读入文件时,列的类型存在差异
在这种情况下,我们就要切换回原型模式并且探索更多。如果我们确定我们的数据管道需要更为弹性化并且能够处理数据特定的变体时,我们可以将我们的探索和管道的逻辑再结合到一起。
以下是我们调整函数以适应不同的删除阈值的示例:
import pandas as pd
def import_clean(file_list, threshold=0.5):
frames = []
for file in file_list:
loans = pd.read_csv(file, skiprows=1, low_memory=False)
loans = loans.drop(['desc', 'url'], axis=1)
threshold_count = len(loans)*threshold
loans = loans.dropna(thresh=half_count, axis=1)
loans = loans.drop_duplicates()
# Drop first group of features
loans = loans.drop(["funded_amnt", "funded_amnt_inv", "grade", "sub_grade", "emp_title", "issue_d"], axis=1)
# Drop second group of features
loans = loans.drop(["zip_code", "out_prncp", "out_prncp_inv", "total_pymnt", "total_pymnt_inv", "total_rec_prncp"], axis=1)
# Drop third group of features
loans = loans.drop(["total_rec_int", "total_rec_late_fee", "recoveries", "collection_recovery_fee", "last_pymnt_d", "last_pymnt_amnt"], axis=1)
frames.append(loans)
return frames
frames = import_clean(['LoanStats3a.csv'], threshold=0.7)
默认值是0.5,如果需要的话,我们也可以改为0.7。
这是一些将管道改得更为弹性的方式,按推荐程度降序排列:
使用可选参数、位置参数和必需参数
在函数中使用if / then语句以及使用布尔输入值作为函数的输入
使用新的数据结构(字典,列表等)来表示特定数据集的自定义操作
这个管道可以扩展到数据科学工作流程的所有阶段。这是一些伪代码,可以总揽它的结构。
import pandas as pd
def import_clean(file_list, threshold=0.5):
## Code
def visualize(df_list):
# Find the most important features and generate pairwise scatter plots
# Display visualizations and write to file.
plt.savefig("scatter_plots.png")
def combine(df_list):
# Combine dataframes and generate train and test sets
# Drop features all dataframes don't share
# Return both train and test dataframes
return train,test
def train(train_df):
# Train model
return model
def validate(train_df, test-df):
# K-fold cross validation
# Return metrics dictionary
return metrics_dict
frames = import_clean(['LoanStats3a.csv', 'LoanStats2012.csv'], threshold=0.7)
visualize(frames)
train_df, test_df = combine(frames)
model = train(train_df)
metrics = test(train_df, test_df)
print(metrics)
下一步
如果你对加深理解和练习感兴趣的话,我推荐:
了解如何将你的管道转化为作为一个模块或者从命令行中单独运行的脚本:
https://docs.python.org/3/library/main.html
了解如何使用Luigi来构建更复杂的、能够在云上面运行的管道
https://marcobonzanini.com/2015/10/24/building-data-pipelines-with-python-and-luigi/
了解更多有关数据工程的信息:
https://www.dataquest.io/blog/tag/data-engineering/
原文标题:
Programming Best Practices For Data Science
原文链接:
https://www.kdnuggets.com/2018/08/programming-best-practices-data-science.html
译者简介
梁傅淇,软件工程本科在读,主修大数据分析,喜好搜索、收集各类信息。希望能在THU数据派平台认识更多对数据分析感兴趣的朋友,一起研究如何从数据挖掘出有用的模型和信息。
翻译组招募信息
工作内容:需要一颗细致的心,将选取好的外文文章翻译成流畅的中文。如果你是数据科学/统计学/计算机类的留学生,或在海外从事相关工作,或对自己外语水平有信心的朋友欢迎加入翻译小组。
你能得到:定期的翻译培训提高志愿者的翻译水平,提高对于数据科学前沿的认知,海外的朋友可以和国内技术应用发展保持联系,THU数据派产学研的背景为志愿者带来好的发展机遇。
其他福利:来自于名企的数据科学工作者,北大清华以及海外等名校学生他们都将成为你在翻译小组的伙伴。
点击文末“阅读原文”加入数据派团队~
转载须知
如需转载,请在开篇显著位置注明作者和出处(转自:数据派ID:datapi),并在文章结尾放置数据派醒目二维码。有原创标识文章,请发送【文章名称-待授权公众号名称及ID】至联系邮箱,申请白名单授权并按要求编辑。
发布后请将链接反馈至联系邮箱(见下方)。未经许可的转载以及改编者,我们将依法追究其法律责任。
点击“阅读原文”拥抱组织
独家 | 2种数据科学编程中的思维模式,了解一下(附代码)相关推荐
- 独家 | 从全方位为你比较3种数据科学工具的比较:Python、R和SAS(附链接)
翻译:张玲 校对:吴金笛 本文约3000字,建议阅读5分钟. 关于三种数据科学工具Python.R和SAS,本文从8个角度进行比较分析并在文末提供记分卡,以便你随时调整权重,快速做出选择. 简介 我们 ...
- sas和python哪个好学_从全方位为你比较3种数据科学工具的比较:Python、R和SAS(附链接)...
原标题:从全方位为你比较3种数据科学工具的比较:Python.R和SAS(附链接) 本文约3000字,建议阅读5分钟. 关于三种数据科学工具Python.R和SAS,本文从8个角度进行比较分析并在文末 ...
- 如何理解数据科学的中的数据泄露(Data Leakage)
数据科学竞赛中有时会出现这样的奇特景观:某只队伍,靠着对极个别feature的充分利用,立即将对手超越,成功霸占冠军位置,而且与第二名的差距远超第二名与第十名的差距.然而,这些feature却不是在因 ...
- 细数数据科学团队中的十大关键角色
作者 Cassie Kozyrkov 编译 Mika 本文为 CDA 数据分析师原创作品,转载需授权 应用数据科学是一项高度跨学科的团队工作,需要用多样性的角度看问题.事实上,比起专业知识和经验,观点 ...
- 盘点数据科学20个最好的Python库(附链接)
来源:网络大数据 本文约3000字,建议阅读6分钟. 本文将给大家介绍数据科学领域20个最好的Python库. Python 在解决数据科学任务和挑战方面继续处于领先地位.去年,我们曾发表一篇博客文章 ...
- html 怪异模式,CSS_浅谈CSS编程中的怪异模式,怪异模式盒模型
今天学习了 - phpStudy...
浅谈CSS编程中的怪异模式 怪异模式盒模型 今天学习了一下css3的box-sizing属性,顺便又温习了一下css的盒模型,最后觉得有必要对盒模型做一个全面整理. 先不考虑css3的情况,盒模型一共 ...
- java必背代码_新人福利,Java编程中必须要死记硬背的几十个代码
原标题:新人福利,Java编程中必须要死记硬背的几十个代码 自己总结,没有先后顺序,希望对大家有用 向文件末尾添加内容 字符串有整型的相互转换 转字符串到日期 java.util.Date = jav ...
- 持久层是什么意思_软件项目实训及课程设计指导—如何在数据持久层中应用DAO模式...
软件项目实训及课程设计指导--如何在J2EE应用系统数据持久层中应用DAO模式 1.为什么要在软件应用系统中提供数据持久层 软件应用系统中的数据持久层主要为整个软件应用系统提供数据访问功能服务,从而可 ...
- python编程模式_Python编程中的反模式
原标题:Python编程中的反模式 这篇文章收集了我在Python新手开发者写的代码中所见到的不规范但偶尔又很微妙的问题. 本文的目的是为了帮助那些新手开发者渡过写出丑陋的Python代码的阶段. 对 ...
最新文章
- 半导体与智能汽车行业解决方案
- 三星s8自带测试硬件软件,三星S8手机国行固件开启测试:或支持桌面级操作体验...
- java程会释放锁join_关于join() 是否会释放锁的一些思考
- markdown引入代码_给你自己的博客加个 Markdown
- 《android深入探索》第四章心得
- 开发人员,请不要抱怨项目没有文档
- iOS开发中常用的宏
- 大一上学期闭组考核(借阅功能有逻辑错误)
- C++:实现量化存在净额结算协议的交易对手风险下的利率互换估值公式测试实例
- android手机之-------64位操作系统 与 64位处理器
- 笔记本电脑怎么打不开计算机,笔记本电脑打不开了怎么办
- Replication Failed to register VRMS. Operation ID: bef61197-acf3-46ac-bffd-d457
- win10安装Mysql8的两种方式(安装/卸载-图文教程)
- 什么是 CSDN ?
- STM32输出PWM波形
- 支付宝支持给微信好友转账/ 14家自动驾驶概念股均价已蒸发80%/ 苹果M2 iPad Pro推出在即…今日更多新鲜事在此...
- 角膜炎是由什么引起的?
- 【转】程序员的好日子什么时候才到头?
- 104-RTKLIB中PPP设计
- 反射避开field.setAccessible(true); field.set(t, lineArray[i]); 赋值
热门文章
- 下一步,该怎么做空中国概念股?
- 演化理解 Android 异步加载图片
- Sqlserver 2000 迷你、便携企业管理器(10M),支持Dts编辑
- mysql内连接和外连接的区别_内连接、外连接的区别
- 计算机丢失filter.dll,AxCoFilter.dll
- 计算机专业人事制度改革,清华大学计算机系人事制度改革正式启动-清华大学新闻网...
- 2021年4月28日 深圳头条后台开发实习面试(hr面)
- 【文本信息抽取与结构化】详聊如何用BERT实现关系抽取
- ValueError: Variable rnn/basic_lstm_cell/kernel already exists, disallowed.
- numpy.matmul处理一维数组的 3维以上的性质