1. 线性回归概述python
回归的目的是预测数值型数据的目标值,最直接的方法就是根据输入写出一个求出目标值的计算公式,也就是所谓的回归方程,例如y = ax1+bx2,其中求回归系数的过程就是回归。那么回归是如何预测的呢?当有了这些回归系数,给定输入,具体的作法就是将回归系数与输入相乘,再将结果加起来就是最终的预测值。说到回归,通常指的都是线性回归,固然也存在非线性回归,在此不作讨论。算法
假定输入数据存在矩阵x中,而回归系数存放在向量w中。那么对于给定的数据x1,预测结果能够经过y1 = x1Tw给出,那么问题就是来寻找回归系数。一个最经常使用的方法就是寻找偏差最小的w,偏差能够用预测的y值和真实的y值的差值表示,因为正负差值的差别,能够选用平方偏差,也就是对预测的y值和真实的y值的平方求和,用矩阵可表示为:
\[ (y - xw)T(y - xw) \]
如今问题就转换为寻找使得上述矩阵值最小的w,对w求导为:xT(y - xw),令其为0,解得:
\[ w = (xTx)-1xTy \]
这就是采用此方法估计出来的.dom
案例: 糖尿病回归分析函数
import numpy as np import pandas as pd from pandas import Series,DataFrame import matplotlib.pyplot as plt %matplotlib inline #导包读取 from sklearn import datasets diabetes = datasets.load_diabetes() #生成DataFrame 与 Series对象 train = DataFrame(data = diabetes.data,columns = diabetes.feature_names) target = diabetes.target # 数据集拆分 训练集和样本集 # 模型选择的包 from sklearn.model_selection import train_test_split ## train 数据样本集 # target 样本标签 # test_size 测试集的比例 # random_state 随机数种子,限定随机取值的随机顺序,每个种子固定一组随机数 X_train, X_test, y_train, y_test = train_test_split(train, target, test_size=0.1, random_state=42) #导入线性回归与KNN模型 from sklearn.linear_model import LinearRegression from sklearn.neighbors import KNeighborsRegressor #训练数据 linear = LinearRegression() linear.fit(X_train,y_train) #预测数据 y_ = linear.predict(X_test) plt.plot(y_,label='Predict') plt.plot(y_test,label='True') plt.legend()
# 线性回归模型的拟合度的好坏,就是看真实值和预测值之间的偏差的大小 # 残差直方图,评价回归模型的好坏,瘦高就是好,矮胖就是很差 plt.hist(y_test - y_,rwidth=0.9,bins=10) plt.xlabel('cost-value') plt.ylabel('numbers')
# 还能够用r2_score来评估回归模型的好坏,拟合优度 # 比较不一样的回归模型的r2的分值大小,越大越好 from sklearn.metrics import r2_score r2_score(y_test,y_) #0.5514251914993504
# 使用KNN回归器处理 knn = KNeighborsRegressor(n_neighbors=7) knn.fit(X_train,y_train) knn_y_ = knn.predict(X_test) plt.plot(y_,label='Linear-Predict') plt.plot(knn_y_,label='knn-Predict') plt.plot(y_test,label='True') plt.legend()
# 先用残差直方图比较KNN和Linear哪一个更好 plt.figure(figsize=(10,4)) axes1 = plt.subplot(1,2,1) axes1.hist(knn_y_ - y_test,rwidth=0.9) axes1.set_xlabel('cost-value') axes1.set_ylabel('numbers') axes1.set_title('KNN') axes2 = plt.subplot(1,2,2) axes2.hist(y_test - y_,rwidth=0.9,bins=10) axes2.set_xlabel('cost-value') axes2.set_ylabel('numbers') axes2.set_title('Linear')
注意:工具
np.random.seed(1)
np.random.randint(0,10,size=10)测试array([5, 8, 9, 5, 0, 0, 1, 7, 6, 9])
1.概述优化
针对于线性回归存在的欠拟合现象,能够引入一些误差获得局部加权线性回归对算法进行优化。在该算法中,给待测点附近的每一个点赋予必定的权重,进而在所创建的子集上进行给予最小均方差来进行普通的回归,分析可得回归系数w可表示为:
\[ w = (xTWx)-1xTWy, \]
其中W为每一个数据点赋予的权重,那么怎样求权重呢,核函数能够当作是求解点与点之间的类似度,在此能够采用核函数,相应的根据预测点与附近点之间的类似程度赋予必定的权重,在此选用最经常使用的高斯核,则权重能够表示为:
\[ w(i,i) = exp(|x(i) - x| / -2k2), \]
其中K为宽度参数,至于此参数的取值,目前仍没有一个确切的标准,只有一个范围的描述,因此在算法的应用中,能够采用不一样的取值分别调试,进而选取最好的结果。spa
1.概述调试
为了解决上述问题,统计学家引入了“岭回归”的概念。简单说来,岭回归就是在矩阵XTX上加上一个λr,从而使得矩阵非奇异,从而能对XTX + λx求逆。其中矩阵r为一个m*m的单位矩阵,对角线上的元素全为1,其余元素全为0,而λ是一个用户定义的数值,这种状况下,回归系数的计算公式将变为:
\[ w = (xTx+λI)-1xTy, \]
其中I是一个单位矩阵。code
岭回归就是用了单位矩阵乘以常量λ,由于只I贯穿了整个对角线,其他元素为0,形象的就是在0构成的平面上有一条1组成的“岭”,这就是岭回归中岭的由来。
岭回归最早是用来处理特征数多与样本数的状况,如今也用于在估计中加入误差,从而获得更好的估计。这里引入λ限制了全部w的和,经过引入该惩罚项,可以减小不重要的参数,这个技术在统计学上也叫作缩减。缩减方法能够去掉不重要的参数,所以能更好的理解数据。选取不一样的λ进行测试,最后获得一个使得偏差最小λ。
优势 :
缩减方法能够去掉不重要的参数,所以能更好地理解数据。此外,与简单的线性回归相比,缩减法能取得更好的预测效果
岭回归是加了二阶正则项的最小二乘,主要适用于过拟合严重或各变量之间存在多重共线性的时候,岭回归是有bias的,这里的bias是为了让variance更小。
为了获得一致假设而使假设变得过分严格称为过拟合
bias:指的是模型在样本上的输出与真实值的偏差
variance:指的是每一个模型的输出结果与全部模型平均值(指望)之间的偏差
特色
应用场景:
2.变量间存在共线性(最小二乘回归获得的系数不稳定,方差很大)
3.应用场景就是处理高度相关的数据
多重共线性(Multicollinearity)是指线性回归模型中的解释变量之间因为存在精确相关关系或高度相关关系而使模型估计失真或难以估计准确
案例: 岭回归案例分析
import numpy as np import pandas as pd from pandas import Series,DataFrame n_samples = 5 n_features = 3 #生成5行3列的样本数据 train = np.random.random(size=(n_samples,n_features)) target = [1,2,3,4,5] from sklearn.linear_model import LinearRegression #导入线性回归模型 linear = LinearRegression() linear.fit(train,target) # 比较普通线性回归和岭回归的区别 from sklearn.linear_model import Ridge from sklearn.linear_model import Lasso n_samples = 200 n_features = 10 #生成样本数据 train = np.random.random(size=(n_samples,n_features)) target = np.random.randint(0,10,size=200) # alpha就是岭回归系数 # 岭回归系数越大,原始系数被压缩的越严重 # 岭回归系数越小,原始系数越趋向于线性回归模型的系数 ridge = Ridge(alpha=10) linear = LinearRegression() # 岭回归的惩罚系数 # 惩罚系数越大,原始系数的做用就越小 # 惩罚系数越小,原始系数的做用就越大 lasso = Lasso(alpha=0.1) ridge.fit(train,target) linear.fit(train,target) lasso.fit(train,target) import matplotlib.pyplot as plt %matplotlib inline ridge_coef = ridge.coef_ line_coef = linear.coef_ lasso_coef = lasso.coef_ plt.plot(ridge_coef,label='Ridge') plt.plot(line_coef,label='Linear') plt.plot(lasso_coef,label='Lasso') plt.legend() plt.title('coefs')
1 概述
Lasso回归: 最小绝对值收缩和选择算子
与岭回归相似,它也是经过增长惩罚函数来判断、消除特征间的共线性。
对于参数w增长一个限定条件,能达到和回归同样的效果:
\[ ∥w∥1=∑i=1d|wi|≤λ \]
当λ足够小时,一些影响较弱的系数会所以被迫缩减到0
综合案例 : 波士顿房价
import numpy as np import pandas as pd from pandas import Series,DataFrame import matplotlib.pyplot as plt %matplotlib inline #导包解析数据 from sklearn import datasets boston = datasets.load_boston() train = boston.data target = boston.target #切分出样本集 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,random_state=2) #用三种模型分别预测 linear = LinearRegression() ridge = Ridge(alpha=0) lasso = Lasso(alpha=0) linear.fit(X_train,y_train) ridge.fit(X_train,y_train) lasso.fit(X_train,y_train) y1_ = linear.predict(X_test) y2_ = ridge.predict(X_test) y3_ = lasso.predict(X_test) print("linear:{},ridge:{},lasso:{}".format(r2_score(y_test,y1_),r2_score(y_test,y2_),r2_score(y_test,y3_))) #linear:0.778720987477258,ridge:0.778720987477258,lasso:0.7787209874772579
# 应该采用普通线性回归处理 plt.plot(y1_,label='Predict') plt.plot(y_test,label='True') plt.xlabel('features') plt.ylabel('prices') plt.legend()
import numpy as np import matplotlib.pyplot as plt %matplotlib inline # 根据实际值与预测值,给模型打分 from sklearn.metrics import r2_score np.random.seed(42) #给numpy随机数指定种子,这样生成随机数,就会固定 n_samples,n_features = 50,200 #生成样本 x = np.random.randn(n_samples,n_features) #系数,也就是W coef = 3*np.random.randn(n_features) #系数归零化索引 inds = np.arange(n_features) #打乱顺序 np.random.shuffle(inds) #对系数进行归零化处理 coef[inds[10:]] = 0 #目标值 y = np.dot(x,coef) #增长噪声 y += 0.01*np.random.normal(n_samples) #训练数据 x_train,y_train = x[:n_samples//2],y[:n_samples//2] #测试数据 x_test,y_test = x[n_samples//2:],y[n_samples//2:]
#使用普通线性回归 from sklearn.linear_model import LinearRegression lreg = LinearRegression() #训练数据 reg = lreg.fit(x_train,y_train) #预测数据 y_pred = lreg.predict(x_test) r2_score(y_test,y_pred) #输出 0.04200879234206356
#使用岭回归 from sklearn.linear_model import Ridge ridge = Ridge() #训练数据 reg2 = ridge.fit(x_train,y_train) #预测数据 y_pred = ridge.predict(x_test) #获取回归模型的分数 r2_score(y_test,y_pred) #输出 0.04340880021578697
from sklearn.linear_model import Lasso lasso = Lasso() reg3 = lasso.fit(x_train,y_train) y_pred_lasso = lasso.predict(x_test) r2_score(y_test,y_pred_lasso) #输出 0.2429444024252334
# 画出参数 plt.figure(figsize=(12,8)) #线性回归 plt.subplot(221) plt.plot(reg.coef_,color = 'lightgreen',lw = 2,label = 'lr coefficients') plt.legend() #岭回归 plt.subplot(222) plt.plot(reg2.coef_,color = 'red',lw = 2,label = 'ridge coefficients') plt.legend() #Lasso回归 plt.subplot(223) plt.plot(reg3.coef_,color = 'gold',lw = 2,label = 'lasso coefficients') plt.legend() #测试数据系统w plt.subplot(224) plt.plot(coef,color = 'navy',lw = 2,label = 'original coefficients') plt.legend()
总结:
与分类同样,回归是预测目标值的过程。回归与分类的不一样在于回归预测的是连续型变量,而分类预测的是离散型的变量。回归是统计学中最有力的工具之一。若是给定输入矩阵x,xTx的逆若是存在的话回归法能够直接使用,回归方程中的求得特征对应的最佳回归系数的方法是最小化偏差的平方和,判断回归结果的好坏能够利用预测值和真实值之间的相关性判断。当数据样本总个数少于特征总数时,矩阵x,xTx的逆不能直接计算,这时能够考虑岭回归。