集智专栏
资源加载中,请稍后...
集智专栏

Patchouli的机器学习系列教程一:概率论初步与其他基础数学知识——『器』

集智小编

本文作者Patchouli Exarch, 毕业于谢菲尔德大学计算机科学专业,《中国味道》文史编辑。


学完了简单的数学原理后,我们来试着把这些思想运用到机器学习中去。

工具上我们决定使用python语言,IDE选择Anaconda的spyder。特别的,假如你是一个C++或者Java工程师的话,我还请您忘记您之前学过的"面向对象的程序设计",因为我们在数据分析和机器学习中将更多的用到“面向过程的程序设计”,这一点还请牢记,程序是动态的而不再是静态的了。这还要感谢Anaconda这家有野心的公司对数据科学库的开发和整合,使得C++和Java那种长篇累牍的“标准代码”可以在两三行内实现;然而值得注意的是,你在编写这几行浓缩代码所耗费的脑力和精力远远超过写几百行那样的标准代码,这也就是为什么人工智能程序员一行千金,而其他程序员难望其项背。

回到教程本身,首先我们要安装Anaconda和对应的科学库,在安装好Anaconda之后,我们打开程序组中的Anaconda Prompt.

Anaconda程序组Anaconda程序组

界面如下:

Anaconda PromptAnaconda Prompt

在其中分别输入:

pip install --upgrade ipython

pip install pods

打开spyder,新建一个.py文件,保存到目录下,随后把本文的附件film-death-counts-Python.csv放到和这个.py文件一样的位置。再在spyder中输入以下语句并运行:

import pandas as pd
film_deaths = pd.read_csv('./film-death-counts-Python.csv')
a=film_deaths.describe()

点此下载数据集

在spyder中视图列表中的这三个勾选(编辑器,控制台,变量观察器)上,其他的也可以勾选,但是这三个是必要的。

双击右侧的变量名我们就可以打开这份数据集并观测里面的内容了:

这是一份怎样的数据呢,听我慢慢道来:

近年来,出现了一个令人担忧的趋势,电影中出现的死人越来越多。也许是因为更多的血腥场景能刺激票房,也许是电影业的发展使得制片方能请到更多的群演演尸体,但是电影中出现越来越多的尸体绝对不是什么好事,作为电视行业的从业人员,一颗冉冉升起的新星,我感到十分的痛心!十分的震惊!为了践行中国特色社会主义核心价值观,为了更好地贯彻落实理解认识十九大精神,我决定对这股歪风邪气做一番研究,确定这波趋势不是杞人忧天。同时借着这次研究,给大家普及一下数据科学的一些基本方法。这份数据包含了几十年来一些电影的常规信息,特意包括了这部电影中死了多少人的条目。

在上面提供的python语句中,有一句:

a=film_deaths.describe()

是pandas自带的对于一个数据集的基本分析,包括最值,标准差,中位数等等,其结果如下所示:

DataFrame是pandas提供的一种数据存储形式,广泛应用于R语言和Python语言中。 DataFrame中的列数据可以被如下调用:

print(film_deaths['Year'])
print(film_deaths['Body_Count'])

以此来读取Year列和Body_Count列。 我们可以尝试用一个图表来表现这些数据:

import pylab as plt
plt.plot(film_deaths['Year'], film_deaths['Body_Count'], 'bx')

得到如上结果,这张图表示每一年中,各个电影中死人的数量。我们可以发现由于电影数量过多,以及个别电影死人过多,导致右下角成了一坨,不利于观测,因此我们需要找出哪些电影最不符合特色社会主义核心价值观。

film_deaths[film_deaths['Body_Count']>200].sort_values(by='Body_Count', ascending=False)

我们可以看到,指环王这个资本主义大毒草,一部王者归来就宰了八百多人,不仅从精神上严重污染着我国观众的思想健康,还让我们的数据变得难以观测。那么问题来了,资本主义世界就真的无药可救了吗?他们的电影真的就只能靠多杀人来博取观众的眼球了吗?凡是要讲科学,这个问题的答案从直观上我们应当从直方图上获取。

film_deaths['Body_Count'].hist(bins=20)

得到如下的结果:

杀人分布直方图杀人分布直方图

显然,万恶的资本主义还是有被拯救的机会,有被解放的价值,几十年来杀人过200的电影也是占了绝对的少数。 对数的发明节约了天文学家的寿命,自然也能延长我们的寿命,对于这样对应每个x的极值趋势成指数函数的数据集,我们不妨采用取对数的方式来让数据集更好的被观测到。我们可以直接操作数据集,但是操作坐标系的方式更为巧妙:

plt.plot(film_deaths['Year'], film_deaths['Body_Count'], 'rx')
ax = plt.gca()
ax.set_yscale('log')

坐标系对数化使得数据变得更为直观。

假如你是在集智网站上做,你会发现这些句子每个都可以独立运行,不需要像传统的计算机语言那样,维持一大堆静态变量的运行。这其实是一种进步,也是一种复古。上古时期的程序员们就是像这样,对着一个控制台,输入一系列复杂的语句,得到他们想要的结果,在那个连IDE都没有的时代他们甚至不得不用纸笔来记录数据集,控制台背后的东西完全无法被观测到。然而随着面向对象的编程的发展,控制台背后的东西被一览无余时,人们又回归了这种对着控制台编程的方式。而编写的内容也变得更复杂更高效,是为历史的螺旋上升。

上面我们还只是以小学生的方式来用数学库里的固有函数操作数据,接下来我们才要用我们在『道』篇中学到的贝叶斯公式来对数据进行处理。

先来一个简单的,假设我从这四百多部电影里随机挑电影,那么我看到的电影里死亡人数超过四十的概率有多大呢?

利用公式:可以写出以下代码:

deaths = (film_deaths.Body_Count>40).sum()
total_films = film_deaths.Body_Count.count()
prob_death = float(deaths)/float(total_films)
print("我看到死好多人的电影的概率为:", prob_death)

得到:我看到死好多人的电影的概率为: 0.37767220902612825。

那么我们完全可以画一张图表来展现每年中所有电影里死亡人数大于40的比例图:

prob_death_arr = np.zeros(len(film_deaths['Year']))
for idx,year in enumerate(film_deaths['Year']):
    deaths = (film_deaths.Body_Count[film_deaths.Year==year]>40).sum() 
    total_films = (film_deaths.Year==year).sum() 
    prob_death_arr[idx] = float(deaths)/float(total_films) 
plt.plot(film_deaths['Year'], prob_death_arr, 'x')

特别的,上面这六行代码可以用一行来实现,对自己python功底有自信的人可以尝试一下。

现在问题来了:我们假设 y 是死的人数, t 是年份,那么 P(Y > 40|T=2000) 是为在2000年里随便挑一部电影,电影中死亡人数大于40的概率,记作 p(y|t) 。求如何计算从所有电影里挑出一部电影,这部电影中死亡人数大于40,同时又正好是2000年的作品的概率?

根据贝叶斯定理我们知道 p(y,t)=p(y|t)p(t) ,而其中 p(y,t) 正是我们要求的数,直接算是算不出来的,必须要用贝叶斯公式来计算。

其中 p(y|t) 我们可以这么求:

p_y_given_t = float((film_deaths.Body_Count[film_deaths.Year==2002]>40).sum())/float((film_deaths.Year==2002).sum())

p(t)是这么求得:

p_t = float((film_deaths.Year==2002).sum())/float(film_deaths.Body_Count.count())

因而我们要求的 p(y,t) 即为:

p_y_and_t = p_y_given_t * p_t

以上,就是对贝叶斯公式在数据处理方面的简单应用。可以发现的是,我在『道』篇所提及的数学原理并没有被全部用上。这主要是因为,我的机器学习课程的难度将在下节课迎来火箭式的提升,这些数学原理主要是在下章被用到,怕你们一次性消化不了,所以先把一些简单的,基础的以及必要的交代出来。这样你们下节课追火箭时比较好追。

阅读上一章内容戳这里

您也许喜欢这些文章

集智专栏

[Kaggle] 泰坦尼克号事故分析 01 数据清洗

发表至数据科学
Kaggle是一个全球性的机器学习竞赛网站,参赛者可以自己编写算法,预测更准者胜。参加竞赛是个练习机器学习技巧的好方法。 Kaggle上的竞赛有很多,目前最火热的一个是推测泰坦尼克号上哪些乘客幸存。本篇将介绍如何分析数据、训练模型、提交答案。当然如果想知道自己的真实成绩,还是需要到Kaggle.com上进行。
集智专栏

浅说深度学习(1):核心概念

发表至系列教程
旨在提供直观简明的深度学习引导,涵盖深度学习的基本概念,而不设计很多数学和理论细节。当然如果要做更深入的研究,数学肯定是必不可少的,但是本系列主要还是用图片和类比等方式,帮助初学者快速建立大局观。
集智专栏

数学不行还学AI - 第5话 - 神经网络平话演义(下)

发表至趣味项目
《神经网络平话演义》下集,承接上集,对神经网络的一些重要概念进行了概括总结,并对人工智能的发展和未来做了展望。

文章评论(0)