【机器学习】机器学习回归模型全解析:线性回归、多项式回归、过拟合与泛化、向量相关性与岭回归的理论与实践

💗💗💗欢迎来到我的博客,你将找到有关如何使用技术解决问题的文章,也会找到某个技术的学习路线。无论你是何种职业,我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章,也欢迎在文章下方留下你的评论和反馈。我期待着与你分享知识、互相学习和建立一个积极的社区。谢谢你的光临,让我们一起踏上这个知识之旅!

文章目录

🥦机器学习中的回归任务及其实现

·

机器学习中的回归任务是指通过训练数据学习一个映射关系,来预测连续值输出。与分类任务不同,回归任务的输出是一个实数值。

回归任务的应用场景

  • 房价预测:根据位置、面积、房间数等特征预测房价。
  • 股市预测:根据历史数据预测股票价格。
  • 气象预测:根据天气数据预测温度、湿度等数值。

回归评价指标

常用的回归模型评价指标包括:

  • 均方误差(MSE):衡量模型预测值与真实值之间的平均误差的平方。
  • 平均绝对误差(MAE):衡量模型预测值与真实值之间的平均绝对误差。
  • R²(决定系数):表示模型拟合数据的好坏,值越接近1表示拟合越好。

🥦线性回归模型

线性回归是最基本的回归方法之一,其假设目标值与输入特征之间存在线性关系。

线性回归模型公式

代码示例:使用Python的scikit-learn实现线性回归

python 复制代码
import numpy as np
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt

# 创建示例数据
X = np.array([[1], [2], [3], [4], [5]])  # 特征
y = np.array([1, 2, 3, 4, 5])  # 目标值

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

# 拟合数据
model.fit(X, y)

# 打印回归系数
print("回归系数:", model.coef_)
print("截距:", model.intercept_)

# 预测
y_pred = model.predict(X)

# 绘制结果
plt.scatter(X, y, color='blue')  # 原数据
plt.plot(X, y_pred, color='red')  # 拟合线
plt.show()

运行结果如下:

🥦机器学习中的最优化方法

  • 梯度下降(Gradient Descent):通过计算损失函数相对于参数的梯度,并更新参数,逐步逼近最优解。
  • 最小二乘法(Least Squares):用于线性回归模型,找到使得所有样本点的误差平方和最小的参数。

代码示例:使用梯度下降优化线性回归

python 复制代码
import numpy as np

# 创建数据
X = np.array([1, 2, 3, 4, 5])
y = np.array([1, 2, 3, 4, 5])

# 初始化参数
w = 0.0
b = 0.0
learning_rate = 0.01
epochs = 1000

# 梯度下降
for epoch in range(epochs):
    # 计算预测值
    y_pred = w * X + b
    
    # 计算损失函数的梯度
    dw = -2 * np.sum(X * (y - y_pred)) / len(X)
    db = -2 * np.sum(y - y_pred) / len(X)
    
    # 更新参数
    w -= learning_rate * dw
    b -= learning_rate * db
    
    if epoch % 100 == 0:
        print(f"Epoch {epoch}: w = {w}, b = {b}")

print(f"训练完毕: w = {w}, b = {b}")

运行结果如下:

🥦多项式回归

多项式回归是通过引入高阶项来捕捉特征之间的非线性关系。

代码示例:使用scikit-learn实现多项式回归

python 复制代码
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt

# 创建数据
X = np.array([1, 2, 3, 4, 5]).reshape(-1, 1)
y = np.array([1, 4, 9, 16, 25])

# 创建多项式特征
poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X)

# 拟合多项式回归模型
model = LinearRegression()
model.fit(X_poly, y)

# 预测
y_pred = model.predict(X_poly)

# 绘制结果
plt.scatter(X, y, color='blue')  # 原数据
plt.plot(X, y_pred, color='red')  # 拟合曲线
plt.show()

运行结果如下:

🥦过拟合与泛化

  • 过拟合:当模型在训练数据上表现很好,但在新数据上表现差时,说明模型过拟合了训练数据。为了避免过拟合,可以使用正则化技术。
  • 泛化:模型能够适应新数据,且不仅仅是训练数据。

代码示例:通过增加多项式的阶数来观察过拟合

python 复制代码
# 增加多项式阶数,观察是否发生过拟合
poly = PolynomialFeatures(degree=10)
X_poly = poly.fit_transform(X)

model.fit(X_poly, y)
y_pred = model.predict(X_poly)

plt.scatter(X, y, color='blue')
plt.plot(X, y_pred, color='red')
plt.show()

🥦向量相关性与岭回归

岭回归(Ridge Regression)是线性回归的一种正则化形式,旨在防止过拟合。

岭回归模型

岭回归通过在损失函数中加入 L2 正则化项来减少模型的复杂度:

其中, λ \lambda λ 是正则化参数。

代码(岭回归实现)

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.model_selection import train_test_split

# 假设数据 X 和 y 已经加载到变量中
X = np.random.rand(100, 1)  # 生成100个随机特征数据
y = 2 * X + np.random.randn(100, 1)  # 生成目标变量

# 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建岭回归模型
ridge_model = Ridge(alpha=1.0)

# 训练模型
ridge_model.fit(X_train, y_train)

# 预测
y_ridge_pred = ridge_model.predict(X_test)

# 计算MSE和R²
mse_ridge = mean_squared_error(y_test, y_ridge_pred)
r2_ridge = r2_score(y_test, y_ridge_pred)

# 打印结果
print(f"岭回归 - MSE: {mse_ridge:.2f}, R²: {r2_ridge:.2f}")

# 可视化结果
plt.scatter(X_test, y_test, color='blue', label='实际值')
plt.plot(X_test, y_ridge_pred, color='purple', label='岭回归预测值')
plt.xlabel('特征值')
plt.ylabel('目标值')
plt.legend()
plt.show()

运行结果如下:

岭回归 - MSE: 1.90, R²: -0.05

  1. MSE(均方误差): 1.90

    MSE 是衡量模型预测与实际值之间差异的一个指标,表示的是预测值与真实值之间误差的平方的平均值。较小的 MSE 值通常意味着模型的预测误差较小。这里的 1.90 表示模型的预测误差相对较大,说明模型对测试集的预测并不准确。

  2. R²(决定系数): -0.05

    R² 是用于评估回归模型拟合度的一个指标,表示模型对数据的解释能力。R² 的范围通常是 [0, 1],越接近 1 表示模型的解释能力越强;值为 0 时表示模型不能解释数据中的变异;而负值通常意味着模型的表现非常差,甚至比一个简单的平均值模型还要差。

负值:当 R² 为负时,通常意味着模型非常不合适 ,预测的效果比一个简单的基准模型(比如直接预测所有输出为目标变量的平均值)还要差。

在这种情况下,R² = -0.05 意味着岭回归模型的预测效果非常差,模型不仅没有提供有用的信息,而且其预测结果远不如基准模型。

毕竟这是虚假的数据,文章的最后我会使用真实的数据集进行测试

解释:

正则化参数:alpha 控制正则化的强度,增大 alpha 会使模型更加简单,从而避免过拟合。

🥦局部回归

局部回归(Local Regression)是指针对每一个查询点,利用其附近的点来进行回归。常见的方法是 LOESS 或 LOWESS(局部加权回归)。

代码(局部回归实现)

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsRegressor
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.model_selection import train_test_split

# 假设数据 X 和 y 已经加载到变量中
# 示例:X = np.random.rand(100, 1)  # 生成100个随机特征数据
# y = 2 * X + np.random.randn(100, 1)  # 生成目标变量

# 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建KNN回归模型
knn_model = KNeighborsRegressor(n_neighbors=5)

# 训练模型
knn_model.fit(X_train, y_train)

# 预测
y_knn_pred = knn_model.predict(X_test)

# 计算MSE和R²
mse_knn = mean_squared_error(y_test, y_knn_pred)
r2_knn = r2_score(y_test, y_knn_pred)

# 打印结果
print(f"KNN回归 - MSE: {mse_knn:.2f}, R²: {r2_knn:.2f}")

# 可视化结果
plt.scatter(X_test, y_test, color='blue', label='实际值')
plt.plot(X_test, y_knn_pred, color='orange', label='KNN回归预测值', linewidth=2)
plt.xlabel('特征值')
plt.ylabel('目标值')
plt.legend()
plt.show()

🥦代码实践(CoNLL-2003数据集)

python 复制代码
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import mean_squared_error
from sklearn.neighbors import KNeighborsRegressor
from gensim.models import Word2Vec


# 1. 加载数据并解析
def load_data(file_path):
    sentences = []
    sentence = []

    with open(file_path, 'r', encoding='utf-8') as file:
        for line in file:
            if line.strip():  # 非空行
                word = line.split()[0]  # 提取词
                sentence.append(word)
            else:
                if sentence:
                    sentences.append(sentence)
                    sentence = []
    if sentence:  # 添加最后一个句子
        sentences.append(sentence)

    return sentences

# 加载训练、验证和测试集
train_sentences = load_data("./data/coll2003/train.txt")
valid_sentences = load_data("./data/coll2003/valid.txt")
test_sentences = load_data("./data/coll2003/test.txt")
# 2. 训练Word2Vec模型并将句子转换为向量
embedding_dim = 100  # 嵌入维度,可以根据需要调整
w2v_model = Word2Vec(sentences=train_sentences, vector_size=embedding_dim, window=5, min_count=1, workers=4)

def sentence_to_vector(sentence, model, embedding_dim):
    # 过滤出句子中存在于词向量模型中的词
    vectors = [model.wv[word] for word in sentence if word in model.wv]
    if len(vectors) > 0:
        # 计算词向量的均值
        vector = np.mean(vectors, axis=0)
    else:
        # 如果句子中没有任何词在词汇表中,返回一个零向量
        vector = np.zeros(embedding_dim)
    return vector

# 应用改进的函数
X_train = np.array([sentence_to_vector(sentence, w2v_model, embedding_dim) for sentence in train_sentences])
X_valid = np.array([sentence_to_vector(sentence, w2v_model, embedding_dim) for sentence in valid_sentences])
X_test = np.array([sentence_to_vector(sentence, w2v_model, embedding_dim) for sentence in test_sentences])

# 检查形状
print("X_train shape:", X_train.shape)
print("X_valid shape:", X_valid.shape)
print("X_test shape:", X_test.shape)

# 假设我们有目标值 y(例如,每个句子的标签或分数),这里使用随机数据进行演示
y_train = np.random.rand(len(X_train))  # 替换为实际的目标值
y_valid = np.random.rand(len(X_valid))  # 替换为实际的目标值
y_test = np.random.rand(len(X_test))    # 替换为实际的目标值

# 3. 线性回归
linear_model = LinearRegression()
linear_model.fit(X_train, y_train)

y_pred_train = linear_model.predict(X_train)
y_pred_valid = linear_model.predict(X_valid)
y_pred_test = linear_model.predict(X_test)

print("线性回归训练集MSE:", mean_squared_error(y_train, y_pred_train))
print("线性回归验证集MSE:", mean_squared_error(y_valid, y_pred_valid))
print("线性回归测试集MSE:", mean_squared_error(y_test, y_pred_test))

# 4. 多项式回归
degree = 2  # 多项式的阶数,可以调整
poly_features = PolynomialFeatures(degree=degree)
X_train_poly = poly_features.fit_transform(X_train)
X_valid_poly = poly_features.transform(X_valid)
X_test_poly = poly_features.transform(X_test)

poly_model = LinearRegression()
poly_model.fit(X_train_poly, y_train)

y_pred_train_poly = poly_model.predict(X_train_poly)
y_pred_valid_poly = poly_model.predict(X_valid_poly)
y_pred_test_poly = poly_model.predict(X_test_poly)

print("多项式回归训练集MSE:", mean_squared_error(y_train, y_pred_train_poly))
print("多项式回归验证集MSE:", mean_squared_error(y_valid, y_pred_valid_poly))
print("多项式回归测试集MSE:", mean_squared_error(y_test, y_pred_test_poly))

# 5. 岭回归
alpha = 1.0  # 正则化强度,可以调整
ridge_model = Ridge(alpha=alpha)
ridge_model.fit(X_train, y_train)

y_pred_train_ridge = ridge_model.predict(X_train)
y_pred_valid_ridge = ridge_model.predict(X_valid)
y_pred_test_ridge = ridge_model.predict(X_test)

print("岭回归训练集MSE:", mean_squared_error(y_train, y_pred_train_ridge))
print("岭回归验证集MSE:", mean_squared_error(y_valid, y_pred_valid_ridge))
print("岭回归测试集MSE:", mean_squared_error(y_test, y_pred_test_ridge))

# 6. 局部回归(KNN回归)
n_neighbors = 10  # 邻居数,可以调整
knn_model = KNeighborsRegressor(n_neighbors=n_neighbors)
knn_model.fit(X_train, y_train)

y_pred_train_knn = knn_model.predict(X_train)
y_pred_valid_knn = knn_model.predict(X_valid)
y_pred_test_knn = knn_model.predict(X_test)

print("局部回归(KNN)训练集MSE:", mean_squared_error(y_train, y_pred_train_knn))
print("局部回归(KNN)验证集MSE:", mean_squared_error(y_valid, y_pred_valid_knn))
print("局部回归(KNN)测试集MSE:", mean_squared_error(y_test, y_pred_test_knn))

# 7. 总结结果
results = {
    "线性回归测试集MSE": mean_squared_error(y_test, y_pred_test),
    "多项式回归测试集MSE": mean_squared_error(y_test, y_pred_test_poly),
    "岭回归测试集MSE": mean_squared_error(y_test, y_pred_test_ridge),
    "局部回归(KNN)测试集MSE": mean_squared_error(y_test, y_pred_test_knn),
}

print("\n测试集误差比较:")
for model, mse in results.items():
    print(f"{model}: {mse}")

运行结果如下:

表格如下:

🥦指标评估详解

线性回归:

  • 在训练集、验证集和测试集上的MSE都在0.08左右,说明模型在三个数据集上的误差比较一致,且误差较小。这意味着线性回归模型在这组数据上的拟合情况比较稳定,适度的表现出良好的泛化性。

多项式回归:

  • 训练集MSE较小(0.06),但验证集和测试集上的MSE相对较大(验证集为0.24,测试集为0.33)。
    这种差异表明多项式回归可能出现了过拟合问题。在训练集上表现很好,但在验证集和测试集上表现较差,无法很好地泛化。这可能是因为多项式模型的复杂度较高,容易捕捉到训练数据的噪声。

岭回归:

  • 在训练集、验证集和测试集上的MSE都在0.08左右,与线性回归的表现相似。
    由于岭回归使用了正则化技术,有助于减少模型的过拟合问题。因此,岭回归在三个数据集上的误差较为一致,说明它的泛化能力较好。

局部回归(KNN):

  • 训练集上的MSE为0.07,而验证集和测试集上的MSE略高,为0.09。
    KNN的表现也较为稳定,但比线性回归和岭回归的误差稍高。这可能是因为局部回归的特性更依赖于邻近数据点,泛化能力相对有限,尤其是在样本较大的测试集上。

总结

线性回归和岭回归在这组数据上表现良好,MSE较低且较为稳定,适合在简单数据特征和较少噪声的场景下使用。

多项式回归出现过拟合,适用于更复杂的特征关系或在特征数量增加、正则化改进的情况下才可能取得更好的泛化效果。

局部回归(KNN)适合小数据集或对局部关系要求更高的任务,但在大数据集或需要全局建模的任务中表现略逊色。

🥦总结

本文深入探讨了机器学习中的回归任务,并通过多种回归模型的详细介绍,帮助大家理解如何利用回归方法解决现实中的预测问题。通过对线性回归、多项式回归、岭回归、局部回归等模型的剖析,我们掌握了不同场景下回归任务的最佳选择和优化技巧。

关键点回顾:

  • 回归任务的基本概念:回归任务旨在预测一个连续的输出值,广泛应用于房价预测、股市预测等领域。
  • 线性回归模型:简单且高效,通过最小化均方误差来训练模型,适合处理线性关系数据。
  • 多项式回归:扩展了线性回归,通过加入高次项处理非线性问题,适用于较复杂的数据关系。
  • 过拟合与泛化问题:过拟合是回归模型常见的难题,通过正则化(如岭回归)或减少模型复杂度来提高模型的泛化能力。
  • 岭回归与正则化:通过在损失函数中加入L2正则化项,控制模型复杂度,防止过拟合,适用于高维数据或特征相关性强的数据。
  • 局部回归(KNN回归):针对每个数据点,使用其邻近的数据点进行回归,适用于数据呈现局部模式的情况。

每种回归方法都有其适用的场景和优缺点,在实际应用中,我们需要根据具体问题选择合适的模型。此外,我们还探讨了梯度下降法和最优化方法,它们是回归模型训练中的核心步骤。为了提升模型性能,我们需要时刻关注模型的泛化能力,避免过拟合带来的负面影响。

挑战与创造都是很痛苦的,但是很充实。

相关推荐
芝麻团坚果7 分钟前
对subprocess启动的子进程使用VSCode python debugger
linux·ide·python·subprocess·vscode debugger
机器之心15 分钟前
全球十亿级轨迹点驱动,首个轨迹基础大模型来了
人工智能·后端
z千鑫15 分钟前
【人工智能】PyTorch、TensorFlow 和 Keras 全面解析与对比:深度学习框架的终极指南
人工智能·pytorch·深度学习·aigc·tensorflow·keras·codemoss
EterNity_TiMe_16 分钟前
【论文复现】神经网络的公式推导与代码实现
人工智能·python·深度学习·神经网络·数据分析·特征分析
Stara051124 分钟前
Git推送+拉去+uwsgi+Nginx服务器部署项目
git·python·mysql·nginx·gitee·github·uwsgi
机智的小神仙儿33 分钟前
Query Processing——搜索与推荐系统的核心基础
人工智能·推荐算法
AI_小站39 分钟前
RAG 示例:使用 langchain、Redis、llama.cpp 构建一个 kubernetes 知识库问答
人工智能·程序人生·langchain·kubernetes·llama·知识库·rag
Doker 多克41 分钟前
Spring AI 框架使用的核心概念
人工智能·spring·chatgpt
Guofu_Liao42 分钟前
Llama模型文件介绍
人工智能·llama
hence..1 小时前
Vscode写markdown快速插入python代码
ide·vscode·python