目录
普通最小二乘法
范数
范数(norm)是数学中的一种基本概念。在泛函分析中,它定义在赋范线性空间中,并满足一定的条件,即①非负性;②齐次性;③三角不等式。它常常被用来度量某个向量空间(或矩阵)中的每个向量的长度或大小。将数视为向量。
当p取1,2,无穷的时候分别是以下几种最简单的情形:
1-范数:║x║1=│x1│+│x2│+…+│xn│
2-范数:║x║2=(│x1│2+│x2│2+…+│xn│2)1/2
∞-范数:║x║∞=max(│x1│,│x2│,…,│xn│)
其中2-范数就是通常意义下的距离。
对于这些范数有以下不等式:║x║∞ ≤ ║x║2 ≤ ║x║1 ≤ n1/2║x║2 ≤ n║x║∞
另外,若p和q是赫德尔(Hölder)共轭指标,即1/p+1/q=1,那么有赫德尔不等式:
|<x,y>| = ||xH*y| ≤ ║x║p║y║q
当p=q=2时就是柯西-许瓦兹(Cauchy-Schwarz)不等式。
岭回归
Ridge
回归通过对系数的大小进行惩罚来解决普通最小二乘的一些问题 。脊系数使受惩罚的残差平方和最小化:
正则化:
L1正则化
L2正则化
套索回归
从数学上讲,它由带有正则化项的线性模型组成。最小化的目标函数是:
套索估计因此解决了最小二乘罚分的最小化 α||w||1 添加,在哪里 α 是一个常数, ||w||1 是个 ℓ1-系数向量的范数。
拟合的时候,拟合函数的系数往往非常大,为什么?如下图所示,过拟合,就是拟合函数需要顾忌每一个点,最终形成的拟合函数波动很大。在某些很小的区间里,函数值的变化很剧烈。这就意味着函数在某些小区间里的导数值(绝对值)非常大,由于自变量值可大可小,所以只有系数足够大,才能保证导数值很大。
而正则化是通过约束参数的范数使其不要太大,所以可以在一定程度上减少过拟合情况。
弹性网络
弹性网络
是一种使用 L1, L2 范数作为先验正则项训练的线性回归模型。 这种组合允许拟合到一个只有少量参数是非零稀疏的模型,就像 Lasso
一样,但是它仍然保持了一些类似于 Ridge
的正则性质。我们可利用 l1_ratio
参数控制 L1 和 L2 的凸组合。
弹性网络在很多特征互相联系的情况下是非常有用的。Lasso 很可能只随机考虑这些特征中的一个,而弹性网络更倾向于选择两个。
在实践中,Lasso 和 Ridge 之间权衡的一个优势是它允许在循环过程(Under rotate)中继承 Ridge 的稳定性。
在这里,最小化的目标函数是
多任务套索
MultiTaskLasso
是,估计多个回归问题共同稀疏系数的线性模型:y
是形状的2D阵列。约束条件是所有回归问题(也称为任务)的所选特征都相同。(n_samples, n_tasks)
下图比较了通过简单套索或MultiTaskLasso获得的系数矩阵W中非零项的位置。套索估计产生分散的非零值,而MultiTaskLasso的非零值是完整的列。
其他回归模型代码演示:
导包
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.model_selection import train_test_split
#均方误差
from sklearn.metrics import mean_squared_error,r2_score
from sklearn import datasets
# CV crosss validation :交叉验证
from sklearn.linear_model import LinearRegression,Ridge,Lasso,ElasticNet,ElasticNetCV,LassoCV
加载糖尿病数据
diabetes = datasets.load_diabetes()
X = diabetes['data']
y = diabetes['target']
训练
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.15)
线性模型
lr = LinearRegression()
lr.fit(X_train,y_train)
# 回归问题的得分,不是准确率
lr.score(X_test,y_test)
回归问题得分计算规则
'''The coefficient R^2 is defined as (1 - u/v), where u is the residual
sum of squares ((y_true - y_pred) ** 2).sum() and v is the total
sum of squares ((y_true - y_true.mean()) ** 2).sum().'''
u = ((y_test - y_)**2).sum()
v = ((y_test - y_test.mean())**2).sum()
r2 = 1 - u/v
r2
score越大,算法越好。
均方误差
mean_squared_error(y_test,y_)
均方误差,越大越不好
使用岭回归
rigde = Ridge(alpha=0.001)#alpha越小越不好,当为0的时候,就是线性回归。
rigde.fit(X_train,y_train)
print(rigde.score(X_test,y_test))
y_ = rigde.predict(X_test)
mean_squared_error(y_test,y_)
交叉验证
from sklearn.linear_model import RidgeCV
ridgeCV = RidgeCV(alphas=np.logspace(-5,1,50),scoring='r2',cv = 6)#等比数列找最佳参数
ridgeCV.fit(X_train,y_train)
y_ = ridgeCV.predict(X_test)
r2_score(y_test,y_)
ridgeCV = RidgeCV(alphas=np.linspace(0.01,5,50),scoring='r2',cv = 6)#等差数列
ridgeCV.fit(X_train,y_train)
y_ = ridgeCV.predict(X_test)
r2_score(y_test,y_)
数值比较小的时候使用logspace,效果更好一点。