基本思想
回归:
假设有一些数据点,我们用一条直线对这些数据点进行拟合(该线成为最佳拟合直线),这个拟合过程就称为回归。
Logistic回归主要思想:
根据现有数据对分类边界线建立回归公式,以此进行分类,使用最优化算法寻找最佳拟合参数。
Logistic回归优缺点
优点:计算代价不高,易于理解和实现
缺点:容易欠拟合,分类精度可能不高
使用数据类型:数值型和标称型
Sigmoid函数
为了对数据进行预测分类,我们想要的函数应该是,能够接受所有的输入,然后预测出分类结果。我们可以使用一些函数对最终的结果进行处理,如Sigmoid函数:
σ(z)=11+e−z
当x=0 时,Sigmoid函数值为0.5,随着x值增大,对应的函数值逼近1,随着x值减小,对应的Sigmoid值逼近于0.
即将样本的每个特征值都乘以回归系数,然后把所有的结果值相加,将这个总和带入Sigmoid函数中,进而得到一个0~1之间的数值,如果数值大于0.5则归为1类,否则归为0类。
Logistic拟合曲线
z=w0x0+w1x1+...+wnXn
or
z=WtX
W为拟合参数, X为特征向量
梯度上升
梯度上升是一种优化算法。其基本思想是沿着函数梯度上升的方向去寻找函数最大值。(梯度下降法同理).梯度记为 ∇,则函数f(x,y)的梯度表示为:
∇f(x,y)=⎛⎝⎜⎜⎜∂f(x,y)∂x∂f(x,y)∂y⎞⎠⎟⎟⎟
梯度即为移动方向,乘以移动步长就可以更新回归系数:
w:=w+α∇wf(w)
python代码实现
def sigmoid(inX):
return 1.0 / (1 + exp(-inX))
#梯度上升算法
def gradAscent(dataMatIn, classLabels):
dataMatrix = mat(dataMatIn) # convert to NumPy matrix
labelMat = mat(classLabels).transpose() # convert to NumPy matrix
m, n = shape(dataMatrix)
alpha = 0.001
maxCycles = 500
weights = ones((n, 1))
for k in range(maxCycles): # heavy on matrix operations
h = sigmoid(dataMatrix * weights) # matrix mult
error = (labelMat - h) # vector subtraction
weights = weights + alpha * dataMatrix.transpose() * error # matrix mult
return weights
#改进后的随机梯度上升算法
def stocGradAscent1(dataMatrix, classLabels, numIter=150):
m, n = shape(dataMatrix)
weights = ones(n) # initialize to all ones
for j in range(numIter):
dataIndex = range(m)
for i in range(m):
alpha = 4 / (1.0 + j + i) + 0.0001 # apha decreases with iteration, does not
randIndex = int(random.uniform(0, len(dataIndex))) # go to 0 because of the constant
h = sigmoid(sum(dataMatrix[randIndex] * weights))
error = classLabels[randIndex] - h
weights = weights + alpha * error * dataMatrix[randIndex]
del (dataIndex[randIndex])
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('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, 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(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))
解释:由于原始梯度梯度上升算法,没更新一次回归系数都要遍历整个数据集,计算复杂度太高,所以对其进行了改进。改进之后的算法成为随机梯度上升算法,它一次仅用一个样本点来更新回归系数。即可以在新样本到来时对数据进行增量式更新,所以该算法是一个在线学习算法。
除此之外,随机梯度上升又进行了两点改进:
1,每次迭代都会调整α 的值,以此来缓解数据波动和高频波动。
2,通过随机选取样本来更新回归系数,以此来减少周期性波动