1.原理
- 线性回归,如果数据不满秩,以及存在多重共线性无法求解,通过L1正则项(lasso)和L2正则项(Ridge)的方式可以求解。
不满秩(针对方阵来说)
一个M*M的方阵,M为阶。方阵经过初等行变换得到的非0行的个数,叫秩。
初等行变换:任意1行和另一行的线性组合,能否等于0.
如:
a1 + b2 + c3 = 1
a2 + b3 + c4 = 3
a2 + b4 + c*6 = 2X W y
1 2 3 w1 1
2 3 4 w2 3
2 4 6 w3 2
此时X为不满秩矩阵,无法求解,因为2行等同,3个未知数,2个公式,无法求解。
- 解决不满秩,多重共线性无法求解的必要性
因为任何样本数据必然具有如下特点:
1.存在噪声
2.多重共线性
而且都是无法避免的
解决多重共线性的问题:
角度一: 算法的角度(正则项)
角度二: 从数据集的角度(主要的解决思路,最有效果)
2. 原理
2.1 岭回归原理
- 加入正则项系数λ
作用: - 1.增加偏差(对样本数据)# 因为直接在数据里加
- 减小方差(最小二乘法,预测值和真实值) # 加了正则项后,会经过最小二乘求w。
- 3.缩减算法: 减少无用特征的影响系数w --> 0
0*(门牌号+5) 100 eg. 缩减的作用:减少过拟合的影响 - 过拟合:模型对训练集的局部特征(个别特征)过分关注导致的
y = f(x) + bias + 正则项
正则项解决了1.矩阵不可求逆 2. 可能会降低噪声的影响
2.2 lasso回归原理
此时100收入 4身高 1地域 0.005电话号 0.01学历 性别
如果将系数和压缩为1,电话号,学历等不重要的系数压缩到近似0了。
3. Ridge回归(岭回归)
3.1 导包,获取特征向量和标签
import numpy as np
X = np.array([[1,2,3,4],[1,3,8,5]])
y = np.array([3,5])
3.2 线性回归和岭回归训练和预测
from sklearn.linear_model import LinearRegression, Ridge
lr = LinearRegression()
lr.fit(X, y)
alpha=1.0 正则项系数
Ridge回归是一个二阶正则项
ridge = Ridge(alpha=1.0)
ridge.fit(X, y)
3.3 获取线性回归的系数和截距
lr.coef_ # 可以通过系数得到各因素的相关性,越大越相关
得到系数array([-5.55111512e-17, 7.40740741e-02, 3.70370370e-01, 7.40740741e-02])
ridge.coef_
得到系数array([0. , 0.06896552, 0.34482759, 0.06896552])
lr.intercept_
得到截距1.4444444444444446
ridge.intercept_
得到截距
1.6206896551724137
4.糖尿病回归分析 (用coef做特征选择)
4.1 导入数据
from sklearn.datasets import load_diabetes
diabetes = load_diabetes()
train = diabetes.data
target = diabetes.target
feature_names = diabetes.feature_names
from pandas import Series, DataFrame
import matplotlib.pyplot as plt
%matplotlib inline
4.2 样本拆分和建模
ridge = Ridge(alpha=1.0) # alpha: 正则项系数
from sklearn.model_selection import train_test_split
X_train ,X_test, y_train, y_test = train_test_split(train, target, test_size=0.2)
ridge.fit(X_train, y_train)
4.3 用系数来表达各个特征对目标的影响
作用:可以根据这个影响的大小来进行特征选择
ridge.coef_
结果:array([ 37.29797438, -74.32803746, 268.00587006, 184.48450326,
10.94253264, -17.99804142, -140.57373159, 134.43872109,
235.1393054 , 124.84227642])
4.4 展示系数
import seaborn as sns
sns.set()
importances = Series(data=ridge.coef_, index=feature_names)
importances.plot(kind='bar')
plt.xticks(rotation=0) # 将横坐标标签方向调整
plt.show()
- 将系数绝对值化并排序展示
importances = Series(data=np.abs(ridge.coef_), index=feature_names).sort_values(ascending=False)
importances.plot(kind='bar')
plt.xticks(rotation=0)
plt.show()
根据特征的重要性,我们发现前7个特征更加重要,所以选择前6个特征重新建模
["sex", "bmi", "bp", "s3", "s4", "s5", "s6"]
4.5 重新建模
4.5.1 获取特征向量和标签
importance_columns = ["sex", "bmi", "bp", "s3", "s4", "s5", "s6"]
dataSets = DataFrame(data=train, columns=feature_names)
dataSets.head()
-
获取重要列数据
X = dataSets[importance_columns]
X.head()
获取特征向量和标签 拆分数据集
y = target
做过特征选择的数据进行拆分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1)
4.5.2 建模并训练评价
ridge = Ridge(alpha=1.0) # 构造岭回归算法对象
ridge.fit(X_train, y_train) # 训练
from sklearn.metrics import mean_squared_error
mean_squared_error(y_test, ridge.predict(X_test))#得到预测结果的 平均平法误差(均方误差)# 2470.843375403734
构造线性回归模型并训练评价
linear = LinearRegression()
linear.fit(X_train, y_train)
mean_squared_error(y_test, linear.predict(X_test)) # 3080.257052972188
4.5.3 比较没做过特征选择的数据集
X_train1 ,X_test1, y_train1, y_test1 = train_test_split(train, target, test_size=0.2, random_state=1) # 样本集拆分
linear = LinearRegression() # 构造线性回归算法对象
linear.fit(X_train1, y_train1) # 用训练数据训练算法对象
mean_squared_error(y_test1, linear.predict(X_test1))# 得到真实值和预测值的均方误差 #2992.5576814529454
Ridge、LienarRegression 的系数可以用来做特征选择
5. 数据建模
核心:数据质量(特征工程) 其次:算法选择和调参
特征工程(目的:让模型可以得到一个更好的数据集)
- 特征选择 (基于算法的选择 ,常用的算法 基于线性回归的模型, 基于决策树的模型)
- 特征提取 (基于经验提取)
- 无量纲处理 (标准正态分布)
- 分箱操作
- 空值填充
- 异常值过滤
6. lasso回归
6.1 导包,获取特征向量和标签
from sklearn.linear_model import Lasso, Ridge, LinearRegression
import numpy as np
X = np.array([[1,2,3,4,5], [2,3,2,1,7]])
y = np.array([1,2])
6.2 数据建模
lasso = Lasso(alpha=0.001) # alpha正则项系数
lasso.fit(X, y)
lasso.coef_ # 获取系数 array([ 0. , 0. , -0. , -0.33288889, 0. ])
ridge = Ridge(alpha=0)
ridge.fit(X, y)
ridge.coef_ # 系数:array([ 0.0625, 0.0625, -0.0625, -0.1875, 0.125 ])
linear = LinearRegression()
linear.fit(X, y)
linear.coef_ # 系数:array([ 0.0625, 0.0625, -0.0625, -0.1875, 0.125 ])