回归分析及模型优化
1、回归分析概括
目标值(因变量)是连续型数据,通过某种函数关系找到因变量和自变量之间的关系,进而预测目标。
- 常见的回归:线性回归、岭回归、非线性回归;
- 回归拟合目标:计算自变量与因变量关系的函数参数;
- 通过不断拟合缩小预测值与真实值的差距:最终使得这个差距(误差项)成为一组均值为0,方差为1的随机数。
2、损失函数
总损失定义为:说明:
- y_i为第i个训练样本的真实值
- h(x_i)为第i个训练样本特征组合预测函数
- 又称最小二乘法
优化模型的目标就是如何尽可能的减少损失。
3、优化算法
使得损失函数值达到最小的方法:正规方程、梯度下降。
正规方程
- X表示自变量
- y表示因变量
- X,y表示矩阵
- 右上角的-1表示逆矩阵(np.linalg.inv(X))
- 右上角的T表示转置(X.T)
- w = np.linalg.inv(X.T.dot(X)).dot(X.T).dot(y)
- 缺点:当特征值过多时,求解速度慢,并且得不到结果
梯度下降
理解:a为学习速率,需要手动指定的超参数,a旁边的的整体表示方向,沿着这个函数的下降的方向找,最终山谷的最低点,然后更新w值使用。其中a设置过大可能会只找到局部最优解。
4、python的API
- statsmodels.formula.api.OLS():普通最小二乘模型拟合- - 常用
- scipy.stats.linregress(): 线性拟合
- scipy.optimize.curve_fit():回归函数拟合
- 使用参考:?回归函数及线性回归分析
5、python机器学习线性模型API
正规方程法计算
sklearn.linear_model.LinearRegressiont(fit_intercept=True)
- fit_intercept:True/False,是否计算偏置(截距)
- LinearRegression.coef_:返回回归系数
- LinearRegression.intercept_:返回偏置(截距)
梯度下降法计算
sklearn.linear_model.SGDRegressor(loss="squared_loss",fit_intercept=True,learning_rate ="invscaling",eta0=0.01)
- SGDRegressor类实现了随机梯度下降学习优化,它支持不同的loss函数和正则化惩罚项来拟合线性回归模型。
- loss:损失类型
- loss="squared_loss":普通最小二乘法
- fit_intercept:是否计算偏置(截距) True/False
- eta0=0.01:起始设定学习率
- learning_rate: 迭代过程中学习率的计算方式:
- "optimal":eta=1.0/(alpha*(t+t0))[default]
- "invscaling":eta=eta0/pow(t,power_t),power_t=0.25:存在父类当中
- "constant":eta=eta0
- 对于一个常数值的学习率来说,可以使用learning_rate='constant',并使用eta0来指定学习率。
- SGDRegressor.coef_:返回回归系数
- SGDRegressor.intercept_:返回偏置
- 更多:https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.SGDRegressor.html
6、机器学习中回归性能评估
均方误差(MSE)越小,模型相对越好。其中m为样本数,y_i为预测值,y~为真实值。
回归性能评估API
- from sklearn.metrics import mean_squared_error #均方误
- error = mean_squared_error(y_true,y_pred)
- y_true:真实值
- y_pred:预测值
- error:返回的均方误差结果
7、欠拟合和过拟合
- 欠拟合:模型拟合欠佳,多加数据及特征变量。
- 过拟合:模型过于复杂,训练集上准确率很高,但测试集上效果差。
- 过拟合原因:原始特征过多,存在嘈杂特征,模型过于复杂,模型尝试去兼顾各个测试数据点。
- 过拟合线性模型解决办法:正则化:L1正则化,L2正则化。
L2正则化
- 作用:可以使得其中一些W的值很小,消弱某个特征的影响。
- 优点:越小的参数说明模型越简单,越简单的模型越不容易产生过度拟合。
- 改进模型:Ridge回归(岭回归)
- 加入L2正则化后的损失函数(m为样本数;n为特征数;alpha(?)正则化力度,惩罚项系数,正则化力度越大,权重系数会越小,正则化力度越小,权重系数会越大):
L1正则化
- 作用:可以使一些特征的W值等于0,删除这个特征的影响
- 改进模型:LASSO回归
8、线性回归的改进–岭回归
岭回归,其实也是一种线性回归。只不过在筛法建立回归方程时候,加上L2正则化的限制,从而达到解决过拟合的效果。
- sklearn.linear_model.Ridge(alpha=1.0,fit_intercept=True,solver=“auto”,nomalize=False)
- 具有L2正则化的线性回归 - 岭回归
- alpha:正则化力度,惩罚项系数(?)。正则化力度越大,权重系数会越小,正则化力度越小,权重系数会越大。取值:0~1,1~10
- solver:会根据数据自动选择优化方法
- sag:如果数据集、特征都比较大,选择随机梯度下降优化
- normalize:数据是否进行标准化
- normalize=False:可以在fit之前调用preprocessing.StandardScaler标准化数据,自动对数据进行标准化
- Ridge.coef_:回归权重
- Ridge.intercept_:回归偏置(截距)
- 更多:https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html
9、案例代码
import numpy as np
import pandas as pd
from sklearn.datasets import load_boston #sklearn波士顿房价预测数据接口
from sklearn.model_selection import train_test_split #划分数据集
from sklearn.preprocessing import StandardScaler #数据标准化
from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge #预估器(正规方程)、预估器(梯度下降学习)、岭回归
from sklearn.metrics import mean_squared_error #均方误
import joblib #模型的加载与保存
def linear1():
"""
正规方程的优化方法对波士顿房价进行预测
:return:
"""
# 1)获取数据
boston = load_boston()#sklearn波士顿房价预测数据
# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
# 3)标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4)正规方程-预估器
estimator = LinearRegression()
estimator.fit(x_train, y_train)
# 5)得出模型
print("正规方程-回归系数为:\n", estimator.coef_)
print("正规方程-截距(偏置)为:\n", estimator.intercept_)
# 6)模型评估
y_predict = estimator.predict(x_test)
# print("预测房价:\n", y_predict)
error = mean_squared_error(y_test, y_predict)
print("正规方程-均方误差为:\n", error)
return None
def linear2():
"""
梯度下降的优化方法对波士顿房价进行预测
:return:
"""
# 1)获取数据
boston = load_boston()
print("特征数量:\n", boston.data.shape)
# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
# 3)标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4)梯度下降-预估器
estimator = SGDRegressor(learning_rate="constant", eta0=0.01, max_iter=10000, penalty="l1")
estimator.fit(x_train, y_train)
# 5)得出模型
print("梯度下降-回归系数为:\n", estimator.coef_)
print("梯度下降-截距为:\n", estimator.intercept_)
# 6)模型评估
y_predict = estimator.predict(x_test)
# print("预测房价:\n", y_predict)
error = mean_squared_error(y_test, y_predict)
print("梯度下降-均方误差为:\n", error)
return None
def linear3():
"""
岭回归对波士顿房价进行预测
:return:
"""
# 1)获取数据
boston = load_boston()
print("特征数量:\n", boston.data.shape)
# 2)划分数据集
x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)
# 3)标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
# 4) 岭回归-预估器
estimator = Ridge(alpha=0.5, max_iter=10000)
estimator.fit(x_train, y_train)
# 保存模型
joblib.dump(estimator, "my_ridge.pkl")
# 加载模型 使用时注销 4)预估器 和 保存模型
# estimator = joblib.load("my_ridge.pkl")
# 5)得出模型
print("岭回归-权重系数为:\n", estimator.coef_)
print("岭回归-偏置(截距)为:\n", estimator.intercept_)
# 6)模型评估
y_predict = estimator.predict(x_test)
# print("预测房价:\n", y_predict)
error = mean_squared_error(y_test, y_predict)
print("岭回归-均方误差为:\n", error)
return None
if __name__ == "__main__":
# 代码1:正规方程的优化方法对波士顿房价进行预测
linear1()
# 代码2:梯度下降的优化方法对波士顿房价进行预测
linear2()
# 代码3:岭回归对波士顿房价进行预测
linear3()
扫码关注更多数据分析与运营知识干货在此,随时学习!