LARS算法---十折交叉验证

参考:《python机器学习预测分析核心算法》4-2 & llx1026同学的修改代码

十折交叉验证整体采用上节的lars算法框架,加入了十折验证,十个β系数,每个β系数进行350次迭代。

算法概要:
1.从网页中读取数据
2.属性存入属性列表,结果存入标签列表
3.计算每列的均值与方差
4.属性和标签分别进行归一化处理
5.设置相关系数
6.进行10折交叉验证(循环10次)
每次循环生成一个β系数,并抽取数据中的1/10行数加入验证效果的列表,剩下的行进行训练,350轮训练是的每次验证产生350个β数据,选取其中最好的那个显示

代码:

# -*- coding:utf-8 -*-
import urllib.request
import numpy
from sklearn import datasets,linear_model
from math import sqrt
import matplotlib.pyplot as plot

#从网页中读取数据
url="http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv"
data=urllib.request.urlopen(url)

#将数据中第一行的属性读取出来放在names列表中,将其他行的数组读入row中,并将row中最后一列提取
#出来放在labels中作为标签,并使用pop将该列从row去去除掉,最后将剩下的属性值转化为float类型存入xList中
xlist=[]
labels=[]
names=[]
firstline=True
for line in data:
    if firstline:
        names=line.strip().split(b';')
        firstline=False
    else:
        row=line.strip().split(b';')
        labels.append(float(row[-1]))
        row.pop()
        floatrow=[float(num) for num in row]
        xlist.append(floatrow)

#计算几行几列
nrows=len(xlist)
ncols=len(xlist[1])
#print("rows:"+nrows)
#print("cols"+ncols)

#计算均值和方差
xmeans=[]
xsd=[]
for i in range(ncols):
    col=[xlist[j][i] for j in range(nrows)]
    mean=sum(col)/nrows
    xmeans.append(mean)
    coldiff=[(xlist[j][i]-mean) for j in range(nrows)]
    sumsq=sum([coldiff[j]*coldiff[j] for j in range(nrows)])
    stddev=sqrt(sumsq/nrows)
    xsd.append(stddev)

#数值减去平均数再除以标准差得到标准分数,反映了各数值的相对位置,也就是书中说的归一化
#对数值进行归一化
xnormalized=[]
for i in range(nrows):
    rownormalized=[(xlist[i][j]-xmeans[j])/xsd[j] for j in range(ncols)]
    xnormalized.append(rownormalized)

#对标签进行归一化
meanlabel=sum(labels)/nrows
sdlabel=sqrt(sum([(labels[i]-meanlabel)*(labels[i]-meanlabel) for i in range(nrows)])/nrows)
labelnormalized=[(labels[i]-meanlabel)/sdlabel for i in range(nrows)]


#设置走多少步
nsteps=350
#设置每一步系数变化多少
stepsize=0.004
#设置交叉数量
nxval=10

#初始化储存错误的列表
errors=[]
for i in range(nsteps):
    b=[]
    errors.append(b)

#进行10折交叉验证
for ixval in range(nxval):
    #书上应该是写错了,ixcal*nxval的话a就没了啊,参考了辣个女生的
    #每次验证取出1/10的行数
    idxtest=[a for a in range(nrows) if a%nxval==ixval]
    idxtrain=[a for a in range(nrows) if a%nxval!=ixval]

    xtest=[xnormalized[r] for r in idxtest]
    xtrain=[xnormalized[r] for r in idxtrain]

    nrowstest=len(xtest)
    nrowstrain=len(xtrain)
    labeltest=[labelnormalized[r] for r in idxtest]
    labeltrain=[labelnormalized[r] for r in idxtrain]
    #初始化初始化向量系数β
    beta=[0.0]*ncols
    #初始化矩阵β的每一步
    betamat=[]
    betamat.append(list(beta))


#计算每列与最终结果的关系系数β
    for i in range(nsteps):
#计算残差
        residuals=[0.0]*nrows
        for j in range(nrowstrain):
#labelshat=每行的各个标准差*相应β系数后的和(预测标准差)
            labelshat=sum([xtrain[j][k]*beta[k] for k in range(ncols)])
#residuals是列表,记录每行的实际标准差与预测标准差的差值
            residuals[j]=labeltrain[j]-labelshat


#通过标准分数和残差值计算列的相关属性
        corr=[0.0]*ncols

        for j in range(ncols):
#corr列表初始化为各列的数值*他所在行的差值后的和再除以行数=各列对残差值减小的贡献数值
#2个属性的关联值=两者归一化的乘积
            corr[j]=sum([xtrain[k][j]*residuals[k] for k in range(nrowstrain)])/nrowstrain

#寻找刚刚计算的关联值中最大的那一列(正负)
        istar=0
        corrstar=corr[0]

        for j in range(1,(ncols)):
            if abs(corrstar)<abs(corr[j]):
                istar=j
                corrstar=corr[j]
#对残差值减小关联最大的这列β进行增大或减小(corrstar/abs(corrstar)控制正负)
        beta[istar]+=stepsize*corrstar/abs(corrstar)
        betamat.append(list(beta))

        for j in range(nrowstest):
            labelshat=sum([xtest[j][k]*beta[k] for k in range(ncols)])
            err=labeltest[j]-labelshat
            errors[i].append(err)

#print("errors= ", errors)              
    cvcurve = []  
    for errvect in errors:  
        mse = sum([x*x for x in errvect]) / len(errvect)  
        cvcurve.append(mse)  

    minemse = min(cvcurve)  
    minpt = [i for i in range(len(cvcurve)) if cvcurve[i] == minemse][0]  
    print("Minimum Mean Square Error", minemse)  
    print("Index of Minimum Mean Square Error", minpt)  

    xaxis = range(len(cvcurve))  
    plot.plot(xaxis, cvcurve)  

    plot.xlabel("Steps Taken")  
    plot.ylabel(("Mean Square Error"))  
    plot.show()  

结果:

Minimum Mean Square Error 0.5873018933136459
Index of Minimum Mean Square Error 311
Minimum Mean Square Error 0.5534955247726759
Index of Minimum Mean Square Error 289
Minimum Mean Square Error 0.5957385843236068
Index of Minimum Mean Square Error 244
Minimum Mean Square Error 0.6163846701751715
Index of Minimum Mean Square Error 265
Minimum Mean Square Error 0.6205467405536572
Index of Minimum Mean Square Error 289
Minimum Mean Square Error 0.6273690438035697
Index of Minimum Mean Square Error 312
Minimum Mean Square Error 0.6214330728517901
Index of Minimum Mean Square Error 285
Minimum Mean Square Error 0.6180113626794431
Index of Minimum Mean Square Error 285
Minimum Mean Square Error 0.6295047735731523
Index of Minimum Mean Square Error 280
Minimum Mean Square Error 0.6494495844086484
Index of Minimum Mean Square Error 285

结果是十个,但是算法是一样的。都是一样的算法,抽取的训练数据不同导致的结果的差异,使用十折交叉验证可以大致评估上节的lars算法的性能

你可能感兴趣的:(python,机器学习)