基于Flask+Bootstrap+机器学习的南昌市租房价格预测系统

🤵♂️ 个人主页:@艾派森的个人主页
✍🏻作者简介:Python学习者
🐋 希望大家多多支持,我们一起进步!😄
如果文章对你有帮助的话,
欢迎评论 💬点赞👍🏻 收藏 📂加关注+
目录
一、项目介绍
1.1项目简介
1.2技术工具
1.3页面概述
二、项目步骤
2.1登录模块
2.2注册模块
2.3训练模型模块
2.3.1导入数据
2.3.2查看数据
2.3.3数据预处理
2.3.4数据可视化
2.3.5特征工程
2.3.6构建模型
2.3.7保存模型
2.4预测房价模块
2.4查看房价信息模块
三、项目总结
一、项目介绍
1.1项目简介
本项目使用Flask框架搭建基于机器学习的南昌市租房价格预测系统 (简易版)
其中关于Flask知识点可参考文章Flask全套知识点从入门到精通,学完可直接做项目
其中关于南昌市租房价格预测可参考文章基于XGBoost算法构造房屋租赁价格评估模型
整个项目分为以下几个模块:
- 1.登录和注册模块
- 2.训练模型模块
- 3.预测价格模块
- 4.查看房价信息模块
项目文件框架如下:

其中manager.py为主程序,password.csv为存储用户账号密码的文件,lianjia是房租价格原始数据集,model.pkl是经过机器学习算法训练出的模型。
1.2技术工具
IDE编辑器:vscode
后端框架:Flask
前端框架:Bootstrap
1.3页面概述
运行manager.py程序后,浏览器打开http://127.0.0.1:5000/
映入眼帘的登录页面,有账号的话就之间输入用户名和密码,没有就点击Sign up先注册再登录
注册页面如下:

登录后进入主页面如下:
在导航栏中有训练模型、预测价格、查看房价信息、退出模块

训练模型模块如下:
需要依次按照步骤进行构建模型

预测房价模块:

在预测模块只需要输入地区、装修情况、楼层情况、电梯情况、房屋面积即可,每个输入类型都有提示(必须按照提示信息填写)
示例如下,填完信息后点击预测即可得到预测的房价信息:
查看房价信息模块:

在查看房价信息模块默认展示的是全部数据,当然你也可以通过输入价格区间进行筛选。
二、项目步骤
2.1登录模块
manager.py
class LoginView(views.MethodView):
def __jump(self,error=None):
return render_template('login.html',error=error)
def get(self, error=None):
return self.__jump()
def post(self):
uname = request.form['username']
pwd = int(request.form['password'])
if uname and pwd:
data = pd.read_csv('password.csv')
for index,item in enumerate(data.values,1):
if uname == item[0] and pwd == item[1]:
return redirect('/main')
if index == len(data):
return self.__jump(error="用户名或者密码错误")
else:
return self.__jump(error="用户名或者密码不能为空")
app.add_url_rule('/login/',view_func=LoginView.as_view('my_login'))
login.html
登录
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
height: 100%;
}
.container {
height: 100%;
background-image: linear-gradient(to right, #999999, #330867);
}
.login-wrapper {
background-color: bisque;
width: 358px;
height: 588px;
border-radius: 15px;
padding: 0 50px;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.header {
font-size: 38px;
font-weight: bold;
text-align: center;
line-height: 200px;
}
.input-item {
display: block;
width: 100%;
margin-bottom: 20px;
border: 0;
padding: 10px;
border-bottom: 1px solid rgb(128, 125, 125);
font-size: 15px;
outline: none;
}
.input-item::placeholder {
text-transform: uppercase;
}
.btn {
text-align: center;
padding: 10px;
width: 100%;
margin-top: 40px;
background-image: linear-gradient(to right, #a6c1ee, #fbc2eb);
color: #fff;
}
.msg {
text-align: center;
line-height: 88px;
}
a {
text-decoration-line: none;
color: #abc1ee;
}
Login
{% if error %}
{{ error }}
{% endif %}
Don't have account?
{url_for('my_register')}}">Sign up
2.2注册模块
manager.py
# 注册类视图
class RegisterView(views.MethodView):
def __jump(self,error=None):
return render_template('register.html',error=error)
def get(self,error=None):
return self.__jump()
def post(self):
# 模拟实现
uname = request.form['username']
pwd = request.form['password']
print(uname,pwd)
if uname and pwd:
with open('password.csv','a',encoding='utf-8',newline='\n')as f:
cswriter = csv.writer(f)
cswriter.writerow((uname,pwd))
f.flush()
return redirect('/login')
else:
return self.__jump(error="用户名或者密码不能为空")
app.add_url_rule('/register/',view_func=RegisterView.as_view('my_register'))
register.html
注册
* {
margin: 0;
padding: 0;
}
html {
height: 100%;
}
body {
height: 100%;
}
.container {
height: 100%;
background-image: linear-gradient(to right, #999999, #330867);
}
.login-wrapper {
background-color: bisque;
width: 358px;
height: 588px;
border-radius: 15px;
padding: 0 50px;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
.header {
font-size: 38px;
font-weight: bold;
text-align: center;
line-height: 200px;
}
.input-item {
display: block;
width: 100%;
margin-bottom: 20px;
border: 0;
padding: 10px;
border-bottom: 1px solid rgb(128,125,125);
font-size: 15px;
outline: none;
}
.input-item::placeholder {
text-transform: uppercase;
}
.btn {
text-align: center;
padding: 10px;
width: 100%;
margin-top: 40px;
background-image: linear-gradient(to right,#a6c1ee, #fbc2eb);
color: #fff;
}
.msg {
text-align: center;
line-height: 88px;
}
a {
text-decoration-line: none;
color: #abc1ee;
}
Register
{% if error %}
{{ error }}
{% endif %}
2.3训练模型模块
2.3.1导入数据
manager.py
@app.route('/load_data')
def load_data():
return render_template('load_data.html')
load_data.html
导入数据
- {url_for('see_data')}}">
- {url_for('index')}}">
导入数据成功!!!
2.3.2查看数据
manager.py
@app.route('/see_data')
def see_data():
return render_template('see_data.html')
see_data.html
查看数据
- {url_for('dispose_data')}}">
- {url_for('index')}}">
数据大小为:(1500,13)
数据基本信息为:
数值型数据描述为:
非数值型数据描述为:
2.3.3数据预处理
manager.py
@app.route('/dispose_data')
def dispose_data():
return render_template('dispose_data.html')
dispose_data.html
数据预处理
- {url_for('display_data')}}">
- {url_for('index')}}">
查看数据缺失值情况:
检测数据是否存在重复值:True
删除重复值前的数据的大小:(1500,13)
删除重复值后的数据的大小:(1445,13)
数据预处理完毕!!!
2.3.4数据可视化
manager.py
@app.route('/display_data')
def display_data():
return render_template('display_data.html')
display_data.html
数据可视化
- {url_for('feature_engineering')}}">
- {url_for('index')}}">
2.3.5特征工程
manager.py
@app.route('/feature_engineering')
def feature_engineering():
return render_template('feature_engineering.html')
feature_engineering.html
特征工程
- {url_for('build_model')}}">
- {url_for('index')}}">
特征工程完毕!!!
2.3.6构建模型
manager.py
@app.route('/build_model')
def build_model():
return render_template('build_model.html')
build_model.html
构建模型
- {url_for('load_data')}}" >
- {url_for('save_model')}}">
- {url_for('index')}}">
Model is: RandomForestRegressor()
Training score: 0.9049714978258847
r2 score is: 0.5589430756516771
MAE: 451.4159751799188
MSE: 450572.2871418395
RMSE: 671.2468153681174
真实值和预测值的差值图如下:
2.3.7保存模型
manager.py
@app.route('/save_model')
def save_model():
return render_template('save_model.html')
save_model.html
构建模型
- {url_for('load_data')}}" >
- {url_for('main')}}">
模型保存成功!!!
2.4预测房价模块
manager.py
class PredictView(views.MethodView):
def __jump(self,result=None,error=None):
return render_template('predict_price.html',result=result,error=error)
def get(self, result=None,error=None):
return self.__jump()
def post(self):
try:
address = request.form['address']
derection = request.form['derection']
floor = request.form['floor']
elevator = request.form['elevator']
area = float(request.form['area'])
new_data = pd.DataFrame(data=[[address,derection,area,floor,elevator]],columns=['address','derection','area','floor','elevator'])
new_data['address'].replace(to_replace={'南昌县':0,'红谷滩':1,'新建区':2,'高新区':3,'东湖区':4,'西湖区':5,'经开区':6,'青山湖区':7,'青云谱区':8,'湾里区':9,'进贤县':10},inplace=True)
new_data['derection'].replace(to_replace={'精装修':1,'简装修':0},inplace=True)
new_data['floor'].replace(to_replace={'高':0,'中':1,'低':2},inplace=True)
new_data['elevator'].replace(to_replace={'有':1,'无':0},inplace=True)
predict = model.predict(new_data)[0]
return self.__jump(result=predict)
except:
return self.__jump(error='输入数据格式不对,请重新输入!')
app.add_url_rule('/predict_price/',view_func=PredictView.as_view('my_predict'))
predict_price.html
预测租房价格
{% if error %}
{{ error }}
{% endif %}
{% if result %}
预测的房价为:{{ result }}
{% endif %}
2.4查看房价信息模块
manager.py
class LookPriceView(views.MethodView):
def __jump(self,houses=None,error=None):
return render_template('look_house_price.html',houses=houses,error=error)
def get(self, houses=None,error=None):
data = pd.read_csv('lianjia.csv')
houses = []
for item in data.values:
house = {}
house['address'] = item[1]
house['price'] = item[2]
house['lease method'] = item[3]
house['layout'] = item[4]
house['derection'] = item[5]
house['area'] = item[6]
house['orientation'] = item[7]
house['floor'] = item[8]
house['elevator'] = item[9]
house['water'] = item[10]
house['power'] = item[11]
house['gas'] = item[12]
houses.append(house)
return self.__jump(houses=houses)
def post(self):
try:
min_price = float(request.form['min'])
max_price = float(request.form['max'])
data = pd.read_csv('lianjia.csv')
data = data[(data['price']>min_price) & (data['price']<max_price)]
houses = []
for item in data.values:
house = {}
house['address'] = item[1]
house['price'] = item[2]
house['lease method'] = item[3]
house['layout'] = item[4]
house['derection'] = item[5]
house['area'] = item[6]
house['orientation'] = item[7]
house['floor'] = item[8]
house['elevator'] = item[9]
house['water'] = item[10]
house['power'] = item[11]
house['gas'] = item[12]
houses.append(house)
return self.__jump(houses=houses)
except:
return self.__jump(error='输入数据格式不对,请重新输入!')
app.add_url_rule('/look_price/',view_func=LookPriceView.as_view('my_look'))
look_house_price.html
查看租房价格信息
——
address
lease method
layout
derection
area
orientation
floor
elevator
water
power
gas
price
{% for house in houses %}
{{ house.address }}
{{ house['lease method'] }}
{{ house.layout }}
{{ house.derection }}
{{ house.area }}
{{ house.orientation }}
{{ house.floor }}
{{ house.elevator }}
{{ house.water }}
{{ house.power }}
{{ house.gas }}
{{ house.price }}
{% endfor %}
三、项目总结
本次我们使用了Flask框架结合了基于机器学习的房价预测模型,构建了一个简易版基于机器学习的南昌市租房价格预测系统,整个项目还有很多地方可以优化,比如页面美化、模块添加等等,这些就留给学习的小伙伴根据自身需求进行创新升级!喜欢本项目的话就三连支持一下啦!
本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://www.net2asp.com/d1af81ff92.html
