# 用于回归的线性回归模型

# 线性回归参数

\quad 机器学习中的线性回归模型属于监督学习。直白点说,线性回归就是在图像上给你一堆点,你来找一条线,然后让这条线尽可能的在所有点的中间。这个找直线的过程,就是在做回归了。
\quad 假设我们只有一个输入量 xx,想要预测输出量 yy,线性回归模型就给要找到他俩之间的线性映射关系:

y^=f(x)=wx+b(1)\hat{y} = f(x) = wx+b \tag{1}

其中 y^\hat{y} 表示 yy 的预测值。w,bw,b 就是我们的回归参数

# 损失函数

\quad 损失函数就是用来衡量模型预言与真实值之间的差。对于连续变量回归问题,最常用的损失函数就是 MSE (Mean squared error) 函数:

L(w,b)i=1m(y^(i)y(i))2(2)L(w,b) \equiv \sum_{i=1}^m (\hat{y}^{(i)}-y^{(i)})^2 \tag{2}

其中 mm 是训练样本的数量。但这样往往随着训练样本样本数的增大,损失函数的值也不可避免地增大,所以我们也可以用这样的损失函数:

L(w,b)1mi=1m(y^(i)y(i))2(3)L(w,b) \equiv \frac{1}{m}\sum_{i=1}^m (\hat{y}^{(i)}-y^{(i)})^2 \tag{3}

根据不同的实际问题,你也可以采取不同的损失函数。但对于大多数的回归问题来说,这个平方差的损失函数是十分实用的。

# 最优化

\quad 损失函数 L(w,b)L(w,b) 是回归参数 w,bw,b 的函数。其实线性回归的过程就是找出使得损失函数值最小的 w,bw,b 参数,本质上就是一个最优化 (optimization) 过程。最常用的优化方法就是梯度下降,就是沿梯度的方向行走求解极小值。关于梯度下降,我们将会在下一节讲述。当然,对线性回归这种简单的问题,很多时候最优解可以解析写出,就不需要什么梯度下降了。

# 用于分类的线性回归模型

# Logistic 函数

\quad 线性回归模型同样可以玩转分类问题。为了方便讨论,我们先从二分类问题开始。线性回归的预测结果 y^\hat{y} 是一个实数,而如果要处理二分类问题,我们希望 y^(0,1)\hat{y}\in(0,1)。那么我们就需要找出一个函数 ff 使得 f(y^)(0,1)f(\hat{y})\in(0,1)。这种函数称为 Logistic 函数。最理想的就是单位阶跃函数:

f(y^)={1,y^>00.5,y^=00,y^<0(4)f(\hat{y}) = \begin{cases} 1,\quad& \hat{y}>0 \\ 0.5,\quad& \hat{y}=0 \\ 0,\quad& \hat{y}<0 \end{cases} \tag{4}

然而单位阶跃函数却不连续,我们希望找到一个单调可微的函数,因此我们选择了对数几率函数:

f(y^)=11+ey^=11+e(wx+b)(5)f(\hat{y}) = \frac{1}{1+e^{-\hat{y}}} = \frac{1}{1+e^{-(wx+b)}} \tag{5}

当某样本 xx 的预测值 y^\hat{y} 使得 f(y^)>0.5f(\hat{y})>0.5 时,即预测为 “正类”;反之则为 “负类”。这样就实现了样本的分类!其中决定了样本被划分的边界 f(y^)=0.5f(\hat{y})=0.5,被称为决策边界

# 损失函数

\quad 上面的说法或许令你产生误解,你或许会认为先进行线性回归产生 y^=wx+b\hat{y}=wx+b,然后再代入 (5)(5) 式实现分类。其实不是这样,我们是直接用 (5)(5) 进行回归训练的。我们可以这样想:假若我们的训练效果非常好,这意味着 “正类” 样本的 y^0\hat{y}\gg 0,从而使得 f(y^)f(\hat{y}) 十分趋于 11;而 “负类” 样本的 y^0\hat{y}\ll 0,从而使得 f(y^)f(\hat{y}) 十分趋于 00。那么我们便可以这样定义一个损失函数:

L(x,z)=i=1m[f(y^(i))]z[1f(y^(i))]1z(6)L(x,z) = \prod_{i=1}^m \left[f(\hat{y}^{(i)})\right]^z \left[1-f(\hat{y}^{(i)})\right]^{1-z} \tag{6}

其中 zz 为类别参数,当 x(i)x^{(i)} 是 “正类” 时,z=1z=1;当 x(i)x^{(i)} 是 “正类” 时,z=0z=0mm 为样本数。按照上面的想法去判断模型的好坏,这就意味着这个损失函数越大越好,即越趋近 11 越好。这又变为了最优化的问题了。

# 推广到多分类问题

\quad 灵魂拷问:二分类解决了,多分类怎么办?最简单的方法就是将其拆分成多个二分类的问题。

# 案例

\quad MNIST 数据集共有 70000 张图像,其中训练集 60000 张,测试集 10000 张。所有图像都是 28×28 的灰度图像,每张图像包含一个手写数字。我们使用线性回归模型来将数字进行分类。先做一个最简单的,我们将 55 和其他的数字区分开来,然后看看正确率:

n
import numpy as np
from sklearn.datasets import fetch_openml
from sklearn import datasets
# 导入 mnist 数据集
mnist = fetch_openml('mnist_784', data_home = 'C:/Users/130/Desktop') #data_home 为数据的路径
X, y = mnist['data'].values, mnist['target'].values
# 70000 个手写图片数据分为训练集和测试集
X_train, X_test, y_train, y_test = X[:60000],X[60000:],y[:60000],y[60000:]
# 进行排序打乱
shuffle_index = np.random.permutation(60000)
X_train, y_train = X_train[shuffle_index],y_train[shuffle_index]
# 这是一个逻辑数组,5:True, 非 5:False
y_train_5 = (y_train == '5')
y_test_5 = (y_test == '5')
from sklearn.linear_model import LogisticRegression #导入逻辑回归模型
clf = LogisticRegression()
clf.fit(X_train, y_train_5) #进行训练
# 看看准确率
from sklearn import metrics
print('Accuracy on the train sample: ', metrics.accuracy_score( clf.predict(X_train), y_train_5))
print('Accuracy on the test  sample: ', metrics.accuracy_score( clf.predict(X_test), y_test_5))
---------------------------------------------------
结果为:
Accuracy on the train sample:  0.9778166666666667
Accuracy on the test  sample:  0.9779

再直接将 0,1,,90,1,\cdot,9 十个数字进行分类,再看看正确率:

n
clf.fit(X_train, y_train)
print('Accuracy on the train sample: ', metrics.accuracy_score( clf.predict(X_train), y_train))
print('Accuracy on the test  sample: ', metrics.accuracy_score( clf.predict(X_test), y_test))
---------------------------------------------------
结果为:
Accuracy on the train sample:  0.9339166666666666
Accuracy on the test  sample:  0.9255