线性回归手写python程序

线性回归可以通过梯度下降和正规方程的方式进行实现求解,这两种算法各有利弊,下面个给出两种算法的python实现,其中数据集使用的是波士顿房价预估数据集。

1. 梯度下降法进行求解
首先对数据集进行处理, 使用梯度下降算法进行求解时, 将数据集 分为测试集和训练集, 并划分出属性和标签。

import numpy as np
import pandas as pd
import random
import matplotlib.pyplot as plt


# 导入数据集
data = pd.read_csv('./Boston-Housing-Price.csv')
m, n = np.shape(data)  # 其中m表示data中样本的数量,n表示属性和标签的总数
data_origin = data.values
data = data_origin/np.mean(data_origin,axis=0)


def split_train_and_test(data,m,n):
    # 首先将数组顺序打乱
    random.shuffle(data)
    # 取出数组的30%作为测试集数据
    data_test = data[:m//3,:]
    data_train = data[m//3:,:]
    # 将测试集和训练集中的属性和标签分出来
    data_test_attr = data_test[:,:n-1]
    data_test_label = data_test[:,n-1]
    data_train_attr = data_train[:,:n-1]
    data_train_label = data_train[:,n-1]
    return data_test_attr,data_test_label,data_train_attr,data_train_label

data_test_attr,data_test_label,data_train_attr,data_train_label = split_train_and_test(data,m,n)


# 建立线性回归模型,使用矢量进行表示,使用了梯度下降的方式
def train(train_Attr,train_Label,num,alpha):
    m,n = np.shape(train_Attr)
    weight=np.ones(n) #生成的是一行n列的数组
    bias = np.zeros(1)
    for i in range(num):
        h = np.dot(train_Attr,weight) + bias # 建立了线性回归模型
        erro = h-train_Label.T
        delt = np.dot(erro.T,train_Attr)
        weight = weight-alpha*delt/m
        bias = bias - alpha*erro.sum()/m
    return weight,bias

weight,bias = train(data_train_attr,data_train_label,200,0.01)

# 进行测试样本的预测
def erro(weight,bias,test_attr,test_label):
    predition = np.dot(test_attr,weight) + bias
    erro = np.square(predition-test_label).sum()
    return erro

list1 = [10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,4000]
erro_list = []
for iteration in list1:
    weight, bias = train(data_train_attr, data_train_label, iteration, 0.01)
    erro_iter = erro(weight, bias, data_test_attr, data_test_label)
    erro_list.append(erro_iter)

# 画出erro随迭代次数的变化曲线
plt.plot(list1,erro_list)
plt.show()
print("最小误差为:",erro_list[-1])   # 大约接近4

2. 正规方程进行求解

import numpy as np
import pandas as pd
import random


# 导入数据集
data = pd.read_csv('./Boston-Housing-Price.csv')
m, n = np.shape(data)  # 其中m表示data中样本的数量,n表示属性和标签的总数
data_origin = data.values
insert = np.ones(m)
data_deal = np.insert(data_origin, 0, values=insert, axis=1)
data = data_deal/np.mean(data_deal,axis=0)


def split_train_and_test(data,m,n):
    # 首先将数组顺序打乱
    random.shuffle(data)
    # 取出数组的30%作为测试集数据
    data_test = data[:m//3,:]
    data_train = data[m//3:,:]
    # 将测试集和训练集中的属性和标签分出来
    data_test_attr = data_test[:,:n]
    data_test_label = data_test[:,n]
    data_train_attr = data_train[:,:n]
    data_train_label = data_train[:,n]
    return data_test_attr,data_test_label,data_train_attr,data_train_label

data_test_attr,data_test_label,data_train_attr,data_train_label = split_train_and_test(data,m,n)

# 根据公式直接计算y_hat
x_xT = np.dot(data_train_attr,data_train_attr.T)
inv_x_xT = np.linalg.pinv(x_xT)   # 求的是广义逆矩阵
y_hat = np.dot(np.dot(inv_x_xT,data_train_label),x_xT)

# 直接计算误差值
erro = np.square(y_hat-data_train_label).sum()
print("封闭解结果为:",erro)  # 最终的误差值为5.3左右

最终结果分析为:梯度下降算法的应用方面比较广泛,如果再使用一些其他的技巧可能会使算法跳出局部的最优解找到全局的最优解。而正规方程可以一次性的将权值求出,但是限制较大,当xTx不可逆时,此方法便不可以使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值