准备数据:处理数据中的缺失值
当数据丢失时,给出了一些方法来解决这个问题。
1、使用可用特征的均值来填补缺失值;
2、使用特殊值来填补缺失值,如-1;
3、忽略有缺失值的样本;
4、使用相似样本的均值填补缺失值;
5、使用另外的机器学习算法预测缺失值。
在预处理阶段做两件事:
第一,所有的缺失值必须用一个实数值来替代,因为我们使用Numpy数据类型不允许包含缺失值。这里选择实数0来替换所有缺失值,恰好能适用于Logistic回归,它在更新时不会影响系数的值。
回归系数的更新公式为:weights = weights + alpha * error * dataMatrix[randIndex]
如果dataMatrix的某特征值对应值为0,那么:weights = weights
第二,如果在测试数据集中发现了一条数据的类别标签已经缺失,那么我们的简单做法是将该条数据丢弃。这是因为类别标签与特征不同,很难确定采用某个合适的值来替换。
测试算法:用Logistic回归进行分类
使用Logistic回归方法进行分类所需要做的只是把测试集上每个特征向量乘以最优化方法得来的回归系数,再将该乘积结果求和,最后输入到Sigmoid函数中即可。如果对应的Sigmoid值大于0.5就预测类别标签为1,否则为0。
Logistic回归分类函数
Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
str.strip([chars]);chars – 移除字符串头尾指定的字符序列。
返回移除字符串头尾指定的字符生成的新字符串。
str = "00000003210Runoob01230000000";
print str.strip( '0' ); # 去除首尾字符 0
str2 = " Runoob "; # 去除首尾空格
print str2.strip();
以上实例输出结果如下:
3210Runoob0123
Runoob
Python split() 通过指定分隔符对字符串进行切片,如果参数 num 有指定值,则仅分隔 num 个子字符串
str.split(str=”“, num=string.count(str)).
str – 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
num – 分割次数。
返回分割后的字符串列表。
str = "Line1-abcdef \nLine2-abc \nLine4-abcd";
print str.split( );
print str.split(' ', 1 );
以上实例输出结果如下:
['Line1-abcdef', 'Line2-abc', 'Line4-abcd']
['Line1-abcdef', '\nLine2-abc \nLine4-abcd']
def classifyVector(inX, weights):#预测输入样本的分类
prob = sigmoid(sum(inX*weights))
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')#以制表符对文本进行分切
lineArr = []
for i in range(21):#数据集中总共有21个特征
lineArr.append(float(currLine[i]))
trainingSet.append(lineArr)
trainingLabels.append(float(currLine[21]))
trainWeights = stocGradAscent1(array(trainingSet), trainingLabels)#计算最优化方法得来的回归系数
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: %f" % errorRate)
return errorRate
def multiTest():#调用10次colicTest并求结果的平均值
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)))
>>> import logRegres
>>> from imp import reload
>>> reload(logRegres)
<module 'logRegres' from 'E:\\Python\\logRegres.py'>
>>> logRegres.multiTest()
Warning (from warnings module):
File "E:\Python\logRegres.py", line 14
return 1.0/(1+exp(-inX))
RuntimeWarning: overflow encountered in exp
the error rate of this test is: 0.402985
the error rate of this test is: 0.328358
the error rate of this test is: 0.388060
the error rate of this test is: 0.373134
the error rate of this test is: 0.358209
the error rate of this test is: 0.402985
the error rate of this test is: 0.343284
the error rate of this test is: 0.417910
the error rate of this test is: 0.402985
the error rate of this test is: 0.492537
after 10 iterations the average error rate is: 0.391045
随机梯度上升算法与梯度上升算法的效果相当,但占用更少的计算资源。随机梯度上升算法是一个在线算法,它可以在新数据到来时就完成参数更新,而不需要重新读取整个数据集来进行批处理运算。