首页 > 编程语言 > 详细

基于python厦门思明区二手房价分析和预测

时间:2021-06-25 09:56:11      阅读:29      评论:0      收藏:0      [点我收藏+]

            基于python厦门思明区二手房价分析和构建基于机器学习的房价预测模型

一,选题背景

  网上有条段子,某地房价5w每平,月收入刚好过万,掐指一算,命中注定买房是不可能的,这辈子都不可能买房,所以要定个小目标:“我真的还想再活500年······”。当然,房子虽贵,但是我可以学学科学的方法了解房价趋势,做到心中有数,万一买的起呢?

 

二,设计方案

1,爬虫名称:基于python厦门思明区二手房价分析和预测

2,爬虫爬取的内容与数据特征分析:内容主要是:房屋信息;数据特征:房屋信息的归一化与存储

3,设计方案概述:房屋信息的爬取并归一化与存储,进行数据预处理与数据可视化,构建房价预测模型进行多特征模型训练,得到构建基于机器学习的房价预测模型结果

 

三,结果特征分析

1,利用网络爬虫获取厦门市思明区二手房信息

技术分享图片

 

 

 

技术分享图片

 

 

 

四,爬虫程序设计

1,数据爬取与采集

# 使用 HTML.parser 解析器

1 import requests
2 from bs4 import BeautifulSoup
3 # requests返回网页内容
4 res = requests.get(rhttps://xm.esf.fang.com/house-a0352/)
5 #res.text
6 
7 # BeautifulSoup解析网页
8 soup = BeautifulSoup(res.text,html.parser) # 使用 HTML.parser 解析器
 1 def get_house(url):
 2     获取页面中每个房子的信息
 3     information = {} # 存储房屋所有信息
 4     res = requests.get(url)
 5     soup = BeautifulSoup(res.text,html.parser)
 6     
 7     # 获取户型、建筑面积、单价、朝向、楼层、装修情况
 8     houses = soup.select(.tab-cont-right .trl-item1) 
 9     #print(houses)
10     for house in houses:
11         me = house.text.strip().split(\n)
12         information[me[1]] = me[0].strip()
13     
14     # 获取小区名字
15     name = soup.select(.rcont .blue)
16     information[小区名称] = name[0].text
17     
18     # 获取房屋总价
19     price = soup.select(.trl-item)
20     information[房屋总价] = price[0].text
21     print(information)
22 
23 # 函数测试
24 get_house("https://xm.esf.fang.com/chushou/3_346676334.htm?channel=1,2&psid=1_15_60") # 每一页中房子的url(注意:链接可能失效)

技术分享图片

 

 

 

 1 def get_page(n):
 2     分页爬取数据
 3     for i in range(1,n+1): # n:爬取页数
 4         url = rhttps://xm.esf.fang.com/house-a0352/i3{}/.format(i) # 总共多少页
 5         res = requests.get(url)
 6         houses = BeautifulSoup(res.text,html.parser)
 7         print(url)
 8         j  = 1
 9         houses = houses.select(.shop_list .clearfix h4 a) # 获取每套房子的href
10         for house in houses:
11             try:
12                 demo_url = house[href]
13                 url = rhttps://xm.esf.fang.com + demo_url + ?channel=1,2&psid=1_{}_60.format(j) # 每一页中有多少套房子
14                 # 获取当前页面中每套房子的信息
15                 #get_house(url) 
16                 j += 1
17             except Exception as e:
18                 print(-------->,e)
19 get_page(1)

技术分享图片

 

 

 

房屋信息的归一化与存储

 1 import requests
 2 from bs4 import BeautifulSoup
 3 
 4 def get_house(url):
 5     获取页面中每个房子的信息
 6     information = {} # 存储房屋所有信息
 7     res = requests.get(url)
 8     soup = BeautifulSoup(res.text,html.parser)
 9     
10     # 获取户型、建筑面积、单价、朝向、楼层、装修情况
11     houses = soup.select(.tab-cont-right .trl-item1) 
12     for house in houses:
13         m = house.text.strip().split(\n)
14         me = m[1]
15         if 朝向 in me:
16             me = me.strip(进门) 
17         if 楼层in me:
18             me = me[0:2]
19         if 地上层数 in me:
20             me = 楼层
21         if 装修程度 in me:
22             me = 装修
23         information[me] = m[0].strip()
24     
25     # 获取小区名字
26     name = soup.select(.rcont .blue)
27     information[小区名称] = name[0].text
28     
29     # 获取房屋总价
30     price = soup.select(.trl-item)
31     information[房屋总价] = price[0].text
32     return information
33 
34 # 函数测试
35 get_house("https://xm.esf.fang.com/chushou/3_346676334.htm?channel=1,2&psid=1_15_60") # 每一页中房子的url

技术分享图片

 

 

 

 1 import pandas as pd
 2 import time
 3 
 4 def get_page(i):
 5     分页爬取数据
 6     url = rhttps://xm.esf.fang.com/house-a0352/i3{}/.format(i) # 总共多少页
 7     res = requests.get(url)
 8     houses = BeautifulSoup(res.text,html.parser)
 9     #print(url)
10     j  = 1
11     houses = houses.select(.shop_list .clearfix h4 a)
12     page_information = [] # 数据存储
13     for house in houses:
14         try:
15             demo_url = house[href]
16             url = rhttps://xm.esf.fang.com + demo_url + ?channel=1,2&psid=1_{}_60.format(j) # 每一页中有多少套房子
17             # 获取当前页中每套房子的信息
18             information = get_house(url)
19             print(正在爬取第{}页第{}套房子···.format(i,j),end=\r)
20             page_information.append(information)
21             j += 1
22             time.sleep(0.5) # 预防爬取频繁,防止ip被封
23         except Exception as e:
24             print(-------->,e)
25     #将爬取的数据转换为DataFrame格式
26     df = pd.DataFrame(page_information)
27     #df.to_csv(‘house_information.csv‘)
28     return df
29 #get_page(1)
 1 # 正式爬取数据并保存为csv数据
 2 
 3 df = pd.DataFrame() # 创建一个空的DataFrame
 4 name_csv = house_information_
 5 for i in range(1,101): # 总共爬取100页数据
 6     try:
 7         df_get = get_page(i)
 8         df = df.append(df_get)
 9         print(df)
10     except Exception as e:
11         print(------->,e)
12     if i/100 == 1:
13         df.to_csv(name_csv+str(i)+.csv)
14         df = pd.DataFrame() # 清空当前爬取完成的数据,防止内存溢出

技术分享图片

 

 

 

2、数据预处理

1 import numpy as np
2 import pandas as pd
3 
4 data = pd.read_csv(rhouse_information.csv) # 如果用pandas打不开数据,可以使用记事本打开把编码格式改成utf-8另存
5 data.head()

技术分享图片

 

 

 

1 data.drop(index,axis=1,inplace=True) # 删除index列(用del更方便)
2 data.head()

技术分享图片

 

 

 

1 # Series的extract支持正则匹配抽取,返回的值是字符串
2 data[[,,]] = data[户型].str.extract(r(\d+)室(\d+)厅(\d+)卫)
3 
4 # 把字符串格式转化为float,并删除户型
5 data[] = data[].astype(float)
6 data[] = data[].astype(float)
7 data[] = data[].astype(float)
8 del data[户型]
9 data.head()

技术分享图片

 

 

 

1 # 将建筑面积后的平方米去除,并将数据类型改成浮点型
2 data[建筑面积] = data[建筑面积].map(lambda e:e.replace(平米,‘‘))# Series中的map
3 data[建筑面积] = data[建筑面积].astype(float)
4 data.head()

技术分享图片

 

 

 

1 # 将单价后的元/平米去除,并将数据类型改成浮点型
2 data[单价] = data[单价].map(lambda e:e.replace(r元/平米,‘‘))
3 data[单价] = data[单价].astype(float)
4 data.head()

技术分享图片

 

 

 

1 # 将房屋总价后的万去除,并将数据类型改成浮点型
2 data[房屋总价] = data[房屋总价].map(lambda e:e.replace(,‘‘))
3 data[房屋总价] = data[房屋总价].astype(float)
4 data.head()

技术分享图片

 

 

 

1 # 使用pd.get_dummies() 量化数据
2 data_direction = pd.get_dummies(data[朝向])
3 data_direction.head()

技术分享图片

 

 

 

1 # 使用pd.get_dummies() 量化数据
2 data_floor = pd.get_dummies(data[楼层])
3 data_floor.head()

技术分享图片

 

 

 

1 # 使用pd.get_dummies() 量化数据
2 data_decoration = pd.get_dummies(data[装修])
3 data_decoration.head()

技术分享图片

 

 

 

1 # 使用pd.concat矩阵拼接,axis=1:水平拼接
2 data = pd.concat([data,data_direction,data_floor,data_decoration],axis=1) 
1 # 拼接后的列名
2 data.columns

技术分享图片

 

 

 

 1 # 特征帅选
 2 del data[小区名称]
 3 del data[朝向]
 4 del data[楼层]
 5 del data[装修]
 6 del data[东西]
 7 del data[南北]
 8 del data[暂无] # 两列都删除
 9 del data[中层] # 多重共线性问题(线性回归)
10 del data[中装修]
11 data.columns

技术分享图片

 

 

 

1 data.head()

技术分享图片

 

 

 

1 data.info() # 发现 室厅卫中 有缺失值

技术分享图片

 

 

 

3、数据可视化

1 import matplotlib.pyplot as plt
2 area = data[建筑面积]
3 price = data[房屋总价]
4 plt.scatter(area,price)
5 plt.show() # 有离群点数据,对线性分析不利,需要过滤

技术分享图片

 

 

 

1 df = data[data[建筑面积] <=300] # 正常住宅面积小于等于300平米
2 area = df[建筑面积]
3 price = df[房屋总价]
4 #print(area.count()) #过滤后的数据量
5 plt.scatter(area,price)
6 plt.xlabel("area")
7 plt.ylabel("price")
8 plt.show()

技术分享图片

 

 

 

4、构建房价预测模型

1 # 先根据建筑面积和房屋总价训练模型(一元线性回归)
2 from sklearn.linear_model import LinearRegression
3 linear = LinearRegression()
4 area = np.array(area).reshape(-1,1) # 这里需要注意新版的sklearn需要将数据转换为矩阵才能进行计算
5 price = np.array(price).reshape(-1,1)
6 # 训练模型
7 model = linear.fit(area,price)
8 # 打印截距和回归系数
9 print(model.intercept_, model.coef_)

技术分享图片

 

 

 

1 # 线性回归可视化(数据拟合)
2 linear_p = model.predict(area)
3 plt.figure(figsize=(12,6))
4 plt.scatter(area,price)
5 plt.plot(area,linear_p,red)
6 plt.xlabel("area")
7 plt.ylabel("price")
8 plt.show()

技术分享图片

 

 

 

多特征模型训练

1 cols = [建筑面积,, , , , 东北, 东南, , , 西,
2        西北, 西南, 低层, 高层, 毛坯, 简装修, 精装修, 豪华装修]
1 X = df[cols]
2 X.head()

技术分享图片

 

 

 

1 y = df[房屋总价]
2 y.head()

技术分享图片

 

 

 

1 print(type(X))
2 print(type(y))
3 # 使用train_test_split进行交叉验证
4 from sklearn.model_selection import train_test_split
5 x_train, x_test, y_train, y_test = train_test_split(X,y,test_size=0.2,random_state=12)
6 print(x_train.shape,y_train.shape)
7 print(x_test.shape,y_test.shape)

技术分享图片

 

 

 

1 # 模型训练
2 linear = LinearRegression()
3 model = linear.fit(x_train,y_train)
4 print(model.intercept_, model.coef_)

技术分享图片

 

 

 

1 # 模型性能评分
2 price_end = model.predict(x_test)
3 score = model.score(x_test,y_test) 
4 print("模型得分:",score)# 一般模型在0.6以上就表现的不错

技术分享图片

 

 

 

使用多种特征组合都可以预测房价,那么怎么找出最佳组合,这里使用假设验证法,选出最佳特征组合

 1 # 使用假设验证法,选出最佳特征组合
 2 cols = [建筑面积,, , , , 东北, 东南, , , 西,
 3        西北, 西南, 低层, 高层, 毛坯, 简装修, 精装修, 豪华装修]
 4 import statsmodels.api as sm
 5 Y = df[房屋总价]
 6 X = df[cols]
 7 X_ = sm.add_constant(X) #增加一列值为1的const列,保证偏置项的正常
 8 #print(X_)
 9 # 使用最小平方法
10 result = sm.OLS(Y,X_)
11 # 使用fit方法进行计算
12 summary = result.fit()
13 # 调用summary2方法打印出假设验证信息(性能指标)
14 summary.summary2() # R-squared:模型评分 AIC:组合完越小越好

技术分享图片

 

 

 #特征超过16个将发生异常

1 import itertools
2 
3 list1 = [1, 2,3, 4, 5,6,7,8,9,10,11,12,13,14,15,16] 
4 list2 = []
5 for i in range(1, len(list1)+1):
6     iter1 = itertools.combinations(list1, i)
7     list2.append(list(iter1))
8 #print(list2)

# 使用itertools,找出AIC最小值的特征组合作为模型训练的特征
# 寻找最小AIC值的特征组合

1 import itertools
2 fileds = [建筑面积,, , , ,, , 西,低层, 高层, 毛坯, 简装修, 精装修, 豪华装修]
3 acis = {}
4 for i in range(1,len(fileds)+1):
5     for virables in itertools.combinations(fileds,i): #从fileds中随机选择i个特征机型组合,返回的virables为元组类型
6         x1 = sm.add_constant(df[list(virables)])
7         x2 = sm.OLS(Y,x1)
8         res = x2.fit()
9         acis[virables] = res.aic # AIC评分越小越好
1 from collections import Counter
2 # 对字典进行统计
3 counter = Counter(acis)
4 # 降序选出AIC最小的10个数,也就是最佳特征组合
5 counter.most_common()[-10:]

技术分享图片

 

 

 

 

1 # 接下来使用AIC值最小的特征组合进行预测
2 col2 = [建筑面积, , , , , 高层, 毛坯, 精装修, 豪华装修]
3 X = df[col2]
4 y = df[房屋总价]
5 x_train, x_test, y_train, y_test = train_test_split(X,y,test_size=0.2,random_state=13)
6 linear = LinearRegression()
7 model = linear.fit(x_train,y_train)
8 model.score(x_test,y_test) # 模型性能有所提高,但是提升的不明显

技术分享图片

 

 

5、房价的预测

现在我可以根据给定的最佳特征组合进行预测房价

1 # 假设我要买一套房子(想想就觉得很美),房子面积120平米,3室,1厅,南面,高层,精装修
2 my_house = [120,3,1,0,1,1,0,1,0] #根据col2特征
3 my_house = np.array(my_house).reshape(-1,1).T
4 #print(x_test)
5 model.predict(my_house)# 预测价格

技术分享图片

 

 完整代码:

  1 import requests
  2 from bs4 import BeautifulSoup
  3 # requests返回网页内容
  4 res = requests.get(rhttps://xm.esf.fang.com/house-a0352/)
  5 #res.text
  6 
  7 # BeautifulSoup解析网页
  8 soup = BeautifulSoup(res.text,html.parser) # 使用 HTML.parser 解析器
  9 
 10 
 11 
 12 def get_house(url):
 13     获取页面中每个房子的信息
 14     information = {} # 存储房屋所有信息
 15     res = requests.get(url)
 16     soup = BeautifulSoup(res.text,html.parser)
 17     
 18     # 获取户型、建筑面积、单价、朝向、楼层、装修情况
 19     houses = soup.select(.tab-cont-right .trl-item1) 
 20     #print(houses)
 21     for house in houses:
 22         me = house.text.strip().split(\n)
 23         information[me[1]] = me[0].strip()
 24     
 25     # 获取小区名字
 26     name = soup.select(.rcont .blue)
 27     information[小区名称] = name[0].text
 28     
 29     # 获取房屋总价
 30     price = soup.select(.trl-item)
 31     information[房屋总价] = price[0].text
 32     print(information)
 33 
 34 # 函数测试
 35 get_house("https://xm.esf.fang.com/chushou/3_346676334.htm?channel=1,2&psid=1_15_60") # 每一页中房子的url(注意:链接可能失效)
 36 
 37 
 38 
 39 def get_page(n):
 40     分页爬取数据
 41     for i in range(1,n+1): # n:爬取页数
 42         url = rhttps://xm.esf.fang.com/house-a0352/i3{}/.format(i) # 总共多少页
 43         res = requests.get(url)
 44         houses = BeautifulSoup(res.text,html.parser)
 45         print(url)
 46         j  = 1
 47         houses = houses.select(.shop_list .clearfix h4 a) # 获取每套房子的href
 48         for house in houses:
 49             try:
 50                 demo_url = house[href]
 51                 url = rhttps://xm.esf.fang.com + demo_url + ?channel=1,2&psid=1_{}_60.format(j) # 每一页中有多少套房子
 52                 # 获取当前页面中每套房子的信息
 53                 #get_house(url) 
 54                 j += 1
 55             except Exception as e:
 56                 print(-------->,e)
 57 get_page(1)
 58 
 59 
 60 
 61 import requests
 62 from bs4 import BeautifulSoup
 63 
 64 def get_house(url):
 65     获取页面中每个房子的信息
 66     information = {} # 存储房屋所有信息
 67     res = requests.get(url)
 68     soup = BeautifulSoup(res.text,html.parser)
 69     
 70     # 获取户型、建筑面积、单价、朝向、楼层、装修情况
 71     houses = soup.select(.tab-cont-right .trl-item1) 
 72     for house in houses:
 73         m = house.text.strip().split(\n)
 74         me = m[1]
 75         if 朝向 in me:
 76             me = me.strip(进门) 
 77         if 楼层in me:
 78             me = me[0:2]
 79         if 地上层数 in me:
 80             me = 楼层
 81         if 装修程度 in me:
 82             me = 装修
 83         information[me] = m[0].strip()
 84     
 85     # 获取小区名字
 86     name = soup.select(.rcont .blue)
 87     information[小区名称] = name[0].text
 88     
 89     # 获取房屋总价
 90     price = soup.select(.trl-item)
 91     information[房屋总价] = price[0].text
 92     return information
 93 
 94 # 函数测试
 95 get_house("https://xm.esf.fang.com/chushou/3_346676334.htm?channel=1,2&psid=1_15_60") # 每一页中房子的url
 96 
 97 
 98 
 99 import pandas as pd
100 import time
101 
102 def get_page(i):
103     分页爬取数据
104     url = rhttps://xm.esf.fang.com/house-a0352/i3{}/.format(i) # 总共多少页
105     res = requests.get(url)
106     houses = BeautifulSoup(res.text,html.parser)
107     #print(url)
108     j  = 1
109     houses = houses.select(.shop_list .clearfix h4 a)
110     page_information = [] # 数据存储
111     for house in houses:
112         try:
113             demo_url = house[href]
114             url = rhttps://xm.esf.fang.com + demo_url + ?channel=1,2&psid=1_{}_60.format(j) # 每一页中有多少套房子
115             # 获取当前页中每套房子的信息
116             information = get_house(url)
117             print(正在爬取第{}页第{}套房子···.format(i,j),end=\r)
118             page_information.append(information)
119             j += 1
120             time.sleep(0.5) # 预防爬取频繁,防止ip被封
121         except Exception as e:
122             print(-------->,e)
123     #将爬取的数据转换为DataFrame格式
124     df = pd.DataFrame(page_information)
125     #df.to_csv(‘house_information.csv‘)
126     return df
127 #get_page(1)
128 
129 
130 
131 
132 # 正式爬取数据并保存为csv数据
133 
134 df = pd.DataFrame() # 创建一个空的DataFrame
135 name_csv = house_information_
136 for i in range(1,101): # 总共爬取100页数据
137     try:
138         df_get = get_page(i)
139         df = df.append(df_get)
140         print(df)
141     except Exception as e:
142         print(------->,e)
143     if i/100 == 1:
144         df.to_csv(name_csv+str(i)+.csv)
145         df = pd.DataFrame() # 清空当前爬取完成的数据,防止内存溢出
146 
147 
148 
149 import numpy as np
150 import pandas as pd
151 
152 data = pd.read_csv(rhouse_information.csv) # 如果用pandas打不开数据,可以使用记事本打开把编码格式改成utf-8另存
153 data.head()
154 
155 
156 data.drop(index,axis=1,inplace=True) # 删除index列(用del更方便)
157 data.head()
158 
159 
160 # Series的extract支持正则匹配抽取,返回的值是字符串
161 data[[,,]] = data[户型].str.extract(r(\d+)室(\d+)厅(\d+)卫)
162 
163 
164 # 把字符串格式转化为float,并删除户型
165 data[] = data[].astype(float)
166 data[] = data[].astype(float)
167 data[] = data[].astype(float)
168 del data[户型]
169 data.head()
170 
171 
172 
173 # 将建筑面积后的平方米去除,并将数据类型改成浮点型
174 data[建筑面积] = data[建筑面积].map(lambda e:e.replace(平米,‘‘))# Series中的map
175 data[建筑面积] = data[建筑面积].astype(float)
176 data.head()
177 
178 
179 
180 # 将单价后的元/平米去除,并将数据类型改成浮点型
181 data[单价] = data[单价].map(lambda e:e.replace(r元/平米,‘‘))
182 data[单价] = data[单价].astype(float)
183 data.head()
184 
185 
186 
187 # 将房屋总价后的万去除,并将数据类型改成浮点型
188 data[房屋总价] = data[房屋总价].map(lambda e:e.replace(,‘‘))
189 data[房屋总价] = data[房屋总价].astype(float)
190 data.head()
191 
192 
193 
194 # 使用pd.get_dummies() 量化数据
195 data_direction = pd.get_dummies(data[朝向])
196 data_direction.head()
197 
198 
199 
200 # 使用pd.get_dummies() 量化数据
201 data_floor = pd.get_dummies(data[楼层])
202 data_floor.head()
203 
204 
205 
206 # 使用pd.get_dummies() 量化数据
207 data_decoration = pd.get_dummies(data[装修])
208 data_decoration.head()
209 
210 
211 
212 # 使用pd.concat矩阵拼接,axis=1:水平拼接
213 data = pd.concat([data,data_direction,data_floor,data_decoration],axis=1) 
214 
215 
216 
217 # 拼接后的列名
218 data.columns
219 
220 
221 # 特征帅选
222 del data[小区名称]
223 del data[朝向]
224 del data[楼层]
225 del data[装修]
226 del data[东西]
227 del data[南北]
228 del data[暂无] # 两列都删除
229 del data[中层] # 多重共线性问题(线性回归)
230 del data[中装修]
231 data.columns
232 
233 
234 
235 data.head()
236 
237 data.info() # 发现 室厅卫中 有缺失值
238 
239 
240 # 删除缺失值
241 data.dropna(inplace=True)
242 data.info() 
243 
244 
245 import matplotlib.pyplot as plt
246 area = data[建筑面积]
247 price = data[房屋总价]
248 plt.scatter(area,price)
249 plt.show() # 有离群点数据,对线性分析不利,需要过滤
250 
251 
252 
253 df = data[data[建筑面积] <=300] # 正常住宅面积小于等于300平米
254 area = df[建筑面积]
255 price = df[房屋总价]
256 #print(area.count()) #过滤后的数据量
257 plt.scatter(area,price)
258 plt.xlabel("area")
259 plt.ylabel("price")
260 plt.show()
261 
262 
263 
264 
265 # 先根据建筑面积和房屋总价训练模型(一元线性回归)
266 from sklearn.linear_model import LinearRegression
267 linear = LinearRegression()
268 area = np.array(area).reshape(-1,1) # 这里需要注意新版的sklearn需要将数据转换为矩阵才能进行计算
269 price = np.array(price).reshape(-1,1)
270 # 训练模型
271 model = linear.fit(area,price)
272 # 打印截距和回归系数
273 print(model.intercept_, model.coef_)
274 
275 
276 
277 # 线性回归可视化(数据拟合)
278 linear_p = model.predict(area)
279 plt.figure(figsize=(12,6))
280 plt.scatter(area,price)
281 plt.plot(area,linear_p,red)
282 plt.xlabel("area")
283 plt.ylabel("price")
284 plt.show()
285 
286 
287 
288 
289 cols = [建筑面积,, , , , 东北, 东南, , , 西,
290        西北, 西南, 低层, 高层, 毛坯, 简装修, 精装修, 豪华装修]
291 
292 X = df[cols]
293 X.head()
294 
295 y = df[房屋总价]
296 y.head()
297 
298 print(type(X))
299 print(type(y))
300 # 使用train_test_split进行交叉验证
301 from sklearn.model_selection import train_test_split
302 x_train, x_test, y_train, y_test = train_test_split(X,y,test_size=0.2,random_state=12)
303 print(x_train.shape,y_train.shape)
304 print(x_test.shape,y_test.shape)
305 
306 
307 
308 # 模型训练
309 linear = LinearRegression()
310 model = linear.fit(x_train,y_train)
311 print(model.intercept_, model.coef_)
312 
313 
314 
315 # 模型性能评分
316 price_end = model.predict(x_test)
317 score = model.score(x_test,y_test) 
318 print("模型得分:",score)# 一般模型在0.6以上就表现的不错
319 
320 
321 
322 # 使用假设验证法,选出最佳特征组合
323 cols = [建筑面积,, , , , 东北, 东南, , , 西,
324        西北, 西南, 低层, 高层, 毛坯, 简装修, 精装修, 豪华装修]
325 import statsmodels.api as sm
326 Y = df[房屋总价]
327 X = df[cols]
328 X_ = sm.add_constant(X) #增加一列值为1的const列,保证偏置项的正常
329 #print(X_)
330 # 使用最小平方法
331 result = sm.OLS(Y,X_)
332 # 使用fit方法进行计算
333 summary = result.fit()
334 # 调用summary2方法打印出假设验证信息(性能指标)
335 summary.summary2() # R-squared:模型评分 AIC:组合完越小越好
336 
337 
338 
339 
340 import itertools
341 
342 list1 = [1, 2,3, 4, 5,6,7,8,9,10,11,12,13,14,15,16] 
343 list2 = []
344 for i in range(1, len(list1)+1):
345     iter1 = itertools.combinations(list1, i)
346     list2.append(list(iter1))
347 #print(list2)
348 
349 
350 
351 
352 import itertools
353 fileds = [建筑面积,, , , ,, , 西,低层, 高层, 毛坯, 简装修, 精装修, 豪华装修]
354 acis = {}
355 for i in range(1,len(fileds)+1):
356     for virables in itertools.combinations(fileds,i): #从fileds中随机选择i个特征机型组合,返回的virables为元组类型
357         x1 = sm.add_constant(df[list(virables)])
358         x2 = sm.OLS(Y,x1)
359         res = x2.fit()
360         acis[virables] = res.aic # AIC评分越小越好
361 
362 
363 
364 from collections import Counter
365 # 对字典进行统计
366 counter = Counter(acis)
367 # 降序选出AIC最小的10个数,也就是最佳特征组合
368 counter.most_common()[-10:] 
369 
370 
371 
372 
373 # 接下来使用AIC值最小的特征组合进行预测
374 col2 = [建筑面积, , , , , 高层, 毛坯, 精装修, 豪华装修]
375 X = df[col2]
376 y = df[房屋总价]
377 x_train, x_test, y_train, y_test = train_test_split(X,y,test_size=0.2,random_state=13)
378 linear = LinearRegression()
379 model = linear.fit(x_train,y_train)
380 model.score(x_test,y_test) # 模型性能有所提高,但是提升的不明显
381 
382 
383 
384 
385 # 假设我要买一套房子(想想就觉得很美),房子面积120平米,3室,1厅,南面,高层,精装修
386 my_house = [120,3,1,0,1,1,0,1,0] #根据col2特征
387 my_house = np.array(my_house).reshape(-1,1).T
388 #print(x_test)
389 model.predict(my_house)# 预测价格

 

五,总结

  经过对数据的分析与可视化,可以得到:使用假设验证法,选出最佳特征组合,打印出假设验证性能指标,对预期的目标已经达到了,这设计多特征模型训练机器学习的模型结果表现不错。

基于python厦门思明区二手房价分析和预测

原文:https://www.cnblogs.com/csy123/p/14929316.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!