尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
基于Python与PyQt5的二手房价预测系统开发实战
简介基于Python和PyQt5实现的二手房价分析与预测系统是一份面向高校学生的毕业设计、期末大作业与课程设计高分项目源码。系统覆盖房价数据清洗、统计分析与预测建模等完整流程界面基于PyQt5构建操作直观。资源共17个文件以Python脚本为核心包含6个py文件分别承担主窗口、业务分析、图表展示等功能另有1个UI界面文件、1个csv格式房价数据集以及运行所需的pyc缓存和png图标图片资源压缩包仅134KB部署轻量。每个模块均带有详细注释代码结构清晰新手也能快速读懂项目已经严格调试确保可运行。已有272人学习使用配套README说明与完整目录结构便于按模块查阅。整体界面美观、功能完善既能直接用于答辩展示也适合作为二次开发的参考具有较高的实际应用价值。1. 把二手房价预测做成桌面系统这个项目到底值不值得做在课程设计和毕业设计里“基于 Python 和 PyQt5 的二手房价分析与预测系统”是出现频率最高的一类题目也是最容易做成“有界面、有预测、能现场演示”的完整项目。它的价值不只是拿高分而是把 pandas 数据处理、机器学习建模和 PyQt5 桌面开发串成了同一条链路数据清洗和特征工程在前模型训练在中PyQt5 界面在后。这篇按我实际交付这类项目的顺序来写——先让数据说话再把模型装进窗口最后踩一遍安装失败、线程卡死、打包翻车的坑。适合想做课程设计、想用完整源码和数据集快速搭出可展示系统又不满足于只交一堆 Jupyter 代码的从业者。2. 先让数据说话二手房价数据集的清洗与特征工程二手房价预测系统的分数高低八成不取决于界面漂不漂亮而取决于你给模型喂了什么数据。数据里的坑不处理干净后面模型训练和 GUI 预测全部跟着遭殃。常见做法是拿到数据集先做三件事字段梳理、缺失值处理、异常值剔除再做特征工程最后才进入模型选型。2.1 拿到数据集先做这三件事字段梳理、缺失值、异常值二手房数据集通常长这样小区名称、区域、朝向、室、厅、面积、楼层、建造年份、总价、单价。但网上找来的数据集字段名五花八门有的叫“总价(万)”有的叫“价格”有的是“平均单价”但单位是元/平米。第一步先把字段类型和取值看一遍避免后面所有代码建立在错误假设上。import pandas as pd df pd.read_csv(data/house_data.csv, encodingutf-8-sig) print(df.shape) # 样本量 print(df.dtypes) # 每个字段的类型 print(df.head(10)) # 快速看前几行数据长什么样 print(df.describe(includeall))这段代码里有两个关键参数。第一是encodingutf-8-sig很多二手房 CSV 是从 Excel 导出的用 utf-8-sig 比 utf-8 更能处理带 BOM 头的文件避免第一列列名出现\ufeff这种隐形前缀。第二是describe(includeall)includeall 会把字符串字段的计数、唯一值数量也带出来方便你直接发现“朝向”里有“南”也有“朝南”这种脏数据。接下来处理缺失值和异常值。二手房价数据的缺失值一般集中在建造年份、楼层、装修情况这几个字段而异常值集中在总价和面积上。最常见的脏数据是面积 3 平米其实是车位、总价 0.1 万单位录错、建造年份 2035 年录入错误。# 数值字段统一转 float转不了的变成 NaN df[总价] pd.to_numeric(df[总价], errorscoerce) df[面积] pd.to_numeric(df[面积], errorscoerce) # 缺失值用中位数填充 df[总价] df[总价].fillna(df[总价].median()) df[面积] df[面积].fillna(df[面积].median()) df[建造年份] df[建造年份].fillna(df[建造年份].median()) # 异常值剔除面积 5 平以下基本是车位500 平以上基本是录入错误 df df[(df[面积] 5) (df[面积] 500)] # 总价 5 万以下不叫房子3000 万以上属于豪宅对普通预测模型是噪声 df df[(df[总价] 5) (df[总价] 3000)]errorscoerce的作用是把“120万”这类带单位文本转成 120转不了的变成 NaNrange 过滤用布尔索引注意这里的边界值要结合你自己的数据集分布调。比如城市是北京总价下限可以提到 20 万城市是三四线3000 万上限基本不会触发。处理完以后重新看一眼df.shape如果过滤掉了超过 10% 的样本先怀疑是不是单位不统一而不是急着删数据。2.2 特征工程决定模型上限朝向编码、房龄计算、区域均价二手房价预测的特征工程有几个固定动作朝向从文本变成数字、楼层从高/中/低变成数字、房龄从建造年份换算出来、区域均价把地理位置信息浓缩成一个数值。这些特征都是二手房领域经验证有效的强特征比把小区名做 one-hot 靠谱得多。from datetime import datetime # 朝向编码8 个主朝向低频朝向统一归为 8 direction_map {东: 0, 南: 1, 西: 2, 北: 3, 东南: 4, 东北: 5, 西南: 6, 西北: 7} df[朝向编码] df[朝向].map(direction_map).fillna(8) # 楼层低/中/高未知楼层按中楼层处理 floor_map {低: 0, 中: 1, 高: 2} df[楼层编码] df[楼层].map(floor_map).fillna(1) # 房龄用当前年份减建造年份未来年份归零 current_year datetime.now().year df[房龄] current_year - df[建造年份] df.loc[df[房龄] 0, 房龄] 0 # 区域均价把地理信息压缩成一个连续数值 df[区域均价] df.groupby(区域)[总价].transform(mean).round(2)朝向不要用 get_dummies 摊成 8 列原因有两个一是树模型对稀疏 one-hot 列不敏感二是 GUI 端输入时会多 8 个控件徒增复杂度。朝向用有序编码就够了因为东南等朝向本身就有价值差异。groupby transform(mean)和groupby map的区别在于transform 返回的是跟原始 df 同样长度的 Series能直接赋给新列不用再 merge这一步最容易写错。房龄这里有个细节直接用datetime.now().year会让模型每年“变老”如果你只是交课程设计没问题如果要长期使用更稳的做法是把当前年份写死成数据集年份比如 2024否则同一套房今年预测和明年预测的特征值会漂移。这就是为什么很多开源项目里能看到“基准年份”这个概念。2.3 房价预测模型怎么选线性回归兜底随机森林和 XGBoost 冲刺房价预测的模型选型有一个黄金原则先跑线性回归拿到一个 baseline再用随机森林这类树模型去提升。线性回归跑不通时先回头查数据不要急着换复杂模型。这能避免你花大量时间调 XGBoost最后发现只是面积单位传错了。from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import r2_score, mean_squared_error import numpy as np import joblib feature_cols [面积, 朝向编码, 房龄, 楼层编码, 区域均价, 室, 厅] X df[feature_cols] y df[总价] X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42) lr LinearRegression() lr.fit(X_train, y_train) lr_pred lr.predict(X_test) rf RandomForestRegressor( n_estimators300, max_depth10, min_samples_leaf2, random_state42 ) rf.fit(X_train, y_train) rf_pred rf.predict(X_test) for name, pred in [(LinearRegression, lr_pred), (RandomForest, rf_pred)]: rmse np.sqrt(mean_squared_error(y_test, pred)) print(f{name} RMSE: {rmse:.2f} 万元, R2: {r2_score(y_test, pred):.4f}) # 保存模型和特征列顺序GUI 端加载时要用 joblib.dump(rf, model.pkl) joblib.dump(feature_cols, feature_columns.joblib)test_size0.2意味着 20% 样本被留出来做评估random_state42固定随机种子保证每次跑出来的划分一致答辩时你能复现同一个数字。随机森林的三个参数值得单独说n_estimators300是树的数量300 颗树在几千条样本上已经够用继续加对精度提升很小但会让 GUI 端加载模型变慢max_depth10控制单棵树深度防止过拟合min_samples_leaf2要求叶子节点至少 2 个样本是抑制噪声的常用手段。我用常规链家风格的 5000 到 10000 条数据训练时线性回归 R2 通常在 0.80 到 0.88随机森林能到 0.90 到 0.95RMSE 差 10 万到 20 万。这个水平的模型已经足够做课程设计演示不必追求刷分。如果数据里有装修、楼龄、梯户比这些字段可以继续加进 feature_cols。特征列顺序非常重要训练时是[面积, 朝向编码, ...]GUI 预测时也必须完全一致所以第 2.3 节最后一行用 joblib 把列名存下来了这就是 3.3 节不翻车的底气。3. 把模型装进窗口PyQt5 界面布局、图表嵌入与预测交互模型训练完成下面进入 PyQt5 界面的部分。这套系统我一般把窗口拆成三块左侧是参数输入区右侧是结果区结果区再分两个 Tab——一个画房价分布一个画真实值和预测值的对比。这个结构对课程设计来说足够完整逻辑也清晰。3.1 主窗口布局表单输入、预测按钮、结果显示主窗口采用 QMainWindow 作为容器左侧用一个 QFormLayout 摆输入项右侧用一个 QTabWidget 放图表。QFormLayout 的特点是标签和输入框自动对齐省去手动调位置的功夫。import sys from PyQt5.QtWidgets import ( QApplication, QMainWindow, QWidget, QHBoxLayout, QVBoxLayout, QFormLayout, QLineEdit, QComboBox, QPushButton, QLabel, QTabWidget) from PyQt5.QtCore import Qt class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle(二手房价分析与预测系统) self.resize(1080, 720) central QWidget() self.setCentralWidget(central) root QHBoxLayout(central) # 左侧输入区 form_box QWidget() form QFormLayout(form_box) self.area_edit QLineEdit() self.area_edit.setPlaceholderText(例如85.5) form.addRow(建筑面积(平米), self.area_edit) self.direction_combo QComboBox() self.direction_combo.addItems([东, 南, 西, 北, 东南]) form.addRow(朝向, self.direction_combo) self.room_combo QComboBox() self.room_combo.addItems([1, 2, 3, 4, 5]) form.addRow(室, self.room_combo) self.floor_combo QComboBox() self.floor_combo.addItems([低, 中, 高]) form.addRow(楼层, self.floor_combo) self.age_edit QLineEdit() self.age_edit.setPlaceholderText(例如12) form.addRow(房龄(年), self.age_edit) self.predict_btn QPushButton(预测总价) self.predict_btn.clicked.connect(self.on_predict) form.addRow(self.predict_btn) self.result_label QLabel(预测结果会显示在这里) self.result_label.setWordWrap(True) form.addRow(self.result_label) root.addWidget(form_box, 1) # 右侧图表区 self.tabs QTabWidget() self.dist_canvas PriceChart() self.compare_canvas PriceChart() self.tabs.addTab(self.dist_canvas, 房价分布) self.tabs.addTab(self.compare_canvas, 真实 vs 预测) root.addWidget(self.tabs, 2)布局里root.addWidget(form_box, 1)中的第二个参数是拉伸因子左侧输入区占 1 份右侧图表区占 2 份窗口拉大图表跟着变大。这个比例对 1080x720 的窗口比较合适。QLineEdit 适合输入面积和房龄这类连续值QComboBox 适合朝向、楼层、室数这些离散值两者搭配从源头减少用户输入非法字符的可能性。一个容易被忽略的点QTabWidget 放在右侧意味着你可以把“数据可视化”和“预测”两个能力分开展示。答辩时先切到“房价分布”讲数据特征再切回输入区做实时预测演示逻辑更顺畅。3.2 用 matplotlib 把数据图表嵌进 PyQt5 窗口matplotlib 嵌入 PyQt5 有一个固定套路用FigureCanvasQTAgg作为画布把它当成普通控件加进布局里。注意 backend 的设置时机要在任何 pyplot 调用之前指定 Qt5Agg否则可能出现无法嵌入窗口的情况。import matplotlib matplotlib.use(Qt5Agg) from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.figure import Figure class PriceChart(FigureCanvas): def __init__(self, parentNone): self.figure Figure(figsize(5, 4)) super().__init__(self.figure) self.setParent(parent) def draw_hist(self, prices): self.figure.clear() ax self.figure.add_subplot(111) ax.hist(prices, bins30, color#4C72B0, edgecolorwhite) ax.set_title(二手房总价分布) ax.set_xlabel(总价(万元)) ax.set_ylabel(数量) self.draw() def draw_scatter(self, y_true, y_pred): self.figure.clear() ax self.figure.add_subplot(111) ax.scatter(y_true, y_pred, alpha0.5, s20) max_val max(max(y_true), max(y_pred)) ax.plot([0, max_val], [0, max_val], colorred, linestyle--) ax.set_xlabel(真实总价(万元)) ax.set_ylabel(预测总价(万元)) ax.set_title(预测值 vs 真实值) self.draw()self.figure.clear()每次画图前清空画布否则重复调用 draw_hist 时旧图会残留。self.draw()是 FigureCanvas 自带的刷新方法注意不是self.figure.canvas.draw()。bins30 是直方图分箱数数据量 5000 条以上时 30 箱能把分布形状摸出来太少会丢失细节太多会出现大量空箱。画散点图时加上 yx 参考线一眼能看出模型是系统性高估还是低估。如果散点整体在参考线下面模型倾向高估房价此时回去看数据里是不是混进了大量挂牌价虚高的房源。这套可视化逻辑答辩时讲 10 分钟绰绰有余。3.3 预测按钮背后加载模型、特征对齐、结果回显预测按钮的事件处理是整个系统里最容易写错环环相扣的部分。要做的三件事是加载模型、把界面输入拼成特征向量、predict 后把结果写回 QLabel。特征对齐是这里的命门我吃过亏后面第 4 章专门讲。from PyQt5.QtCore import QThread, pyqtSignal import pandas as pd import joblib class MainWindow(QMainWindow): def __init__(self): # ... 前面布局代码不变 ... self.model joblib.load(model.pkl) self.feature_columns joblib.load(feature_columns.joblib) self.direction_map {东: 0, 南: 1, 西: 2, 北: 3, 东南: 4, 东北: 5, 西南: 6, 西北: 7} self.floor_map {低: 0, 中: 1, 高: 2} def on_predict(self): try: area float(self.area_edit.text()) age float(self.age_edit.text()) except ValueError: self.result_label.setText(面积和房龄必须是数字) return if area 0 or age 0: self.result_label.setText(请输入合理的面积和房龄) return sample pd.DataFrame([{ 面积: area, 朝向编码: self.direction_map[self.direction_combo.currentText()], 房龄: age, 楼层编码: self.floor_map[self.floor_combo.currentText()], 区域均价: self.area_avg, 室: int(self.room_combo.currentText()), 厅: int(self.hall_combo.currentText()) }]) # 用训练时的列顺序强制对齐这一步不能省 sample sample[self.feature_columns] price float(self.model.predict(sample)[0]) self.result_label.setText(f预测总价{price:.1f} 万元)sample[self.feature_columns]是这段代码最重要的一行。它用训练时保存的列名列表对 DataFrame 做列选择即使你写代码时把列顺序弄反了经过这一步也会被纠正。try-except包住 float 转换拦截空输入和乱输入避免点击预测按钮时程序直接崩溃。self.area_avg是数据集里该小区的区域均价如果界面上没有让用户选区域就取整个数据集区域均价的均值。实际项目中我一般还会加一个“区域”下拉框从数据集里把区域列表读出来填进 QComboBox选中区域后自动更新 self.area_avg。这样预测同一个户型在不同区域的价格差异演示效果比固定一个均价好得多。4. PyQt5 项目避坑手册安装失败、界面卡死与打包翻车的 5 个真实问题这部分写我在这类项目上反复踩过的坑每条都是血泪经验按“现象 → 原因 → 解决”的顺序写直接照做就能省半天时间。4.1 pip 安装 PyQt5 失败或极慢现象执行pip install PyQt5后长时间停在进度条不动最后提示 timeout 或者Could not find a version that satisfies the requirement PyQt5。很多人在装 labelme 这类依赖 PyQt5 的工具时也会遇到同样的问题。原因默认访问的 PyPI 源在网络不稳定时响应很慢PyQt5 包体积在 50MB 以上慢源很容易超时另一个原因是 Python 版本过新PyQt5 的 wheel 还没跟上。解决换国内镜像源安装同时设一个超时上限装不上能快速报错而不是干等。pip install PyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple --timeout 60选择源时优先用清华源或阿里源兼容性最好。如果这个源还是装不上试试python -m pip install PyQt55.15.9指定版本。Python 版本在 3.8 到 3.10 之间最稳妥3.13 以上建议直接改用 PySide6接口和 PyQt5 几乎一致迁移成本很低。4.2 点击预测按钮后界面直接“未响应”现象点击“预测总价”按钮后窗口标题栏出现“未响应”过几秒甚至十几秒才恢复。如果在模型加载阶段就卡死可能连窗口都弹不出来。原因把耗时操作直接写在按钮槽函数里PyQt5 的 UI 事件循环被阻塞。随机森林模型单次预测本身不快再叠加每次点击都重新加载模型文件就会出现明显卡顿。解决模型在窗口初始化时加载一次不要在槽函数里重复加载耗时预测放到 QThread 里执行避免阻塞 UI 线程。class PredictWorker(QThread): finished pyqtSignal(float) def __init__(self, model, sample, parentNone): super().__init__(parent) self.model model self.sample sample def run(self): price float(self.model.predict(self.sample)[0]) self.finished.emit(price)在主窗口里调用时先启动线程再把线程的 finished 信号连接到更新标签的槽函数。注意保存 worker 引用否则线程会被垃圾回收。这个改动对演示体验提升非常大预测转圈时界面还能响应用户操作。4.3 matplotlib 图表中文全部显示成方块现象图表的标题、坐标轴标签中文全部变成方块但界面上的 QLabel 中文正常。原因matplotlib 默认字体是 DejaVu Sans不支持中文。PyQt5 界面用的系统字体正常不代表 matplotlib 也认识中文。解决在绘制前设置字体为系统中文字体同时关闭 unicode 负号问题。import matplotlib matplotlib.rcParams[font.sans-serif] [SimHei, Microsoft YaHei] matplotlib.rcParams[axes.unicode_minus] FalseSimHei 是黑体Windows 系统自带Microsoft YaHei 是微软雅黑。设置后如果还显示方块检查系统里是否装了对应字体。Linux 服务器上跑这套系统时可以换成WenQuanYi Zen Hei或Noto Sans CJK SC这两个是开源字体不存在版权问题。4.4 PyInstaller 打包后提示找不到 model.pkl现象源码跑起来一切正常用 PyInstaller 打包成 exe 后点击预测按钮程序报FileNotFoundError: model.pkl或者模型能加载但数据集图表画不出来。原因PyInstaller 打包后程序运行在临时解压目录当前工作路径不再是源码目录相对路径model.pkl自然找不到。模型文件默认也不会被打进 exe需要手动声明。解决在代码里写一个资源路径转换函数打包状态和非打包状态分别处理路径。import sys import os def resource_path(relative): try: base_path sys._MEIPASS except AttributeError: base_path os.path.abspath(.) return os.path.join(base_path, relative) # 加载模型时统一走 resource_path self.model joblib.load(resource_path(model.pkl))同时要在 spec 文件里把模型和数据打包进去a Analysis([main_window.py], datas[(model.pkl, .), (data/house_data.csv, data)], ...)datas[(model.pkl, .)]中的圆点表示把模型文件放到解压根目录。打包后 exe 的体积会明显变大这是正常的PyQt5 matplotlib sklearn 本身就有几百 MB不要试图用 upx 压成几十 MB容易压出隐藏崩溃。4.5 预测结果和训练时差一大截玄学拉满现象模型在训练集上的 R2 是 0.92界面预测某套房给的价格比实际行情高了一倍还多而且换几组输入都发生同样的偏差。原因训练和预测时的特征顺序不一致或特征值计算逻辑不一致。最典型的是区域均价在训练时用groupby.transform(mean)计算预测时却用了另一个区域的均价还有把朝向编码表改过训练时南1预测时南0。解决训练时把特征列顺序存下来预测时用同一份列名列表对齐所有编码映射表集中定义修改时两个方向同步。# 训练阶段文件里保存固定顺序 joblib.dump(feature_cols, feature_columns.joblib)# 预测阶段强制按这个顺序取列 sample sample[self.feature_columns]这个方法能挡掉大部分这类问题。剩下的小概率偏差靠第 4.1 节和第 4.5 节配合基本都能在上台前抓到并修正。5. 完整跑通这套系统环境配置、目录结构与训练预测流程前四章把核心原理和坑都讲完了这一章解决“怎么从零跑起来”的问题。拿到完整源码和数据集项目后按这里给的顺序核对环境、目录、命令能少走很多弯路。5.1 环境准备Python 版本选型与依赖清单这套系统对 Python 版本相对敏感核心原因是 PyQt5 的 wheel 发布速度和 sklearn 的依赖关系。我一般推荐用 Python 3.10PyQt5 5.15.9 在 3.10 上稳定scikit-learn 1.2.x 也完整支持 3.10。Python 3.12 以上部分依赖会有兼容问题会多花时间在装环境上。requirements.txt 长这样版本都是组合验证过可以一起工作的pandas1.5.3 numpy1.23.5 scikit-learn1.2.2 matplotlib3.7.2 PyQt55.15.9 joblib1.2.0安装命令建议加上镜像源尤其是第一次装 PyQt5 时pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple注意不要混用镜像源安装中途换源可能导致依赖版本解析错乱最后出现“已安装版本冲突”的提示。如果装完后 PyQt5 导入报 DLL 加载失败先检查是不是装了多个版本的 Qt 相关包比如PyQt5和PyQt5-Qt5版本对不上。5.2 项目目录结构数据、模型、界面代码各归其位拿到别人给的源码包时第一件事是核对目录结构不要急着打开 Python 文件。一个规范的项目目录通常长这样house_price_system/ ├── data/ │ └── house_data.csv ├── src/ │ ├── train_model.py │ └── main_window.py ├── requirements.txt ├── model.pkl └── feature_columns.joblib模型文件和特征列文件放在根目录是常见做法因为 resource_path 函数处理打包路径时相对简单。如果源码包里模型文件在 model/ 子目录记得把 resource_path 的路径改成os.path.join(base_path, model, model.pkl)。数据集的编码值得多看一眼用记事本打开 CSV 如果中文正常说明是 UTF-8 或 GBK读代码时注意 train_model.py 里的 encoding 参数有没有写成 utf-8-sigGBK 编码的数据用 utf-8-sig 读会乱码。5.3 训练与启动两条命令跑完再核对三个输出完整跑通只需要两条命令但跑之前建议先把训练脚本里的特征列和界面代码里的预测列对照一遍确保一致。# 第一步训练模型生成 model.pkl 和 feature_columns.joblib python src/train_model.py # 第二步启动 GUI python src/main_window.py训练脚本运行完检查三样东西终端输出的 R2 和 RMSE 值、根目录下是否生成了 model.pkl 文件、feature_columns.joblib 是否包含 7 个字段名。缺任何一个后面 GUI 都会报错。GUI 启动后先不要急着预测点一遍右侧两个图表 Tab确认图表能画出来。然后输入一套你自己熟悉区域的真实房源数据比如“85 平、南向、3 室、高楼层、房龄 10 年”点击预测看结果是否在合理区间。如果模型给出 50 万总价而同类房源市场价在 200 万说明模型训练有问题按第 4.5 节的排查方法回溯特征是否对齐。6. 从“能交作业”到“能演示”影响因子、预测区间与答辩现场技巧模型和界面都跑通之后还有三个能让这套系统显得更专业的小技巧都是我实践下来答辩时最加分的点。第一个是特征重要性排序。随机森林自带feature_importances_把它展示在界面或答辩 PPT 里比单纯说“我的模型 R2 是 0.9”有说服力得多。importances self.model.feature_importances_ pairs sorted(zip(self.feature_columns, importances), keylambda x: x[1], reverseTrue) for name, imp in pairs: print(f{name}: {imp:.4f})它能回答“到底什么在影响房价”这个非技术评委也关心的问题。常见结论是面积和区域均价排前二朝向和楼层影响偏小这非常符合二手房领域的直觉讲出来比堆数据更可信。第二个是给预测结果加一个区间。随机森林几百棵树每一棵树都有自己的预测值取 10% 到 90% 分位数就能得到一个价格范围比单一数字更能体现模型的不确定性。import numpy as np tree_preds np.array([tree.predict(sample)[0] for tree in self.model.estimators_]) low np.percentile(tree_preds, 10) high np.percentile(tree_preds, 90) print(f预测总价区间{low:.1f} - {high:.1f} 万元)这个区间在演示时格外好用。比如预测结果落在 180 万到 210 万之间你可以顺势说一句“模型认为这房源 9 成概率落在这个区间再结合挂牌数据可以做议价参考”顿时把课程设计的层次拉高到分析工具级别。第三个是答辩演示的细节。提前从数据集里挑 2 到 3 套典型房源把参数抄在纸条上现场输入现场预测再把房价分布图和真实对预测散点图各生成一张清晰版本放进答辩 PPT 备用。现场如果图表刷新慢PPT 里的截图就是后悔药。我最早做这个项目时给模型加预测区间、保存特征列名这些事情都没做答辩现场演示时模型把一套西向顶层老房子的估价拉高到市场价两倍当场翻车。后来我在每个交付的项目里固定保留两个习惯训练完必须打印一份特征列清单并和 GUI 代码核对预测按钮的槽函数里永远不写文件读取。这两个习惯让我后面再没出过同类问题希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

谐振电路设计实战:从88MHz射频匹配到LLC电源仿真

谐振电路设计实战:从88MHz射频匹配到LLC电源仿真

1. 谐振电路到底在“谐振”什么很多人第一次接触谐振电路,都是从中学物理里的那个LC振荡实验开始的:一个电容一个电感并在一起,用示波器一搭,居然能自己振出正弦波来。当时觉得神奇,但真到工程里要用的时候&#xff0c…

📅 2026/10/3 9:16:50
VMware创建CentOS虚拟机:从安装到配置的完整实战指南

VMware创建CentOS虚拟机:从安装到配置的完整实战指南

VMware里创建CentOS虚拟机,这个操作我这些年做了太多次了,从大学时装的CentOS 5到现在的CentOS Stream,中间踩过不少坑。今天就把整套流程完整捋一遍,从VMware Workstation的下载安装、CentOS镜像的选型,到虚拟机创建、…

📅 2026/10/3 9:16:50
Java校园旧物交易系统开发实战:从环境配置到论文答辩

Java校园旧物交易系统开发实战:从环境配置到论文答辩

每年毕业季,图书馆和宿舍楼下总能看到一堆堆被遗弃的教材、台灯、自行车。其实这些东西里很多都还有使用价值,但缺乏一个靠谱的流转渠道。我前两年带学生做课设时,恰好有小组选了这个题目——Java实现的校园旧物交易系统,当时跟着…

📅 2026/10/3 9:16:50
MORE NEWS

更多资讯

📰

二级MS Office选择题20分怎么稳拿?300道精选题库PDF刷题攻略

每年3月和9月,计算机二级MS office的考场外总是挤满临时抱佛脚的考生。有人在最后一周拼命刷操作题,有人把题库从头到尾过一遍,但真正能把选择题稳定拿高分的人不多。很多人不知道,二级MS office总分100分里,选择题占2…

📰

海口债权债务官司怎么找靠谱律师?本地实战经验全解析

很多债主问我同一个问题:在海口这种熟人社会加商事往来密集的地方,真要打起债权债务官司,到底怎么找到真正靠谱的律师?说实话,这类纠纷的标的额有大有小,法律关系说复杂也复杂,说简单也简单&…

📰

图书馆自动预约座位系统:从数据模型到高并发控制实战解析

简介:基于Python开发的图书馆自动预约座位系统源码包,面向高校学生、计算机相关专业课程设计及毕业设计人群,解决图书馆座位难预约、定时抢座等痛点。项目支持通过GitHub Actions在每周五、周六早晨自动运行,可设置学号、密码和座…

📰

SpringBoot+Vue+MySQL实现历史馆藏管理系统设计与部署

最近有朋友问我,搞一套线上历史馆藏系统信息管理系统要多久。我直接把之前整理好的源码翻了出来:SpringBoot后端Vue前端MySQL,三件套齐全,数据库脚本、初始化数据、部署说明全都配好了,拿到就能跑。这套系统不是什么大…

📰

机器狗自主导航实战:FastLIO2+TEB四足适配全链路拆解

1. 项目概述:为什么机器狗的自主导航不能照搬轮式小车那一套?FastLIO2 TEB 这个组合在ROS社区里常被拿来跑仿真小车,但真把它焊死在机器狗身上,我踩过三个大坑——第一是IMU数据抖动直接让FastLIO2建图飘移超过30厘米&#xff1b…

📰

没有明确项目标题,技术博文如何保证内容质量?

当前输入的项目标题为“【无标题】”,且热搜词、网络热词、标题网络搜索结果均为空。由于博文生成需要以【项目标题】为核心锚点,提取核心领域、潜在需求、技术点与应用场景,目前缺少可拆解的有效信息,我无法在保证内容质量与紧贴…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬