机器学习入门之线性回归(3)- 波士顿房价预测(python实现)

一、知识储备

  1. 本次主要完成了线性回归的经典模型-波士顿房价预测,一共十三个特征,假设函数如下:
    h θ ( x ) = [ 1 x 1 1 x 2 1 ⋯ x 13 1 1 x 1 2 x 2 2 ⋯ x 13 2 ⋮ ⋮ ⋯ ⋯ ⋮ 1 x 1 m x 2 m ⋯ x 13 m ] [ θ 0 θ 1 θ 2 ⋮ θ 13 ] (1) h_\theta(x)=\left[ \begin{matrix} 1 & x_1^1 & x_2^1 & \cdots & x_{13}^1 \ 1 &x_1^2 & x_2^2 & \cdots & x_{13}^2\ \vdots & \vdots & \cdots & \cdots & \vdots\ 1 &x_1^m & x_2^m & \cdots & x_{13}^m \end{matrix} \right]\left[ \begin{matrix} \theta_0 \ \theta_1 \ \theta_2 \ \vdots \ \theta_{13} \end{matrix} \right]\tag{1}h θ​(x )=⎣⎢⎢⎢⎡​1 1 ⋮1 ​x 1 1 ​x 1 2 ​⋮x 1 m ​​x 2 1 ​x 2 2 ​⋯x 2 m ​​⋯⋯⋯⋯​x 1 3 1 ​x 1 3 2 ​⋮x 1 3 m ​​⎦⎥⎥⎥⎤​⎣⎢⎢⎢⎢⎢⎡​θ0 ​θ1 ​θ2 ​⋮θ1 3 ​​⎦⎥⎥⎥⎥⎥⎤​(1 )
    也可以表达成函数形式,读者可自行转化,较为简单。
  2. 批量梯度下降
    批量梯度下降的相关知识请读者去看线性回归系列的第一篇文章,这里不详细介绍相关知识,下面主要介绍一下怎么实现正则化( 关于需要正则化原因请看线性回归系列的第二篇),来减少高阶、维度高对拟合、模型的影响,添加的地方有损失函数与梯度下降函数:
    J ( θ ) = 1 2 m ( ∑ i = 0 m ( h θ ( x ( i ) ) − y ( i ) ) 2 ) + λ 2 m ∑ j = 1 n θ j 2 J(\theta)=\frac{1}{2m}(\sum_{i=0}^m(h_\theta(x^{(i)})-y^{(i)})^2)+\frac{\lambda}{2m}\sum_{j=1}^n\theta_j^2 J (θ)=2 m 1 ​(i =0 ∑m ​(h θ​(x (i ))−y (i ))2 )+2 m λ​j =1 ∑n ​θj 2 ​
    实际上上式是可以合并的,为了读者更容易理解,写开了形式。注意:我们规定进行正则化时的θ \theta θ 是从 1开始的,也就是只有特征的系数才会参与正则化。λ \lambda λ 的作用是维护损失函数与正则化参数之间的平衡关系,更好的去拟合训练集的目标和将参数控制得更小的目标,保持假设模型的相对简单。
    有读者应该现在已经明白了下一个需要改变的地方,是的,我们的J ( θ ) J(\theta)J (θ)发生了改变,那么我们梯度下降的减数项也应该发生变化,因为减数项时通过J ( θ ) J(\theta)J (θ)求导得来的( 这块有问题的请移步到线性回归第一篇,梯度下降的知识点
    θ j : = θ j − 1 m ( ∑ i = 0 m ( h θ ( x ( i ) ) − y ( i ) ) x ( i ) + λ θ j ) \theta_j:=\theta_j – \frac{1}{m}(\sum_{i=0}^m(h_\theta(x^{(i)})-y^{(i)})x^{(i)}+\lambda\theta_j)θj ​:=θj ​−m 1 ​(i =0 ∑m ​(h θ​(x (i ))−y (i ))x (i )+λθj ​)
    上面就是加上正则化变化的地方,建议读者从第一篇看过来,这样应该不会有什么障碍,如果哪地方有错或说的不详细,欢迎大家留言。

二、代码实现

  1. 读取与处理数据、拟合图、误差图代码,文件名: housegradient.p
from ftplib import error_reply
import imp
from math import ceil
from pydoc import doc
from turtle import right, shape
import numpy as  np
import matplotlib.pyplot as plt
from housegradient import gradientFun

theta = np.array([0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,0.1,0.2,0.3,0.4])
theta_0 = 0.5

lamda = 0.02
origin_data = np.loadtxt(fname='housing.data')
np.random.shuffle(origin_data)
trans_data = origin_data[0:int(0.8*(np.size(origin_data)/14))]
test_data = origin_data[-ceil(0.2*(np.size(origin_data)/14)):]

trans_data_std = np.std(trans_data[:,0:13],axis=0)

trans_data_std = np.insert(trans_data_std,13,values=[1],axis=0)
trans_data_average = np.mean(trans_data[:,0:13],axis=0)

trans_data_average = np.insert(trans_data_average,13,values=[0],axis=0)
trans_data_handled = (trans_data-trans_data_average)/trans_data_std
trans_data_y = trans_data_handled[:,-1]
error_array_j = np.array([])
for i in range(100):
    if i !=0:

        np.random.shuffle(trans_data_handled)
    trans_data_x = trans_data_handled[:,0:13]
    trans_data_y = trans_data_handled[:,-1]
    current_tran_ones = np.ones((1,np.size(trans_data_y)))

    trans_data_x_batch = np.array_split(trans_data_x,10)
    trans_data_y_batch = np.array_split(trans_data_y,10)

    for j in range(10):
        current_trans_data_x = trans_data_x_batch[j]
        current_trans_data_y = trans_data_y_batch[j]
        y = np.dot(theta,current_trans_data_x.T)+theta_0
        error_array = y-current_trans_data_y
        theta,theta_0= gradientFun(current_trans_data_x,error_array,theta,theta_0=theta_0,lamda=lamda)

    error_y = (np.dot(theta,trans_data_x.T)+theta_0) - trans_data_y

    error_j  = (np.dot(error_y,error_y.T)+lamda*np.dot(theta,theta.T))/(2*np.size(trans_data_y))

    error_array_j=np.concatenate((error_array_j,np.array([error_j])),axis=0)
index = np.arange(0,np.size(error_array_j)).reshape(np.size(error_array_j))

plt.plot(index,error_array_j)
plt.show()

test_data_std = np.std(test_data[:,0:13],axis=0)

test_data_std = np.insert(test_data_std,13,values=[1],axis=0)
test_data_average = np.mean(test_data[:,0:13],axis=0)

test_data_average = np.insert(test_data_average,13,values=[0],axis=0)
test_data_handled = (test_data-test_data_average)/test_data_std
test_data_x = test_data_handled[:,0:13]
test_data_y = test_data_handled[:,-1]

error_test_y = (np.dot(theta,test_data_x.T)+theta_0) - test_data_y

index = np.arange(0,np.size(error_test_y)).reshape(np.size(error_test_y))
error_j  = np.dot(error_test_y,error_test_y.T)/(2*np.size(test_data_y))
print(error_test_y)
plt.figure()
plt.plot(index,error_test_y)
plt.show()
  1. 下面是梯度下降函数,文件名为: housegradient.py
import numpy as np
def gradientFun(x,error_array,theta,theta_0,lamda):
    alpha = 0.006
    theta_0 = theta_0  - alpha * (np.sum(error_array)/np.size(error_array))
    theta = theta - alpha * ((np.dot(error_array,x)+lamda*theta.T)/np.size(error_array))
    print('损失为{}'.format(error_array))
    print('\ntheta的值为{}'.format(theta))
    print('theta_0的值为{}'.format(theta_0))
    return theta,theta_0

下图是误差函数的图像:

机器学习入门之线性回归(3)- 波士顿房价预测(python实现)
下图是测试集的误差,基本在 -5~5之间
机器学习入门之线性回归(3)- 波士顿房价预测(python实现)
以上若有问题,请大佬指出,感激不尽,共同进步。

Original: https://blog.csdn.net/qq_43583319/article/details/125696467
Author: Small White
Title: 机器学习入门之线性回归(3)- 波士顿房价预测(python实现)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/613490/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球