815惩罚回归之Boston_housing exercise

在tutorial1里,part b是关于boston housing的练习,这个练习主要有以下几个步骤:
1.读取数据,构建自变量的平方项和三次方项,为自变量ZN构建一个哑变量
2.对数据进行标准化,跑一个最小二乘回归
3.使用Lasso做惩罚回顾
4.使用交叉验证做Lasso

# -*- coding: utf-8 -*-
"""
Created on Fri Jan 28 13:35:35 2022

@author: Clementine

"""

# In[1]:
#首先是我们熟悉的导入包过程
#可以看到有些包用都没用,不知道他为什么要导入,但是他要导入就导入吧
import numpy as np
import pandas as pd
import seaborn as sns
import requests
from matplotlib import pyplot as plt
from urllib.request import urlopen
sns.set()
from sklearn.datasets import load_boston #使用sklearn连接boston数据库
from sklearn import linear_model #sklearn是一个机器学习包,这里导入的是线性模型

x,y=load_boston(return_X_y=True) #从数据库导入数据

y=pd.DataFrame(y, columns=['medv']) #把数据转换成pandas的dataframe类型
x=pd.DataFrame(x, columns=["crim","zn","indus","chas","nox","rm","age","dis","rad","tax","ptratio","b","lstat"])

sns.set(rc={'figure.figsize':(11.7,8.27)}) #设置图片参数
sns.distplot(y, bins=30) #生成y的图像
plt.show() #输出y的图像

distribution of y

没啥好说的就是把xy读了进来,然后把y的分布画了出来。


# In[2]:

x2=x**2 #x平方项
x2.columns=x2.columns+'^2'#一开始x2的列名和x的列名一样,这里把列名改成xxx^2,即crim变成crim^2

x3=x**3 #x3次方项
x3.columns=x3.columns+'^3'

dummy=(x['zn']>0)*1 #x中zn列对应的哑变量,如果zn为正,则dummy为1,否则为0
dummy.columns=['zn Dummy']

newX=pd.concat((x, dummy, x2, x3), axis=1) #把x,dummy,x2,x3合成新的dataframe (newX)
#前面改列名就是为了这里,如果一个dataframe里面有同样名称的列名那么调用的时候会出问题的。(虽然我们也没有调用,但是也要严谨

mean=np.mean(newX, axis=0) #计算每列的平均值
std=np.std(newX, axis=0) #计算每列的方差

stdX=(newX-mean)/std #对newX进行标准化

np.std(stdX.iloc[:,1])
#计算第一列的方差,是1哟~(因为标准化了,所以是均值为0方差为1

这里输出了1

# In[3]:

XX=pd.concat((pd.DataFrame(np.ones([newX.shape[0],1]), columns=['intercept']), stdX), axis=1)
#新加一列自变量,全为1,那么这一列对应的beta就是截距~哒哒~

beta=np.linalg.inv(XX.T@XX)@(XX.T@y)
#为了让我们的XX有点存在感,俺把它替换上去了,但是它对应的beta好像是0
#beta=np.linalg.inv(stdX.T@stdX)@(stdX.T@y)
plt.plot(beta)#画出beta

这里要专门解释一下,老师写的代码里面没有使用XX,都是用的stdX,俺觉得不对,俺就要用XX,当然,你也可以用stdX,这样就能得到和老师一样的答案了。
如图是OLS的beta,OLS就是使用np.linalg.inv做的,就是矩阵算出来的。
ols betas
下面是使用Lasso做惩罚回归


# In[4]:

model=linear_model.Lasso(alpha=0.5, tol=1e-4, max_iter=10000)
model.fit(XX,y)

print(model.coef_)

得到如下系数
[ 0. -0. 0. -0. 0.0039127 -0.
0. -0. -0.04050466 -0. -0. -1.41279353
0.54466037 -3.32007833 0. -0.21952744 0. -0.
0.20497481 -0. 0. -0. -0. -0.
-0. -0. 0. -0. -0. 0.
-0. 0.15540629 -0.17625958 3.60267302 -0. -0.
-0. -0. -0. 0. 0. ]

然后我们使用如下语句查看哪些自变量被删掉了,即beta=0

# In[5]:

np.where(model.coef_==0)

得到的结果是
(array([ 0, 1, 2, 3, 5, 6, 7, 9, 10, 14, 16, 17, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 34, 35, 36, 37, 38, 39, 40],
dtype=int64),)

随后,将beta系数画出来

# In[6]:

idx=np.where(model.coef_!=0)
XX.iloc[:,list(idx[0][:])]
plt.plot(model.coef_)

lasso beta

然后是交叉验证的Lasso,关于交叉验证是验证什么,我个人认为是lambda的选择,我看那个函数的参数没看懂,有想要弄懂的可以到
偷来的sklearn.linear_model.LassoCV()网页
如果你看懂了,麻烦也给我讲讲,谢谢(狗头)

这里我们做的是10-fold cross validation,关于这个方法,我想我们是学过的,不过考虑到说不定有网友来看我的笔记,我还是
随便偷了个cross validation链接
方便大家理解什么是交叉验证

# In[7]:

model=linear_model.LassoCV(cv=10, random_state=5, tol=1e-10, max_iter=10000000).fit(XX,y.values.ravel())
print(model.coef_)

得到的结果是:
[ 0. -2.86520855 -2.23432575 -1.09056479 0.0469 -0.74657588
-5.4953677 -0.34864818 -4.91586789 3.08878787 -1.9710501 -3.51545216
1.52223698 -9.53535708 0.99927966 1.26852115 -0. 1.21409531
0.05863961 -1.56442394 0. -0. 2.32359789 0.
-0. 0. 0. 5.37498803 -0. 1.80580263
0. 0.55458561 -0. 7.91782261 0.40985549 0.
0. -0. 1.89813824 -1.05774706 -0. ]

定位被退化为0的beta

# In[8]:

np.where(model.coef_==0)

得到:
(array([ 0, 16, 20, 21, 23, 24, 25, 26, 28, 30, 32, 35, 36, 37, 40],
dtype=int64),)

最后一步啦~画出beta

# In[9]:

idx=np.where(model.coef_!=0)
XX.iloc[:,list(idx[0][:])]
plt.plot(model.coef_)

lassoCV beta
请自行思考这些beta图的不同说明了什么,因为我也不知道 (狗头)

我宣布,下班!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

端午节放纸鸢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值