菜鸟入门_Python_机器学习(2)_最基本统计特性的证明


@sprt
*写在开头:博主在开始学习机器学习和Python之前从未有过任何编程经验,这个系列写在学习这个领域一个月之后,完全从一个入门级菜鸟的角度记录我的学习历程,代码未经优化,仅供参考。有错误之处欢迎大家指正。
系统:win7-CPU;
编程环境:Anaconda2-Python2.7,IDE:pycharm5;
参考书籍:
《Neural Networks and Learning Machines(Third Edition)》- Simon Haykin;
《Machine Learning in Action》- Peter Harrington;
《Building Machine Learning Systems with Python》- Wili Richert;
C站里都有资源,也有中文译本。
我很庆幸能跟随老师从最基础的东西学起,进入机器学习的世界。*


我们老师有句名言:统计,说白了就是在‘凑’。我学的不好,理解不了这话高深的意境……还是从最基本的做起,就是那几个统计领域基石一般定理的证明。包括切比雪夫大数定律、中心极限定理、最大似然定理、贝叶斯定理。

先来看我们的任务:

随机样本生成:针对以下3种不同的分布函数分别生成随机样本各N个,计算并画出直方图(用一幅图展示)。设置5个不同的N=10,30,100,300,1000。
•均匀分布[-1,1]
•正态分布N(0,1)
•伯努利分布p=0.3
•用模拟的方法验证大数定律:对以上不同分布生成的随机样本分别求平均E(N),画出E(N)(用一幅图)
•用模拟的方法验证中心极限定律

几个基本定理的证明我手推了一遍,但实在懒得再敲,大家可以上网查一下,也可以参考下面这个手推的笔记(妹子的笔记,征得同意),写的有点繁琐(觉得枯燥的自行解决),但胜在详细,比网上大部分生搬硬套公式来的实在的多,方便辅助理解,另外贝叶斯定理手打,应该看得清楚:










当用数学语言完全推导完一遍之后,已经有了个大体的印象了,然后进行编程模拟就会顺利很多(我突然觉得,编程真的是比这些证明要容易有意思的多啊[笑哭])。废话不多说直接上代码,先是生成三种随机分布图,并验证大数定律:

import numpy as np
import matplotlib.pylab as plb

number=[10,30,100,300,1000]

def uniform_dis():
    ave_uniform=[]
    for i in range(len(number)):
        data=np.random.uniform(-1,1,number[i])
        summer=sum(data)
        ave_uniform.append(summer/number[i])
        plb.subplot(230+i+1)
        plb.hist(data)
        plb.xlabel('data{}'.format(i+1))
    plb.subplot(236)
    plb.plot(number,ave_uniform,'b*-')
    plb.xlabel('large_law')
    plb.show()

def bernoulli_dis():
    ave_bernoulli=[]
    for i in range(len(number)):
        data=np.random.binomial(1,0.3,number[i])
        summer=sum(data)
        ave_bernoulli.append(summer*1.0/number[i])
        plb.subplot(230+i+1)
        plb.hist(data)
        plb.xlabel('data{}'.format(i+1))
    plb.subplot(236)
    plb.plot(number,ave_bernoulli,'b*-')
    plb.xlabel('large_law')
    plb.show()

def normal_dis():
    ave_normal=[]
    for i in range(len(number)):
        data=np.random.normal(0,1,number[i])
        summer=sum(data)
        ave_normal.append(summer/number[i])
        plb.subplot(230+i+1)
        plb.hist(data)
        plb.xlabel('data{}'.format(i+1))
    plb.subplot(236)
    plb.plot(number,ave_normal,'b*-')
    plb.xlabel('large_law')
    plb.show()

uniform_dis()
bernoulli_dis()
normal_dis()

觉得numpy库实在是太方便了,这里直接调用库中的分布函数就可以,当然各位有兴趣的也可以自己试一下。运行结果如下:

伯努利分布:

均匀分布:

正态分布:

按照之前任务书中列表给出的样本数,分别生成各自的频数直方图,这里将它们画到一副图中(画图技巧参考我上一篇博文中的连接),可以看出随着样本数的增加逐步体现出各自的分布趋势。右下角的折线图是用来验证大数定律,及随着样本数的增加,样本的算术平均值逐步趋近与分布函数的期望值。当然,这个方法存在很多缺陷,例如我的样本点太少;这种方法只是反应了大数定律的部分特性,不足以证明等等,有兴趣的话可以尝试下别的方法。

接下来是中心极限定理的证明(这个定理真是骄傲到不讲道理,真是奇妙),直接上代码:

中心极限定理:

import numpy as np
import matplotlib.pylab as plb
from scipy import stats
import math

number=[30,100,300,1000,5000,30000]
y=[]
for i in range(len(number)):
    ave_uniform=[]
    for j in range(1000):
        data=np.random.uniform(-1,1,number[i])
        variance=(1.0/3.0)/(1.0*number[i])
        summer=sum(data)
        ave_uniform.append(summer/(1.0*number[i]))
        Range=np.arange(-0.5,0.5,0.001)
    plb.subplot(230+i+1)
    plb.plot(Range,stats.norm.pdf(Range,0,math.sqrt(variance)))
    plb.hist(ave_uniform,bins=100)
plb.show()

就是证明过程的重现,这里将不同样本数下正态分布的均值求平均,每种样本数下重复1000次画线,与一个满足同样参数的正态分布样本集作比较,结果很明显。这里用正态分布是因为它的期望和方差很好手算,在用pdf函数的时候可以直接带入,也算偷懒。结果如下:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章