python flask智能租房项目——详情页
基本信息展示
1. 后端接?設(shè)計(jì)
接?描述 接?參數(shù)
請求?? 詳情?
請求?式 GET
請求地址 /house/int:hid
返回?cái)?shù)據(jù) 房源對象,包括:id、address、rooms、area、price、liulanliang等信息
房源數(shù)據(jù)所需字段如下:
參數(shù) 類型 說明
id int 房源id
title str 標(biāo)題
rooms str 戶型
area str ?積
price str 價(jià)格
addr str 房源地址
traffic str 交通情況
region str 地區(qū)
direction str 朝向
type str 瀏覽量
time int 發(fā)布時(shí)間,格式是時(shí)間戳
liangdian str 房屋亮點(diǎn)
sheshi str 房屋?帶的電器、家具等設(shè)施
tel str 房東電話
2. 后端邏輯
# 實(shí)現(xiàn)房源的基本信息展示 """ 1. 創(chuàng)建?個(gè)視圖函數(shù) 動(dòng)態(tài)路由 /house/<int:hid> method=get 2. 使?房源編號 通過sqlalchemy獲取編號對應(yīng)的房源對象 就可以獲取對象中的信息了 3. 使?render_template進(jìn)?模板的渲染 """ @detail_page.route('/house/<int:hid>') def detail(hid): # 使?房源編號 通過sqlalchemy獲取編號對應(yīng)的房源對象 house = House.query.get(hid) # 處理配套設(shè)施的數(shù)據(jù),變換成列表 sheshi_str = house.sheshi # 床-寬帶-洗?機(jī)-空調(diào)-熱?器-暖? sheshi_list = sheshi_str.split('-') return render_template('detail_page.html', house=house, sheshi=sheshi_list)配套設(shè)施
之前我們存放在數(shù)據(jù)庫中的配套設(shè)施信息是這樣的
空調(diào)-熱?器-暖?-可做飯-衛(wèi)?間
所以我們在使?的時(shí)候,需要對其進(jìn)?處理,轉(zhuǎn)換成 [‘空調(diào)’, ‘熱?器’,‘暖?’,‘可做飯’,‘衛(wèi)?間’]
3. 前端邏輯
<!--大標(biāo)題--><div class="col-lg-12 col-md-12 detail-header"><h3>{{ house.address }} {{ house.rooms }}</h3><div class="describe"><span>為您精準(zhǔn)定位,當(dāng)前城市房源信息</span></div></div><!--左詳情--><div class="col-lg-8 col-md-8"><div class="course"><!--圖--><div><a href="#"><img class='img-fluid img-box' src="/static/img/house-bg1.jpg" alt=""></a></div><!--價(jià)格--><div class="house-info"><span class="price">¥ {{ house.price }}/月</span><span class="collection" id="btn-collection"><a><i class="fa fa-heart"aria-hidden="true"> 收藏</i></a></span></div><!--基本信息標(biāo)題--><div class="attribute-header"><h4>基本信息</h4></div><!--屬性1--><div class="row attribute-info"><div class="col-lg-2 col-md-2"><span class="attribute-text">基本屬性</span></div><div class="col-lg-4 col-md-4"><div><span class="attribute-text">房屋戶型:</span><span class="info-text">{{ house.rooms }}</span></div><div><span class="attribute-text">建筑面積:</span><span class="info-text">{{ house.area }}平米</span></div><div><span class="attribute-text">房屋朝向:</span><span class="info-text">{{ house.direction }}</span></div></div><div class="col-lg-6 col-md-6"><div><span class="attribute-text">所在區(qū)域:</span><span class="info-text">{{ house.address }}</span></div><div><span class="attribute-text">租住類型:</span><span class="info-text">{{ house.rent_type }}</span></div><div><span class="attribute-text">房東電話:</span><span class="info-text">{{ house.phone_num }}</span></div></div></div><!--屬性2--><div class="row attribute-info"><div class="col-lg-2 col-md-2"><span class="attribute-text">房屋賣點(diǎn)</span></div><div class="col-lg-8 col-md-8"><div><span class="attribute-text">交通條件:</span><span class="info-text">{{ house.traffic | dealNone }}</span></div><div><span class="attribute-text">優(yōu)勢條件:</span><span class="info-text">{{ house.title }}</span></div></div></div><!--房源配套設(shè)施--><div class="attribute-header"><h4>房源配套設(shè)施</h4></div><!--設(shè)施列表--><div class="row attribute-info"><div class="col-lg-2 col-md-2"><span class="icon-1"></span>{% if '冰箱' in sheshi %}<span class="attribute-text-sm" style="color: #f1c40f">冰箱</span>{% else %}<span class="attribute-text-sm"><s>冰箱</s></span>{% endif %}</div><div class="col-lg-2 col-md-2"><span class="icon-2"></span>{% if '洗衣機(jī)' in sheshi %}<span class="attribute-text-sm" style="color: #f1c40f">洗衣機(jī)</span>{% else %}<span class="attribute-text-sm"><s>洗衣機(jī)</s></span>{% endif %}</div><div class="col-lg-2 col-md-2"><span class="icon-3"></span>{% if '電視' in sheshi %}<span class="attribute-text-sm" style="color: #f1c40f">電視</span>{% else %}<span class="attribute-text-sm"><s>電視</s></span>{% endif %}</div><div class="col-lg-2 col-md-2"><span class="icon-4"></span>{% if '空調(diào)' in sheshi %}<span class="attribute-text-sm" style="color: #f1c40f">空調(diào)</span>{% else %}<span class="attribute-text-sm"><s>空調(diào)</s></span>{% endif %}</div><div class="col-lg-2 col-md-2"><span class="icon-5"></span>{% if '暖氣' in sheshi %}<span class="attribute-text-sm" style="color: #f1c40f">暖氣</span>{% else %}<span class="attribute-text-sm"><s>暖氣</s></span>{% endif %}</div></div><div class="row attribute-info"><div class="col-lg-2 col-md-2"><span class="icon-6"></span>{% if '熱水器' in sheshi %}<span class="attribute-text-sm" style="color: #f1c40f">熱水器</span>{% else %}<span class="attribute-text-sm"><s>熱水器</s></span>{% endif %}</div><div class="col-lg-2 col-md-2"><span class="icon-7"></span>{% if '天然氣' in sheshi %}<span class="attribute-text-sm" style="color: #f1c40f">天然氣</span>{% else %}<span class="attribute-text-sm"><s>天然氣</s></span>{% endif %}</div><div class="col-lg-2 col-md-2"><span class="icon-8"></span>{% if '床' in sheshi %}<span class="attribute-text-sm" style="color: #f1c40f">床</span>{% else %}<span class="attribute-text-sm"><s>床</s></span>{% endif %}</div><div class="col-lg-2 col-md-2"><span class="icon-9"></span>{% if '寬帶' in sheshi %}<span class="attribute-text-sm" style="color: #f1c40f">WIFI</span>{% else %}<span class="attribute-text-sm"><s>WIFI</s></span>{% endif %}</div><div class="col-lg-2 col-md-2"><span class="icon-10"></span>{% if '電梯' in sheshi %}<span class="attribute-text-sm" style="color: #f1c40f">電梯</span>{% else %}<span class="attribute-text-sm"><s>電梯</s></span>{% endif %}</div></div></div></div>戶型占?
1. 后端接?設(shè)計(jì)
接?描述 接?參數(shù)
請求?? 詳情?
請求?式 GET
請求地址 /get/piedata/
返回?cái)?shù)據(jù) json數(shù)據(jù)格式
每?組的房源數(shù)據(jù)所需字段如下:
參數(shù) 類型 說明
name str 戶型
value int 數(shù)量
2. 效果及功能介紹
功能的作?:
統(tǒng)計(jì)房源所屬街道的戶型占?
功能的?途:
提供房源附近的戶型占?信息,?便?戶了解哪種戶型更加好找
關(guān)于所屬街道的解釋:
房源的address:順義-順義城-怡馨家園
那么房源所屬街道:順義-順義城,對應(yīng)房源的block字段
3. 戶型占?功能實(shí)現(xiàn)邏輯
4.1 第?步和第?步 前端發(fā)送請求
// 獲取pie $.ajax({ url: "/get/piedata/{{ house.block }}", type: 'get', dataType: 'json', success: function (data) { pie_chart(data['data']) } });4.2 第三步 數(shù)據(jù)選擇、處理、變換和返回
# 實(shí)現(xiàn)戶型占比功能 """ 1. 創(chuàng)建一個(gè)視圖函數(shù) /get/piedata/<block> get請求方式 2. 獲取block字段 使用sqlalchemy來查詢符合block字段的房源 3. 分組統(tǒng)計(jì)房源中的戶型 和 數(shù)量 根據(jù)數(shù)量對 戶型進(jìn)行排序 降序排序 4. 封裝數(shù)據(jù) 5. 提交給echarts """ @detail_page.route('/get/piedata/<block>') def return_pie_data(block):print(block)# 1. 選擇 filter(House.block == block)# 2. 預(yù)處理 group_by(House.rooms).order_by(func.count().desc())# 3. 預(yù)處理的結(jié)果是 resultresult = House.query.with_entities(House.rooms, func.count()).filter(House.block == block).group_by(House.rooms).order_by(func.count().desc()).all()# 4. 對數(shù)據(jù)進(jìn)行變換 result ==> {'name': one_house[0], 'value': one_house[1]}data = []for one_house in result:data.append({'name': one_house[0], 'value': one_house[1]})return jsonify({'data': data})4.3. 渲染-數(shù)據(jù)展示
function pie_chart(data) {var myChart = echarts.init(document.getElementById('pie'));window.addEventListener('resize', function () {myChart.resize();});var option = {tooltip : {trigger: 'item',formatter: "{a} <br/>{b} : {c} (ozvdkddzhkzd%)",},series:[{name: '戶型的占比',type: 'pie',radius: ['0%', '50%'],center: ['50%', '50%'],labelLine: {normal: {show: true},// 選中后加重表現(xiàn)emphasis: {show: true}},// 餅狀圖的內(nèi)部名字label: {normal: {show: true},emphasis: {show: true}},//itemStyle: {emphasis: {shadowBlur: 10,shadowOffsetX: 0,shadowColor: 'rgba(0, 0, 0, 0.5)'}},data: data,}]};myChart.setOption(option); }?區(qū)房源數(shù)量TOP20
1. 后端接?設(shè)計(jì)
接?描述 接?參數(shù)
請求?? 詳情?-當(dāng)前街道的?區(qū)數(shù)量top20
請求?式 GET
請求地址 /get/columndata/
返回?cái)?shù)據(jù) json數(shù)據(jù)格式
圖表類型 柱狀圖
參數(shù) 類型 說明
name_list_x 列表 X軸的變量,?區(qū)名稱
num_list_y 列表 Y軸的變量,?區(qū)數(shù)量
2. 效果及功能介紹
功能的作?:
先獲取房源所處街道附近的所有?區(qū),然后統(tǒng)計(jì)各個(gè)?區(qū)的在租房源數(shù)量
功能的?途:
提供房源附近各個(gè)?區(qū)在租房源數(shù)量,?便?戶尋找?標(biāo)房源
4.1 第?步 前端發(fā)送請求
// 獲取column$.ajax({url: "/get/columndata/{{ house.block }}",type: 'get',dataType: 'json',success: function (data) {column_chart(data['data'])}});4.2 第?步 數(shù)據(jù)選擇、處理變換和返回?cái)?shù)據(jù)
# 實(shí)現(xiàn)本地區(qū)小區(qū)數(shù)量TOP20功能 """ 1. 創(chuàng)建一個(gè)視圖函數(shù) /get/columndata/<block> get請求方式 2. 獲取block字段 使用sqlalchemy獲取符合這個(gè)block字段的所有房源數(shù)據(jù) --- 目標(biāo)數(shù)據(jù) 3. 預(yù)處理 對目標(biāo)數(shù)據(jù) 進(jìn)行分組 依據(jù)小區(qū)名字進(jìn)行分組 統(tǒng)計(jì)每個(gè)小區(qū)的房源數(shù)量 就可以根據(jù)房源數(shù)量 對小區(qū)進(jìn)項(xiàng)排序 降序排序的方式————預(yù)處理的結(jié)果 4. 進(jìn)行數(shù)據(jù)的變換 變換成能夠提交給echarts的數(shù)據(jù)格式 5. 使用jsonify返回?cái)?shù)據(jù)給前端 """ @detail_page.route('/get/columndata/<block>') def return_bar_data(block):result = House.query.with_entities(House.address, func.count()).filter(House.block == block).group_by(House.address).order_by(func.count().desc()).all() # 小區(qū)名字出現(xiàn)在address這個(gè)字段中# {'name_list_x':['xxx小區(qū)','xxx小區(qū)','xxx小區(qū)'],'num_list_y':[160,149,128]}name_list = []num_list = []for addr, num in result:# 順義-順義城-西辛南區(qū) ==> ['順義-順義城', '西辛南區(qū)'] ==> 西辛南區(qū)xiaoqu_name = addr.rsplit('-', 1)[1]name_list.append(xiaoqu_name)num_list.append(num)# 獲取TOP20的數(shù)據(jù) 大于20的就直接舍去if len(name_list) > 20:data = {'name_list_x': name_list[:20], 'num_list_y': num_list[:20]}else:data = {'name_list_x': name_list, 'num_list_y': num_list}return jsonify({'data': data})4.3 渲染-數(shù)據(jù)展示
function column_chart(data) {var salaru_line = echarts.init(document.getElementById('scolumn_line'));window.addEventListener('resize', function () {salaru_line.resize();});// var XData=['東方鳳雅臺(tái)', '仙桐御景', '仙湖山莊二期', '仙湖楓景家園', '蘭亭國際公寓', '華景園御庭軒', '合正錦園一期', '名駿豪庭', '廣嶺家園', '新世界四季御園', '新世界鹿茵翠地', '桐景花園', '聚寶華府', '金色年華家園', '鴻景翠峰', '鵬興花園一期', '鵬興花園三期', '鵬興花園二期', '鵬興花園六期', '鵬蓮花園'];// var yData=[1, 1, 1, 3, 1, 1, 1, 3, 4, 1, 1, 1, 2, 2, 1, 2, 1, 8, 1, 1];// {'name_list_x': name_list, 'num_list_y': num_list}var XData = data['name_list_x'];var yData = data['num_list_y'];var dataMin = parseInt(Math.min.apply(null, yData)/2);var option = {backgroundColor: "#fff",grid: {height:'200px'},xAxis: {axisTick: {show: false},splitLine: {show: false},splitArea: {show: false},data: XData,axisLabel: {formatter: function (value) {var ret = ""; //拼接加\n返回的類目項(xiàng)var maxLength = 1; //每項(xiàng)顯示文字個(gè)數(shù)var valLength = value.length; //X軸類目項(xiàng)的文字個(gè)數(shù)var rowN = Math.ceil(valLength / maxLength); //類目項(xiàng)需要換行的行數(shù)if (rowN > 1) //如果類目項(xiàng)的文字大于3,{for (var i = 0; i < rowN; i++) {var temp = ""; //每次截取的字符串var start = i * maxLength; //開始截取的位置var end = start + maxLength; //結(jié)束截取的位置//這里也可以加一個(gè)是否是最后一行的判斷,但是不加也沒有影響,那就不加吧temp = value.substring(start, end) + "\n";ret += temp; //憑借最終的字符串}return ret;} else {return value;}},interval: 0,fontSize: 11,fontWeight: 100,textStyle: {color: '#555',}},axisLine: {lineStyle: {color: '#4d4d4d'}}},yAxis: {axisTick: {show: false},splitLine: {show: false},splitArea: {show: false},min: dataMin,axisLabel: {textStyle: {color: '#9faeb5',fontSize: 16,}},axisLine: {lineStyle: {color: '#4d4d4d'}}},"tooltip": {"trigger": "item","textStyle": {"fontSize": 12},"formatter": "{b0}: {c0}套"},series: [{type: "bar",itemStyle: {normal: {color: {type: 'linear',x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: '#00d386' // 0% 處的顏色}, {offset: 1,color: '#0076fc' // 100% 處的顏色}],globalCoord: false // 缺省為 false},barBorderRadius: 15,}},// barWidth: 7,data: yData}]};salaru_line.setOption(option, true); }戶型價(jià)格?勢
1. 后端接?設(shè)計(jì)
接?描述 接?參數(shù)
請求?? 詳情?
請求?式 GET
請求地址 /get/brokenlinedata/
返回?cái)?shù)據(jù) json數(shù)據(jù)格式
圖表類型 折線圖
2. 效果及功能介紹
功能的作?:
先獲取房源所處街道附近的所有房源價(jià)格,然后獲取最近半個(gè)?四個(gè)戶型的平均價(jià)格(租?/?積)
功能的?途:
提供房源街道區(qū)域的戶型價(jià)格?勢,?便?戶了解市場?情
4.1 第?步 前端發(fā)送請求
// 獲取broken_line $.ajax({url: "/get/brokenlinedata/{{ house.block }}",type: 'get',dataType: 'json',success: function (data) {broken_line_chart(data['data'])} });4.2 第?步 數(shù)據(jù)選擇、處理變換和返回?cái)?shù)據(jù)
# 實(shí)現(xiàn)戶型價(jià)格走勢 """ 1. 創(chuàng)建一個(gè)視圖函數(shù) /get/brokenlinedata/<block> get請求方式 2. 獲取block字段 使用sqlalchemy獲取符合block字段 和 戶型的房源數(shù)據(jù) --- 目標(biāo)數(shù)據(jù) 3. 預(yù)處理 對目標(biāo)數(shù)據(jù) 進(jìn)行分組 分組的依據(jù)是房源的發(fā)布時(shí)間 使用func函數(shù)中avg()獲取 price/area價(jià)格 按照發(fā)布時(shí)間來進(jìn)行排序 默認(rèn)方式進(jìn)行排序 --- 預(yù)處理的結(jié)果 4. 對預(yù)處理的結(jié)果 進(jìn)行變換 的到 提供給echarts的數(shù)據(jù) {'data':{'1室1廳':[76.49, 42.86]}} """ @detail_page.route('/get/brokenlinedata/<block>') def return_brokenline_data(block):# 1室1廳的戶型result = House.query.with_entities(func.avg(House.price / House.area)).filter(House.block == block,House.rooms == '1室1廳').group_by(House.publish_time).order_by(House.publish_time).all()data = []for i in result[-14:]:data.append(round(i[0], 2))# 2室1廳的戶型result1 = House.query.with_entities(func.avg(House.price / House.area)).filter(House.block == block,House.rooms == '2室1廳').group_by(House.publish_time).order_by(House.publish_time).all()data1 = []for i in result1[-14:]:data1.append(round(i[0], 2))# 2室2廳的戶型result2 = House.query.with_entities(func.avg(House.price / House.area)).filter(House.block == block,House.rooms == '2室2廳').group_by(House.publish_time).order_by(House.publish_time).all()data2 = []for i in result2[-14:]:data2.append(round(i[0], 2))# 3室2廳的戶型result3 = House.query.with_entities(func.avg(House.price / House.area)).filter(House.block == block,House.rooms == '3室2廳').group_by(House.publish_time).order_by(House.publish_time).all()data3 = []for i in result3[-14:]:data3.append(round(i[0], 2))return jsonify({'data': {'1室1廳': data, '2室1廳': data1, '2室2廳': data2, '3室2廳': data3}})4.3 第三步 渲染-數(shù)據(jù)展示
function broken_line_chart(data) {var salaru_line = echarts.init(document.getElementById('broken_line'), 'infographic');window.addEventListener('resize', function () {salaru_line.resize();});// data ==> {'3室2廳': [26, 28, 42, 26, 22, 28, 22, 26, 32, 17, 22], '2室1廳': [25, 28, 27, 40, 33, 29, 28, 37, 30, 28, 32], '2室2廳': [37, 37, 36, 47, 34, 32, 32, 37, 36, 29, 31], '1室1廳': [35, 47, 44, 47, 44, 44, 31, 32, 34, 34, 34]}var Data1 = data['3室2廳'];var Data2 = data['2室2廳'];var Data3 = data['2室1廳'];var Data4 = data['1室1廳'];var date_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14];var option = {tooltip: {trigger: 'axis',},grid: {containLabel: true,left: '3%',right: '4%',bottom: '3%',},xAxis: {type: 'category',boundaryGap: false,data: date_list},yAxis: {type: 'value'},series: [{name:'3室2廳',type:'line',data:Data1},{name:'2室2廳',type:'line',data:Data2},{name:'2室1廳',type:'line',data:Data3},{name:'1室1廳',type:'line',data:Data4}] };salaru_line.setOption(option, true); }預(yù)測房價(jià)
1. 后端接?設(shè)計(jì)
接?描述 接?參數(shù)
請求?? 詳情?-所在區(qū)域內(nèi)房價(jià)預(yù)測
請求?式 GET
請求地址 /get/scatterdata/
返回?cái)?shù)據(jù) json數(shù)據(jù)格式
圖表類型 散點(diǎn)圖
參數(shù) 類型 說明
data 數(shù)組列表 數(shù)組[X,Y]。X為時(shí)間,Y為單價(jià)。
2. 效果展示
功能的作?:
先獲取房源所處街道附近的所有房源價(jià)格,然后根據(jù)時(shí)間統(tǒng)計(jì)每?的平均價(jià)格(租?/?積)
功能的?途:
提供房源街道區(qū)域的價(jià)格?勢,?便?戶了解市場?情
4.1 第?步 前端發(fā)送請求
// 獲取scatter$.ajax({url: "/get/scatterdata/{{ house.block }}",type: 'get',dataType: 'json',success: function (data) {getdata1(data['data']);}});3.2 第?步 數(shù)據(jù)選擇、處理、變換和返回?cái)?shù)據(jù)
# 實(shí)現(xiàn)房價(jià)預(yù)測功能 """ 1. 創(chuàng)建一個(gè)視圖函數(shù) /get/scaterdata/<block> get請求方式 2. 獲取block字段 然后使用sqlalchemy獲取符合blocl字段的所有房源 --- 目標(biāo)數(shù)據(jù) 3. 預(yù)處理 對目標(biāo)數(shù)據(jù)進(jìn)行分組 分組的依據(jù)就是房源的發(fā)布時(shí)間 使用func中avg()獲取 price/area價(jià)格 按照發(fā)布時(shí)間進(jìn)行排序 --- 預(yù)處理的結(jié)果 4. 對預(yù)處理的結(jié)果進(jìn)行變換 得到能夠提交給echarts的數(shù)據(jù)格式 {'data':[[0,50],[1,16.87],[2,76.49]]} """ @detail_page.route('/get/scatterdata/<block>') def return_scatter_data(block):# 1. 實(shí)現(xiàn)已有數(shù)據(jù)的渲染result = House.query.with_entities(func.avg(House.price / House.area)).filter(House.block == block).group_by(House.publish_time).order_by(House.publish_time).all()data = []X = []Y = []for index, i in enumerate(result):X.append([index])Y.append(round(i[0], 2))data.append([index, round(i[0], 2)]) # round函數(shù) 可以完成浮點(diǎn)數(shù)的四舍五入的運(yùn)算 傳入兩個(gè)參數(shù) 第一參數(shù):浮點(diǎn)數(shù) 第二參數(shù):保留的小數(shù)位# 2. 對未來一天(第二天)的價(jià)格進(jìn)行預(yù)測predict_value = len(data)predict_outcome = linear_model_main(X, Y, predict_value)print(predict_outcome)p_outcome = round(predict_outcome[0], 2)# 3. 將預(yù)測的數(shù)據(jù)添加入data中data.append([predict_value, p_outcome])return jsonify({'data': data})4. 渲染-數(shù)據(jù)展示
function getdata1(data) {var center1 = echarts.init(document.getElementById('f_line'), 'infographic');window.addEventListener('resize', function () {center1.resize();});var myRegression = ecStat.regression('linear', data);myRegression.points.sort(function (a, b) {return a[0] - b[0];});option = {title: {subtext: '根據(jù)最近的房價(jià),預(yù)測價(jià)格走勢',left: 'center',},tooltip: {trigger: 'axis',axisPointer: {type: 'cross'}},grid: {show: true,//是否顯示直角坐標(biāo)系的網(wǎng)格,true顯示,false不顯示left: '13%',//grid組件離容器左側(cè)的距離containLabel: false,//grid 區(qū)域是否包含坐標(biāo)軸的刻度標(biāo)簽,在無法確定坐標(biāo)軸標(biāo)簽的寬度,容器有比較小無法預(yù)留較多空間的時(shí)候,可以設(shè)為 true 防止標(biāo)簽溢出容器。},xAxis: {type: 'value',height: '100px',splitLine: {lineStyle: {type: 'dashed'}},},yAxis: {type: 'value',min: 1.5,splitLine: {lineStyle: {type: 'dashed'}},},series: [{name: '分散值(實(shí)際值)',type: 'scatter',label: {emphasis: {show: true,position: 'left',textStyle: {color: 'blue',fontSize: 12}}},data: data}, {name: '線性值(預(yù)測值)',type: 'line',showSymbol: false,data: myRegression.points,markPoint: {itemStyle: {normal: {color: 'transparent'}},label: {normal: {show: true,position: 'left',formatter: myRegression.expression,textStyle: {color: '#333',fontSize: 12}}},data: [{coord: myRegression.points[myRegression.points.length - 1]}]}}]};center1.setOption(option, true);}協(xié)同過濾算法
1. 協(xié)同過濾算法
通過尋找與??興趣、?為相似的對象 使?他們以往的數(shù)據(jù) ,來給??推薦??想要的東?。
2. 協(xié)同過濾算法的分類
2.1 基于物品的協(xié)同算法
2.2 基于?戶的協(xié)同算法
3. 本項(xiàng)?使?基于?戶的協(xié)同過濾算法
4. 使??爾遜相關(guān)系數(shù)做推薦
4.2 實(shí)現(xiàn)pearson推薦算法
from utils.con_to_db import query_data from math import sqrt# 獲取推薦表中所有的用戶id """ 1. 創(chuàng)建一個(gè)函數(shù) 2. 獲取推薦表中的所有用戶瀏覽的信息, 根據(jù)用戶id進(jìn)行分類 ,獲取所有的用戶的id 3. 對獲取到的結(jié)果進(jìn)行變形 """ def get_total_u_id():# 用來獲取推薦表中 所有的用戶idsql = 'select user_id from tuijian group by user_id'result = query_data(sql)# print(result)# 將所有的用戶id放入到一個(gè)列表中total_u_id = list([i[0] for i in result])# print(total_u_id)return total_u_id# 獲取每個(gè)用戶的歷史記錄的需求 """ 1. 創(chuàng)建一個(gè)函數(shù) 2. 通過user_id這個(gè)字段 來過濾出當(dāng)前用戶的所有的瀏覽歷史 從當(dāng)前的這組數(shù)據(jù)中 獲取house_id 和 score 3. 對獲取到的數(shù)據(jù) 進(jìn)行組裝 {1: {123:4, 234:2} } ==> {u_id: {house_id: score, house_id:score.....}} """ def get_user_info(user_id):# 使用sql語句完成數(shù)據(jù)庫的查詢sql = 'select user_id, house_id, score from tuijian where user_id = "{}"'.format(user_id)result = query_data(sql)# print(result)data = {}for info in result:# data字典中 還沒有插入過當(dāng)前用戶的信息的操作if info[0] not in data.keys():data[info[0]] = {info[1]: info[2]}else:data[info[0]][info[1]] = info[2]# print(data)return data# 獲取兩個(gè)用戶的相似度 """ 1. 創(chuàng)建一個(gè)函數(shù) 2. 獲取兩個(gè)用戶的 各自的瀏覽記錄 3. 后去兩個(gè)用戶共同的瀏覽過的房源 4. 使用pearson公式 來獲取他們的相似度 """def pearson_sim(user1, sim_user):# 獲取兩個(gè)用戶的 各自的瀏覽記錄user1_data = get_user_info(user1)[int(user1)]user2_data = get_user_info(sim_user)[int(sim_user)]# 兩個(gè)用戶共同的瀏覽過的房源common = []for key in user1_data.keys(): # keys函數(shù)使用來獲取字典中 所有的鍵 返回的是盛放鍵的列表if key in user2_data.keys():common.append(key)# 如果沒有共同評論過的房源 就返回0if len(common) == 0:return 0# 統(tǒng)計(jì)相同房源的個(gè)數(shù)n = len(common)# print(n, common)# 計(jì)算評分和 Ex和Eyuser1_sum = sum([user1_data[hid] for hid in common])user2_sum = sum([user2_data[hid] for hid in common])# 計(jì)算評分的平方和 E(x)^2 E(y)^2pow_sum1 = sum([pow(user1_data[hid], 2) for hid in common])pow_sum2 = sum([pow(user2_data[hid], 2) for hid in common])# 計(jì)算乘積的和PSum = sum([float(user1_data[hid] * float(user2_data[hid])) for hid in common])# 組裝成分子fenzi = PSum - (user1_sum * user2_sum / n)# 組裝分母fenmu = sqrt(pow_sum1 - pow(user1_sum, 2) / n) * (pow_sum2 - pow(user2_sum, 2) / n)if fenmu == 0:return 0result = fenzi / fenmu# print(result)return result# 獲取相似度在前十名的用戶 """ 1. 創(chuàng)建一個(gè)函數(shù) 2. 獲取推薦表中的全部的用戶的id 3. 遍歷全部用戶的id 獲取除自己之外的所有用戶的 相似度 4. 使用sort函數(shù)來進(jìn)行降序排序 獲取前十名的用戶id """def top10_similar(UserID):# 獲取推薦表中的全部的用戶的idtotal_u_id = get_total_u_id()# 遍歷全部用戶的id 獲取除自己之外的所有用戶的 相似度res = []for u_id in total_u_id:if int(UserID) != u_id:similar = pearson_sim(int(UserID), int(u_id))if similar > 0:res.append((u_id, similar))# print(res)# 使用sort函數(shù)來進(jìn)行降序排序 獲取前十名的用戶idres.sort(key=lambda val: val[1], reverse=True)# sort函數(shù)可以對列表進(jìn)行排序 默認(rèn)使用升序方式排序 使用reverse改為降序排序# print(res[:10])return res# 獲取推薦的房源 """ 1. 創(chuàng)建一個(gè)函數(shù) 2. 獲取相似度最高的用戶 通過這個(gè)用戶 獲取他完整的 瀏覽記錄 3. 獲取當(dāng)前這個(gè)用戶的 完整瀏覽記錄 4. 判斷 當(dāng)前用戶中沒有 但是在 相似用戶中 評價(jià)最高的房源 5. 按照 評分 使用sort來進(jìn)行排序 降序排序 獲取前6個(gè) """def recommed(user):# 判斷獲取到的top10_similar()函數(shù)的結(jié)果 是否有值,如果沒有值 返回Noneif len(top10_similar(user)) == 0:return None# 獲取相似度最高的用戶idtop_sim_user = top10_similar(user)[0][0]# 獲取相似度最高的用戶 的完整瀏覽記錄items = get_user_info(top_sim_user)[int(top_sim_user)] # {1: {123:4, 234:2}}# 獲取當(dāng)前用戶自己的瀏覽記錄user_data = get_user_info(user)[int(user)]# 篩選當(dāng)前用戶 未瀏覽的房源 并添加到列表中recommendata = []for item in items.keys():if item not in user_data.keys():recommendata.append((item, items[item]))# print(recommendata)recommendata.sort(key=lambda val: val[1], reverse=True)# print(recommendata)# 返回評分最高的6套房源if len(recommendata) > 6:return recommendata[:6]else:return recommendataif __name__ == '__main__':# get_total_u_id()# get_user_info(1)# pearson_sim(1, 23)# top10_similar(3)recommendata= recommed(1)print(recommendata)智能推薦
1. 后端邏輯
智能推薦的邏輯應(yīng)該在詳情?detail視圖函數(shù)的中實(shí)現(xiàn)。?在實(shí)現(xiàn)的時(shí)候,我們需要分登陸狀態(tài)和?登錄狀態(tài)兩種情況來進(jìn)?討論,詳細(xì)的邏輯如下圖所示:
源代碼
鏈接:https://pan.baidu.com/s/1oBlP7B52Kp9mcqoIeHLX7Q
提取碼:yovx
復(fù)制這段內(nèi)容后打開百度網(wǎng)盤手機(jī)App,操作更方便哦
總結(jié)
以上是生活随笔為你收集整理的python flask智能租房项目——详情页的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 账号通过邮箱找回密码功能设计
- 下一篇: python读取海康威视摄像头价格_Op