python-sklearn岭回归与lasso回归模型代码实操
hello大家好这里是小L😊在这里想和大家一起学习一起进步。💪
这次笔记内容:学习岭回归与LASSO回归模型的sklearn实现。岭回归:平方和(L2正则化);LASSO回归:绝对值(L1正则化)。
为了防止线性回归的过拟合,加了正则化系数,系数可能有正有负,因此将他的绝对值或者平方和加起来,使得误差平方和最小。
L2正则化

sklearn.linear_model.Ridge(
- alpha=1:正则化因子(系数theta),入越大,越限制theta(即斜率k)越平缓,系数越小。系数越小误差越小。入越大,绝对值越接近于0。(限制x的发展,如果取0,x放飞)
- fit_ intercept=True:截距,是否计算该模型截距。(除非数据标准化之后可false. )
- normalize=False:标准化false,标准化一般在建模之前做(sklearn.preprocessing.StandardScale)。
- copy_X=True:原始的x还在,中间的用另一个存在。如false不要原来的x,新数据覆盖旧数据。
- max_iter=None: 最大迭代次数
- tol =0.001:忍耐力,每努力一次提升的效果不大,提升没有超过0.001就停止
- solver =‘auto’:提供很多方法
- random_state:随机种子
)
属性
- intercept_ :截距
- coef_ :系数theta1到thetan,第几个自变量前面的系数,没有截距,只限制theta1–thetan来防止过拟合(决定斜率k),theta0(截距)没有关系
- n_iter_:迭代多少次
方法
- fit 训练
- predict预测
- score模型评估,不大于1,越大越好
- get_params返回超参数的值
- set_params修改超参数的值重新训练
from sklearn.datasets import load_diabetes
diabetes=load_diabetes()#以糖尿病模型为例
X=diabetes.data#自变量
y=diabetes.target#因变量
from sklearn.model_selection import train_test_split#数据划分
X_train,X_test,y_train,y_test=train_test_split(X,y,random=8)
from sklearn.linear_model import Ridge#导入岭回归模型
ridge=Ridge()#模型实例化
ridge.fit(X_train,y_train)#模型训练
print("训练集的得分为:{:,2f}".format(ridge.score(X_train,y_train)))
print("测试集的得分为:{:,2f}".format(ridge.score(X_test,y_test)))
运行结果如下:
训练数据集得分:0.43
测试数据集得分:0.43
可以看出效果并不是很好,但是也不能因为一次结果否定这个模型,可以通过调参的方法,重新进行模型训练。
#岭回归调参
#正则化系数alpha=10
ridge10=Ridge(alpha=10).fit(X_train,y_train)
print("训练数据集得分:{:.2f}".format(ridge10.score(X_train,y_train)))
print("测试数据集得分:{:.2f}".format(ridge10.score(X_test,y_test)))
运行结果如下:
训练数据集得分:0.15
测试数据集得分:0.16
可以看出结果更加糟糕
#正则化系数alpha=0.1
ridge01=Ridge(alpha=0.1).fit(X_train,y_train)
print("训练数据集得分:{:.2f}".format(ridge01.score(X_train,y_train)))
print("测试数据集得分:{:.2f}".format(ridge01.score(X_test,y_test)))
运行结果如下:
训练数据集得分:0.52
测试数据集得分:0.47
#岭迹分析
#10个特征0-9,在4种回归的系数画出来
#模型系数的可视化比较
%matplotlib inline
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.plot(ridge.coef_,'s',label='Ridge alpha=1')
plt.plot(ridge10.coef_,'^',label='Ridge alpha=10')
plt.plot(ridge01.coef_,'v',label='Ridge alpha=0.1')
plt.plot(lr.coef_,'o',label='linear regression')
plt.xlabel("系数序号")
plt.ylabel("系数量级")
plt.hlines(0,0,len(lr.coef_))#hlines水平线从0到10(查)
plt.legend(loc='best')
plt.grid(linestyle=':')

alpha越大,绝对值越接近于0。(限制x的发展,如果取0,x放飞)
#绘制学习曲线:取固定alpha的值,改变训练集的数量
import numpy as np
from sklearn.model_selection import learning_curve,KFold
def plot_learning_curve(est,X,y):
training_set_size,train_scores,test_scores=learning_curve(
est,X,y,train_sizes=np.linspace(.1,1,20),cv=KFold(20,shuffle=True,random_state=1))
estimator_name=est.__class__.__name__
line=plt.plot(training_set_size,train_scores.mean(axis=1),'--',
label='training'+estimator_name)
plt.plot(training_set_size,test_scores.mean(axis=1),'-',
label='test'+estimator_name,c=line[0].get_color())
plt.xlabel('Training set size')
plt.ylabel('Score')
plt.ylim(0,1.1)
plot_learning_curve(Ridge(alpha=1),X,y)
plot_learning_curve(LinearRegression(),X,y)
plt.legend(loc=(0,1.05),ncol=2,fontsize=11)
plt.grid(linestyle=':')

L1正则化

sklearn.linear_model.Lasso(
- alpha=1:正则化因子(系数theta),入越大,越限制theta(即斜率k)越平缓,系数越小。系数越小误差越小。入越大,绝对值越接近于0。(限制x的发展,如果取0,x放飞)
- fit_ intercept=True:截距,是否计算该模型截距。(除非数据标准化之后可false. )
- normalize=False:标准化false,标准化一般在建模之前做(sklearn.preprocessing.StandardScale)。
- precompute=False
- **copy_X=**True:原始的x还在,中间的用另一个存在。如false不要原来的x,新数据覆盖旧数据。
- max_iter=1000: 最大迭代次数
- tol =0.0001:忍耐力,每努力一次提升的效果不大,提升没有超过0.001就停止
- warm_start =True:下一次运行会从当前的点继续往下走,若False每次都重新运行一次[重新开始](深度学习中经常有这个参数)
- positive=False
- random_state=None:随机种子
selection=‘cyclic’
)
from sklearn.datasets import load_diabetes
diabetes=load_diabetes()#以糖尿病模型为例
X=diabetes.data#自变量
y=diabetes.target#因变量
from sklearn.model_selection import train_test_split#数据划分
X_train,X_test,y_train,y_test=train_test_split(X,y,random=8)
from sklearn.linear_model import Lasso#导入Lasso回归模块
lasso=Lasso()#模型实例化
lasso.fit(X_train,y_train)#模型训练
print("套索回归在训练集的得分为:{:,2f}".format(lasso.score(X_train,y_train)))
print("套索回归在测试集的得分为:{:,2f}".format(lasso.score(X_test,y_test)))
运行结果如下:
训练数据集得分:0.36
测试数据集得分:0.37
可以看出效果并不是很好,但是也不能因为一次结果否定这个模型,可以通过调参的方法,重新进行模型训练。
#岭回归圈圈(L2范数,里面可以有多个0,削尖,把很多特征都削成0),Lasso回归四条直线(L1范数方形)
lasso和岭回归,根据最小二乘法,最后需要使误差最小。



由于岭回归对w的限制空间是圆形的,lasso对w的限制空间是由棱角的。椭圆更容易切在w为某一维的图形为有棱角的图形,即Lasso回归模型。(圆形有凸起会阻挡切在0的位置)
LASSO回归相对于岭回归,更适合做特征选择。(面试问题)
怎样调节优化多个特征,选出更重要的特征,使得我们的精度更高
print("套索回归使用的特征数:{}".format(np.sum(lasso.coef_!=0)))
运行结果如下:
套索回归使用的特征数:3
比较一下岭回归和Lasso回归中能使用的特征数
Lasso回归
lasso.coef_
运行结果如下:
array([ 0. , -0. , 384.73421807, 72.69325545,
0. , 0. , -0. , 0. ,
247.88881314, 0. ])
岭回归
ridge.coef_
运行结果如下:
array([ 36.8262072 , -75.80823733, 282.42652716, 207.39314972,
-1.46580263, -27.81750835, -134.3740951 , 98.97724793,
222.67543268, 117.97255343])
#增大最大迭代次数的默认设置,(默认max_iter=1000)
lasso=Lasso(max_iter=100000)
lasso.fit(X_train,y_train)
print("训练数据集得分:{:.2f}".format(lasso.score(X_train,y_train)))
print("测试数据集得分:{:.2f}".format(lasso.score(X_test,y_test)))
print("套索回归中使用的特征数:{}".format(lasso.score(X_test,y_test)))
运行结果如下:
训练数据集得分:0.36
测试数据集得分:0.37
套索回归中使用的特征数:0.36561858962128
可以看出结果并没有什么变化,所以换一个参数继续调参
#增加最大迭代次数的默认值设置,(默认max_iter=1000)
#同时调整alpha的值
lasso01=Lasso(alpha=0.1,max_iter=100000)
lasso01.fit(X_train,y_train)
print("训练数据集得分:{:.2f}".format(lasso01.score(X_train,y_train)))
print("测试数据集得分:{:.2f}".format(lasso01.score(X_test,y_test)))
print("套索回归中使用的特征数:{}".format(lasso01.score(X_test,y_test)))
运行结果如下:
训练数据集得分:0.52
测试数据集得分:0.48
套索回归中使用的特征数:0.47994757514558173
继续尝试探索规律
#增加最大迭代次数的默认值设置,(默认max_iter=1000)
#同时调整alpha的值
lasso00001=Lasso(alpha=0.0001,max_iter=100000)
lasso00001.fit(X_train,y_train)
print("训练数据集得分:{:.2f}".format(lasso00001.score(X_train,y_train)))
print("测试数据集得分:{:.2f}".format(lasso00001.score(X_test,y_test)))
print("套索回归中使用的特征数:{}".format(lasso00001.score(X_test,y_test)))
结果如下:
训练数据集得分:0.53
测试数据集得分:0.46
套索回归中使用的特征数:0.4594509683706015
alpha越大,选的特征越少。alpha=0时,普通的线性回归(限制x的发展,如果取0,x放飞)
plt.plot(ridge.coef_,'s',label='Ridge alpha=1')
plt.plot(ridge10.coef_,'^',label='Ridge alpha=10')
plt.plot(ridge01.coef_,'v',label='Ridge alpha=0.1')
plt.plot(lr.coef_,'o',label='linear regression')
plt.plot(lasso.coef_,'D',label='Lasso alpha=1')
plt.plot(lasso01.coef_,'H',label='Lasso alpha=0.1')
plt.plot(lasso00001.coef_,'p',label='Lasso alpha=0.0001')
plt.xlabel("系数序号")
plt.ylabel("系数量级")
plt.hlines(0,0,len(lr.coef_))#hlines水平线从0到10(查)
plt.legend(loc='best')
plt.grid(linestyle=':')

关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby
在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我有一些非常大的模型,我必须将它们迁移到最新版本的Rails。这些模型有相当多的验证(User有大约50个验证)。是否可以将所有这些验证移动到另一个文件中?说app/models/validations/user_validations.rb。如果可以,有人可以提供示例吗? 最佳答案 您可以为此使用关注点:#app/models/validations/user_validations.rbrequire'active_support/concern'moduleUserValidationsextendActiveSupport:
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs