最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

畢業(yè)設(shè)計(jì) 大數(shù)據(jù)上海租房數(shù)據(jù)分析與可視化

2023-02-16 11:54 作者:丹成學(xué)長(zhǎng)  | 我要投稿

1 前言

?? 這兩年開始畢業(yè)設(shè)計(jì)和畢業(yè)答辯的要求和難度不斷提升,傳統(tǒng)的畢設(shè)題目缺少創(chuàng)新和亮點(diǎn),往往達(dá)不到畢業(yè)答辯的要求,這兩年不斷有學(xué)弟學(xué)妹告訴學(xué)長(zhǎng)自己做的項(xiàng)目系統(tǒng)達(dá)不到老師的要求。

為了大家能夠順利以及最少的精力通過畢設(shè),學(xué)長(zhǎng)分享優(yōu)質(zhì)畢業(yè)設(shè)計(jì)項(xiàng)目,今天要分享的是

?? ?基于大數(shù)據(jù)上海租房數(shù)據(jù)爬取與分析可視化

??學(xué)長(zhǎng)這里給一個(gè)題目綜合評(píng)分(每項(xiàng)滿分5分)

  • 難度系數(shù):3分

  • 工作量:3分

  • 創(chuàng)新點(diǎn):5分

畢設(shè)幫助,選題指導(dǎo),技術(shù)解答,歡迎打擾,見B站個(gè)人主頁

https://space.bilibili.com/33886978


1 課題背景

基于Python的上海自如租房大數(shù)據(jù)聚類分析與可視化,爬取自如所有上海房源,進(jìn)行k-means聚類分析,將房源劃分為不同等級(jí)。并對(duì)數(shù)據(jù)進(jìn)行可視化分析。

2 實(shí)現(xiàn)效果

聚類后的dataframe結(jié)果

在這里插入圖片描述

堆疊柱狀圖

在這里插入圖片描述

餅圖

在這里插入圖片描述

3D柱狀圖

在這里插入圖片描述


在這里插入圖片描述

3 獲取房源數(shù)據(jù)

此次側(cè)重XPath的使用和反爬蟲小技巧。XPath是用路徑表達(dá)式在XML文檔中選取節(jié)點(diǎn),這里也同樣適用于HTML文檔的搜索。

3.1 確定URL

打開上海鏈家網(wǎng)的租房頁面,選擇篩選條件,示例如下。確認(rèn)后地址欄的URL會(huì)根據(jù)篩選條件而發(fā)生變化。(當(dāng)然如果沒有想好想要住的區(qū)域,地鐵線,租金,面積,朝向,戶型也沒有關(guān)系,可以直接爬取全部的上海房源數(shù)據(jù)。)

共計(jì)28頁房源信息,點(diǎn)擊切換下一頁,觀察URL會(huì)發(fā)現(xiàn)鏈家網(wǎng)是靜態(tài)的網(wǎng)頁,頁面切換通過在URL中加入pg{i}參數(shù)實(shí)現(xiàn)。因此我們只要能爬取一頁的信息,就可以通過參數(shù)循環(huán)來爬取所有頁面。

3.2 解析頁面

按F12打開開發(fā)者工具,在頁面中選擇一個(gè)元素以進(jìn)行檢查。可以看到右側(cè)的房源列表模塊和左邊的房源信息是一一對(duì)應(yīng)的。左側(cè)的每一條房源信息都等價(jià)于右側(cè)的class屬性為content__list --item的一個(gè)div圖層。因此我們只需要觀察了解第一個(gè)房源信息即可。

繼續(xù)展開這個(gè)div圖層,會(huì)發(fā)現(xiàn)我們需要的信息基本都被包含在屬性為content__list--item-- main的子div圖層中,尤其是其中幾個(gè)class為title,description,price的元素里。

以屬性為content__list--item-- title的paragraph為例,其中包含了租賃方式,街區(qū),房屋朝向等信息。我們可以用XPath來匹配和定位到這個(gè)段落,取出里面的文本。常用的匹配規(guī)則為 / 代表選取直接子節(jié)點(diǎn),// 代表選擇所有子孫節(jié)點(diǎn),. 代表選取當(dāng)前節(jié)點(diǎn),.. 代表選取當(dāng)前節(jié)點(diǎn)的父節(jié)點(diǎn),@ 則是加了屬性的限定,選取匹配屬性的特定節(jié)點(diǎn)。下面是租賃方式(整租/合租)的匹配方式。


LeaseMethod = li.xpath('.//div[@class="content__list--item--main"]/p[@class="content__list--item--title"]/a/text()')[0].strip().split(' ')[0].split('·')[0]

以此類推,我們可以輕易的取出街區(qū),租賃方式,朝向,每月租金,行政區(qū),板塊,房屋面積,格局和發(fā)布時(shí)長(zhǎng)等信息。

3.3 反爬蟲解決措施

網(wǎng)站的反爬措施有很多,比如檢測(cè)訪問請(qǐng)求頭。且如果一個(gè)header短期頻繁發(fā)送請(qǐng)求,也很容易被識(shí)別。這種情況下可以通過添加多個(gè)請(qǐng)求頭,每次隨機(jī)選取一個(gè)header,偽裝成瀏覽器訪問;且設(shè)置time sleep,每次發(fā)送請(qǐng)求隨機(jī)間隔一段時(shí)間來防止出現(xiàn)error403/404。還有一些方法如添加Referer,host,代理IP等,這里不做過多闡述,感興趣的小伙伴歡迎自行探索。

完整代碼和最終結(jié)果如下??梢钥吹降谝徊皆阪溂抑黜撍阉鲿r(shí)顯示的828條記錄已經(jīng)全部獲取到數(shù)據(jù)框中??梢赃M(jìn)行下一步的分析啦!



import requests
from lxml import etree
import random
import time
import pandas as pd
? ?
#偽裝請(qǐng)求頭
user_agents = [
? ?'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60',
? ?'Opera/8.0 (Windows NT 5.1; U; en)',
? ?'Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50',
? ?'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50',
? ?'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0',
? ?'Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10',
? ?'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2',
? ?'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36',
? ?'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
? ?'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.133 ',
? ?'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36',
? ?"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
? ?"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36",
? ?"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0",
? ?"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14",
? ?"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)",
? ?'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11',
? ?'Opera/9.25 (Windows NT 5.1; U; en)',
? ?'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
? ?'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)',
? ?'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12',
? ?'Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9',
? ?"Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Ubuntu/11.04 Chromium/16.0.912.77 Chrome/16.0.912.77 Safari/535.7",
? ?"Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0 "
]

def getHeaders():
? ?user_agent = user_agents[random.randint(0, len(user_agents)-1)]
? ?headers = {
? ? ? ?'User-Agent': user_agent
? ?}
? ?return headers


? ? ?

#對(duì)一個(gè)URL發(fā)送請(qǐng)求,解析結(jié)果,獲取所需數(shù)據(jù)
def get_data(url):
? ?#反爬蟲策略1:隨機(jī)取headers
? ?response = requests.get(url, headers=getHeaders(), stream=True)
? ?tree = etree.HTML(response.text)
? ?# 定位到content__list
? ?li_list = tree.xpath('//div[@class="content w1150"]/div[@class="content__article"]/div[@class="content__list"]/div')
? ?# all_house_list = []
? ?for li in li_list:
? ? ? ?#下面是兩種定位方式,都可
? ? ? ?# Nbhood = li.xpath('.//div[@class="content__list--item--main"]/p[@class="content__list--item--title"]/a[@class="twoline"]/text()')[0].strip().split(' ')[0].split('·')[1]
? ? ? ?Nbhood = li.xpath('.//div[@class="content__list--item--main"]/p[@class="content__list--item--title"]/a/text()')[0].strip().split(' ')[0].split('·')[1]
? ? ? ?LeaseMethod = li.xpath('.//div[@class="content__list--item--main"]/p[@class="content__list--item--title"]/a/text()')[0].strip().split(' ')[0].split('·')[0]
? ? ? ?HouseOrientation = li.xpath('.//div[@class="content__list--item--main"]/p[@class="content__list--item--title"]/a/text()')[0].strip().split(' ')[2]
? ? ? ?Rent = li.xpath('.//div[@class="content__list--item--main"]/span[@class="content__list--item-price"]/em/text()')[0]
? ? ? ?District = li.xpath('.//div[@class="content__list--item--main"]/p[@class="content__list--item--des"]/a/text()')[0]
? ? ? ?Location = li.xpath('.//div[@class="content__list--item--main"]/p[@class="content__list--item--des"]/a/text()')[1]
? ? ? ?Size = li.xpath('.//div[@class="content__list--item--main"]/p[@class="content__list--item--des"]/text()')[4].strip()
? ? ? ?HouseType = li.xpath('.//div[@class="content__list--item--main"]/p[@class="content__list--item--des"]/text()')[6].strip()
? ? ? ?releaseTime = li.xpath('.//div[@class="content__list--item--main"]/p[@class="content__list--item--brand oneline"]/span[@class="content__list--item--time oneline"]/text()')[0]
? ? ? ?Link = li.xpath('.//div[@class="content__list--item--main"]/p[@class="content__list--item--title"]/a[@class="twoline"]//@href')[0]
? ? ? ?all_house_list.append((Nbhood,LeaseMethod,HouseOrientation,Rent,District,Location,Size,HouseType,releaseTime))
? ? ? ?
? ?return all_house_list

#循環(huán)爬取所需租房信息
pages = ['https://sh.lianjia.com/ditiezufang/li143685063/pg{}rt200600000001l1l0ra1ra2ra0rp5rp6/'.format(x) for x in range(1,29)]
all_house_list = []
count = 0
for page in pages:
? ?a = get_data(page)
? ?#反爬蟲策略2:每次爬取隨機(jī)間隔3-10s
? ?time.sleep(random.randint(3,10))
? ?count=count+1
? ?print ('the '+str(count)+' page is sucessful')

name = ["街區(qū)", "租賃方式", "朝向", "每月租金", "行政區(qū)","板塊","房屋面積","格局","發(fā)布時(shí)長(zhǎng)"]
page_data = pd.DataFrame( columns= name,data=all_house_list)

4 K-means聚類算法

基本原理

k-Means算法是一種使用最普遍的聚類算法,它是一種無監(jiān)督學(xué)習(xí)算法,目的是將相似的對(duì)象歸到同一個(gè)簇中。簇內(nèi)的對(duì)象越相似,聚類的效果就越好。該算法不適合處理離散型屬性,但對(duì)于連續(xù)型屬性具有較好的聚類效果。

聚類效果判定標(biāo)準(zhǔn)

使各個(gè)樣本點(diǎn)與所在簇的質(zhì)心的誤差平方和達(dá)到最小,這是評(píng)價(jià)k-means算法最后聚類效果的評(píng)價(jià)標(biāo)準(zhǔn)。

在這里插入圖片描述

算法實(shí)現(xiàn)步驟

1)選定k值

2)創(chuàng)建k個(gè)點(diǎn)作為k個(gè)簇的起始質(zhì)心。

3)分別計(jì)算剩下的元素到k個(gè)簇的質(zhì)心的距離,將這些元素分別劃歸到距離最小的簇。

4)根據(jù)聚類結(jié)果,重新計(jì)算k個(gè)簇各自的新的質(zhì)心,即取簇中全部元素各自維度下的算術(shù)平均值。

5)將全部元素按照新的質(zhì)心重新聚類。

6)重復(fù)第5步,直到聚類結(jié)果不再變化。

7)最后,輸出聚類結(jié)果。

算法缺點(diǎn)

雖然K-Means算法原理簡(jiǎn)單,但是有自身的缺陷:

1)聚類的簇?cái)?shù)k值需在聚類前給出,但在很多時(shí)候中k值的選定是十分難以估計(jì)的,很多情況我們聚類前并不清楚給出的數(shù)據(jù)集應(yīng)當(dāng)分成多少類才最恰當(dāng)。

2)k-means需要人為地確定初始質(zhì)心,不一樣的初始質(zhì)心可能會(huì)得出差別很大的聚類結(jié)果,無法保證k-means算法收斂于全局最優(yōu)解。

3)對(duì)離群點(diǎn)敏感。

4)結(jié)果不穩(wěn)定(受輸入順序影響)。

5)時(shí)間復(fù)雜度高O(nkt),其中n是對(duì)象總數(shù),k是簇?cái)?shù),t是迭代次數(shù)。

算法實(shí)現(xiàn)關(guān)鍵問題說明

K值的選定說明

根據(jù)聚類原則:組內(nèi)差距要小,組間差距要大。我們先算出不同k值下各個(gè)SSE(Sum of squared errors)值,然后繪制出折線圖來比較,從中選定最優(yōu)解。從圖中,我們可以看出k值到達(dá)5以后,SSE變化趨于平緩,所以我們選定5作為k值。

在這里插入圖片描述


初始的K個(gè)質(zhì)心選定說明

初始的k個(gè)質(zhì)心選定是采用的隨機(jī)法。從各列數(shù)值最大值和最小值中間按正太分布隨機(jī)選取k個(gè)質(zhì)心。

關(guān)于離群點(diǎn)

離群點(diǎn)就是遠(yuǎn)離整體的,非常異常、非常特殊的數(shù)據(jù)點(diǎn)。因?yàn)閗-means算法對(duì)離群點(diǎn)十分敏感,所以在聚類之前應(yīng)該將這些“極大”、“極小”之類的離群數(shù)據(jù)都去掉,否則會(huì)對(duì)于聚類的結(jié)果有影響。離群點(diǎn)的判定標(biāo)準(zhǔn)是根據(jù)前面數(shù)據(jù)可視化分析過程的散點(diǎn)圖和箱線圖進(jìn)行判定。根據(jù)散點(diǎn)圖和箱線圖,需要去除離散值的范圍如下:

1)單價(jià):基本都在100000以內(nèi),沒有特別的異常值。

2)總價(jià):基本都集中在3000以內(nèi),這里我們需要去除3000外的異常值。

3)建筑面積:基本都集中在500以內(nèi),這里我們需要去除500外的異常值。

數(shù)據(jù)的標(biāo)準(zhǔn)化

因?yàn)榭們r(jià)的單位為萬元,單價(jià)的單位為元/平米,建筑面積的單位為平米,所以數(shù)據(jù)點(diǎn)計(jì)算出歐幾里德距離的單位是沒有意義的。同時(shí),總價(jià)都是3000以內(nèi)的數(shù),建筑面積都是500以內(nèi)的數(shù),但單價(jià)基本都是20000以上的數(shù),在計(jì)算距離時(shí)單價(jià)起到的作用就比總價(jià)大,總價(jià)和單價(jià)的作用都遠(yuǎn)大于建筑面積,這樣聚類出來的結(jié)果是有問題的。這樣的情況下,我們需要將數(shù)據(jù)標(biāo)準(zhǔn)化,即將數(shù)據(jù)按比例縮放,使之都落入一個(gè)特定區(qū)間內(nèi)。去除數(shù)據(jù)的單位限制,將其轉(zhuǎn)化為無量綱的純數(shù)值,便于不同單位或量級(jí)的指標(biāo)能夠進(jìn)行計(jì)算和比較。

我們將單價(jià)、總價(jià)和面積都映射到500,因?yàn)槊娣e本身就都在500以內(nèi),不要特別處理。單價(jià)在計(jì)算距離時(shí),需要先乘以映射比例0.005,總價(jià)需要乘以映射比例0.16。進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化前和進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化后的聚類效果對(duì)比如下:圖32、圖33是沒有數(shù)據(jù)標(biāo)準(zhǔn)化前的聚類效果散點(diǎn)圖;圖34、圖35是數(shù)據(jù)標(biāo)準(zhǔn)化后的聚類效果散點(diǎn)圖。

數(shù)據(jù)標(biāo)準(zhǔn)化前的單價(jià)與建筑面積聚類效果散點(diǎn)圖:

在這里插入圖片描述



聚類結(jié)果分析

聚類結(jié)果如下

在這里插入圖片描述

5 部分核心代碼

from sklearn.cluster import KMeans # 導(dǎo)入Kmeans
k=5 # 聚類類別數(shù)
kmodel = KMeans(n_clusters=k, n_jobs=4)
kmodel.fit(housing_prepared)

kmodel.cluster_centers_[0:5,:3]

ss.inverse_transform(kmodel.cluster_centers_[0:5,:3],copy=True)

housing_data = housing.copy()
housing_data.head(1)

c = pd.DataFrame(kmodel.cluster_centers_).sort_values(2)
c['房屋等級(jí)']=['交通不便普通','交通一般普通','交通便利普通','高端房源','豪宅']
#c

labels = c
# 高價(jià)值
expensive = labels[labels['房屋等級(jí)']=='豪宅'].index[0]
high = labels[labels['房屋等級(jí)']=='高端房源'].index[0]
mid = labels[labels['房屋等級(jí)']=='交通便利普通'].index[0]
normal = labels[labels['房屋等級(jí)']=='交通一般普通'].index[0]
low = labels[labels['房屋等級(jí)']=='交通不便普通'].index[0]
#print(expensive,high,mid,low)

kmeans_type_shift = {
? ?expensive:'豪宅',
? ?high:'高端房源',
? ?mid:'交通便利普通',
? ?normal:'交通一般普通',
? ?low:'交通不便普通'
}
housing_data['聚類類別'] = housing_data['聚類類別'].map(kmeans_type_shift)

housing_data.head()

housing_data.shape
#housing_data.info()

housing_data.to_csv('housing_with_type.csv')

6 最后

畢設(shè)幫助,選題指導(dǎo),技術(shù)解答,歡迎打擾,見B站個(gè)人主頁

https://space.bilibili.com/33886978

畢業(yè)設(shè)計(jì) 大數(shù)據(jù)上海租房數(shù)據(jù)分析與可視化的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
罗江县| 辉县市| 东莞市| 云林县| 邳州市| 平原县| 姜堰市| 西盟| 鹤山市| 汶川县| 辽阳市| 开化县| 台安县| 固原市| 濉溪县| 高碑店市| 阜南县| 调兵山市| 和静县| 顺义区| 平舆县| 青铜峡市| 汝阳县| 新郑市| 开鲁县| 轮台县| 中阳县| 朝阳市| 衡阳县| 遂平县| 新乡市| 双鸭山市| 乾安县| 高要市| 遂宁市| 密山市| 沅陵县| 政和县| 博白县| 长丰县| 涿鹿县|