logistic回归是一种广义线性回归(generalized linear model),因此与多重线性回归分析有很多相同之处。它们的模型形式基本上相同,都具有 w‘x+b,其中w和b是待求参数,其区别在于他们的因变量不同,多重线性回归直接将w‘x+b作为因变量,即y =w‘x+b,而logistic回归则通过函数L将w‘x+b对应一个隐状态p,p =L(w‘x+b),然后根据p 与1-p的大小决定因变量的值。如果L是logistic函数,就是logistic回归,如果L是多项式函数就是多项式回归。 --摘自百度百科
简单说logistic回归分类就是把 训练数据 输入到 函数( Sigmoid函数 )中,然后由函数返回的数值进行分类.Logistic回归分类可以进行二分类和多分类,但多用于二分类问题.
Sigmoid函数
Sigmoid函数就是Logistic回归分类中用来计算 分类值 的函数.
Sigmoid函数公式:
Sigmoid函数图像:
Logistic中我们需要的是称为 海維塞德阶跃函数(或称 单位阶跃函数) 的函数,该函数具有接受所有输出然后预测出类别(如两个类别输出0或1);但这个函数在阶跃点上从0直接跳跃到1,而这个跳跃过程有时很难处理.
而Sigmoid函数也具有 这个性质 也更易处理,另外从图中也能看出Sigmoid函数的分布也十分均匀.
例:红绿点分类
Logistic回归梯度上升算法分类
梯度上升的基本思想是找到某个函数的最大值.而最好的方法就是沿着该函数的梯度方向进行查找.
先加载有各点位置和分类信息的数据
def LoadData():
data = []
label = []
f = open('testSet.txt')
for i in f.readlines():
s = i.strip().split()
data.append([1.0,float(s[0]),float(s[1])])
label.append(int(s[2]))
return data,label
然后通过Sigmoid函数进行分类并训练
#计算分类用于下面训练
def Sigmoid(x):
return 1/(1+exp(-x))
#训练
def Logistic(data,label):
#转为矩阵用于下面计算
dataM = mat(data)
labelM = mat(label).transpose()
go = 0.001 #移动步长,使训练趋近最佳结果
x,y = shape(dataM)
cycle = 500 #训练次数
weight = ones((y,1))
for i in range(cycle):
h = Sigmoid(dataM*weight) #计算分类
error = (labelM - h) #获得计算的分类和数据集标记的差值
weight = weight + go*dataM.transpose()*error #矫正
return weight
最后使用一个函数画出决策边界看下训练结果
def plotBestFit(weights,dataMat,labelMat):
#绘制红绿点
dataArr = array(dataMat)
n = shape(dataArr)[0]
xcord1 = []; ycord1 = []
xcord2 = []; ycord2 = []
for i in range(n):
if int(labelMat[i])== 1:
xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])
else:
xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
ax.scatter(xcord2, ycord2, s=30, c='green')
#绘制边界
x = arange(-3.0, 3.0, 0.1)
y = (-weights[0]-weights[1]*x)/weights[2]
ax.plot(x, y)
plt.xlabel('X1'); plt.ylabel('X2');
plt.show()
x,y = LoadData()
weight = Logistic(x,y)
plotBestFit(weight.getA())
从途中可以看到有五个红点划分错了,划分结果还是不错的.
但是这各方法需要的计算量比较大,每次dataM*weight有300乘法运算.
Logistic回归随机梯度上升算法分类
只用把梯度上升稍微改下就行了:
def Logistic0(data,label):
m,n = shape(data)
go = 0.01
weight = ones(n)
for i in range(m):
h = Sigmoid(sum(data[i]*weight))
error = label[i] - h
weight = weight + go*error*data[i]
return weight