
努力是为了不平庸~
学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰
线性回归是一种统计学习方法,用于建立一个线性模型来预测因变量与自变量之间的关系。它假设因变量与自变量之间存在线性关系,并通过最小化残差平方和来拟合数据。
线性回归模型用于波士顿房价预测的示例是一个经典的应用场景。在这个问题中,我们希望根据一些特征(如房间数量、犯罪率、学生-教师比例等)来预测波士顿地区的房价。
比如利用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()