阿里云大学笔记——线性回归:梯度下降法

1. 导入波士顿房价数据集

import numpy as np
import pandas as pd

data=pd.read_csv("data/boston.csv")
data.head()
CRIMZNINDUSCHASNOXRMAGEDISRADTAXPTRATIOBLSTATMEDV
00.0063218.02.3100.5386.57565.24.0900129615.3396.904.9824.0
10.027310.07.0700.4696.42178.94.9671224217.8396.909.1421.6
20.027290.07.0700.4697.18561.14.9671224217.8392.834.0334.7
30.032370.02.1800.4586.99845.86.0622322218.7394.632.9433.4
40.069050.02.1800.4587.14754.26.0622322218.7396.905.3336.2

2. 实现线性回归:梯度下降

class LinearRegression:
    """线性回归算法:梯度下降法实现"""
    def __init__(self,alpha,times):
        """alpha: float 学习率。用来控制步长(权重调整的幅度)
           times:int 循环迭代的次数"""
        self.alpha=alpha
        self.times=times
        
    def fit(self,X,y):
        
        X=np.asarray(X)
        y=np.asarray(y)
        #创建权重的向量,初始值为0(或其他值),长度比特征数量多1(多出来的值是截距)
        self.w_=np.zeros(1+X.shape[1])
        #创建损失列表,用来保存每次迭代过后的损失值。损失计算:(预测值-真实值)的平方和/2
        self.loss_=[]
        #进行循环迭代,调整权重值,使损失函数的值不断减小。
        for i in range(self.times):
            #计算预测值
            y_hat=np.dot(X,self.w_[1:])+self.w_[0]
            #计算真实值和预测值之间的差距
            error=y-y_hat
            #将损失值加入到损失列表中
            self.loss_.append(np.sum(error**2)/2)
            # 根据差距调整权重w_,根据公式,调整为:权重(j)=权重(j)+学习率*sum((y-y_hat)*x(j))
            self.w_[0]+=self.alpha*np.sum(error)#截距
            self.w_[1:]+=self.alpha*np.dot(X.T,error)#特征属性
            
    def predict(self,X):
        
        X=np.asarray(X)
        result=np.dot(X,self.w_[1:])+self.w_[0]
        
        return result
    
            

3.数据切分

t=data.sample(len(data),random_state=666)
X_train=t.iloc[:400,:-1]
y_train=t.iloc[:400,-1]
X_test=t.iloc[400:,:-1]
y_test=t.iloc[400:,-1]

4. 线性回归预测(没标准化)

my_reg=LinearRegression(alpha=0.0005,times=20)
my_reg.fit(X_train,y_train)
result=my_reg.predict(X_test)
display(my_reg.w_)
display(my_reg.loss_)
display(np.mean((result-y_test)**2))
array([-6.59441004e+91, -1.40968186e+92, -6.83088551e+92, -7.91819869e+92,
       -4.03805906e+90, -3.74461053e+91, -4.12255808e+92, -4.69487511e+93,
       -2.37774656e+92, -7.33988713e+92, -2.93151961e+94, -1.23169166e+93,
       -2.34499035e+94, -8.68295194e+92])



[118525.505,
 363708382156678.0,
 1.4463556286428806e+24,
 5.755546457407455e+33,
 2.290338437939112e+43,
 9.11407858329823e+52,
 3.6268189476416507e+62,
 1.443241415877832e+72,
 5.743175533643604e+81,
 2.2854156516968003e+91,
 9.094489051263666e+100,
 3.619023569832781e+110,
 1.4401393552929022e+120,
 5.730831321331474e+129,
 2.2805034466177901e+139,
 9.074941624398248e+148,
 3.6112449471793515e+158,
 1.4370439621856128e+168,
 5.718513641305657e+177,
 2.2756017996876753e+187]



4.361920130943844e+194

5. 进行标准化处理

class StandardScaler:
    """该类对数据进行标准化处理"""
    
    def fit (self,X):
        """根据传递的样本,计算每个特征列的均值和方差"""
        X=np.asarray(X)
        self.std_=np.std(X,axis=0)#按列进行
        self.mean_=np.mean(X,axis=0)
        
    def transform(self,X):
        """对给定的数据X进行标准化处理。(将X的每一列都转化为标准正态分布:均值为1,方差为0"""
        
        return (X-self.mean_)/self.std_
    
    def fit_transform(self,X):
        """对数据进行训练,并进行标准化处理"""
        
        self.fit(X)
        return self.transform(X)

6.线性回归预测:标准化处理

#为了避免每个特征属性数量级的不同,从而在梯度下降的过程中带来影响。
#所以对每个特征进行标准化处理

t=data.sample(len(data),random_state=666)
X_train=t.iloc[:400,:-1]
y_train=t.iloc[:400,-1]
X_test=t.iloc[400:,:-1]
y_test=t.iloc[400:,-1]


#对数据进行标准化处理
s=StandardScaler()
X_train=s.fit_transform(X_train)
X_test=s.transform(X_test)

s2=StandardScaler()
y_train=s2.fit_transform(y_train)
y_test=s2.transform(y_test)

#进行线性回归
reg=LinearRegression(alpha=0.0005,times=20)
reg.fit(X_train,y_train)
result1=reg.predict(X_test)
display(np.mean((result1-y_test)**2))
display(reg.w_)
display(reg.loss_)
0.21492617454147625



array([ 5.64659430e-16,  1.95047851e-02,  4.17596271e-02, -6.72431209e-02,
        1.08055415e-01, -1.00875900e-01,  3.19801377e-01, -2.18037208e-02,
       -2.17426807e-01,  8.04056926e-02, -6.75273910e-02, -1.82418768e-01,
        9.39966020e-02, -4.13050262e-01])



[200.0,
 109.21432152379548,
 87.0452598536069,
 76.53800264630138,
 70.55588355152493,
 66.96828493244492,
 64.73083847262916,
 63.272165227255414,
 62.27233491795431,
 61.549981193179754,
 61.00090033178433,
 60.56421933693936,
 60.203637354956086,
 59.89695732596468,
 59.63019822805497,
 59.39425170905927,
 59.18296126355835,
 58.99200309779758,
 58.81822318519731,
 58.65923694602755]

7. 进行可视化展示

import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams["font.family"]="SimHei"
mpl.rcParams["axes.unicode_minus"]=False

plt.figure(figsize=(10,10))
plt.plot(result1,"ro-",label="预测值")
plt.plot(y_test.values,"go--",label="真实值")
plt.title("线性回归—梯度下降")
plt.xlabel("样本序号")
plt.ylabel("房价")
plt.legend()
<matplotlib.legend.Legend at 0x219b25f4648>

在这里插入图片描述

#绘制累计误差值
plt.plot(range(1,reg.times+1),reg.loss_,"ro-")
[<matplotlib.lines.Line2D at 0x219b2792188>]

在这里插入图片描述

#因为房价分析涉及多个维度,不方便进行可视化展示
#所以我们只选择一个维度(RM),画出直线,实现拟合
lr=LinearRegression(alpha=0.0005,times=50)
t=data.sample(len(data),random_state=666)

X_train=t.iloc[:400,5:6]
y_train=t.iloc[:400,-1]
X_test=t.iloc[400:,5:6]
y_test=t.iloc[400:,-1]

#进行标准化处理
s1=StandardScaler()
X_train=s1.fit_transform(X_train)
X_test=s1.transform(X_test)
s2=StandardScaler()
y_train=s2.fit_transform(y_train)
y_test=s2.transform(y_test)

lr.fit(X_train,y_train)
result2=lr.predict(X_test)
display(np.mean((result2-y_test)**2))
0.3576747881088171
plt.scatter(X_train["RM"],y_train)
#查看方程系数
display(lr.w_)
#构建方程
x=np.arange(-5,5,0.1)
y=3.31734640e-16+6.62422223e-01*x
#plt.plot(x,y,"r")
#也可以这样
plt.plot(x,lr.predict(x.reshape(-1,1)),"r")
array([3.31734640e-16, 6.62422223e-01])





[<matplotlib.lines.Line2D at 0x219af61f0c8>]

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值