机器学习实战(一)—— 线性回归


前言

本文是基于《机器学习实战》和吴恩达的ML课程自己的总结,也包括作业代码的重写和注释。


一、线性回归

1.定义

线性回归假设特征和结果满足线性关系。每个特征对结果的影响都可以通过特征前的参数体现,且每个特征变量可以先映射到一个函数,然后再参与线性计算。从而表达特征与结果之间的非线性关系。

如果用 x 1 x_1 x1, x 2 x_2 x2 x n x_n xn描述特征,就可以通过以下函数做出估计:
在这里插入图片描述
这里的θ表示了每个特征的重要性,如果令x0=1就可以用向量来表示此函数:
在这里插入图片描述
为了评估算出来的θ是否合适,我们用损失(错误)函数来描述拟合程度:
线性回归的loss函数

2.θ的计算

梯度下降

为了确定θ的值,用梯度下降来使函数向J(θ)也就是损失函数下降最快的方向走,从而求得全局最小值。哪个点向上,我们就向反方向下坡,所以我们可以更新J(θ):
在这里插入图片描述
梯度下降的方法一般有:

  1. 批量梯度下降:在计算梯度下降的每一步时,都是基于完整的训练集X的。且可以找到全局最小值,只是用的时间比较长。
  2. 随机梯度下降:每一步在训练集中随机选择一个实例,且仅基于该实例来计算梯度,其在达到最小值之后也会不断反弹,此时不断降低学习率从而尽可能接近全局最小值。
  3. 小批量梯度下降:在小批量的随机实例集上计算梯度,在参数空间中更稳定,其在最终比随机梯度下降更接近最小值,但其可能很难摆脱局部最小值。

最小二乘法

也是确定θ的方法之一,将训练特征表示为X矩阵,结果表示为y向量,从而得出θ:
在这里插入图片描述

3.带权重的线性回归

带权重的线性回归加入了权重,此算法是假设离要预测的特征越近影响越大,越远越小,从而可以应用于非参数学习。
在这里插入图片描述
其中 w ( i ) w^{(i)} w(i)符合公式:
在这里插入图片描述

二、逻辑回归

1.定义

一般来说回归不会被用于分类,因为回归是连续型模型,且受噪声影响较大,如果必须使用,可以使用对数回归,即在特征到结果的映射中加入了一层函数映射,先把特征线性求和,然后使用函数g(z)做运维假设函数来预测,g(z)可以将连续值映射到0和1上。

此时的回归方程:
在这里插入图片描述
其中g(z):
在这里插入图片描述
所以就可以实现用回归来进行二值分类,假设二值回归符合伯努利分布,即:

在这里插入图片描述

他的损失函数为:
在这里插入图片描述
其实与线性回归类似,只是将 θ T X ( i ) \theta^TX^{(i)} θTX(i)通过g(z)映射到 h θ ( x ( i ) ) h_\theta\left(x\left(i\right)\right) hθ(x(i))

2.Softmax回归

是将逻辑回归推广到多分类问题,对于一个给定的实例x,Softmax回归首先计算出每个类k的分数 s k ( x ) s_k(x) sk(x),然后将这些分数应用softmax(归一化)函数,从而估算出每个类的概率。

对于某个类k:
s k ( x ) = x T θ ( k ) s_k(x)=x^T\theta^{(k)} sk(x)=xTθ(k)

softmax函数:
p ^ k = e x p ( s k ( x ) ) / ∑ i = 1 k e x p ( s j ( x ) ) {\widehat p}_k=exp(s_k(x))/\sum_{i=1}^kexp(s_j(x)) p k=exp(sk(x))/i=1kexp(sj(x))

交叉熵

用于衡量一组估算出的类概率跟目标类的匹配程度。

下面给出交叉熵:
J ( ⊙ ) = − 1 / m ( ∑ i = 1 m ∑ k = 1 K y k ( i ) l o g ( p ^ k ( i ) ) ) J(\odot)=-1/m(\sum_{i=1}^m\sum_{k=1}^Ky_k^{(i)}l\mathrm{og}(\widehat p_k^{(i)})) J()=1/m(i=1mk=1Kyk(i)log(p k(i)))

也是softmax回归函数的成本函数。

下面给出类k的交叉熵梯度向量:
∇ θ ( k ) J ( ⊙ ) = 1 / m ( ∑ i = 1 m ( p ^ k    ( i ) − y k ( i ) ) x ( i ) ) \nabla_{\theta(k)}J(\odot)=1/m(\sum_{i=1}^m(\widehat p_{k\;}^{(i)}-y_k^{(i)})x^{(i)}) θ(k)J()=1/m(i=1m(p k(i)yk(i))x(i))

三、练习

用softmax进行批量梯度下降,实现提前停止法

1.数据导入

from sklearn import datasets
iris = datasets.load_iris()
list(iris.keys())
#取data的2,3列,即为花瓣的长度和宽度来预测
X = iris["data"][:,(2,3)]
y = iris["target"]
#np.c_列结合,所有的x0=1
import numpy as np
X_with_bias = np.c_[np.ones([len(X),1]),X]
#打乱output方便复用
np.random.seed(2042)
#分成训练集、验证集、测试集
test_ratio = 0.2
validation_ratio = 0.2
total_size = len(X_with_bias)

test_size = int(total_size*test_ratio)
validation_size = int(total_size*validation_ratio)
train_size = total_size-test_size-validation_size

rnd_indices = np.random.permutation(total_size)#np.random.permutation()为0-total_size之间的序列进行随机排序

X_train = X_with_bias[rnd_indices[:train_size]]
y_train = y[rnd_indices[:train_size]]
X_valid = X_with_bias[rnd_indices[train_size:-test_size]]
y_valid = y[rnd_indices[train_size:-test_size]]
X_test = X_with_bias[rnd_indices[-test_size:]]
y_test = y[rnd_indices[-test_size:]]
#onehot编码,为了方便训练softmax回归模型
def to_one_hot(y):
  n_classes = y.max() + 1
  m = len(y)
  Y_one_hot = np.zeros((m, n_classes))
  Y_one_hot[np.arange(m),y] = 1
  return Y_one_hot
Y_train_one_hot = to_one_hot(y_train)
Y_valid_one_hot = to_one_hot(y_valid)
Y_test_one_hot = to_one_hot(y_test)

2.定义softmax函数

def softmax(logits):
  exps = np.exp(logits)
  exp_sum = np.sum(exps, axis=1, keepdims=True)
  return exps/exp_sum

3.定义输入输出

#定义输入输出数量
n_inputs = X_train.shape[1] #两个特征及偏置项
n_outputs = len(np.unique(y_train)) #对应3种分类

4.训练模型

#训练softmax回归模型,加入l2正则化和停止标志
eta = 0.1
n_iterations = 5001
m = len(X_train)
epsilon = 1e-7
alpha = 0.1 #正则化超参数
best_loss = np.infty

Theta = np.random.randn(n_inputs, n_outputs)

for iteration in range(n_iterations):
  logits = X_train.dot(Theta)
  Y_proba = softmax(logits)
  xentropy_loss = -np.mean(np.sum(Y_train_one_hot * np.log(Y_proba+epsilon), axis=1))
  l2_loss = 1/2 * np.sum(np.square(Theta[1:]))
  loss = xentropy_loss + alpha * l2_loss
  error = Y_proba - Y_train_one_hot
  gradients = 1/m * X_train.T.dot(error) + np.r_[np.zeros([1, n_outputs]), alpha*Theta[1:]]
  Theta = Theta - eta*gradients

  logits = X_valid.dot(Theta)
  Y_proba = softmax(logits)
  xentropy_loss = -np.mean(np.sum(Y_valid_one_hot * np.log(Y_proba+epsilon), axis=1))
  l2_loss = 1/2 * np.sum(np.square(Theta[1:]))
  loss = xentropy_loss + alpha * l2_loss
  if iteration%500 == 0:
    print(iteration, loss)
  if loss < best_loss:
    best_loss = loss
  else:
    print(iteration-1, best_loss)
    print(iteration, loss, "early stopping")
    break

在这里插入图片描述

5.验证结果

#验证
logits = X_valid.dot(Theta)
Y_proba = softmax(logits)
y_predict = np.argmax(Y_proba, axis=1)

accuracy_score = np.mean(y_predict == y_valid)
accuracy_score

等于1.0

#最后验证在测试集上效果
logits = X_test.dot(Theta)
Y_proba = softmax(logits)
y_predict = np.argmax(Y_proba, axis=1)

accuracy_score = np.mean(y_predict == y_test)
accuracy_score

约等于0.93

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值