什么是偏拟合和什么是过拟合,解决方法是什么

简介: 什么是偏拟合和什么是过拟合,解决方法是什么

什么是偏拟合和什么是过拟合,解决方法是什么


过拟合(Overfitting)


过拟合指的是模型在训练集上表现良好,但在测试集或实际应用中表现不佳的现象。通常,过拟合是由于模型过度学习了训练集中的噪声和细节,而忽略了数据的真正趋势。这导致模型在新数据上的泛化能力较差。


过拟合的案例


假设我们有一个简单的线性回归问题,数据集包含了年龄和身高的关系。下面是一个示例代码:

import numpy as np
import matplotlib.pyplot as plt

# 生成数据集
np.random.seed(0)
X = np.random.rand(100, 1) * 10
y = 2.5 * X + np.random.randn(100, 1) * 2

# 添加噪声点
X_outliers = np.array([[15]])
y_outliers = np.array([[160]])

X = np.append(X, X_outliers, axis=0)
y = np.append(y, y_outliers, axis=0)

# 可视化数据集
plt.scatter(X, y)
plt.xlabel('Age')
plt.ylabel('Height')
plt.title('Data Distribution')
plt.show()


在上述代码中,我们生成了一个包含年龄和身高关系的数据集,并添加了一些噪声点。接下来,我们将使用线性回归模型拟合这个数据集:

from sklearn.linear_model import LinearRegression

# 训练线性回归模型
model = LinearRegression()
model.fit(X, y)

# 可视化拟合结果
plt.scatter(X, y)
plt.plot(X, model.predict(X), color='red')
plt.xlabel('Age')
plt.ylabel('Height')
plt.title('Linear Regression Fit')
plt.show()


这段代码中的过拟合原因可以通过以下几个方面来解释:


  1. 模型复杂度过高: 在上述代码中,使用了简单的线性回归模型来拟合数据。然而,数据并不是完全线性关系,而是带有一定的噪声。当模型过于简单时,它可能无法捕捉到数据中的复杂关系,导致拟合不足(欠拟合)。为了尝试更好地拟合训练数据,我们可能会尝试使用更复杂的模型,如多项式回归。
  2. 过多的噪声: 数据中存在的噪声可能会干扰模型的学习过程。在生成数据集时,我们添加了一些噪声点,这些点可能不符合数据的整体趋势,但却被模型试图拟合。过拟合模型可能会试图尽可能地拟合所有数据点,包括噪声点,从而导致模型过于复杂。
  3. 训练数据量不足: 当训练数据量不足时,模型可能会过度拟合已有的数据,而无法很好地泛化到新的数据上。在这个案例中,只生成了100个数据点,并添加了一些噪声点。如果训练数据量更大,模型可能会更好地学习数据的真实关系。


解决过拟合问题的方法通常包括:


  • 增加训练数据量: 更多的数据有助于模型更好地学习数据的真实关系,从而减少过拟合的可能性。
  • 简化模型结构: 减少模型的复杂度,例如减少多项式的次数,使用更简单的模型结构。
  • 正则化: 在损失函数中引入正则化项,以惩罚模型复杂度,如L1和L2正则化。
  • 交叉验证: 使用交叉验证来评估模型的性能,确保模型能够在不同的数据集上都表现良好,而不仅仅是在训练数据上。


1. 增加训练数据量:

增加训练数据量通常可以帮助模型更好地学习数据的真实关系。在这个例子中,生成更多的数据来演示这一点。

import numpy as np
import matplotlib.pyplot as plt

# 生成更多的数据
np.random.seed(0)
X_additional = np.random.rand(100, 1) * 10
y_additional = 2.5 * X_additional + np.random.randn(100, 1) * 2

# 合并原始数据和新数据
X_combined = np.concatenate((X, X_additional), axis=0)
y_combined = np.concatenate((y, y_additional), axis=0)

# 可视化数据集
plt.scatter(X_combined, y_combined)
plt.xlabel('Age')
plt.ylabel('Height')
plt.title('Data Distribution with Additional Data')
plt.show()

2. 简化模型结构:

简化模型结构是减少过拟合的一种方法。在这里,可以降低多项式的次数来简化模型。

from sklearn.preprocessing import PolynomialFeatures

# 使用更低次数的多项式拟合数据
polynomial_features = PolynomialFeatures(degree=1)
X_poly = polynomial_features.fit_transform(X_combined)

# 训练线性回归模型
model = LinearRegression()
model.fit(X_poly, y_combined)

# 绘制拟合结果
plt.scatter(X_combined, y_combined)
plt.plot(X_combined, model.predict(X_poly), color='red')
plt.xlabel('Age')
plt.ylabel('Height')
plt.title('Linear Regression Fit with Simplified Model')
plt.show()

3. 正则化:

通过引入正则化项,可以惩罚模型的复杂度,防止过拟合。这里使用L2正则化。

from sklearn.linear_model import Ridge

# 使用Ridge回归进行正则化
ridge_model = Ridge(alpha=0.1)  # 设置正则化参数alpha
ridge_model.fit(X_poly, y_combined)

# 绘制拟合结果
plt.scatter(X_combined, y_combined)
plt.plot(X_combined, ridge_model.predict(X_poly), color='green')
plt.xlabel('Age')
plt.ylabel('Height')
plt.title('Ridge Regression Fit with Regularization')
plt.show()

4. 交叉验证:

使用交叉验证可以评估模型在不同数据集上的性能,从而更好地评估其泛化能力。

from sklearn.model_selection import cross_val_score

# 使用交叉验证评估模型性能
scores = cross_val_score(model, X_poly, y_combined, cv=5)
print("Linear Regression Cross-Validation Scores:", scores)

ridge_scores = cross_val_score(ridge_model, X_poly, y_combined, cv=5)
print("Ridge Regression Cross-Validation Scores:", ridge_scores)


欠拟合(Underfitting)


欠拟合指的是模型无法在训练集上学习数据的趋势,表现为模型过于简单,无法捕获数据的复杂性。这导致模型在训练集和测试集上都表现不佳。


欠拟合的案例


继续使用上述年龄和身高的数据集,考虑一个过于简单的模型,比如使用线性模型拟合非线性关系的数据:

from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline

# 创建线性模型
model = make_pipeline(PolynomialFeatures(1), LinearRegression())

# 训练模型
model.fit(X, y)

# 可视化拟合结果
plt.scatter(X, y)
plt.plot(X, model.predict(X), color='red')
plt.xlabel('Age')
plt.ylabel('Height')
plt.title('Underfitting: Linear Model')
plt.show()

在这个案例中,我们尝试使用一个过于简单的线性模型来拟合非线性关系的数据,这导致了欠拟合的问题。让我们详细讲解一下欠拟合的原因:


欠拟合原因分析:


  1. 模型过于简单: 在代码中,使用了一个线性模型来拟合非线性关系的数据。线性模型无法很好地捕捉数据中的复杂关系,因为它只能拟合直线,无法描述数据中的曲线关系。
  2. 特征不足: 在这个案例中,只使用了原始特征的一次多项式特征,即线性特征。这限制了模型的表达能力,无法很好地适应数据的非线性特征。


解决欠拟合的方法:


1. 增加模型的复杂度:

可以增加多项式的次数,使用更高阶的多项式特征来拟合数据的非线性关系。这样可以增加模型的灵活性,更好地适应数据。

from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt

# 创建多项式特征转换器
poly_features = PolynomialFeatures(degree=5)  # 选择更高阶的多项式

# 将原始特征转换为多项式特征
X_poly = poly_features.fit_transform(X)

# 创建线性回归模型
model = LinearRegression()

# 训练模型
model.fit(X_poly, y)

# 绘制拟合结果
plt.scatter(X, y)
plt.plot(X, model.predict(X_poly), color='red', label='Polynomial Regression (Degree 5)')
plt.xlabel('Age')
plt.ylabel('Height')
plt.title('Polynomial Regression Fit (Degree 5)')
plt.legend()
plt.show()

2. 增加特征:

可以添加更多的特征,例如原始特征的多项式特征、交叉特征等,以提供更多的信息来拟合数据。

from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt

# 创建多项式特征转换器
poly_features = PolynomialFeatures(degree=2)  # 选择更高阶的多项式

# 将原始特征转换为多项式特征
X_poly = poly_features.fit_transform(X)

# 创建线性回归模型
model = LinearRegression()

# 训练模型
model.fit(X_poly, y)

# 绘制拟合结果
plt.scatter(X, y)
plt.plot(X, model.predict(X_poly), color='red', label='Polynomial Regression (Degree 2)')
plt.xlabel('Age')
plt.ylabel('Height')
plt.title('Polynomial Regression Fit (Degree 2)')
plt.legend()
plt.show()

3. 使用其他算法:

可以尝试使用其他算法来处理非线性数据,例如决策树、支持向量机等。

from sklearn.tree import DecisionTreeRegressor

# 创建决策树回归模型
model = DecisionTreeRegressor(max_depth=5)  # 设置树的最大深度

# 训练模型
model.fit(X, y)

# 绘制拟合结果
plt.scatter(X, y)
plt.plot(X, model.predict(X), color='red', label='Decision Tree Regression')
plt.xlabel('Age')
plt.ylabel('Height')
plt.title('Decision Tree Regression Fit')
plt.legend()
plt.show()

4. 正则化参数调整:

如果使用了带有正则化的模型,可以尝试调整正则化参数来提高模型的灵活性。

from sklearn.linear_model import Ridge

# 创建岭回归模型
model = Ridge(alpha=0.1)  # 设置正则化参数alpha

# 训练模型
model.fit(X_poly, y)

# 绘制拟合结果
plt.scatter(X, y)
plt.plot(X, model.predict(X_poly), color='red', label='Ridge Regression (alpha=0.1)')
plt.xlabel('Age')
plt.ylabel('Height')
plt.title('Ridge Regression Fit (alpha=0.1)')
plt.legend()
plt.show()
相关文章
|
5G 数据安全/隐私保护
5G终端标识SUPI,SUCI及IMSI解析
IMSI,SUPI,SUCI均为UE终端标识,区别在于IMSI为LTE终端标识,SUPI为5G非加密终端标识,一般等同于IMSI,SUCI为5G加密终端标识,需要解密后才能得到SUPI。
3417 0
5G终端标识SUPI,SUCI及IMSI解析
QGS
(麒麟V10-arm)编译安装php-7.4及部分依赖
记(麒麟V10-arm)编译安装php-7.4及部分依赖
QGS
1773 0
(麒麟V10-arm)编译安装php-7.4及部分依赖
|
SQL 关系型数据库 MySQL
docker(15):以docker 方式启动 单机版 tidb
1,关于tidb tidb 其灵感来自于 Google 的 F1 和 Google spanner, TiDB 支持包括传统 RDBMS 和 NoSQL 的特性。 sql 完全支持mysql,同时人家还是一个分布式数据库。 什么分库分表都弱爆了,这个直接分,超级方便。而且还是开源的。 是国内的 技术大牛 黄东旭 的公司 pincap 开发的。 就是之前写 codi
7085 0
|
测试技术 C# 数据库
C# 单元测试框架 NUnit 一分钟浅谈
【10月更文挑战第17天】单元测试是软件开发中重要的质量保证手段,NUnit 是一个广泛使用的 .NET 单元测试框架。本文从基础到进阶介绍了 NUnit 的使用方法,包括安装、基本用法、参数化测试、异步测试等,并探讨了常见问题和易错点,旨在帮助开发者有效利用单元测试提高代码质量和开发效率。
680 64
|
机器学习/深度学习 自然语言处理 PyTorch
从零开始构建nlp情感分析模型!
本教程介绍了如何使用PyTorch和Hugging Face的Transformers库构建一个情感分析模型。主要内容包括导入所需库、读取训练数据集、加载预训练的BERT模型和分词器、定义情感数据集类、划分训练集和验证集、创建数据加载器、设置训练参数、训练模型、评估模型性能以及定义和测试预测函数。通过这些步骤,可以实现一个简单而有效的情感分析模型。
1005 2
|
存储 前端开发
【大前端】用html和css写一个QQ邮箱登录页面
【大前端】用html和css写一个QQ邮箱登录页面
1218 0
【大前端】用html和css写一个QQ邮箱登录页面
|
机器学习/深度学习 自然语言处理 索引
【Transformer系列(4)】Transformer模型结构超详细解读
【Transformer系列(4)】Transformer模型结构超详细解读
2023 0
【Transformer系列(4)】Transformer模型结构超详细解读
|
存储 XML 缓存
前端知识笔记(一)———Base64图片是什么?原理是什么?优缺点是什么?
前端知识笔记(一)———Base64图片是什么?原理是什么?优缺点是什么?
366 0
|
IDE 开发工具 Python
关于 Pycharm专业版 安装教程,简单好用
关于 Pycharm专业版 安装教程,简单好用
389 0
关于 Pycharm专业版 安装教程,简单好用

热门文章

最新文章