机器学习_线性回归
线性回归的通俗解释:
在一个平面(空间)存在诸多散列分布的点,求解一个通用表达式画出一条连续的线(平面)穿过这些点,并尽可能使得这些点在线(平面)的上下均匀分布。
截距项
y = ax + b; 这个b就是截距项
选择合适的截距项可以表达式更好的穿过这些点
在大模型中有类似的概念叫偏置
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl## 设置字符集,防止中文乱码
mpl.rcParams['font.sans-serif'] = [u'simHei']
mpl.rcParams['axes.unicode_minus'] = False# 一、构造数据
# 第 1 列:房屋面积;第 2 列:房间数量
X1 = np.array([[10, 1],[15, 1],[20, 1],[30, 1],[50, 2],[60, 1],[60, 2],[70, 2]])
Y = np.array([0.8, 1.0, 1.8, 2.0, 3.2, 3.0, 3.1, 3.5]).reshape((-1, 1))flag = True # 是否添加截距项,默认为 True
if flag:# 添加一个截距项对应的 x 值,添加到最后 1 列X = np.column_stack((X1, np.ones(shape=(X1.shape[0], 1))))# X = np.hstack((X1,np.ones(shape=(X1.shape[0], 1))))
else:# 不加入截距项X = X1
print('添加截距项后的X值:\n', X, sep='')
# print(Y)# 二、根据解析式的公式(1)求解 θ 值
# theta = (X.T * X).I * X.T * Y
theta = np.linalg.pinv(X) @ Y
print('θ值: \n', theta, sep="")# 三、 根据求解出来的 θ 求出预测值
predict_y = X @ theta
print(predict_y)# 基于训练好的模型参数对一个未知的样本做一个预测
# 添加截距项和不添加截距项
if flag:x = np.array([[55.0, 2.0, 1.0]])
else:x = np.array([[55.0, 2.0]])
pred_y = x @ theta
print("当面积为55平并且房间数目为2的时候,预测价格为: ", pred_y)# 四、画图可视化(TODO: 自己更改为立体的图像)
# from mpl_toolkits.mplot3d import Axes3D# 房屋面积和房间数量
x1 = X[:, 0]
# print(x1)
x2 = X[:, 1]
# print(x2)# 定义 1 个图对象,设置背景为白色
# 实例化 3D 图对象
fig = plt.figure(facecolor='w')
ax = fig.add_subplot(projection='3d')
"""
在坐标轴 ax 上绘制散点图
- x1 是散点的 x 坐标数组;
- x2 是散点的 y 坐标数组;
- Y 是散点的 z 坐标数组;
- s 是散点的大小,默认为40;
- c 是散点的颜色,默认为红色;
- depthshade 用于控制是否启用深度阴影效果,默认为 False
"""
ax.scatter(x1, x2, Y, s=40, c='r', depthshade=False)x1 = np.arange(0, 100)
x2 = np.arange(0, 4)
"""
将两个一维数组 x1 和 x2 转换为两个二维数组(矩阵),分别表示网格中的 x 坐标和 y 坐标;
其形状分别为 (4, 100) 和 (4, 100),表示了一个 4 行 100 列的网格
"""
x1, x2 = np.meshgrid(x1, x2)
# print(x1.shape)
# print(x2.shape)# base=False,默认不添加截距项
# y_ = x1 * theta[0] + x2 * theta[1] + theta[2],这么做(而不是 X * theta)是因为 x1, x2 都单独取出来了
# 截距项放在最后,是因为之前这样做了
def predict(x1, x2, theta, base=False):"""返回预测值"""if base:y_ = x1 * theta[0] + x2 * theta[1] + theta[2]else:y_ = x1 * theta[0] + x2 * theta[1]return y_zip_x1_x2 = zip(x1.flatten(), x2.flatten()) # 将 x1、x2 中的元素一对一组成元组
# print(list(zip_x1_x2)[:5]) # [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0)]
"""
返回由预测值构成的迭代器
base=flag:是否添加截距项
"""
map_predict_y = map(lambda t: predict(t[0], t[1], theta, base=flag), zip_x1_x2)
z = np.array(list(map_predict_y)) # 用预测值表示散点的 z 坐标
# print(z)
print('z修改形状前:', z.shape)
z.shape = x1.shape
print('z修改形状后:', z.shape)
# print(z)
"""
画超平面使用3D坐标轴对象ax上的plot_surface方法,绘制曲面图:
- x1是曲面上点的 x 坐标的二维数组;
- x2是曲面上点的 y 坐标的二维数组;
- z是曲面上点的 z 坐标的二维数组;
- rstride是网格行的步长,默认为1;
- cstride是网格列的步长,默认为1;
- cmap是用于指定颜色映射的参数,默认为plt.cm.jet,表示使用彩虹色的颜色映射
"""
ax.plot_surface(x1, x2, z, rstride=1, cstride=1, cmap=plt.cm.jet)
ax.set_title(u'房屋租赁价格预测')
plt.show()