# 用于回归的线性回归模型
# 线性回归参数
机器学习中的线性回归模型属于监督学习。直白点说,线性回归就是在图像上给你一堆点,你来找一条线,然后让这条线尽可能的在所有点的中间。这个找直线的过程,就是在做回归了。
假设我们只有一个输入量 ,想要预测输出量 ,线性回归模型就给要找到他俩之间的线性映射关系:
其中 表示 的预测值。 就是我们的回归参数。
# 损失函数
损失函数就是用来衡量模型预言与真实值之间的差。对于连续变量回归问题,最常用的损失函数就是 MSE (Mean squared error) 函数:
其中 是训练样本的数量。但这样往往随着训练样本样本数的增大,损失函数的值也不可避免地增大,所以我们也可以用这样的损失函数:
根据不同的实际问题,你也可以采取不同的损失函数。但对于大多数的回归问题来说,这个平方差的损失函数是十分实用的。
# 最优化
损失函数 是回归参数 的函数。其实线性回归的过程就是找出使得损失函数值最小的 参数,本质上就是一个最优化 (optimization) 过程。最常用的优化方法就是梯度下降,就是沿梯度的方向行走求解极小值。关于梯度下降,我们将会在下一节讲述。当然,对线性回归这种简单的问题,很多时候最优解可以解析写出,就不需要什么梯度下降了。
# 用于分类的线性回归模型
# Logistic 函数
线性回归模型同样可以玩转分类问题。为了方便讨论,我们先从二分类问题开始。线性回归的预测结果 是一个实数,而如果要处理二分类问题,我们希望 。那么我们就需要找出一个函数 使得 。这种函数称为 Logistic 函数。最理想的就是单位阶跃函数:
然而单位阶跃函数却不连续,我们希望找到一个单调可微的函数,因此我们选择了对数几率函数:
当某样本 的预测值 使得 时,即预测为 “正类”;反之则为 “负类”。这样就实现了样本的分类!其中决定了样本被划分的边界 ,被称为决策边界。
# 损失函数
上面的说法或许令你产生误解,你或许会认为先进行线性回归产生 ,然后再代入 式实现分类。其实不是这样,我们是直接用 进行回归训练的。我们可以这样想:假若我们的训练效果非常好,这意味着 “正类” 样本的 ,从而使得 十分趋于 ;而 “负类” 样本的 ,从而使得 十分趋于 。那么我们便可以这样定义一个损失函数:
其中 为类别参数,当 是 “正类” 时,;当 是 “正类” 时,。 为样本数。按照上面的想法去判断模型的好坏,这就意味着这个损失函数越大越好,即越趋近 越好。这又变为了最优化的问题了。
# 推广到多分类问题
灵魂拷问:二分类解决了,多分类怎么办?最简单的方法就是将其拆分成多个二分类的问题。
# 案例
MNIST 数据集共有 70000 张图像,其中训练集 60000 张,测试集 10000 张。所有图像都是 28×28 的灰度图像,每张图像包含一个手写数字。我们使用线性回归模型来将数字进行分类。先做一个最简单的,我们将 和其他的数字区分开来,然后看看正确率:
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 |
再直接将 十个数字进行分类,再看看正确率:
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 |