努力是为了不平庸~
学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰
线性回归是一种统计学习方法,用于建立一个线性模型来预测因变量与自变量之间的关系。它假设因变量与自变量之间存在线性关系,并通过最小化残差平方和来拟合数据。
线性回归模型用于波士顿房价预测的示例是一个经典的应用场景。在这个问题中,我们希望根据一些特征(如房间数量、犯罪率、学生-教师比例等)来预测波士顿地区的房价。
比如利用sklearn库中的方法,我们可以实现线性回归模型的三个主要模块:数据准备、模型训练和预测。
1. 数据准备:
首先,我们需要收集波士顿房价的相关数据集,如sklearn库中的波士顿房价数据集(load_boston)。
然后,我们将数据集分为特征(X)和目标(y),其中X包含所有的自变量特征,y包含对应的因变量(房价)。
我们可以通过数据预处理的方式,如标准化或归一化,对数据进行必要的转换和缩放。
2. 模型训练:
使用sklearn库中的线性回归模型(LinearRegression)进行模型训练。
调用fit()方法,将特征数据X和目标数据y作为输入,拟合线性回归模型。
在训练过程中,模型会自动计算最佳的回归系数以及截距,以最小化残差平方和。
3. 预测:
使用训练好的线性回归模型进行预测。
调用predict()方法,将待预测的特征数据作为输入,得到预测结果。
预测结果可以用于判断波士顿地区的房价。
先来看看线性回归相关模拟
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# 1、线性回归模拟
## 1.1 读取模拟数据ex0_1.csv
df = pd.read_csv("ex0_1.csv")
data = df.values
X = data[:, 0].reshape((-1, 1))
y = data[:, 1].reshape((-1, 1))
## 1.2 绘制散点图
plt.scatter(X, y)
plt.xlabel('X')
plt.ylabel('y')
plt.title('Scatter Plot')
plt.show()
## 1.3 正规方程解 inv(X.T * X ) * X.T * y
X_b = np.c_[np.ones((len(X), 1)), X] # 添加偏置项
theta = np.linalg.inv(X_b.T @ X_b) @ X_b.T @ y
## 1.4 绘制拟合的直线
plt.scatter(X, y)
plt.plot(X, X_b @ theta, color='red') # 使用X_b计算预测值
plt.xlabel('X')
plt.ylabel('y')
plt.title('Fitted Line')
plt.show()
## 1.5 函数形式
intercept, slope = theta[0][0], theta[1][0]
print("拟合函数形式为:y = {:.2f} + {:.2f}x".format(intercept, slope))
## 1.6 利用梯度下降法求
def gradient_descent(X, y, theta, alpha, num_iters):
m = len(y)
for iter in range(num_iters):
h = X.dot(theta)
loss = h - y
gradient = X.T.dot(loss) / m
theta -= alpha * gradient
return theta
alpha = 0.01 # 学习率
num_iters = 1000 # 迭代次数
theta = np.zeros((X_b.shape[1], 1)) # 初始化参数
theta = gradient_descent(X_b, y, theta, alpha, num_iters)
print("利用梯度下降法求得的参数为:", theta)
下面我们使用两种方法来实现波士顿房价预测
# -*- coding: utf-8 -*-
import pickle
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
import numpy as np
import matplotlib.pyplot as plt
# 2.1 数据准备
data = pickle.load(open("data.save","rb"))
X = data[:,:-1]
y = data[:,-1]
print(data)
# 数据划分
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2,random_state=420)
# 2.3 调用LR函数
def LR(X, y):
ones = np.ones((X.shape[0], 1))
X_ones = np.hstack((ones, X))
XT = X_ones.T
XTX = np.dot(XT, X_ones)
XTX_1 = np.linalg.inv(XTX)
XTX_1XT = np.dot(XTX_1, XT)
W = np.dot(XTX_1XT, y)
return W
W=LR(X_train,y_train)
# 2.4 预测
ones = np.ones((X_test.shape[0],1))
X_test_ones=np.hstack((ones,X_test))
y_predict=np.dot(X_test_ones,W)
# 2.5 评估
print("均方根误差:",mean_squared_error(y_test,y_predict))
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False # 解决负号无法正常显示的问题
# 绘制房间数量与房屋价格的关系
plt.scatter(X_train[:, 5], y_train, label='训练数据')
plt.scatter(X_test[:, 5], y_test, label='测试数据')
plt.xlabel('每个住宅的平均房间数量')
plt.ylabel('房价')
plt.title('房间数量与价格的关系')
plt.legend()
plt.show()
注意,这里是直接导入数据集,因为高版本python版本不适配
下面则是采用另外的导入方法
# -*- coding: utf-8 -*-
# 3.利用sklearn中的方法实现
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#导入数据集
data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="\s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
#划分数据集
X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2, random_state=38)
## 3.1 训练模型
model = LinearRegression()
model.fit(X_train, y_train)
## 3.2 预测
y_pred = model.predict(X_test)
## 3.3 评估
mse = mean_squared_error(y_test, y_pred)
print("均方根误差:", mse)
r2 = model.score(X_test, y_test)
print("拟合优度:", r2)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False # 解决负号无法正常显示的问题
# 绘制房间数量与房屋价格的关系
plt.scatter(X_train[:, 5], y_train, label='训练数据')
plt.scatter(X_test[:, 5], y_test, label='测试数据')
plt.xlabel('每个住宅的平均房间数量')
plt.ylabel('房价')
plt.title('房间数量与价格的关系')
plt.legend()
plt.show()