Python 数据科学入门

Python 数据科学入门

英文:Vik Paruchuri

译文: 伯乐在线 – XiaoxiaoLi

链接:http://python.jobbole.com/85394/

 

Python 在数据科学领域越来越流行了。它的流行不无道理。 Python 容易学,有超强数据科学库,并且和 Hadoop 以及 Spark 等数据库和工具整合得非常好。Python 可以从头至尾完成一个数据科学项目,无论是读取数据、分析数据、数据可视化还是用机器学习来做预测都可以。

 

本文介绍如何用 Python 上手数据科学。如果想要了解更多内容请访问 Dataquest(https://www.dataquest.io/), 那里有使用 Python 完成数据科学任务的深入讲解。

 

本文使用的是关于 2016 美国总统大选政治资助的数据集(http://www.fec.gov/disclosurep/PDownload.do)。文件是 csv 格式,每行代表对一个候选人的一次捐赠。这个数据集有几列比较值得一提,比如:

 

  • cand_nm – 接受捐赠的候选人姓名
  • contbr_nm – 捐赠人姓名
  • contbr_state – 捐赠人所在州
  • contbr_employer – 捐赠人所在公司
  • contbr_occupation – 捐赠人职业
  • contb_receipt_amount – 捐赠数额(美元)
  • contb_receipt_dt – 收到捐款的日期

 

安装 Python

 

要分析这些数据,首先要安装 Python。利用 Anaconda 这个工具来安装 Python 是非常简单的。Anaconda 在安装 Python 的同时还会安装一些流行的数据分析库。点击 这里 下载 Anaconda。建议安装最新的 Python 3.5 版本。这个链接(https://wiki.python.org/moin/Python2orPython3) 里介绍了一些 Python 2 与 Python 3 的对比。

 

Anaconda 会自动安装一些这篇文章会用到的库,包括 Jupyter、Pandas、scikit-learn 和 matplotlib。

 

Jupyter 入门

 

都安装好之后可以启动 Jupyter notebook (原名 IPython notebook)。Jupyter notebook 是个强有力的数据分析工具。它能够帮助快速查看数据、将结果可视化以及把结果分享给他人。谷歌、IBM、微软的数据科学家都用它来分析数据以及组内协作。

 

在命令行里输入 ipython notebook 来运行 Jupyter。如果遇到问题可以去它的 官方文档 里查找答案。

 

 

启动后会出现一个可以查看文件的浏览器界面,在这个页面上可以创建新的 notebook。请创建一个叫 Python 3 的 notebook,一会儿的数据分析中会用到它。如果刚才的安装还没成功,这篇文章(https://www.dataquest.io/mission/118/project-python-and-pandas-installation)也许有帮助。

 

Notebook 工作区块

 

每个 Jupyter notebook 都包含多个区块(cell),区块可以运行代码也可以只包含文档。每个 notebook 开始时都自带一个区块,如有需要可以自行增加多个区块,比如:

 

In [ ]:

# 代码区块示例。产生的输出会在下方显示。

 

print(10)

b = 10

 

In [ ]:

# 可以建立多个区块,每个代码区块可以根据分析的需求跑任意次

# Jupyter notebook 中一个很赞的功能是每个区块跑出来的结果会被缓存起来, 这样一个区块可以利用另一个区块跑出来的结果。

 

print(b * 10)

 

如果想要了解更多关于 Jupyter 的知识请阅读作者提供的更深入的 教程(https://www.dataquest.io/mission/162/guided-project-using-jupyter-notebook)。

 

Pandas 入门

 

Pandas 是 Python 上的一个数据分析库。它能读取包括 csv 在内的不同格式的数据,分析数据也很有效。可以通过下面的代码来读取数据:

 

In [2]:

import pandas as pd

 

donations = pd.read_csv(“political_donations.csv”)

 

In [3]:

donations.shape

 

Out[3]:

(384885, 18)

 

In [4]:

donations.head(2)

 

Out[4]:


(表格太宽,可在网页版中查看完整版)

 

上面的区块用 import pandas as pd 这个语句导入了 Pandas 库,然后用 read_csv() 这个函数把 political_donations.csv 这个文件读入了变量 donations 中。变量 donations 现在就是一个 Pandas DataFrame。Pandas DataFrame 可以被看做是加强版的矩阵,它自带数据分析函数,并且允许不同的列包含不同的数据类型。

 

可以通过变量 donations 的 shape 属性来打印它多少行多少列。每个区块的最后一行语句或变量都会自动显示,这个功能超赞!下一个区块用了 DataFrames 的 head() 函数打印出了变量 donations 的头两行,这样就能看里面的数据了。

 

如想更深入地了解 Pandas 请参阅作者提供的 课程(https://www.dataquest.io/section/data-analysis)。

 

每个候选人收到的捐款总额

 

使用Pandas 中的 groupby() 函数能计算出每个候选人的整体统计数据。根据变量 cand_nm(候选人姓名)来把变量 donations 分成不同的子集就可以针对每个候选人分别统计数据。首先要算的是捐款总额。把候选人的 contb_receipt_amount 这一列加起来就可以得到收到的捐款总额了。

 

In [14]:

donations.groupby(“cand_nm”).sum().sort(“contb_receipt_amt”)

 

Out[14]:

 

上面的代码首先用donations.groupby(“cand_nm”) 根据cand_nm 把donations 分成了不同的组。这个语句返回的是 GroupBy 对象,GroupBy 类型自带一些专门用来整合数据的函数。其中就包含sum() 函数,在这个问题中可以用来计算每组中每一列中数据的和。

 

Pandas 在读取数据的时候就会自动识别每一列的数据类型,在进行求和时只会针对数字类型的列来操作。这样就得到了一个包含每个候选人contb_receipt_amt列中所有数字之和及file_num 列中所有数字之和的 DataFrame。最后使用 DataFrames 中的 sort() 函数将contb_receipt_amt 的和从小到大排序。这样就得到了每个候选人收到的捐款总额。

 

将捐款总额可视化

 

Python 中最主要的可视化包就是 matplotlib,可以用它来画图。Jupyter notebook 能够在浏览器中直接渲染 matplotlib 的图表。这个功能需要通过激活 matplotlib 的 inline 模式来开启。可以利用 Jupyter magics 中的命令来激活它就能直接在 notebook 中看图表了。

 

Magics 就是以 % 或者 %% 开头的、能改变 Jupyter notebook 本身的命令。它们是为了让能够通过命令行改变 Jupyter 的设置,同时尽量不与 Python 代码混淆而存在的。要想在浏览器里直接看 matplotlib 的图表,需要在代码区块里运行 %matplotlib inline。更多关于用 Jupyter 画图的内容可以 在此(https://ipython.org/ipython-doc/3/notebook/notebook.html#plotting) 阅读。

 

用下面的代码来导入 matplotlib 库并且开启 inline 模式:

 

In [15]:

import matplotlib.pyplot as plt

 

%matplotlib inline

 

Pandas 中的 DataFrames 自带对可视化的支持,调用 plot() 函数就可以生成 matplotlib 图表。这么用一般会比调用 matplotlib 更方便快捷。先给之前的 DataFrame 赋值给一个变量 total_donations,再利用 indexing 来选择 DataFrame 中的一列: contb_receipt_amt。这样就生成了一个 Pandas 中的 Series 类型的变量。

 

Pandas 中的 Series 和 DataFrames 包含的函数都差不多,但是 Series 只能存一维数据,比如单一行或者单一列。调用 Series 的 plot() 函数就生成了一个显示每个候选人收到的捐款总额的柱状图。

 

In [16]:

total_donations = donations.groupby(“cand_nm”).sum().sort(“contb_receipt_amt”)

 

In [20]:

total_donations[“contb_receipt_amt”].plot(kind=”bar”)

 

Out[20]:

<matplotlib.axes._subplots.AxesSubplot at 0x108892208>

 

 

如果想深入学习 matplotlib, 可以学习作者提供的 课程(https://www.dataquest.io/section/data-visualization)。

 

计算捐款平均值

 

已经学会算捐款总额啦,再想算捐款平均值超级容易。直接用求平均值的 mean() 函数来替换求和用的 sum() 函数就得了。

 

In [22]:

avg_donations = donations.groupby(“cand_nm”).mean().sort(“contb_receipt_amt”)

avg_donations[“contb_receipt_amt”].plot(kind=“bar”)

 

Out[22]:

<matplotlib.axes._subplots.AxesSubplot at 0x108d82c50>

 

 

预测捐款数目

 

下面来写个简单的根据一个人所在的州(contbr_st)、职业(contbr_occupation)及支持的候选人(cand_nm)来预测捐款数额的简单算法吧。首先用这几列及要预测的 contb_receipt_amt 列来另外创建一个 Dataframe。

 

In [41]:

pdonations = donations[[“contbr_st”, “contbr_occupation”, “cand_nm”, “contb_receipt_amt”]]

 

下面来看看变量 pdonations 里每一列的数据类型。Pandas 读取 csv 文件时会自动给每列赋予数据类型。只有数值型(numeric)的列才能用来做预测。

 

In [42]:

pdonations.dtypes

 

Out[42]:

contbr_st                   object

contbr_occupation     object

cand_nm                    object

contb_receipt_amt     float64

dtype: object

 

倒霉的是想要用的列都是 object 型的(都是字符串)。这是因为它们都是分类数据(categorical data)。每列中有几个可能的值,但这些选项是用文本来表示的而不是用数值型代码来表示的。可以先把每列都转换成分类型(categorical),然后再转换成数值型。这里 有关于分类型数据的更多介绍。本质上就是分类型数据在后台给一列中每个不同的值赋予了一个不同的数值型代号。可以将一列种的值都换成这些代号,这样一列就完全被转换成数值型的了。

 

In [43]:

pdonations[“contbr_st”] = pdonations[“contbr_st”].astype(‘category’)

pdonations[“contbr_st”] = pdonations[“contbr_st”].cat.codes

 

In [44]:

pdonations[“contbr_st”]

 

Out[44]:

0     1

1     1

2     1

3     2

4     2

5     2

6     2

7     2

8     2

9     2

10    2

11    2

12    2

13    2

14    2

384870    75

384871    75

384872    75

384873    75

384874    75

384875    75

384876    75

384877    75

384878    75

384879    75

384880    75

384881    75

384882    75

384883    77

384884    77

Name: contbr_st, Length: 384885, dtype: int8

 

可以看到 contbr_st 列已经被转换成数值型的了。下面对 contbr_occupation 及 cand_nm 两列也进行同样的操作。

 

In [ ]:

for column in [“contbr_st”, “contbr_occupation”, “cand_nm”]:

    pdonations[column] = pdonations[column].astype(‘category’)

    pdonations[column] = pdonations[column].cat.codes

 

训练集和测试集的拆分

 

接下来的预测步骤中可以利用到 Python 中最主要的机器学习包 scikit-learn。首先要把数据拆分成两个部分。一部分用于训练算法,称为训练集;另一部分用于评估模型的效果,称为测试集。这样做是为了避免过拟合(overfitting)产生的有误导性的结果。

 

用 train_test_split() 这个函数可以将 pdonations 拆分成一个训练集和一个测试集。

 

In [48]:

from sklearn.cross_validation import train_test_split

 

train, test, y_train, y_test = train_test_split(pdonations[[“contbr_st”, “contbr_occupation”, “cand_nm”]], pdonations[“contb_receipt_amt”], test_size=0.33, random_state=1)

 

上面的代码将训练算法需要用的列及结果列(contb_receipt_amt)中的值分成了训练集和测试集。测试集中包含33%的数据。每行数据被随机分配到训练集中或者测试集中。

 

拟合模型

 

下面会使用随机森林(random forest)算法来做预测。随机森林是一个效果比较好并且适用于很多问题的算法,在 scikit-learn 包中是通过 RandomForestRegressor 类来实现的。使用这个类训练模型及用模型做预测都很简单。

 

首先用 train 和 y_train 来训练模型:

 

In [52]:

from sklearn.ensemble import RandomForestRegressor

 

model = RandomForestRegressor(n_estimators=100, min_samples_leaf=10)

 

model.fit(train, y_train)

 

Out[52]:

RandomForestRegressor(bootstrap=True, compute_importances=None,

           criterion=‘mse’, max_depth=None, max_features=‘auto’,

           max_leaf_nodes=None, min_density=None, min_samples_leaf=10,

           min_samples_split=2, n_estimators=100, n_jobs=1,

           oob_score=False, random_state=None, verbose=0)

 

scikit-learn 包一个优点是里面所有算法都有一致的 API。训练一个线性规划(linear regression)模型和训练一个随机森林模型用的方法是一模一样的。有了合适的模型就可以用它来做预测了。

 

预测及误差计算

 

用 scikit-learn 包做预测也非常简单。直接把测试集传给训练好的模型就行了。

 

In [54]:

predictions = model.predict(test)

 

有了预测结果之后来算算误差值。误差能体现模型的效果,在调整模型时也能作为一个衡量标准。下面会用一个常见的误差标准,均方误差(mean squared error)。

 

In [57]:

from sklearn.metrics import mean_squared_error

import math

 

mean_squared_error(predictions, y_test)

 

Out[57]:

756188.21680533944

 

如果想了解更多关于 scikit-learn 的知识可以阅读作者撰写的 教程(https://www.dataquest.io/section/machine-learning)。

 

接下来做点什么

 

对误差求平方根得到的值和捐款额之间的关系更直观。如果不求平方根而只用平均方差 (average squared error),那它就和上面用的数据没什么直接关系。无论怎么算目前的误差值都很大,有很多减小误差的方法,比如:

 

  • 利用上其他列中的数据
  • 看看是否对每个候选人训练一个模型效果会更好
  • 尝试用其他算法

 

还有一些有意思的对数据的探索可以做,比如:

 

  • 找出每个州哪个候选人得到的捐款最多
  • 画出对每个候选人来说,来自哪种职业的人捐的钱最多的图
  • 根据候选人是民主党还是共和党划分,看看是否会有有意思的模式出现
  • 通过名字给数据添加性别,看看如果根据性别划分数据是否会显现出有意思的模式
  • 根据美国不同地区的捐款总额画一个热图(heatmap)

 

想要深入了解本文讲解到的概念,请参阅作者提供的 Python 数据科学(https://www.dataquest.io/) 课程。

 

评论

还没有任何评论,你来说两句吧

发表评论

浙ICP备16008686 -
善始者实繁,克终者盖寡