从疝气病症预测病马的死亡率
1 准备数据
处理数据中缺失值的方法:
- 使用可用特征的均值来填补缺失值
- 使用特殊值来填补缺失值,如-1
- 忽略有缺失值的样本
- 使用相似样本的均值添补缺失值
- 使用另外的机器学习算法预测缺失值
此例中选择用0来代替缺失值,可以在使用该样本跟新回归系数时不产生影响。
忽略标签数据缺失的样本
2 测试算法:使用Logistic回归进行分类
思想:首先将原始数据进行格式化处理,并根据训练集计算回归系数向量,并导入测试集计算分类错误率。
进行10次训练测试,并求结果的平均值。
代码:
from numpy import *
#sigMiod函数
def sigmoid(inX):
return 1 / (1 + exp(-inX))
'''
函数功能:根据特征,标签获得回归系数
输入:特征数据,标签数据,迭代次数
输出:回归系数
思想:调整每次迭代时的步长,且步长随着迭代次数不断减少,但不会减少到0(确保多次迭代之后新数据仍具有一定的影响)
可避免步长的严格下降:alpha每次减少1/(i+j),i为样本点下标,j为迭代次数。当j<max(i),alpha就不是严格下降的
可通过随机选择样本来更新回归系数,将减少周期性的波动。
可指定迭代次数,默认为150次
'''
def stocGradAscent1(dataMatrix, classLabels, numIter = 150):
m,n = shape(dataMatrix)#获取样本行数和特征个数
weights = ones(n)#初始化回归系数
#进行多次迭代
for j in range(numIter):
dataIndex = list(range(m))#定义0-行数的随机序列,用于对样本进行随机选择
#根据随机的样本,更新回归系数
for i in range(m):
alpha = 4 / (1.0 + j + i) + 0.01#步长在每次迭代时需要调整
randIndex = int(random.uniform(0, len(dataIndex)))#获得随机样本的位置
h = sigmoid(sum(dataMatrix[randIndex] * weights))#计算随机样本的分类结果
error = classLabels[randIndex] - h
weights = weights + alpha * error * dataMatrix[randIndex]#更新回归系数
del(dataIndex[randIndex])#删除此样本的位置,避免重复选择
return weights
'''
函数功能:根据输入的特征向量和权重系数,得到分类结果
输入:欲分类的特征向量数据,和已计算得到的权重系数,均为数组类型
输出:该样本的分类结果
思想:特征向量*权重系数,得到一个结果。将该结果输入sigmoid函数,得到对应的分类的一个概率。
若>0.5,则为1类。反之,为0类
'''
def classifyVector(inX, weights):
prob = sigmoid(sum(inX * weights))#[a,b]*[c,d]=[ab,cd]
if prob > 0.5:
return 1.0
else:
return 0.0
'''
函数功能:格式化处理训练集和测试集,并根据训练集得到回归系数向量,然后在测试集上计算分类错误率
输入:无
输出:分类错误率
思想:
'''
def colicTest():
frTrain = open('horseColicTraining.txt')
frTest = open('horseColicTest.txt')
trainingSet = []#存放训练集的特征数据
trainingLabels = []#存放训练集对应的标签数据
#根据原始文本文档得到训练集的特征数据和标签数据
for line in frTrain.readlines():
currLine = line.strip().split('\t')#类型为list,一行为一个list
lineArr = []
for i in range(21):#共21个特征
lineArr.append(float(currLine[i]))
trainingSet.append(lineArr)
trainingLabels.append(float(currLine[21]))
#根据训练集,利用随机梯度上升法得到回归系数,此处迭代500次
trainWeights = stocGradAscent1(array(trainingSet), trainingLabels, 500)
#定义测试中错误样本数和总样本数
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(array(lineArr), trainWeights)) != int(currLine[21]):
errorCount += 1
#计算错误率
errorRate = float(errorCount / numTestVec)
print('the error rate of this test is : ', errorRate)
return errorRate
'''
函数功能:调用colicTest()10次并求结果的平均值
'''
def multiTest():
numTests = 10
errorSum = 0.0
for k in range(numTests):
errorSum += colicTest()
print('after %d iterations the average error rate is :%f'%(numTests, errorSum/float(numTests)))
multiTest()