当前位置:   article > 正文

线性回归-最小二乘python实现_最小二乘线性回归代码python

最小二乘线性回归代码python
import numpy as np
import pandas as pd
  • 1
  • 2

波士顿房价数据集字段说明

  • CRIM:房屋所在镇的犯罪率
  • ZN:面积大于25000平方英尺住宅所占的比例
  • INDUS :房屋所在镇非零售区域所占比例
  • CHAS:房屋是否位于河边 若位于河边,值为1,否则为0
  • NOX:一氧化氮的浓度
  • RM:平均房间的数量
  • AGE:1940年前建成房屋所占比例
  • DIS:房屋距离波斯顿五大就业中心的加权距离
  • RAD:距离房屋最近的公路
  • TAX:财产税额度
  • PIRATIO:房屋所在镇师生比例
  • B:计算公式(房屋所在镇非美籍人口所占比例):1000*(房屋所在镇非美籍人口所占比例-0.63)**2
  • LSTAT:弱势群体人口所占比例
  • MEDV:房间的平均价格

data=pd.read_csv(r"F:\数据集\dataset\boston.csv")
#data
#查看数据的基本信息,同时也可以用来查看,各个特征列是否存在缺失值
data.info()
#查看是否有重复值
data.duplicated().any()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 506 entries, 0 to 505
Data columns (total 15 columns):
 #   Column      Non-Null Count  Dtype  
---  ------      --------------  -----  
 0   Unnamed: 0  506 non-null    int64  
 1   crim        506 non-null    float64
 2   zn          506 non-null    float64
 3   indus       506 non-null    float64
 4   chas        506 non-null    int64  
 5   nox         506 non-null    float64
 6   rm          506 non-null    float64
 7   age         506 non-null    float64
 8   dis         506 non-null    float64
 9   rad         506 non-null    int64  
 10  tax         506 non-null    int64  
 11  ptratio     506 non-null    float64
 12  black       506 non-null    float64
 13  lstat       506 non-null    float64
 14  medv        506 non-null    float64
dtypes: float64(11), int64(4)
memory usage: 59.4 KB





False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

定义线性回归类

  • 利用正规方程解出向量 θ \theta θ:
    θ = ( X T X ) − 1 X T Y \theta=(X^{T}X)^{-1}X^{T}Y θ=(XTX)1XTY
class linearRegression:
    """
    使用python实现的线性回归。(最小二乘法)
    
    """
    def fit(self,X,y):
        """
        根据提供的训练数据X ,对模型进行训练。
        Parameters:
        _________
        X:类数组类型。形状:[样本数量,特征数量]
          特征矩阵,用来对模型进行训练。
        y: 类数组类型,形状:[样本数量]
        
        """
        # 将X转换成矩阵格式,注意:这里的X必须是一个完整的数组格式,不能是数组的一部分。所以这里用到X.copy()
        #说明:如果X是数组对象的一部分,而不是完整的对象数据(例如,X是其他对象通过切片传递过来),这是则无法完成矩阵的转换 
        #这里创建X的拷贝对象,避免转换矩阵的时候失败
        X=np.asmatrix(X.copy())
        # y 是一维结构(行向量或列向量),对于一维结构可以不用进行拷贝
        #注意:我们现在需要进行矩阵的计算,因此需要二维的结构,我们通过reshape方法进行转换
        #reshape(-1,1)表示根据实际情况转换成多少行(-1),一列。
        y=np.asmatrix(y).reshape(-1,1)
        #通过最小二乘公式求戒除最佳的权重值
        self.w_=(X.T*X).I*X.T*y
        
    def predict(self,X):
        """
        根据参数传递的样本X,对样本数据进行预测。
        Parameters:
        ___________
        X:类数组类型。形状:[样本数量,特征数量]
          待预测的样本特征(属性)
        Returns:
        ________
        result:数组类型
             预测的结果
        """
        #将X转换成矩阵,注意,需要对X进行拷贝(理由同上)
        X=np.asmatrix(X.copy())
        result=X*self.w_
        #result是一个矩阵,且是二维的,所以将result转化为ndarray数组,进行扁平化(result.ravel())处理,然后返回结果
        #使用ravel()可以将数组进行扁平化处理
        return np.array(result).ravel()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

不考虑截距的情况

#不考虑截距的情况
t=data.sample(len(data),random_state=0)
train_X=t.iloc[:400,:-1]
train_y=t.iloc[:400,-1]
test_X=t.iloc[400:,:-1]
test_y=t.iloc[400:,-1]
lr=linearRegression()
lr.fit(train_X,train_y)
result=lr.predict(test_X)
display(np.mean((result-test_y)**2))
#查看模型的权重值
display(lr.w_)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
16.892575069960635



matrix([[-2.25548227e-03],
        [-9.36187378e-02],
        [ 4.57218914e-02],
        [ 3.67703558e-03],
        [ 2.43746753e+00],
        [-2.96521997e+00],
        [ 5.61875896e+00],
        [-4.94763610e-03],
        [-8.73950002e-01],
        [ 2.49282064e-01],
        [-1.14626177e-02],
        [-2.50045098e-01],
        [ 1.49996195e-02],
        [-4.56440342e-01]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

考虑截距的情况

#考虑截距:增加一列,使该列的所有值都是1
t=data.sample(len(data),random_state=0)
#可以这样增加一列
#t["intercept"]=1,这是在最右边增加intercept列,且该列所有值都取1
#按照习惯,截距作为w0,我们为之而配上一个x0,x0列放在最前面
#t.columns  返回所有列的信息;insert(0,"Intercept"):将Intercept增加到第一列
new_columns=t.columns.insert(0,"Intercept")
#重新安排列的信息,如果值为空,则使用fail_value参数指定的值进行填充
t=t.reindex(columns=new_columns,fill_value=1)
#t
t=data.sample(len(data),random_state=0)
train_X=t.iloc[:400,:-1]
train_y=t.iloc[:400,-1]
test_X=t.iloc[400:,:-1]
test_y=t.iloc[400:,-1]
lr=linearRegression()
lr.fit(train_X,train_y)
result=lr.predict(test_X)
#不知为何lr.w_的值为“nan”
display(np.mean((result-test_y)**2))
#display(lr.w_)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
16.892575069960635
  • 1

可视化

import matplotlib as mpl
import matplotlib.pyplot as plt
#设置字体为黑体,以支持中文显示
mpl.rcParams["font.family"]="SimHei"
#设置在中文字体是,能正常显示负号(-)
mpl.rcParams["axes.unicode_minus"]=False
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
plt.figure(figsize=(10,10))
#绘制预测值
plt.plot(result,"ro-",label="预测值")
#绘制真实值
plt.plot(test_y.values,"go--",label="真实值")
plt.title("线性回归预测——最小二乘法")
plt.xlabel("样本序号")
plt.ylabel("房价")
plt.legend()
plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述


  • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/131500
推荐阅读
相关标签
  

闽ICP备14008679号