《机器学习与数据挖掘》实验二-使用梯度下降法训练多元线性回归模型

实验题目:   使用梯度下降法训练多元线性回归模型                                             

实验目的:   掌握线性回归的基本原理,以及梯度下降法                                           

实验环境(硬件和软件)   Anaconda/Jupyter notebook/Pycharm                               

实验内容:

(1)编码实现基于梯度下降的多元线性回归算法,包括梯度的计算与验证;

(2)画数据散点图,以及得到的直线;

(3)画梯度下降过程中损失的变化图;

(4)基于训练得到的参数,输入新的样本数据,输出预测值;

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
from sklearn.model_selection import train_test_split

train_data = pd.read_csv("输入自己文件的路径", header=1,
                         names=['Size', 'Bedrooms', 'Price'])
x = np.array(train_data, 'float32')
x = np.delete(x, [2], axis=1)
y = np.array(train_data.Price, 'float32')

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)


def scaler(train, test):
    '''
     #归一化函数
    :param train:
    :param test:
    :return: train test
    '''
    min = train.min(axis=0)
    max = train.max(axis=0)
    gap = max - min
    train -= min
    train /= gap
    test -= min
    test /= gap
    return train, test


def min_max_gap(train):
    '''
    计算训练集最小值。
    :param train:
    :return:
    '''
    min = train.min(axis=0)
    max = train.max(axis=0)
    gap = max - min
    return min, max, gap


y_min, y_max, y_gap = min_max_gap(y_train)
x_train_origin = x_train.copy()



def loss_function(x, y, W):
    '''
     损失函数
    :param X:
    :param y:
    :param W:
    :return:
    '''
    y_hat = x.dot(W.T)
    loss = y_hat - y.reshape((len(y_hat), 1))
    cost = np.sum(loss ** 2) / (2 * len(x))
    return cost


x_train, x_test = scaler(x_train, x_test)
y_train, y_test = scaler(y_train, y_test)

iterations = 1000
alpha = 0.1
weight = np.array([[1, 1],])
# print(loss_function(x_train, y_train, weight))


def gradient_descent(x, y, w, lr, iterations):
    '''
    梯度下降函数
    :param X:
    :param y:
    :param W:
    :param lr:
    :param iter:
    :return:
    '''
    l_history = np.zeros(iterations)
    w_history = np.zeros((iterations, 2))
    for iter in range(iterations):
        y_hat = x.dot(w.T)
        loss = y_hat - y.reshape((len(y_hat), 1))
        derivative_w = x.T.dot(loss) / len(x)
        derivative_w = derivative_w.T
        w = w - lr * derivative_w
        l_history[iter] = loss_function(x, y, w)
        w_history[iter] = w
    return l_history, w_history


def liner_regression(x, y, weight, alpha, iter):
    loss_history, weight_history = gradient_descent(x, y, weight, alpha, iter)
    print("训练最终损失", loss_history[-1])
    return loss_history, weight_history
loss_history, weight_history = liner_regression(x_train, y_train, weight, alpha, iterations)
print(weight_history)
print("#"*20)
print(loss_history)

plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.title("损失函数图")
plt.plot(np.arange(iterations),loss_history,'r')
plt.show()

theat = weight_history[-1]
print(theat)

x1 = np.linspace(x_train[:, 0].min(), x_train[:, 0].max(), 100)
x2 = np.linspace(x_train[:, 1].min(), x_train[:, 1].max(), 100)
x1, x2 = np.meshgrid(x1, x2)
f = theat[0] * x1 + theat[1] * x2

fig = plt.figure()
Ax = Axes3D(fig)
Ax.plot_surface(x1, x2, f,
                rstride=1,
                cstride=1,
                cmap=plt.get_cmap('winter'))

plt.title("3D散点图")
Ax.scatter(x_train[:, 0], x_train[:, 1], y_train, c="r")


def costs_fun(theat1, theat2):
    global x_train, y_train
    theat = np.array([theat1, theat2])
    y_hat = x_train.dot(theat.T)
    loss = y_hat.reshape(len(y_hat), 1)
    cost = np.sum(loss * 2) / (2 * len(x_train))
    return cost


theat1 = np.arange(0.0, 1.0, 0.005)
theat2 = np.arange(0.0, 1.0, 0.005)
theat1, theat2 = np.meshgrid(theat1, theat2)
f = np.array(list(map(lambda t:costs_fun(t[0], t[1]),zip(theat1.flatten(), theat2.flatten()))))
f = f.reshape(theat1.shape[0], -1)
fig = plt.figure()
Ax = Axes3D(fig)
Ax.plot_surface(theat1, theat2, f, rstride=1, cstride=1, cmap=plt.get_cmap('winter'))
plt.title('在theat1 theat2两个参数下损失变化图')
plt.show()


x_plan = np.random.randn(1650, 2)
x_train, x_plan = scaler(x_train_origin,x_plan)

n = weight_history.shape[0]-1
t = weight_history[n, :].reshape(2,-1)
y_plan = np.dot(x_plan, t)

y_value = y_plan * y_gap + y_min


print(x_plan)
print(y_value)
print("预测值", y_value.astype(int))

猜你喜欢

转载自blog.csdn.net/m0_64351669/article/details/127172990