概念
- 最优化算法
- 回归:用一条直线对点(多个数据)进行拟合,(该线条称为最佳拟合直线)这个拟合过程就称作回归
- 主要思想:根据现有数据对分类边界线建立回归公式,以此进行分类
- 过程:
收集数据
准备数据,数值型,结构化数据格式最佳
分析数据
训练算法,大部分时间用于训练,目的是为了找到最佳回归系数。
测试算法
使用算法,首先输入一些数据,转换成对应的结构化数值,接着基于训练好的回归系数,就可以对这些数值进行简单的回归计算,判断它们属于哪个类别,在这之后,我们就可以在输出的类别上做一些其他分析工作。
优点,代价不高,易于理解和实现,缺点:容易欠拟合,分类精度可能不高,数值型和标称型。
- sigmoid函数
- 基于最优化方法的最佳回归系数确定
sigmoid的输入记为z:
x是分类器的输入数据,向量W也就算最佳参数(系数) - 梯度上升法
思想:要找到某函数的最大值,最好的方法是沿着该函数的梯度方向探寻。
梯度公式:
必须在待计算的点上有定义并且可微;
梯度上升算法的迭代公式:
梯度下降算法的迭代公式:
上升算法求函数的最大值,下降算法求函数的最小值。
例子: 使用梯度上升找到最佳参数。
给定100个样本点,每个点两个数值型特征:伪代码如下:
每个回归系数初始化为1:
重复R次:
计算整个数据集的梯度,
使用alpha*gradient更新回归系数的向量
返回回归系数
def gradAscent(dataMatIn, classLabels):
"""
返回一个最佳权值
:param dataMatIn:
:param classLabels:
:return:
"""
dataMatrix = mat(dataMatIn)
labelMat = mat(classLabels).transpose()
m, n = shape(dataMatrix)
alpha = 0.001
maxCycles = 500
weights = ones((n, 1))
for k in range(maxCycles):
h = sigmoid(dataMatrix * weights)
error = (labelMat - h)
weights = weights + alpha * dataMatrix.transpose() * error
return weights
其分类效果:
改进1:使用随机梯度上升
一次仅用一个样本点来更新回归系数
伪代码:
所有回归系数初始化为1.
对数据集中每个样本。
计算该样本的梯度
使用alpha*gradient更新回归系数值
返回回归系数值。
随机梯度上升比梯度上升算法要省一些时间,但是结果比较粗糙,分类不是最佳状态。
def stocGradAscent0(dataMatrix, classLabels):
m, n = shape(dataMatrix)
alpha = 0.01
weights = ones(n)
for i in range(m):
h = sigmoid(sum(dataMatrix[i] * weights))
error = classLabels[i] - h
weights = weights + alpha * error * dataMatrix[i]
return weights
分类效果:
改进2:使用改进的随机梯度上升算法
def stocGradAscent1(dataMatrix, classLabels, numIter=150):
m, n = shape(dataMatrix)
weights = ones(n)
for j in range(numIter):
dataIndex = list(range(m))
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
分类效果:
使用样本随机选择和alpha动态减少机制的随机梯度上升算法,比采用固定alpha的方法收敛速度更快。
示例:从疝气病症预测病马的死亡率
步骤:
1. 收集数据
2. 准备数据,用python解析文本文件并填充缺失值
3. 分析数据:可视化并观察数据
4. 训练算法:使用优化算法,找到最佳的系数
5. 测试算法:为了量化回归的效果,需要观察错误率,根据错误率决定是否回退到训练阶段,通过改变迭代次数和步长等参数来得到更好的回归系数
6. 使用算法
def classifyVector(inX, weights):
"""
计算出sigmod函数结果,大于0.5返回1,否则返回0
:param inX:特征向量
:param weights:权重向量
:return: 返回分类结果
"""
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):
lineArr.append(float(currLine[i]))
trainingSet.append(lineArr)
trainingLabels.append(float(currLine[21]))
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: %f" % errorRate)
return errorRate
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()
测试结果:
the error rate of this test is: 0.402985
the error rate of this test is: 0.313433
the error rate of this test is: 0.298507
the error rate of this test is: 0.343284
the error rate of this test is: 0.313433
the error rate of this test is: 0.388060
the error rate of this test is: 0.388060
the error rate of this test is: 0.283582
the error rate of this test is: 0.358209
the error rate of this test is: 0.432836
after 10 iterations the average error rate is : 0.352239
平均错误率是 0.352239
详细代码参考项目:github机器学习实战第五章