机器学习初学者 2024年12月31日
【机器学习】突破最强算法模型,回归算法 !!
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

文章围绕回归类算法展开,包括特征工程的重要性、缺失值和异常值处理、回归模型诊断、学习曲线和验证曲线解读、线性回归工作原理等内容,为读者提供了全面的知识

💡特征工程重要性:提高模型性能、降低计算成本、减少过拟合风险、提高模型解释性

🎯缺失值和异常值处理:探索理解数据,选择合适处理方式,注意数据透明度和可解释性

📈回归模型诊断:进行残差分析、检查回归假设,通过代码实现模型诊断

📊学习曲线和验证曲线:分析模型性能,指导调整模型参数

🧮线性回归工作原理:解释数学原理,通过代码实现梯度下降算法

cos大壮 2024-12-30 14:20 浙江

回归类算法,读者问的细节。16个大块,大家可以收藏学习~

今天是上次文章的一个延续,就是把昨天关于回归类算法剩余的内容进行补充。

前前后后回归类问题Q&A总共是16个方面。

另外,昨天评论区有同学觉得在内容上,缺乏代码,这个会在下周的时间进行继续补充,到时候大家可以收藏学习~

咱们今天第 2 期:回归类总结,总共是16个问题,也就是大概16个核心点的分享。

# 特征工程的重要性

读者问: 最近刚刚开始学习算法,有一个小问题。在构建回归模型时,进行特征选择和特征工程为什么这么重要?初学者,不是特别的明白

答: 你好。其实,特征选择和特征工程在构建任何算法模型的时候,都非常非常重要。

首先,让我们明确一下这两个概念。

特征选择是指从所有可用的特征中选择最相关和最有用的特征,以用于模型的训练和预测。而特征工程则涉及对原始数据进行预处理和转换,以便更好地适应模型的需求,包括特征缩放、特征变换、特征衍生等等操作。

那么,为什么这两个步骤如此重要呢?我这边从4个方面概括下~

1. 提高模型性能:通过选择最相关的特征和对特征进行适当的工程处理,可以提高模型的性能。过多的不相关特征会增加模型的复杂性,降低模型的泛化能力,导致过拟合。而合适的特征工程可以帮助模型更好地理解数据的结构和关系,提高模型的准确性。

2. 降低计算成本:在实际的数据集中,可能存在大量的特征,而并非所有特征都对预测目标具有重要影响。通过特征选择,可以减少模型训练的计算成本和时间消耗,提高模型的效率。

3. 减少过拟合风险:过拟合是模型在训练数据上表现很好,但在新数据上表现不佳的现象。特征选择和特征工程可以帮助降低过拟合的风险,使模型更加泛化到未见过的数据上。

4. 提高模型的解释性:经过特征选择和特征工程处理的模型,其特征更加清晰明了,更容易理解和解释。这对于实际应用中的决策和解释至关重要。

常用的特征选择方法包括基于统计检验、正则化方法、基于树模型的方法等;而特征工程则涉及到缺失值处理、标准化、归一化、编码、特征组合、降维等技术。

下面举一个简单的案例,在代码中进行特征选择和特征工程,结合上面所说以及代码中的注释进行理解~

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.feature_selection import SelectKBest, f_regression
from sklearn.preprocessing import StandardScaler
# 随机生成示例数据
np.random.seed(0)
X = np.random.rand(1005)  # 5个特征
y = X[:, 0] + 2*X[:, 1] - 3*X[:, 2] + np.random.randn(100)  # 线性关系,加入噪声
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 特征工程:标准化特征
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 特征选择:选择k个最好的特征
selector = SelectKBest(score_func=f_regression, k=3)
X_train_selected = selector.fit_transform(X_train_scaled, y_train)
X_test_selected = selector.transform(X_test_scaled)
# 训练回归模型
model = LinearRegression()
model.fit(X_train_selected, y_train)
# 在测试集上评估模型性能
score = model.score(X_test_selected, y_test)
print("模型在测试集上的R^2得分:", score)

上面代码中 ,我们首先生成了一些示例数据,然后对数据进行了标准化处理。接着,我们使用方差分析选择了3个最佳特征。最后训练了一个线性回归模型并在测试集上评估了其性能。

通过特征选择和特征工程,在实际的算法建模中,可以更好地理解数据,提高模型的性能。

# 缺失值和异常值的处理

读者问: 最近在处理数据的时候,遇到缺失值和异常值就没思路了。在我的回归分析中,应该怎么样处理缺失值和异常值呢?

答: 这是一个太太太常见的问题了。首先说,处理缺失值和异常值在回归分析中非常关键,因为它们可能会对模型的准确性和可靠性造成影响。

咱们从处理缺失值和处理异常值两个方面,详细的说说~

处理缺失值

1. 数据探索与理解

2. 缺失值的处理方式

3. 代码示例

import pandas as pd
from sklearn.impute import SimpleImputer
# 假设 df 是你的数据框
# 使用均值填充缺失值
imputer = SimpleImputer(strategy='mean')
df_filled = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)

处理异常值

1. 异常值的识别

2. 异常值的处理方式

3. 代码示例

# 假设 df 是你的数据框
# 假设我们使用 Z 分数方法来检测异常值并替换为均值
from scipy import stats
z_scores = stats.zscore(df)
abs_z_scores = np.abs(z_scores)
filtered_entries = (abs_z_scores < 3).all(axis=1)
df_no_outliers = df[filtered_entries]

总的来说,咱们遇到这样的情况,有几点需要注意:

加油~

# 回归模型的诊断

读者问: 有一个问题想要跟你学习一下。就是我如何对我的回归模型进行有效的诊断?例如,我应该如何进行残差分析或检查模型是否符合回归假设?

答: 咱们互相学习。当进行回归算法实验时,对回归模型进行有效的诊断是至关重要的,以确保模型的准确性和可靠性。

这里,总结了一些非常常见的回归模型诊断方法:

残差分析

检查回归假设

Cook's距离

我这里用代码实现一下,帮助你理解模型诊断相关内容~

import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt
# 生成示例数据
np.random.seed(0)
X = np.random.rand(1001)
y = 2 * X.squeeze() + np.random.normal(scale=0.5, size=100)
# 添加截距项
X = sm.add_constant(X)
# 拟合线性回归模型
model = sm.OLS(y, X).fit()
# 残差分析
residuals = model.resid
plt.figure(figsize=(126))
# 绘制残差图
plt.subplot(121)
plt.scatter(model.fittedvalues, residuals)
plt.xlabel('Fitted values')
plt.ylabel('Residuals')
plt.title('Residual Plot')
# 绘制正态概率图
plt.subplot(122)
sm.qqplot(residuals, line='45')
plt.title('Normal Probability Plot')
plt.show()
# 检查回归假设
name = ['Lagrange multiplier statistic''p-value''f-value''f p-value']
test = sm.stats.diagnostic.het_breuschpagan(residuals, X)
print(dict(zip(name, test)))
# Cook's距离
influence = model.get_influence()
cooks_distance = influence.cooks_distance[0]
plt.figure(figsize=(86))
plt.stem(np.arange(len(cooks_distance)), cooks_distance, markerfmt=",", linefmt="b-.")
plt.xlabel('Data points')
plt.ylabel("Cook's Distance")
plt.title("Cook's Distance")
plt.show()

这里给出其中一个结果图,你可以自己执行代码,把其他的图进行打印,以便理解。

通过以上代码以及给出的图形,可以进行残差分析、检查回归假设以及计算Cook's距离,从而对线性回归模型进行全面的诊断。

有问题,随时再提哈~

# 学习曲线和验证曲线的解读

读者问: 这几天遇到一个问题,就是我应该如何使用学习曲线和验证曲线来评估我的回归模型?这些曲线能告诉我什么,以及我该如何根据它们来调整模型参数?

答: 在实验中,很多时候,使用学习曲线和验证曲线可以帮助评估回归模型的性能,并指导调整模型参数。

下面我会分别介绍学习曲线验证曲线,并说明它们能告诉我们的信息以及如何根据它们来调整模型参数。

学习曲线

学习曲线(Learning Curve)是一种用于分析模型性能的图表,它展示了训练数据大小与模型性能之间的关系。通常,学习曲线会随着训练数据量的增加而变化。学习曲线的两个关键指标是训练集上的性能和验证集上的性能。

学习曲线能告诉我们的信息:

如何根据学习曲线调整模型参数:

验证曲线

验证曲线(Validation Curve)是一种图表,用于分析模型性能与某一参数(例如正则化参数、模型复杂度等)之间的关系。通过在不同参数取值下评估模型的性能,我们可以找到最优的参数取值。

验证曲线能告诉我们的信息:

如何根据验证曲线调整模型参数:

这里,用代码演示了使用学习曲线和验证曲线来评估回归模型,并调整模型参数,可以作为参考~

from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import learning_curve, validation_curve
# 生成随机回归数据
X, y = make_regression(n_samples=1000, n_features=20, noise=0.2, random_state=42)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 定义线性回归模型
estimator = LinearRegression()
def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None, n_jobs=None, train_sizes=np.linspace(.11.05)):
    plt.figure()
    plt.title(title)
    if ylim is not None:
        plt.ylim(*ylim)
    plt.xlabel("Training examples")
    plt.ylabel("Score")
    train_sizes, train_scores, test_scores = learning_curve(estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)
    train_scores_mean = np.mean(train_scores, axis=1)
    train_scores_std = np.std(train_scores, axis=1)
    test_scores_mean = np.mean(test_scores, axis=1)
    test_scores_std = np.std(test_scores, axis=1)
    plt.grid()
    plt.fill_between(train_sizes, train_scores_mean - train_scores_std,
                     train_scores_mean + train_scores_std, alpha=0.1,
                     color="r")
    plt.fill_between(train_sizes, test_scores_mean - test_scores_std,
                     test_scores_mean + test_scores_std, alpha=0.1, color="g")
    plt.plot(train_sizes, train_scores_mean, 'o-', color="r",
             label="Training score")
    plt.plot(train_sizes, test_scores_mean, 'o-', color="g",
             label="Cross-validation score")
    plt.legend(loc="best")
    return plt
def plot_validation_curve(estimator, title, X, y, param_name, param_range, cv=None, scoring=None):
    train_scores, test_scores = validation_curve(
        estimator, X, y, param_name=param_name, param_range=param_range,
        cv=cv, scoring=scoring)
    train_scores_mean = np.mean(train_scores, axis=1)
    train_scores_std = np.std(train_scores, axis=1)
    test_scores_mean = np.mean(test_scores, axis=1)
    test_scores_std = np.std(test_scores, axis=1)
    plt.title(title)
    plt.xlabel(param_name)
    plt.ylabel("Score")
    plt.ylim(0.01.1)
    lw = 2
    plt.plot(param_range, train_scores_mean, label="Training score",
                 color="darkorange", lw=lw)
    plt.fill_between(param_range, train_scores_mean - train_scores_std,
                     train_scores_mean + train_scores_std, alpha=0.2,
                     color="darkorange", lw=lw)
    plt.plot(param_range, test_scores_mean, label="Cross-validation score",
                 color="navy", lw=lw)
    plt.fill_between(param_range, test_scores_mean - test_scores_std,
                     test_scores_mean + test_scores_std, alpha=0.2,
                     color="navy", lw=lw)
    plt.legend(loc="best")
    return plt
# 使用示例
plot_learning_curve(estimator, "Learning Curve", X_train, y_train, cv=5)
plt.show()

在这段代码中,我们首先定义了一个线性回归模型 LinearRegression(),然后将其传递给了 plot_learning_curve 函数。这样就可以成功绘制学习曲线了。

# 解释线性回归的工作原理

读者问: 能否详细解释一下线性回归的数学原理,比如它是如何通过损失函数和梯度下降来工作的?看了一圈,还是有点懵 

答: 你好。当我们谈到线性回归时,我们实际上在讨论一种用于建立输入变量(特征)与连续输出变量之间关系的模型。

在实验中,我们通常想要了解输入特征如何影响输出,或者用已知的输入输出数据来预测未知的输出。线性回归正是解决这种问题的一种常见方法。

下面从数学原理和代码结合起来进行解释,应该会很好的理解~

数学原理

1. 模型表示

在线性回归中,我们假设输出变量与输入变量之间存在线性关系。这可以用以下公式表示:

其中:

2. 损失函数

我们需要定义一个损失函数来衡量模型的预测与实际观测值之间的差异。

在线性回归中,最常见的损失函数是均方误差,其公式为:

其中:

3. 梯度下降

梯度下降是一种优化算法,用于最小化损失函数。其思想是通过不断沿着损失函数梯度的反方向更新模型参数,直到达到损失函数的最小值。

梯度下降的更新规则如下:

其中:

根据上面提到的理论内容,咱们通过代码来实现一番。使用梯度下降算法进行参数优化的Python代码~

import numpy as np
class LinearRegression:
    def __init__(self, learning_rate=0.01, n_iterations=1000):
        self.learning_rate = learning_rate
        self.n_iterations = n_iterations
        self.weights = None
        self.bias = None
    
    def fit(self, X, y):
        n_samples, n_features = X.shape
        self.weights = np.zeros(n_features)
        self.bias = 0
        
        for _ in range(self.n_iterations):
            y_predicted = np.dot(X, self.weights) + self.bias
            # 计算损失函数的梯度
            dw = (1/n_samples) * np.dot(X.T, (y_predicted - y))
            db = (1/n_samples) * np.sum(y_predicted - y)
            # 更新模型参数
            self.weights -= self.learning_rate * dw
            self.bias -= self.learning_rate * db
            
    def predict(self, X):
        return np.dot(X, self.weights) + self.bias
# 使用样例数据进行线性回归
X = np.array([[11.5], [22.5], [33.5], [44.5]])
y = np.array([2345])
model = LinearRegression()
model.fit(X, y)
# 打印模型参数
print("Coefficients:", model.weights)
print("Intercept:", model.bias)
# 进行预测
X_test = np.array([[55.5], [66.5]])
predictions = model.predict(X_test)
print("Predictions:", predictions)
# Coefficients: [0.37869152 0.65891856]
# Intercept: 0.5604540832879905
# Predictions: [6.07796379 7.11557387]

这段代码演示了如何使用梯度下降算法拟合线性回归模型,并进行预测。

在读懂简洁的理论之上,自行推到,最后结合代码,应该是比较容易理解的。

# 非线性回归模型的例子

读者问: 能给我一些非线性回归模型的例子吗?它们与线性回归主要有什么不同?

答: 当谈到非线性回归模型时,我们通常指的是模型中自变量和因变量之间的关系不是线性的,而是通过非线性函数来描述的一类回归模型。

下面我会介绍几种常见的非线性回归模型,并与线性回归进行对比。这样会更加的容易理解。

1. 多项式回归

多项式回归是一种将自变量的高次项加入模型的方法,例如:

这与线性回归的不同之处在于,自变量  的幂次不仅限于一次。通过增加高次项,模型能够更好地拟合非线性关系。

2. 指数回归

指数回归是一种通过指数函数来建模的方法,例如:

这种模型表达了因变量随自变量呈指数增长或指数衰减的趋势。

3. 对数回归

对数回归是一种通过对自变量或因变量取对数来建模的方法,例如:

或者

这种方法适用于当数据呈现出指数增长或衰减的趋势时。

4. 广义可加模型(Generalized Additive Models, GAM): GAM 是一种更一般化的非线性回归模型,它使用非线性函数来拟合每个自变量,例如:

这里的  是非线性函数,可以是平滑的样条函数或其他灵活的函数形式。

这些非线性回归模型与线性回归的主要不同之处在于它们允许了更加灵活的自变量和因变量之间的关系。线性回归假设了自变量和因变量之间的关系是线性的,而非线性回归模型通过引入非线性函数来更好地拟合真实世界中更为复杂的数据关系。这使得非线性模型能够更准确地描述数据,但也可能导致更复杂的模型结构和更难以解释的结果。

下面是一个使用多项式回归的代码~

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
# 设置随机种子,生成带噪声的非线性数据
np.random.seed(0)
X = np.linspace(-33100)
y = 2 * X**5 - 3 * X**4 + 4 * X**3 - 5 * X**2 + 6 * X - 7 + np.random.normal(088100)
# 将 X 转换成矩阵形式
X = X[:, np.newaxis]
# 使用更高阶的多项式特征进行变换
poly = PolynomialFeatures(degree=5)
X_poly = poly.fit_transform(X)
# 构建并拟合多项式回归模型
model = LinearRegression()
model.fit(X_poly, y)
# 预测值和残差
y_pred = model.predict(X_poly)
residuals = y - y_pred
# 计算误差带(预测值的标准差)
error = np.std(residuals)
# 绘图
plt.figure(figsize=(106))  # 设置画布大小
# 绘制原始数据
plt.scatter(X, y, color='blue', label='Data', alpha=0.7, edgecolor='k')
# 绘制拟合曲线
plt.plot(X, y_pred, color='red', label='Polynomial Fit', linewidth=2)
plt.fill_between(X.flatten(), y_pred - error, y_pred + error, color='red', alpha=0.2, label='Error Band')
plt.title('Higher Degree Polynomial Regression with Error Band', fontsize=16)
plt.xlabel('X', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.legend(fontsize=12)
plt.grid(True, linestyle='--', alpha=0.7)
# 显示图形
plt.tight_layout()
plt.show()

这段代码使用了 PolynomialFeatures 来对自变量进行多项式特征变换,然后使用 LinearRegression 拟合多项式回归模型,并绘制了原始数据和拟合曲线的图像。

如果有问题,随时再反馈~

# 如何处理过拟合

读者问: 咱们在实验当中,很多时候回归模型出现了过拟合,有没有通用的方式,如何识别和解决这个问题呢?

答: 你好。咱们先聊聊过拟合,过拟合是指模型在训练数据上表现很好,但在未见过的数据上表现不佳的情况。

这种现象通常发生在模型过于复杂或者训练数据量不足的情况下。针对回归算法中出现的过拟合问题,我们可以采取以下方法来识别和解决:

识别过拟合

解决过拟合

下面是一个使用岭回归来解决回归模型过拟合问题的示例代码:

from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
import numpy as np
import matplotlib.pyplot as plt
# 生成一些模拟数据
np.random.seed(0)
X = 2 * np.random.rand(1001)
y = 4 + 3 * X + np.random.randn(1001)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 特征缩放
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 使用岭回归解决过拟合问题
ridge_reg = Ridge(alpha=1)  # alpha为正则化参数
ridge_reg.fit(X_train_scaled, y_train)
# 计算在训练集和测试集上的均方误差
train_error = mean_squared_error(y_train, ridge_reg.predict(X_train_scaled))
test_error = mean_squared_error(y_test, ridge_reg.predict(X_test_scaled))
print("训练集均方误差:", train_error)
print("测试集均方误差:", test_error)
# 绘制学习曲线
alphas = np.linspace(010100)
train_errors = []
test_errors = []
for alpha in alphas:
    ridge_reg = Ridge(alpha=alpha)
    ridge_reg.fit(X_train_scaled, y_train)
    train_errors.append(mean_squared_error(y_train, ridge_reg.predict(X_train_scaled)))
    test_errors.append(mean_squared_error(y_test, ridge_reg.predict(X_test_scaled)))
plt.plot(alphas, train_errors, label='Training error')
plt.plot(alphas, test_errors, label='Testing error')
plt.xlabel('Alpha')
plt.ylabel('Mean Squared Error')
plt.title('Ridge Regression')
plt.legend()
plt.show()

在这个示例中,我们使用岭回归来解决过拟合问题。通过调整正则化参数alpha,我们可以控制正则化的程度,从而调节模型的复杂度,避免过拟合。

最后,通过绘制学习曲线,我们可以直观地观察到模型在不同正则化参数下的表现,从而选择合适的参数值。

最后

大家有问题可以直接在评论区留言即可~

喜欢本文的朋友可收藏、点赞、转发起来!

往期精彩回顾





请备注:”昵称-学校/公司-研究方向“,例如:”张小明-浙大-CV“加群。

也可以加入机器学习交流qq群772479961


阅读原文

跳转微信打开

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

回归类算法 特征工程 模型诊断 学习曲线 线性回归
相关文章