Logistic回归与多重线性回归类似,区别就在于它们的因变量不同。多重线性回归的因变量连续,而Logistic回归的因变量是离散的,一般为二项分布,即对应二分类问题。

回归问题的常规步骤:

  1. 构造假设函数h
  2. 构造损失函数J
  3. 调整回归参数θ使得损失J最小。

预测函数

常用的Logistic function是Sigmoid函数:

s(x)=11+ex

Sigmoid函数及导函数图像

设数据集的特征维数为n,参数为θ=(θ1,θ2,,θn),则预测函数

hθ(x)=s(θTx)=11+eθTx

表示对于输入x分类结果为类别1和类别0的概率:

{P(y=1x;θ)=hθ(x)P(y=0x;θ)=1hθ(x)

损失函数

似然函数是一种关于统计模型参数的函数。给定输出x时,关于参数θ的似然函数L(θ|x)在数值上等于给定参数θ后变量X的概率:

L(θx)=P(X=xθ)

在Logistic回归中,对于输入x的分类概率P可以表示为

P(yx;θ)=(hθ(x))y(1hθ(x))1y

因此,似然函数:

L(θ)=i=1mP(yxi;θ)=i=1m(hθ(xi))yi(1hθ(xi))1yi

对数似然函数:

l(θ)=logL(θ)=i=1m(yiloghθ(xi))+(1yi)log(1hθ(xi))

最大似然估计是求当l(θ)的值最大时的参数θ的值,取损失函数

J(θ)=1ml(θ)

梯度下降法求解参数

梯度下降法更新θ的过程:

θj=θjαθjJ(θ)=θjα1mi=1m(hθ(xi)yi)xij

对于给定数据集,可以认为是有m条记录,n个特征的m×n维矩阵X,训练数据集的分类结果是一个 长度为m的列向量Y,参数θ是一个长度为n的列向量,将上述过程向量化,可得

θ=θαXT(s(Xθ)Y)

简单实现

m = 400      ## size of train set.
n = 300      ## number of features.
alpha = 0.1  ## learning rate

D = (rng.randn(m, n), rng.randint(size = m, low = 0, high = 2))
training_steps = 1000
x = T.dmatrix('x') ## input
y = T.dvector('y') ## output

## initialize weights
w = shared(rng.randn(n), name='w')

## initialize bias term, used to avoid overfitting.
b = shared(0., name='b')

# Construct Theano expression graph
p = 1 / (1 + T.exp(-T.dot(x, w) - b))        # Probability that target = 1
prediction = p > 0.5                         # The prediction thresholded
## xent = -y * T.log(p) - (1-y) * T.log(1-p)    # Cross-entropy loss function
## cost = xent.mean() ## + 0.01 * (w**2).sum()  # The cost to minimize
cost = T.nnet.binary_crossentropy(p, y).mean()
gw, gb = T.grad(cost, [w, b])                # Compute the gradient of the cost on w and b.

# compile
train = function(
        inputs=[x, y],
        outputs=[prediction, cost],
        updates=[(w, w - alpha * gw), (b, b - alpha * gb)])
predict = function(inputs=[x], outputs=prediction)

# train
for i in range(training_steps):
    pred, err = train(D[0], D[1])

# display arguments result:
# print(w.get_value(), b.get_value())

lables = D[1]            ## original labels.
classify = predict(D[0]) ## classify result using logistic regression.
ks = len([i for i in range(0, m) if D[1][i] != classify[i]])
print("correctness: ", (m-ks)/m)