📖 机器学习项目实战:预测二手房价格
✨ 故事背景:想象一下,你是某家房地产中介公司的数据分析师。你的老板找到你,说:“我们希望用数据来预测房子的合理价格,让买家和卖家都能得到公平的交易。你能搞定吗?” 你信心满满地点点头,于是,一场数据科学的探险就此开始!
📌 第 1 节:问题的提出
🔎 思考:房子该值多少钱?
假设你准备买一套房子,它的价格是 100 万元,你觉得这个价格合理吗?
- 你可能会问:“这房子在哪里?”(地段很重要!)
- 你可能会问:“面积多大?”(大房子贵,小房子便宜。)
- 你可能会问:“新不新?”(老破小 vs. 新小区,价格天差地别!)
📊 结论:房价受多种因素影响,我们要找出这些关键因素,让机器学习算法去学习其中的规律,进而自动估算房价。
📌 第 2 节:获取数据
方案 1:使用公开数据
最省事的方法,就是使用已经整理好的房价数据集。例如:
- Kaggle 房价预测数据集
- Zillow 房价数据(美国)
📌 你可以直接下载 CSV 文件,然后用 Python 读取数据!
import pandas as pd
df = pd.read_csv("house_prices.csv") # 读取房价数据
print(df.head()) # 查看前5行数据
示例输出:
城市 面积(㎡) 卧室数 卫生间数 房龄(年) 价格(万元)
0 深圳 194 3 2 17 1454
1 广州 190 4 1 1 1336
2 上海 95 1 2 12 910
3 深圳 84 2 2 26 892
4 深圳 183 1 2 19 1315
方案 2:爬取网页数据
如果你希望使用最新的数据,可以爬取二手房网站(如链家、贝壳、Zillow)。但爬虫涉及法律问题,建议遵守网站的 robots.txt 规则。
📌 第 3 节:数据预处理
🎯 问题来了!
你拿到的数据可能一团乱麻:
- 有些房子缺少价格(比如新房刚上市)。
- 有些房子价格异常高(例如 999999 万)。
- 城市是文本,但机器学习模型只认识数字!
🔨 如何处理?
- 去掉缺失值:
df.dropna(inplace=True)
📌解析: 这行代码用于删除数据集中包含缺失值的行,其中:
- dropna() 是 Pandas 方法,用于删除缺失值(NaN,Not a Number)。
- inplace=True 表示 直接修改原数据,而不返回新的 DataFrame。
- 识别异常值(比如极端高房价):
import matplotlib.pyplot as plt# 绘制箱线图
plt.boxplot(df["价格(万元)"]) # 画房价数据的箱线图
plt.title("房价分布箱线图") # 设置标题
plt.ylabel("房价(万元)") # 设置y轴标签
plt.show() # 显示图表
示例输出:
📌 图中关键部分解析:
- 盒子(box):代表 Q1(25% 分位数)到 Q3(75% 分位数)的范围。
- 中间的线(中位数):数据的中间值。
- 上下的“胡须”(whiskers):正常数据的最大范围。
- 离群点(outliers)(小圆点 ●):异常高或异常低的数据。
🛠 总结:
- plt.boxplot(df[“价格(万元)”]) 用于可视化房价数据的分布,识别异常值。
- 箱线图能帮助你直观地看到房价的极端值,从而决定是否进行数据清理。
- 你可以删除异常值或用均值/中位数填充,以确保机器学习模型不会受到极端值的影响。
🎯 建议:运行这段代码,看看你的数据是否有异常值! 🚀
- 转换文本数据(比如“上海”变成 0,“北京”变成 1):
📌 机器学习模型只能处理数值数据,不能直接理解“上海”“北京”“深圳”这些文本!所以,我们需要把文本转换成数值,让模型可以理解。
pd.get_dummies() 将文本类别转换成数值类别,适用于分类变量(如“城市”)。
独热编码(One-Hot Encoding) 用 0/1 变量表示不同类别,方便机器学习模型处理。
🎯 建议:在你的数据上运行 df.head() 看看转换后的效果!
df = pd.get_dummies(df, columns=["城市"], drop_first=True)
print(df.head())
示例输出:
面积(㎡) 卧室数 卫生间数 房龄(年) 价格(万元) 城市_北京 城市_广州 城市_深圳
0 194 3 2 17 1454 False False True
1 190 4 1 1 1336 False True False
2 95 1 2 12 910 False False False
3 84 2 2 26 892 False False True
4 183 1 2 19 1315 False False True
🚀 这样,我们的数据就变得更干净、更适合机器学习了!
📌 第 4 节:选择机器学习模型
🏠 思考:如果你是房产专家,你会怎么预测房价?
可能的方法有:
- 简单相加法:
- “地段好+100 万,面积大+50 万,学区房+30 万……”
- 这就是线性回归(Linear Regression)!
- 如果你是资深中介:
- 你会按经验判断:“这套房子和某某房子很像,那应该值 300 万。”
- 这就类似于 K 近邻(KNN)!
- 如果你是 AI:
- 你会综合很多数据,比如房龄、地段、面积,自动归纳出规律,用 决策树(Decision Tree) 预测房价!
我们尝试三种模型:
- 线性回归(Linear Regression)
- 决策树(Decision Tree)
- 随机森林(Random Forest)
让我们从线性回归开始:
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split# 拆分训练集和测试集
X = df.drop(columns=["价格(万元)"])
y = df["价格(万元)"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 训练模型
lr = LinearRegression()
lr.fit(X_train, y_train)# 预测
y_pred_lr = lr.predict(X_test)
📌 问题来了!线性回归靠谱吗?
- 现实中的房价并非严格线性关系。
- 有些影响房价的因素不能简单相加(比如学区房 vs 普通房)。
💡 试试决策树!
from sklearn.tree import DecisionTreeRegressor
dt = DecisionTreeRegressor(max_depth=5)
dt.fit(X_train, y_train)
y_pred_dt = dt.predict(X_test)
🔥 随机森林(更强的模型!)
from sklearn.ensemble import RandomForestRegressor
rf = RandomForestRegressor(n_estimators=100)
rf.fit(X_train, y_train)
y_pred_rf = rf.predict(X_test)
📌 第 5 节:模型评估
📊 哪个模型表现更好?
在本次二手房价格预测任务中,我们尝试了三种模型,并使用 均方误差(MSE) 和 决定系数(R²) 来评估它们的表现。
from sklearn.metrics import mean_squared_error, r2_scoredef evaluate_model(model, X_test, y_test, model_name):y_pred = model.predict(X_test)mse = mean_squared_error(y_test, y_pred)r2 = r2_score(y_test, y_pred)print(f"{model_name} 结果:")print(f"📉 均方误差 (MSE): {mse:.2f}")print(f"📈 决定系数 (R²): {r2:.2f}")print("-" * 30)return y_pred# 评估所有模型
y_pred_lr = evaluate_model(lr, X_test, y_test, "线性回归")
y_pred_dt = evaluate_model(dt, X_test, y_test, "决策树")
y_pred_rf = evaluate_model(rf, X_test, y_test, "随机森林")
以下是它们的评估结果:
模型 | 均方误差 (MSE) | 决定系数 (R²) |
---|---|---|
线性回归 | 743.83 | 0.98 |
决策树 | 🚨 5000.16 | 🚨 0.87 |
随机森林 | 1260.79 | 0.97 |
📊 对比结果
- 线性回归 在本任务中效果很好(MSE 最小,R² 最高)。
- 随机森林 适用于更复杂的特征关系,并且比决策树更稳定。
- 随机森林 vs 线性回归的选择:如果数据线性关系强,选择线性回归;如果数据有非线性特征,选择随机森林。
📌 第 6 节:可视化结果
为了更直观地对比三个模型的预测效果,我们可以绘制真实房价 vs. 预测房价的散点图。
📊 真实房价 vs 预测房价(对比图)
import matplotlib.pyplot as plt# 画出真实 vs 预测对比
def plot_results(y_test, y_pred, title):plt.figure(figsize=(6, 6))plt.scatter(y_test, y_pred, alpha=0.5, color='blue')plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--') # 画对角线plt.xlabel("真实房价(万元)")plt.ylabel("预测房价(万元)")plt.title(title)plt.show()# 可视化
plot_results(y_test, y_pred_lr, "线性回归:真实 vs 预测")
plot_results(y_test, y_pred_dt, "决策树:真实 vs 预测")
plot_results(y_test, y_pred_rf, "随机森林:真实 vs 预测")
📌 结果分析
📌 如何解读?
- 如果散点沿着红色虚线(y = x)分布,说明预测值接近真实值,模型准确性高。
- 如果散点离红线较远,分布很散,说明模型误差较大。
- 通常,随机森林的散点会比决策树更接近红线,说明预测更准确!
-
线性回归:预测值最接近真实值,效果最佳!
-
决策树:散点分布较散,说明模型误差较大。
-
随机森林:预测值接近真实值,效果可以!
📌 结论
- 如果数据是线性的(如面积和房价),线性回归可能是最佳选择。
- 如果数据有很多复杂关系(如学区、交通),随机森林效果最好。
- 单棵决策树的表现较差,容易过拟合,通常不推荐单独使用。
📌 课后思考
- 如果你要改进这个房价预测模型,你会增加哪些特征?
- 你认为哪个模型最好?为什么?
- 除了房价预测,你还能用机器学习预测哪些东西?(例如:汽车价格、股票走势)
✨ 总结
🎯 这次项目让你掌握了:
✅ 如何获取数据(爬取/公开数据)
✅ 数据清理与特征工程
✅ 训练不同模型(线性回归、决策树、随机森林)
✅ 评估和优化模型
🚀 你已经迈出了成为机器学习工程师的第一步! 🎉