题目
使用逻辑回归算法预测患有疝病的马的死亡率,该数据包含368个样本和28个特征,要求底层算法实现及使用sklearn库。
做题思路和流程
(1)收集数据:给定数据文件。
(2)准备数据:数据预处理,使用实数0来替代所有缺失值。
(3)分析数据
(4)训练算法:使用优化算法,找到最佳的系数。
(5)测试算法:为了量化回归的效果,需要观察错误率,根据错误率决定是否退到训练阶段,通过改变迭代次数和步长等参数来得到更好的回归系数。
(6)使用算法:
首先,我们需要输入一些数据,并将其转换成对应的结构化数值;
接着,基于训练好的回归系数就可以对这些数值进行简单的回归计算,判定它们属于哪个类别;在这之后,我们就可以在输出的类别上做一些其他分析工作。
代码
# -*- coding: utf-8 -*-
# from numpy import*
import numpy as np
#数据加载
def loadDataSet(filePath):
f = open(filePath)
dataList = []
labelList = []
for line in f.readlines():
currLine = line.strip().split(' ')
lineArr = []
for i in range(21):
lineArr.append(float(currLine[i]))
dataList.append(lineArr)
labelList.append(float(currLine[21]))
return dataList,labelList
# sigmoid函数
def sigmoid(inX): #sigmoid函数
return 1.0 / (1 + (np.exp((-inX))))
#随机梯度下降算法
def stocGradAscent(dataList, labelList, numIter=150):
dataArr = np.array(dataList)
m, n = np.shape(dataArr)
weights = np.ones(n)
for j in range(numIter):
dataIndex = list(range(m))
for i in range(m):
alpha = 4 / (1.0 + j + i) + 0.0001
# 步长为动态变化
rand = int(np.random.uniform(0, len(dataIndex)))
choseIndex = dataIndex[rand]
h = sigmoid(np.sum(dataArr[choseIndex] * weights))
error = h-labelList[choseIndex]
weights = weights + alpha * error * dataArr[choseIndex]
del (dataIndex[rand])
return weights
#进行分类
def classifyVector(inX, weights):
prob = sigmoid(sum(inX * weights))
if prob > 0.5:
return 1.0
else:
return 0.0
#在测试集上计算分类错误率
def colicTest():
frTrain = open(r'./horseColicTraining.txt');
frTest = open(r'./horseColicTest.txt')
trainingSet = [];
trainingLabels = []
for line in frTrain.readlines():
currLine = line.strip().split('\t')
lineArr = []
for i in range(21):
lineArr.append(float(currLine[i]))
trainingSet.append(lineArr)
trainingLabels.append(float(currLine[21]))
trainWeights = stocGradAscent(np.array(trainingSet), trainingLabels, 1000)
errorCount = 0
numTestVec = 0.0
for line in frTest.readlines():
numTestVec += 1.0
currLine = line.strip().split('\t')
lineArr = []
for i in range(21):
lineArr.append(float(currLine[i]))
if int(classifyVector(np.array(lineArr), trainWeights)) != int(currLine[21]):
errorCount += 1
errorRate = (float(errorCount) / numTestVec)
print ("the error rate of this test is: %f" % errorRate)
return errorRate
def multiTest():
numTests=10;
errorSum=0.0
for k in range(numTests):
errorSum += colicTest()
print('在 %d 次之后,平均错误率为: %f' %(numTests,errorSum/float(numTests)))
if __name__ == '__main__':
multiTest()
运行结果
经过多次运行,结果趋于30%左右
总结
(1) 逻辑回归的目的是寻找一个非线性函数Signmoid的最佳拟合参数,求解过程可以由最优化算法来完成。在最优化算法中,最常用的是梯度上升算法,而梯度上升算法又可以简化为随机梯度上升算法。
(2) 随机梯度上升算法与梯度上升算法的效果相当,但占用更少的计算机资源。此外,随机梯度上升算法是一个在线算法,它可以在新数据到来时完成参数更新,而不需要重新读取整个数据集来进行批处理运算。