Python 数据分析师必备的入门学习路线和技能

工作 5 年多,前软件工程师,现算法工程师,Pandas 开源库贡献者。为人厚道,做事严谨,公众号:Python与算法社区

文章正文

我们离不开数据分析

首先,非常感谢你订阅了这场 chat, 我会努力准备,用心书写,将我过去的项目经历、学习心得,一五一十地、毫无保留地记录下来。并且,我会尽力写的通俗易懂,逻辑更有条理一些。不出意外,我还会反复修改多次,直到做到最好。

相信订阅本场 chat 的小伙伴中,有的已经工作了,可能平时还要经常加班。和你们一样,我也工作 5 年了,也是经常加班。不过,我会每天抽时间,写点技术文章,也不知怎么地,只有这样,我才觉得一天过得充实,才觉得没有虚度。

最近几年,做的这些项目,大多与数据分析与算法应用相关。岗位虽然是算法工程师,但是与数据分析打得交道也很多,双管齐下,最后才能确保算法的落地。在几年前,我还想当然地认为做算法的就应该偏重算法研究与应用,可能数据分析相关的技术真的没那么重要,不过我很快意识到自己的错误,重新将数据分析放在一个重要的位置,去研究学习。

结合过往经历,说下自己对算法设计和数据分析工作的一些浅显体会。

对于算法落地而言,个人认为准确性和稳定性是最重要的。在校园时,相信老师都跟我们讲过算法的几个重要性质,比如算法的时间复杂度,空间复杂度,鲁棒性等等,都具备了这些性质的算法当然是一个好算法。

然而,实际情况是,实际场景往往比较复杂,比如,影响因素及之间的关系很复杂;数据匮乏不说,手上的数据还有一半是垃圾等等,这一系列难点,都加大了我们算法设计的难度,哪怕只是设计一个满足基本场景的算法。这使我明白,设计的算法要优先保证能得到一个正确的结果。

其次,作为工程项目,确保系统的稳定性,尽量或者上线后基本没有 bug 显得同样重要。否则,你连觉都睡不好,还提什么其他性能。所以为了稳妥起见,大部分算法设计都不会从零做起,大都会基于成熟稳定的开源框架,然后在上面扩展,开花结果。

已经说的很直白了,还没有工作的小伙伴,可以思考一下。光鲜的事物背后,未必有它真正看起来那样的光彩夺目。

人工智能的强大离不开数据,既然离不开数据,自然就少不了数据处理与分析的相关技术,那么公司就一定需要数据处理与分析的人员。

数据分析为啥如此重要呢? 一句话,喂进去的是垃圾,出来的就是垃圾。机器学习、深度学习的算法设计的再牛叉,如果进去的是垃圾数据,深度学习学出来的模型也不会好到哪里去。

所以,数据科学相关的技术,工作中是离不开的,未来只会越来越重要。

说完我的一些体会后,我简单引出一个文章展开的思路。

作为数据分析的入门课程,首先说一下入门数据科学的完整学习路线;然后,介绍数据分析中花费时间较多的:数据清理 (data munging);

学习路线、主要任务介绍完后,接下来就要开始动手实践、实现这些任务了。Python 作为数据分析和人工智能的首选语言,介绍关于它的一些核心知识,让帮助入门者快速上手。

为了工作中加速数据分析的脚步,依次介绍基于 Python 的科学计算库 NumPy, Pandas, 要想快速上手这些库,理解它们的机制是必不可少的,比如 NumPy 的广播机制。数据分析的另一个重要任务就是数据可视化,接下来,介绍基于 Python 生态的可视化库:Matplotlib, 使用 100 行左右的代码,来打包常用的函数用法。

数据分析往往需要做一些回归分析,分类分析等,作为目前火热的机器学习、深度学习,我们通过一个经典的回归算法,深刻明白其原理,知道公式推导,手写实现它。

学习这些理论和工具的同时,你也需要开始实战了。为此,我们选用哈佛大学的数据分析课,它是开源的,并且授课所用数据全部来自实际场景,算是最大贴近你的实际工作日常了,可谓干货十足!

接下来,你可以去寻找数据分析、机器学习相关的工作了。作为全面的学习路线,我还非常用心地为小伙伴们,准备了 2 个数据分析、机器学习相关的真实面试经历。

让我们开始数据分析的学习之旅吧!

数据分析入门学习路线

在开始介绍学习路线之前,我想告诉大家,本篇 chat 展开提纲中,已经包括了数据分析知识的主要部分,因此,大家应该已经有一个大概轮廓了。

每个人学习一门新知识前,大都想去了解下这门知识的学习思路是怎样的,都有哪些知识是必须要学的。所以,我们也只去论述关于数据分析,那些必须要学习的知识,也就是学好数据分析的必备技能。

1.1 统计学基本知识

首先,入门数据分析需要必备一些统计学的基本知识,在这里我们简单列举几个入门级的重要概念。概率,平均值,中位数,众数,四分位数,期望,标准差,方差。在这些基本概念上,又衍生出的很多重要概念,比如协方差,相关系数等。

这一些列常用的统计指标,都在强大的数据分析包 Pandas 中实现了,非常方便,在下面的 Pandas 介绍章节,会详细列出。

我们看下概率的通俗理解。 概率 P 是对随机事件发生的可能性的度量。例如,小明在期末考试前,统计了下自己在今年的数学考试成绩,结果显示得到 80 分以下的次数为 2 次,得 80 分~ 90 分的次数为 10 次,得到 90 分以上次数为 3 次,那么:

小明得到 80 分以下的概率为:
P( < 80 ) = 2/(2+10+3) = 13.3%

80~90分的概率为:
P( 80 ~ 90) = 10/(2+10+3) = 66.7%

90分以上的概率:
P( > 90) = 3/(2+10+3) = 20%

期望值 E,在一个离散性随机变量实验中,重复很多次实验,每次实验的结果乘以其出现的概率的总和。如上例中,小明在今年的期末考试,我们对他的期望值大约是多少呢?套用上面的公式,80 分以下的值取一个代表性的分数:70 分,80~90:85 分,90 分以上:95 分,

E =  70 * 0.133 + 85 * 0.667 + 95 * 0.2

计算出的结果为 85,即期末考试我们对小明的合理期望是 85 分左右。

方差 ,用来度量随机变量取值和其期望值之间的偏离程度,公式为:

$$\sigma^2 =\frac{\sum(X-\mu)^2}{N}$$

其中:

$X$ 表示小明的分数这个随机变量 $\mu$ 表示样本平均值 $N$ 表示样本的个数,即在此等于 15 个

已经知道小明的 15 次考试的分数,均值刚才我们也计算出来了为 85 分,带入到上面的公式中,便能得出偏离 85 分的程度大小。

如果方差很大,那么小明在期末考试的分数可能偏离 85 分的可能性就越大;如果方差很小,那么小明很可能期末考试分数在 85 分左右。

当然,你还得了解,事件,离散事件,连续性事件,了解数据的常见分布,比如泊松分布,正态分布等,归一化等知识。限于篇幅,在此,我就不一一展开了。我为大家推荐一本精简的这方面入门书籍,浙大盛骤等老师合编的《概率论与数理统计》这本书,大家可以有选择地学习书中的重要个概念。

1.2 机器学习基本算法

说统计学是一种基于事实的演绎学问,它是严谨的,可以给出确切解释的。不过,机器学习就不一样了,它是一门归纳思想的学问,比如深度学习得出的模型,你就很难解释其中的具体参数为什么取值为某某某。它的应用在于可以提供一种预测,给我们未来提供一种建设性的指导。

数据分析师需要了解机器学习的基本理论、常见的那十几种算法,这样对于我们做回归、分类、聚类分析,都是不可缺少的。

直到现在,也有很多小伙伴在公众号后台,问我,该如何入门机器学习。我通常的回答都是,先理解一种基本的算法,包括从算法的原理,公式推导,手写编码实现这个算法,可视化算法的结果。当完成整个一遍时,你也就差不多入门了,知道机器学习是怎么一回事了。

这种方法,比较直接、奏效,作为过来人,当时我也是这么做的,可以说实践出真知,同样推荐给还有这方面疑惑的小伙伴,不要再拖延了,没有一个神奇魔幻的方法,可以帮助你不用动手的,就可以掌握它 。

从现在开始学习和动手,参考接下来的介绍机器学习的章节,我会附上完整的代码,你只需要从头敲一遍,差不多你就可以入门机器学习了。越直接,越奏效,先上路,再上道!

1.3 编程语言及工具

如果说数学是纯理论,可能只需要动脑的学问地话,计算机和它最不同的一点就是,需要动手。记得 linux 大神托瓦兹,作为世界上最著名的程序员、计算机科学家,linux 内核和 git 的主要发明人。他就曾经说过,talk is poor, show me the code.

的确,计算机属于工科学问,动手编码的能力非常重要,现在越来越多的理工科博士,也开始注重编码能力了,而且有的编码能力也是超强,写出来的代码可读性、可扩展性都很好。这在过去,博士能做到这个的,大概还不是太多(这是个人观察得出,未经数据考证,结论可能有误 ),或许,当前,博士找工作面临压力也很大,物竞天择,适者生存,民营、私企不会养一个闲人。

数据分析和机器学习领域,同样需要能熟练使用至少一门变成语言,目前此领域,使用较多的就是 Python 和 R 语言。Python 又适合与机器学习领域,所以数据分析相关的从业人员,目前使用 Python 的也较多,当然 R 语言也不少。基于 Python 的生态环境也很不错,有很多数据科学包,比如文中提到的 NumPy、SciPy、Pandas 等等。

入行前,多多动手实践一些项目和名校的开源课程,可以驱动我们掌握它们,毕竟面对一些实际需求,这样做目标明确,自然会驱使你去掌握这些包的更多功能和 API 使用。

总结,这个数据分析的入门路线,主要分为三部分,现在相信小伙伴们已经目标已经很明确了。

下面,看下数据分析的重头戏,数据整理(data munging)。

数据分析重头戏之数据整理

数据整理,英文名称 data munging,是指在获取到的原数据基础上,理解这些业务数据,整理清洗它们,作为接下来算法建模的输入数据。在文章刚开始,我们就提到过,这部分工作的重要性,绝不亚于算法模型,时间占比可能大于算法选择和设计环节。

2.1 理解你的业务数据

我们在拿到需要分析的数据后,千万不要急于立刻开始做回归、分类、聚类分析。

第一步应该是认真理解业务数据,可以试着理解去每个特征,观察每个特征,理解它们对结果的影响程度。

然后,慢慢研究多个特征组合后,它们对结果的影响。借助上个章节提到的,常用的统计学指标,比如四分位,绘制箱形图,可以帮助我们寻找样本的取值分布。

同时,可以借助另一个强大的可视化工具: seaborn ,绘制每个特征变量间的相关系数热图 heatmap,帮助我们更好的理解数据,如下图所示:

colormap = plt.cm.RdBu
plt.figure(figsize=(14,12))
sns.heatmap(train.astype(float).corr(),linewidths=0.1,vmax=1.0, square=True, cmap=colormap, linecolor='white', annot=True)

enter image description here

2.2 明确各个特征的类型

明确我们的数据类型,也是数据整理阶段的必备任务之一。

如果这些数据类型不是算法部分期望的数据类型,你还得想办法编码成想要的。比如常见的数据自增列 id 这类数据,是否有必要放到你的算法模型中,因为这类数字很可能被当作数字读入。

某些列的取值类型,虽然已经是数字了,它们的取值大小表示什么含义你也要仔细捉摸。因为,数字的相近相邻,并不一定代表另一种层面的相邻。

有些列是类别型变量(categorical variable),例如著名的 Kaggle 泰坦尼克生还预测比赛中,乘客上船地点 Embarked 这个变量就是类别型变量。如果给 Embarked 变量用 Embarked 编码为 1、2、3 ,这样编码是不合理的。

一般这种类型的编码方式有 one-hot 编码,dummy variable 两种方式。

2.3 找出异常数据

有时候我们的数据存在异常值,并且这种概率挺大的。这实际上会导致结果出现偏差。比如,统计中国家庭人均收入时,如果源数据里面,有王建林,马云等这种富豪,那么,人均收入的均值就会受到极大的影响,这个时候最好,绘制箱形图,看一看百分位数。

了解数据范围,设定最大值、最小值限度是很非常重要的。

2.4 不得不面对缺失值

现实生产环境中,拿到的数据恰好完整无损、没有任何缺失数据的概率,和买彩票中将的概率差不多。

数据缺失的原因太多了,业务系统版本迭代, 之前的某些字段不再使用了,自然它们的取值就变为 null 了;再或者,压根某些数据字段在抽样周期里,就是没有写入数据......

处理缺失数据,最好弄明白它们为什么缺失了,比如,像上面说道的,如果是在抽样周期里,这些字段取值缺失了,那么可以咨询业务人员,这些字段大概率会取得哪些值。

接下来,填充缺失数据,比如均值填充,或者,为缺失的数据创建一类特殊值。

极端情况下,如果发现模型的效果受此字段影响较大,发现彻底删除此字段效果更好,那完全剔除可能是不错的选择。不过这样做也有风险,可能为模型带来更大的偏差。

2.5 令人头疼的数据不均衡

理论和实际总是有差距的,理论上很多算法都存在一个基本假设,即数据分布总是均匀的。这个美好的假设,在实际中,真的存在吗?很可能不是!

算法基于不均衡的数据学习出来的模型,在实际的预测集上,效果往往差于训练集上的效果。实际数据往往分布得很不均匀,存在所谓的 “长尾现象”,又称:“二八原理”。

就不均衡解决的难易程度而言,数据量越大,不均衡的问题越容易解决,相反,数据量很小,再不均衡,解决起来就比较困难了,比如典型的太空中是否有生命迹象这个事情,压根就没有太多相关的因素数据,如果某个特征的取值远多于另外一种,处理这种数据不均衡问题,就比较困难了。

所有以上 5 个方面的问题,对于一个数据分析师或数据科学家而言,都是需要认真处理对待的。限于篇幅,每个方面的详细解决技术,大家可以自行搜索相关文献和技术博客,一般大都有对应的解决措施。通过这个 chat,你能知道数据整理工作主要有这 5 个方面或者任务,等着你去探索解决,基本也就可以了。

当然,数据分析完成数据整理后,接下来的主要任务:特征工程,也是非常重要的。大家也可以查询相关资料,记得在我的公众号里,关于这个话题,曾经不只一次的探讨过,大家可以参考,一起交流。

接下来,开始介绍编程工具环节,继续我们的数据分析探索之旅。

Python 入门必备知识

Python 语言主要的特点,通俗的说就是语法简洁,开发效率高,一般数据分析,机器学习,深度学习会选用 Python 语言,同时基于 Python 的开发生态环境比较友好。

下面,从 Python 语言的特点,以及平时使用较多的几个典型对象展开,这些都是入门必备的功能,掌握这些你就可以说自己入门 Python 了。

不过,为了兼顾已经比较熟悉 Python 的小伙伴,我打算留有一定篇幅介绍一些 Python 的进阶功能,它们作为 Python 的重要特性,在平时工作中也会用到。

3.1 解释型Vs编译型

Python 是解释型语言,对于 Python 刚刚入门的小伙伴,可能对解释性有些疑惑。不过,没关系,我们可以通过大家已经熟悉的编译型语言,来帮助我们理解 Python 的解释性。

编译型语言,如 C++、Java,它们会在编译阶段做类型匹配检查等,因此,数据类型不匹配导致的编译错误,在编译阶段就会被检查出来,例如:

Intger a = 0;
Double b = 0.0;
a = b; // Double类型的变量 b 试图赋值给 Integer 型的变量 a, 编译报错
         // 因为 Integer 类型 和 Double 类型 不存在继承关系,
         // 类型不能互转

但是,Python 就不会在编译阶段做类型匹配检查,比如,Python 实现上面的几行语句,会这样写:

a = 0 # 不做任何类型声明
b = 0.
a = b # 这种赋值,Python 会有问题吗?

答案是不会的。此处就体现了 Python 的解释特性,当我们把 0 赋值给 a 时,Python 解释器会把它 a 解释为 int 型,可以使用内置函数 type(variable) 显示地检查 variable 的类型:

In [70]: type(a)
Out[70]: int

In [69]: type(b)
Out[69]: float

In [71]: a = b # 在把 float 型 b 赋值给 a 后, # a 就被解释为float

In [72]: type(a)
Out[72]: float

在把 float 型 b 赋值给 a 后, a 就被解释为 float. 相信此时,你已经对 Python 的解释型有一定了解了,下面说一些 Python 最常用的对象及其方法。

3.2 Python 最常用的对象

Python 最常用的几个对象: list、dict、tuple 以及它们三者的灵活组合。list 可以看作是线性表和链表的结合体,dict 可以看作是 key-value 对的组合,tuple 是不可更改的 "list"(注意,这种表述未必严谨,但个人认为比较通俗易懂,尤其对于入门者而言)。

上面提到 Python 用于数据分析,机器学习,非常方便。我们平时需要处理的数据怎么也有成千上万行,要想利用这些数据做分析,不可避免地当要将它们缓存到内存中。很显然,最直接的存储结构必然是容器。无一例外,list、dict、tuple 都是 Python 中构建好的容器,都是可迭代的对象,它们因此被使用频次高也就不足为奇了。

简单来说,我们使用 [] 创建一个 list,使用 {} 创建一个 dict,使用 () 创建一个 tuple。创建好我们的容器后,下一步就要知道如何添加、删除、更新、查询访问里面的元素。

3.2.1 list 核心知识

先说说 list 的这些操作:

In [73]: a = [[1,3,5],[7,4,2]] # 创建二维数组 a                                                                  
In [74]: a
Out[74]: [[1, 3, 5], [7, 4, 2]]

In [75]: a.append([0,8,3])  # 插入元素[0,8,3]

In [76]:
Out[76]: [[1, 3, 5], [7, 4, 2], [0, 8, 3]]

注意 append 操作直接插入到 a 的末尾,而不是 a 的副本的末尾,这样做无疑节省了内存空间。面向对象编成,不管是 C++、Java、Python 都会有这类问题,务必要清楚操作是在 a 上修改,还是在 a 的副本上修改,各有用处,此处不再详细展开讨论,后面的进阶课程,我们可以再展开。

如果想批量增加元素,可以使用 extend,如下所示,我们先使用 copy 下 a ,返回 b ,注意 list 实例的 copy 一律属于浅>拷贝(shallow copy),注意这种拷贝带来的副作用,在此我们也不详细展开,后续我们可以找时间讨论无论哪种面向对象的语言都存在的 shallow copy and deep copy 问题,以及如何选用哪种 copy 节省内存空间的同时,也能按预期实现目标。可以看到 b.extend(a) 后,b 内批量导入了 a。

In [100]: a
Out[100]: [[1, 3, 5], [7, 4, 2], [0, 8, 3]]

In [101]: b = a.copy()

In [102]: b
Out[102]: [[1, 3, 5], [7, 4, 2], [0, 8, 3]]

In [103]: b.extend(a)

In [104]: b
Out[104]: [[1, 3, 5], [7, 4, 2], [0, 8, 3], [1, 3, 5], [7, 4, 2], [0, 8,3]]

list 提供的删除元素方法有 pop,它默认删除 list 实例的最后一个元素,基于此,可以模拟栈(first in last out)的功能,因此 Python 中没有内置单独的栈对象。

In [94]:
                        
作者正在撰写中...
隐藏内容 支付可见
¥9.99 购买
× 订阅 Java 精选频道
¥ 元/月
订阅即可免费阅读所有精选内容