学会了简单的logistic的回归后,一定会发现这个函数无法适用于大规模数据,因为数据量太大的时候,计算量的规模是几何式增长的。接下来我们讨论下如何优化logistic回归,现在我们来写个简单的优化函数:
def stocGradAscent0(dataMatrix, classLabels):
m,n = shape(dataMatrix)
alpha = 0.01
weights = ones(n) #initialize to all ones
for i in range(m):
h = sigmoid(sum(dataMatrix[i]*weights))
error = classLabels[i] - h
weights = weights + alpha * error * dataMatrix[i]
return weights
当然这个函数依然非常简单,感觉是否没有什么变化,相对于前面的梯度优化,但是仔细观察发现这个随机梯度优化使用的是简单的单个值,而非矩阵,这样计算量就减少为原来的1/n,嘿嘿。当然天下没有免费的午餐,这种优化的后果当然是精度损失了。不过这种损失在数据量比较大的时候还是可以原谅的。
下面来一种精度和效率兼顾的方式,这种方法比前面的一种稍显复杂了一点。我们来看代码吧。
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
呵呵,这样我们的logistic回归的大多数方法就都实现了。当然还少了测试部分的代码:
def classifyVector(inX, weights):
prob = sigmoid(sum(inX*weights))
if prob > 0.5: return 1.0
else: return 0.0
这样所有的代码就都有了,然后我们就可以使用这些东西来做点事情了。好了logistic回归我也刚刚理解了,至于高深的优化目标函数,这里就先不拿出来了,因为我也没看懂,O(∩_∩)O哈哈~