当前位置:首页>python>手把手教你使用Python+线性回归预测房价

手把手教你使用Python+线性回归预测房价

  • 2026-10-11 08:09:51
手把手教你使用Python+线性回归预测房价

上一节我们讲了线性回归的理论知识,那么怎么用呢?这节我们直接进入实战环节。我们将使用sklearn中加州房价数据集,训练一个线性回归模型,预测房子的中位数价格。

  • • 输入特征: 收入中位数、人口数等8个特征维度;
  • • 输出目标: 房价中位数

一、数据集

我们使用scikit-learn库中的加州房价数据集。

数据规模

一共20640条样本,每条样本有8个特征和1个目标值。

特征说明

特征名称
含义
MedInc
街区收入中位数(千美元)
HouseAge
房屋年龄中位数
AveRooms
平均房屋数量
AveBedrms
平均卧室数量
Population
街区人口数
AveOccup
每户平均居住人口数
Latitude
纬度
Longitude
经度

目标变量

MedHouseVal:房价中位数(单位:十万美元)

二、代码实战

2.1 环境准备



1
2
3
4
5
6
7
8
9
10
11
12
13
14

# numpy 数学计算
import numpy as np
# pandas 处理表格数据
import pandas as pd
# 画图
import matplotlib.pyplot as plt
# 获取加州房价数据集
from sklearn.datasets import fetch_california_housing
# 用来把数据分成训练集和测试集
from sklearn.model_selection import train_test_split
# 线性回归模型
from sklearn.linear_model import LinearRegression
# 模型打分指标
from sklearn.metrics import mean_squared_error, r2_score


2.2 加载数据集



1
2
3
4
5
6

data = fetch_california_housing()
X, y = data.data, data.target  # y 单位:千美元(k$)

# 查看特征名
print("特征:", data.feature_names)
print("数据形状:", X.shape)  # (20640, 8)


输出结果:



1
2

特征: ['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']
数据形状: (20640, 8)


2.3 划分数据集

划分训练集和测试集,占比分别为80%和20%。



1
2
3

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)


2.4 训练模型



1
2

model = LinearRegression()
model.fit(X_train, y_train)


2.5 预测结果



1

y_pred_test = model.predict(X_test)


2.6 评估模型



1
2
3
4
5

test_r2 = r2_score(y_test, y_pred_test)
test_mse = mean_squared_error(y_test, y_pred_test)

print(f"测试集 R²: {test_r2:.4f}")
print(f"测试集 MSE: {test_mse:.4f} (单位: (k$)^2)")


结果如下:



1
2

测试集 R²: 0.5758
测试集 MSE: 0.5559 (单位: (k$)^2)


  • • R方:越接近1越好,代表模型解释了数据中多少波动;
  • • MSE: 越小越好,代表预测值与真实值的平均差距;
  • • 线性回归用8个特征,解释了房价57.6%的变化。

2.7 特征系数

特征系数也可以看作特征的重要性,在sklearn中,可以使用自带属性查看:



1
2
3
4

print("前3个特征名字及权重:")
for name, coef in zip(data.feature_names, model.coef_[:3]):
    print(f"  {name}: {coef:.4f}")
print(f"偏置项 (Intercept): {model.intercept_:.4f}")


结果如下:



1
2
3
4
5

前3个特征名字及权重:
  MedInc: 0.4487
  HouseAge: 0.0097
  AveRooms: -0.1233
偏置项 (Intercept): -37.0233


2.8 可视化



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 加载字体,图像中中文显示
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False


plt.figure(figsize=(10, 6))
plt.scatter(test_y, y_pred, color='blue')
# 横轴真实价格,纵轴预测价格
plt.plot([test_y.min(), test_y.max()], [test_y.min(), test_y.max()], 'r--', lw=3) 
plt.xlabel('真实房价')
plt.ylabel('预测房价')
plt.title('线性回归:加州房价预测效果图')
plt.grid(True, linestyle='--', alpha=0.6)
plt.tight_layout()
plt.show()


结果如下:

如果点都聚集在红色的虚线附近,说明预测非常准。

三、模型改进

在训练模型前,还有很多特征工程工作可以做,以此来提高模型准确率。比如构造新的特征、去除异常值、归一化等,这里我们先不讲述,直接使用原始特征,只使用多项式和正则化对模型进行改进。

3.1 使用多项式特征

当特征值与目标值不是简单的线性关系时,可以构造多项式特征来表示输入特征与输出之间的非线性关系。在sklearn中,提供了构造函数,可以将原始特征转换为多项式特征,然后再使用线性回归进行训练。



1
2
3
4
5
6
7
8
9
10

from sklearn.preprocessing import PolynomialFeatures

poly = PolynomialFeatures(degree=2, include_bias=False, interaction_only=True)
X_train_poly = poly.fit_transform(X_train)
X_test_poly = poly.transform(X_test)

model_poly = LinearRegression()
model_poly.fit(X_train_poly, y_train)
r2_poly = r2_score(y_test, model_poly.predict(X_test_poly))
print(f"多项式模型 R²: {r2_poly:.4f}")


结果如下:



1

多项式模型 R²: 0.6225


3.2 L1&L2正则化



1
2
3
4
5
6
7
8
9
10
11
12
13
14

from sklearn.linear_model import Lasso, Ridge

# L1正则化
lasso = Lasso(alpha=0.01)
lasso.fit(X_train, y_train)
r2_lasso = r2_score(y_test, lasso.predict(X_test))
# L2正则化
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)
r2_ridge = r2_score(y_test, ridge.predict(X_test))


print(f"L1 正则化 R²: {r2_lasso:.4f}")
print(f"L2 正则化 R²: {r2_ridge:.4f}")


结果如下:



1
2

L1 正则化 R²: 0.5845
L2 正则化 R²: 0.5759


3.3 结果对比

模型
R方
基础线性回归模型
0.5758
多项式特征回归
0.6225
L1正则化
0.5845
L2正则化
0.5759

从中可以看出,使用多项式特征结果有一定提升,但是正则化结果并不明显。

四、完整代码



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

# 加载所需库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.linear_model import Lasso, Ridge
# 加载字体,图像中中文显示
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False

# 获取数据
data = fetch_california_housing()
X, y = data.data, data.target  

# 划分训练集、测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# 训练模型
model = LinearRegression()
model.fit(X_train, y_train)

# 测试集预测
y_pred_test = model.predict(X_test)

# 评估模型
test_r2 = r2_score(y_test, y_pred_test)
test_mse = mean_squared_error(y_test, y_pred_test)

print(f"测试集 R²: {test_r2:.4f}")
print(f"测试集 MSE: {test_mse:.4f} (单位: (k$)^2)")

# 画图
plt.figure(figsize=(10, 6))
plt.scatter(test_y, y_pred, color='blue')
# 横轴真实价格,纵轴预测价格
plt.plot([test_y.min(), test_y.max()], [test_y.min(), test_y.max()], 'r--', lw=3) 
plt.xlabel('真实房价')
plt.ylabel('预测房价')
plt.title('线性回归:加州房价预测效果图')
plt.grid(True, linestyle='--', alpha=0.6)
plt.tight_layout()
plt.show()

# 多项式
poly = PolynomialFeatures(degree=2, include_bias=False, interaction_only=True)
X_train_poly = poly.fit_transform(X_train)
X_test_poly = poly.transform(X_test)
model_poly = LinearRegression()
model_poly.fit(X_train_poly, y_train)
r2_poly = r2_score(y_test, model_poly.predict(X_test_poly))
print(f"多项式模型 R²: {r2_poly:.4f}")


# L1正则化
lasso = Lasso(alpha=0.01)
lasso.fit(X_train, y_train)
r2_lasso = r2_score(y_test, lasso.predict(X_test))
# L2正则化
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)
r2_ridge = r2_score(y_test, ridge.predict(X_test))
print(f"L1 正则化 R²: {r2_lasso:.4f}")
print(f"L2 正则化 R²: {r2_ridge:.4f}")


总结

通过上述代码,我们完成了一个除了特征工程以外的机器学习工作流, =0.62,那么这个结果到底算好还是不好?这个我们将在下一篇文章中进行详细讲解。

说明:文章封面配图使用AI生成。

最新文章

随机文章