python 学习简记 《编程导论》 CH12&CH13

《编程导论》 CH12 随机算法、概率以及统计

12.1 随机程序

函数random.choice 接受一个非空序列作为参数并返回一个从序列中随机选择的元素。

random中的绝大多数函数都使用函数random.random实现,这个函数会返回0.0和1.0之间的一个随机浮点数。

掷骰子

 

import random

def rollDie():
    """return an int between 1 and 6"""
    return random.choice([1,2,3,4,5,6])

def rollN(n):
    result =''
    for i in range(n):
        result = result + str(rollDie())
    print result

rollN(10)


12.2 统计推断和模拟

 

统计推断:从一个群体中选出的随机样本趋向于表现出和这个群体相同的属性

抛硬币:

 

def flip(numFlips):
    heads = 0.0
    for i in range(numFlips):
        if random.random()<0.5:
            heads += 1
    return heads/numFlips

def flipSim(numFlipsPerTrial,numTrials):
    fracHeads = []
    for i in range(numTrials):
        fracHeads.append(flip(numFlipsPerTrial))
    mean = sum(fracHeads)/len(fracHeads)
    return mean

print flipSim(100,1)
print flipSim(100,1)
print flipSim(100,100)
print flipSim(100,100)
print flipSim(100,100000)
print flipSim(100,100000)


大数定律——>避免赌徒谬误、比例VS数量

 

下面的函数flipPlot会生成一些曲线来证明大数原则确实起作用了。倒数第二句random.seed(0)确保代码执行时random.random每次生成的伪随机数序列都是相同的,这样调试起来会比较方便。

绘制抛硬币的结果:

 

def flipPlot(minExp,maxExp):
    """assume minExp&maxExp are possitive integers and minExp<maxExp
        draw the result of flipping coins between 2**minExp and 2**maxExp times"""
    ratios=[]
    diffs = []
    xAxis = []
    for exp in range(minExp,maxExp + 1):
        xAxis.append(2**exp)
    for numFlips in xAxis:
        numHeads = 0
        for n in range(numFlips):
            if random.random()<0.5:
                numHeads += 1
        numTails = numFlips - numHeads
        ratios.append(numHeads/float(numTails))
        diffs.append(abs(numHeads - numTails))
    pylab.title('Difference Between Heads and Tails')
    pylab.xlabel('Number of Flips')
    pylab.ylabel('Abs(#Heads - #Tails)')
    pylab.plot(xAxis,diffs)
    #pylab.show()
    pylab.savefig('1')
    pylab.figure()

    pylab.title('Heads/Tails Ratios')
    pylab.xlabel('Number of Flips')
    pylab.ylabel('#Heads/#Tails')
    pylab.plot(xAxis,ratios)
    pylab.savefig('2')
random.seed(0)
flipPlot(4,20)


pylab.plot(xAxis,diffs,'bo')可以让程序只绘制点

 

pylab.semilogx()或者pylab.semilogy()分别让x轴和y轴使用对数刻度。

 

衡量不同输出之间的分散程度:方差——>标准差

 

def stdDev(X):
    """assume X is a list of numbers"""
    mean = float(sum(X))/len(X)
    tot = 0.0
    for x in X:
        tot += (x - mean)**2
    return (tot/len(X))**0.5

 

 

可以通过标准差来判断我们得出的结论的可信度。

下面的代码展示了一个flipPlot的修改版本。对于不同的抛掷次数,它会进行多次实验并绘制出abs(heads-tails)的平均值、比例heads/tails以及两者的标准差。

 

def makePlot(xVals,yVals,title,xLabel,yLabel,style,logX=False,logY=False):
    pylab.figure()
    pylab.title(title)
    pylab.xlabel(xLabel)
    pylab.ylabel(yLabel)
    pylab.plot(xVals,yVals,style)
    if logX:
        pylab.semilogx()
    if logY:
        pylab.semilogy()

def runTrial(numFlips):
    numHeads = 0
    for n in range(numFlips):
        if random.random()<0.5:
            numHeads += 1
    numTails = numFlips - numHeads
    return (numHeads,numTails)

def flipPlot1(minExp,maxExp,numTrials):
    ratiosMeans,diffsMeans,ratiosSDs,diffsSDs = [],[],[],[]
    xAxis =[]
    for exp in range(minExp,maxExp+1):
        xAxis.append(2**exp)
    for numFlips in xAxis:
        ratios = []
        diffs =[]
        for t in range(numTrials):
            numHeads, numTails = runTrial(numFlips)
            ratios.append(numHeads/float(numTails))
            diffs.append(abs(numHeads - numTails))
        ratiosMeans.append(sum(ratios)/float(numTails))
        diffsMeans.append(sum(diffs)/float(numTails))
        ratiosSDs.append(stdDev(ratios))
        diffsSDs.append(stdDev(diffs))
    numTrialsString ='('+str(numTrials)+' Trails)'
    title = 'Mean Heads/Tails Ratios'+numTrialsString
    makePlot(xAxis,ratiosMeans,title,'Number of flips','Mean Heads/Tails','bo',logX=True)
    title = 'SD Heads/Tails Ratios'+numTrialsString
    makePlot(xAxis,ratiosSDs,title,'Number of flips','Standard Deviation','bo',logX=True,logY=True)


flipPlot1(4,20,20)

正面和反面数量的绝对差值:

 

 

    title = 'Mean abs(#Heads - #Tails)' + numTrialsString
    makePlot(xAxis,diffsMeans,title,'Number of Flips','Mean abs(#Heads-#Tails)','bo',logX=True,logY = True)
    title = 'SD abs(#Heads -#Tails)'+numTrialsString
    makePlot(xAxis,diffsSDs,title,'Number of Flips','Standard Deviation','bo',logX = True,logY = True)


标准差要结合平均值来看。如果平均值是10亿,而标准差是100,那我们就认为数据很集中。如果平均值是100,而标准差也是100,那我们就认为数据很分散。

 

变异系数是标准差除以平均值。在处理平均值变化较大的数据集时,变异系数比标准差有意义。

 

def CV(X):
    mean = sum(X)/float(len(X))
    try:
        return stdDev(X)/mean
    except ZeroDivisionError:
        return float('nan')

 

 

 

 

 

 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值