相关概念
监督学习:
监督学习是机器学习的一种方法,它利用一组已知类别的样本调整分类器的参数,使其达到所要求性能的过程。在监督学习中,每个实例都是由一个输入对象(通常为矢量)和一个期望的输出值(也称为监督信号)组成。 监督机器学习问题主要有两种,分别叫作分类(classification)与回归(regression)。分类问题的目标时预测类别标签,分类问题可分为二分类(binary classification)和多分类(multiclass classification)。
输入变量与输出变量均为连续的变量的预测问题称为回归问题,输出变量为有限个离散变量的预测问题称为分类问题, 监督算法常见的有:线性回归,神经网络,决策树,支持向量机,KNN等。
样本与特征
在机器学习中,每个实体或者每一行被称为一个样本或数据点,每一列则被称为特征。如何构建良好的数据表征则被称为特征提取或特征工程。
Train、Validation、Test
在机器学习和深度学习中,我们通常将数据集分为三部分:训练集(Train)、验证集(Validation)和测试集(Test)。这三部分在模型的训练和评估过程中扮演着不同的角色。
- 训练集(Train):用于训练模型。我们使用训练集来训练我们的模型,调整其参数,以便在给定输入时能够产生所需的输出。训练集通常占总数据集的绝大部分。
- 验证集(Validation):用于验证模型。验证集用于评估模型的性能,以及检查模型在未见过的数据上的表现。我们通常会使用验证集来调整模型的参数(例如,学习率、批次大小等),以便在训练过程中达到最好的性能。验证集通常占总数据集的一小部分。
- 测试集(Test):用于最终评估模型。测试集是在模型开发过程中未使用过的数据,因此,这是我们在实际应用中将要使用的数据。我们使用测试集来最终评估模型的性能,以及确定模型在新数据上的泛化能力。测试集通常占总数据集的一小部分,但也可能占很大比例。 这种划分数据集的方式是为了确保我们能够准确地评估模型的性能,并在训练过程中避免过拟合和欠拟合等常见问题。一般来说,为了有效地利用资源,我们可能首先使用训练集进行训练,然后使用验证集进行参数调整,最后使用测试集进行最终评估。
泛化、过拟合、欠拟合:
- 泛化(generalize)是指模型在训练数据和未知数据上的表现能力。一个好的泛化能力意味着模型可以对新数据做出准确的预测或分类。
- 过拟合(Overfitting)是指模型在训练数据上表现得过于优秀,但在未见过的数据上表现较差。这就像一个学生死记硬背了一本题库的所有答案,但当遇到新的题目时无法正确回答。
- 欠拟合(Underfitting)是指模型无法很好地拟合训练数据,无法捕捉到数据中的真实模式和关系。这就像一个学生连基本的知识都没有掌握好,无论是老题还是新题都无法解答。
| 过拟合 | 欠拟合 |
|---|---|
| 训练数据占总数据过少 | 训练数据占总数据过多 |
| 模型过于复杂 | 模型过于简单 |
| 采样过于不均衡 | 采样过于简单 |
| 没有正则化 | |
| 异常值没有处理 | 数据过于集中 |
模型越复杂,在训练数据上的预测结果就越好。但是,模型过于复杂,就开始过多关注训练集中每个单独的数据点,模型就不能很好地泛化到新数据上。二者之间存在一个最佳位置,可以得到最好的泛化性能。这就是我们想要的模型。
用于回归的线性模型
线性模型是在实践中广泛使用的一类模型,利用输入特征的线性函数(linear function)进行预测。 对于回归问题,线性模型预测的一般公式如下:
这里x[0]到x[p]表示单个数据点的特征,w和b是学习模型的参数, 是模型的预测结果。用于回归的线性模型可以表示为这样的回归模型:对单一特征的预测结果是一条直线,两个特征时是一个平面,或者在更高维度(即更多特征)时是一个超平面。
线性回归(普通最小二乘法)
线性回归寻找参数w和b,使得对训练集的预测值与真实的回归目标值y之间的均方误差最小。均方误差(mean squared error)是预测值与真实值之差的平方和除以样本数。
以mglearn的数据集中的波士顿房价为例,我们看一下线性回归模型:
def lineRegression():
X, y = mglearn.datasets.load_extended_boston()
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
lr = LinearRegression().fit(X_train, y_train)
print("lineRegression training score:{:.2f}".format(lr.score(X_train, y_train)))
print("lineRegression test score:{:.2f}".format(lr.score(X_test, y_test)))
lineRegression training score:0.95 lineRegression test score:0.61
从运行结果来看,训练集和测试集之间存在过拟合,因此应该试图找到一个可以控制复杂度的模型。
正则化
在机器学习中,正则化通常被用于防止模型过度拟合训练数据。具体来说,正则化可以通过增加一个额外的成本函数(称为正则化项)到原有的模型损失函数中来实现。这个正则化项通常反映了模型的复杂性,如果模型的复杂性越高(例如,拥有更多的参数或更复杂的结构),则正则化项的值会越大。因此,正则化能够促使模型在拟合训练数据的同时,也尽可能地保持简单,从而避免过度拟合。常用的正则化方法包括L1正则化(也称为Lasso回归)和L2正则化(也称为Ridge回归)。
岭回归
L2正则化,也被称为岭回归或Ridge回归,通过对模型参数的平方进行约束,以防止过拟合。L2正则化不会像L1正则化那样产生稀疏模型,因为它的约束项不会使任何参数变为零。L2正则化在处理特征之间存在多重共线性的情况时特别有用,因为它可以使得所有特征的系数都缩小,但不会缩小到零。标准线性回归最常用的替代方法之一就是岭回归(ridge regression),下面来看一下。
def ridgeRegression():
X, y = mglearn.datasets.load_extended_boston()
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
# alpha参数不同,训练的效果与测试效果也不同,当alpha=0时,效果与线性回归一样
ridge = Ridge(alpha=1).fit(X_train, y_train)
print("ridgeRegression training score:{:.2f}".format(ridge.score(X_train, y_train)))
print("ridgeRegression test score:{:.2f}".format(ridge.score(X_test, y_test)))
ridgeRegression training score:0.89 ridgeRegression test score:0.75
从运行结果可以看出,Ridge在训练集上的分数要低于LinearRegression,但在测试集上的分数更高。 此外,无论是岭回归还是线性回归,所有数据集大小对应的训练分数都要高于测试分数。由于岭回归是正则化的,因此它的训练分数要整体低于线性回归的训练分数。但岭回归的测试分数要更高,特别是对较小的子数据集。随着模型可用的数据越来越多,两个模型的性能都可以得到一定的提升,线性回归的性能也会慢慢追上岭回归。因此,如果有足够多的训练数据,正则化变得不那么重要,并且岭回归和线性回归将具有相同的性能。
Lasso回归
L1正则化是一种线性回归的优化算法,通过对模型参数的绝对值进行约束,以实现稀疏模型,即模型中的很多参数为零,达到特征选择的目的。由于其稀疏性,L1正则化在处理高维数据时特别有用,因为它可以自动确定哪些特征对模型是重要的,哪些是冗余的。 以mglearn的数据集中的波士顿房价为例,我们看一下Lasso回归模型:
def lassoRegression():
X, y = mglearn.datasets.load_extended_boston()
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
# alpha默认值为1.0, max_iter=1000
lasso = Lasso().fit(X_train, y_train)
print("lassoRegression training score:{:.2f}".format(lasso.score(X_train, y_train)))
print("lassoRegression test score:{:.2f}".format(lasso.score(X_test, y_test)))
print("Number of features used:{}".format(np.sum(lasso.coef_ != 0)))
lassoRegression training score:0.29 lassoRegression test score:0.21 Number of features used:4 从运行结果可以看出,Lasso在训练集与测试集上的表现都很差。这表示存在欠拟合,我们发现模型只用到了105个特征中的4个。与Ridge类似,Lasso也有一个正则化参数alpha,可以控制系数趋向于0的强度。此次我们用的是默认值alpha=1.0。为了降低欠拟合,我们尝试减小alpha,这么做的同时我们增加迭代次数看一下效果:
def lassoRegressionUseSmallerAlpha():
X, y = mglearn.datasets.load_extended_boston()
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
# 调整alpha使其变小,以便拟合一个更复杂的模型,使其在训练集和测试集上的表现更好
# 如果把alpha设得太小,那么就会消除正则化的效果,并出现过拟合,得到与LinearRegression类似的结果
lasso = Lasso(alpha=0.01, max_iter=100000).fit(X_train, y_train)
print("lassoRegression training score:{:.2f}".format(lasso.score(X_train, y_train)))
print("lassoRegression test score:{:.2f}".format(lasso.score(X_test, y_test)))
print("Number of features used:{}".format(np.sum(lasso.coef_ != 0)))
alpha值变小,我们可以拟合一个更复杂的模型,在训练集和测试集上的表现也更好。模型性能比使用Ridge时略好一点,而且我们只用到了105个特征中的33个。这样模型可能更容易理解。但如果把alpha设得太小,那么就会消除正则化的效果,并出现过拟合.
用于分类的线性模型
大多数分类问题类别都是不相交的,即一个样本只有一个类别。用于分类的线性模型是一个用于划分类别的、找出决策边界的一个模型函数。下面我们以一个三分类的问题,介绍线性模型找出决策边界后的效果:
- 先预测类别:
import mglearn
import mglearn.datasets
import numpy as np
from sklearn.svm import LinearSVC
from sklearn.datasets import make_blobs
if __name__ == '__main__':
X, y = make_blobs(random_state=42)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
linear_svc = LinearSVC().fit(X, y)
mglearn.plots.plot_2d_classification(linear_svc, X, fill=True, alpha=.7)
plt.show()
- 找出决策边界
import matplotlib.pyplot as plt
import mglearn
import numpy as np
from sklearn.svm import LinearSVC
from sklearn.datasets import make_blobs
if __name__ == '__main__':
X, y = make_blobs(random_state=42)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
linear_svc = LinearSVC().fit(X, y)
line = np.linspace(-15, 15)
for coef, intercept, color, in zip(linear_svc.coef_, linear_svc.intercept_, ['b', 'r', 'g']):
plt.plot(line, -(line * coef[0] + intercept) / coef[1], c=color)
plt.xlim(-10, 8)
plt.ylim(-10, 15)
plt.xlabel("Feature 0")
plt.ylabel("Feature 1")
plt.legend(["Class 0", "Class1", "Class2", "Line class 0", "Line class 1", "Line class 2"], loc=(1.01, 0.3))
plt.show()
从上图可以看出数据集被很好地划分成三个类别。对于三角形区域,离哪条直线更近,则属于哪个类别。
总结: 线性模型的主要参数是正则化参数,在回归模型中叫做alpha, 在LinearSVC和Logistic-Regression中叫做C。 alpha值越大或者C越小,则说明模型比较简单。特别是对于回归模型而言,调节这些参数非常重要。如果特征数量大于样本数量,线性模型的表现通常都很好。如果只有几个特征是真正重要的,应该使用L1正则化,否则应默认使用L2正则化。虽然利用线性模型的回归和分类进行预测相对比较容易,训练速度和预测速度都还比较快,但是不太容易理解系数为什么会是这样。