机器算法实战中logistcal回归与SKlearn库算法对比

来源:互联网 发布:带网络变压器的rj45 编辑:程序博客网 时间:2024/06/07 02:30

<<机器算法实战>>中logistcal回归中省略部分的推导

在该书中,第一版本的logistcal回归梯度上升优化算法中有几行代码:
log code
其中最后一行代码隐含了一个结论,即:
equation1

初次接触时难免会对该结论有些困惑。该结论的具体的推导过程如下:

这里写图片描述

<<机器算法实战>>中logistcal回归中系数的收敛

书中利用随机梯度下降法预测病马死亡率时,多次重复调用模型,可以看出错误率变动仍然会比较大。这说明回归系数并没有很好的收敛。适当修改梯度下降函数,记录每次迭代回归系数的变动

def colicTest():    '''    @fun: colicTest      --- 调用logistical regression训练函数,并返回模型的错误率    @para: N/A    @return: erroRate    --- 模型错误率    '''    #载入训练数据    trainingFilePaht='horseColicTraining.txt'    trainingData=[]    trainingLabel=[]    with open(trainingFilePaht) as fr:        for line in fr.readlines():            strList=line.strip().split()            lineArray=[1.0]            for i in range(21):                lineArray.append(float(strList[i]))            trainingData.append(lineArray)            trainingLabel.append(float(strList[21]))    #调用训练函数,得到权重,和权重变化的趋势    weights,weightsTrend=randomGradAscent1(trainingData,trainingLabel)    #读取测试数据,进行测试    testFilePath='horseColicTest.txt'    erroCount=0    count=0    with open(testFilePath) as fr:        for line in fr.readlines():            strList=line.strip().split()            testDataArr=[1]            for i in range(21):                testDataArr.append(float(strList[i]))            testRes=classifyVector(testDataArr,weights)            if int(testRes)!=int(strList[21]): erroCount+=1            count+=1        erroRate=float(erroCount)/count        print('the erroRate is: ',erroRate)    return erroRate,weightsTrenddef plotWeightsTrend(weightsTrend):    '''    @fun: plotWeightsTrend --- 画出weight的变化趋势    @input: weightsTrend   --- weightsTrend的list    @return: N/A    '''    weight0=[]    weight1=[]    weight2=[]    for i in range(len(weightsTrend)):        weight0.append(weightsTrend[i][0,0])        weight1.append(weightsTrend[i][0,1])        weight2.append(weightsTrend[i][0,2])    x=list(range(len(weightsTrend)))    fig=plt.figure()    ax0=fig.add_subplot(311)    ax0.set_ylabel('weght0')    ax0.plot(x,weight0,label='weight0')    ax1=fig.add_subplot(312)    ax1.set_ylabel('weight1')    ax1.plot(x,weight1,label='weight1')    ax2=fig.add_subplot(313)    ax2.set_ylabel('weight2')    ax2.plot(x,weight2,label='weight2')    plt.show()#调用画图函数,画出变化趋势if __name__=='__main__':   datat,labelList=loadDataSet()   weights,weightsTrend=randomGradAscent1(dataList,labelList)   plotWeightsTrend(weightsTrend)

最终可以得到以下输出:
the erroRate is: 0.3283582089552239
这里写图片描述
由于该模型中回归系数很长,这里只画出了前三个系数随迭代次数的波动的变化。从图中可以看出,除了W0相对而言基本收敛以外,另两个系数仍然在波动。这也导致了该模型的重复性较差。同时,模型的训练过程也比较慢。因此,更好的做法是调用sklearn库中的LogisticRegression来进行模型训练。

利用sklearn库中的LogisticRegression,以及<<机器算法实战>>书中马病数据训练模型

sklearn库中的LogisticRegression中有很多参数可以选择。我们尝试选择的调整参数C和solver。从sklearn库的注释可以得知C是正则化系数的倒数。C值越小,正则化系数越大,也就越能抑制过拟合(注:LogisticRegression默认了L2的惩罚函数)。solver是指用哪种算法来得到最优化的回归系数。

首先我们调用grid_search来寻找最优化的参数选择。

from sklearn.linear_model import LogisticRegressionimport logRegimport numpy as npfrom sklearn import grid_searchdef gridSearchForLogReg():    '''    @fun: gridSearchForLogReg   ---  调用sklearn包中的gridSearch来寻找最佳参数设置    @para: N/A    @return:     '''    trainingFilePath='horseColicTraining.txt'    testFilePath='horseColicTest.txt'    traningData,trainingLabel=loadDataSet(trainingFilePath)    testData,testLabel=loadDataSet(testFilePath)    parameters={'C':[0.1,1,3],'solver':['newton-cg', 'lbfgs', 'liblinear'] }    clf=grid_search.GridSearchCV(LogisticRegression(),parameters)    clf.fit(traningData,trainingLabel)    print(clf.best_params_)

该函数将会输出由grid_search给出的参数选择{‘C’: 0.1, ‘solver’: ‘newton-cg’}。接下类我们用这个参数来构建模型。

def skLogReg():    '''    @fun: skLogReg   ---  调用sklearn包中的logistical regression,计算错误率    @para: N/A    @return: erroRate --- 模型错误率    '''    trainingFilePath='horseColicTraining.txt'    testFilePath='horseColicTest.txt'    traningData,trainingLabel=loadDataSet(trainingFilePath)    testData,testLabel=loadDataSet(testFilePath)    logRgClassifier=LogisticRegression(C=0.1,solver='newton-cg') #使用默认的分类器,所有参数均为默认    # logRgClassifier=LogisticRegression()    logRgClassifier.fit(traningData,trainingLabel)  #使用训练数据训练模型    logRgRes=logRgClassifier.predict(testData)    cooefficient=logRgClassifier.coef_    erroCount=0    count=0    for i in range(len(logRgRes)):        if int(logRgRes[i])!=int(testLabel[i]):            erroCount+=1        count+=1    erroRate=erroCount/float(count)    print("erroRate is: " ,erroRate)   return erroRate

该函数的输出为:erroRate is: 0.2537313432835821。
错误率有了明显的提高。且回归系数时收敛的。多次运行该模型会得到相同的结果。同时由于Sklearn包里使用了C++库,运行速度也有了明显的提高。

阅读全文
1 0
原创粉丝点击