小白学python
非原创,汇总迁移,只想找个地儿存代码
版权声明:本文为CSDN博主「Panda0306」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36278207/article/details/89298136
《Python 机器学习实践指南》@Alexander
Ch2-构建应用程序,发现低价公寓
# -*- coding: utf-8 -*-
#《Python 机器学习实践指南》@Alexander ——Ch2-构建应用程序,发现低价公寓
#———————————————————2.1获取公寓房源数据————————————————————#
#使用import.io抓取房源数据,http://www.import.io/,自动抓取网页,
#爬取参考https://www.import.io/post/how-to-get-data-from-a-website/
#Import.io:智能网页转化应用平台是一个可以让用户点击几下就能把任意网页转化为一个API的平台,帮助开发者轻松的从网络上抓取数据,进行对数据进行二次开发和使用。
# 两步得到网站API
# 打开https://magic.import.io/ 输入要爬取的网址,比如http://producthunt.com
# 调整你需要的数据列,比如把url_link那列改为title
# 点击下面的GET API...
#https://www.zillow.com/homes/Manhattan,-NY_rb/
#代码copy from https://blog.csdn.net/qq_36278207/article/details/89298136
# ———————————————————2.2检查和准备数据————————————————————
import pandas as pd
import re
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
pd.set_option("display.max_columns", 30)
pd.set_option("display.max_colwidth", 100)
pd.set_option("display.precision", 3)
CSV_PATH =r"E:\Data mining & AI\10-Python\python egs\python machine learning blueprint\PMLB Datasets\PMLB Datasets copy\magic.csv"
df = pd.read_csv(CSV_PATH)
# print(df.columns)#为数据提供列标题的输出
# print(df.head().T)#查找数据样本,.T转置数据框并加以显示,NaN表示数据包含缺失值
#listingtype_value 字段将数据拆分为单一单元single units和多单元multiple units
#multiple units
mu = df[df['listingtype_value'].str.contains('Apartments For')]
#single units
su = df[df['listingtype_value'].str.contains('Apartment For')]
# print(len(mu))
# print(len(su))
#将数据进行标准化解析
#选取单一单元类型房源进行研究。因为卧室浴室以及房间大小的信息位于单一列(propertyinfo_value),查看该列:
# print(su['propertyinfo_value'])
#检查数据是否有缺失值,并排除掉缺失值对应数据:
# 检查没有包含'bd'或'Studio'的行数
print(len(su[~(su['propertyinfo_value'].str.contains('Studio')|su['propertyinfo_value'].str.contains('bd'))]))
#检查没有包含'ba'的行数,即为缺失数据点
print(len(su[~(su['propertyinfo_value'].str.contains('ba'))]))
##排除那些缺失了浴室信息的房源
no_baths=su[~(su['propertyinfo_value'].str.contains('ba'))]
sucln = su[~su.index.isin(no_baths.index)]
# print(len(sucln))
#最终输出结果为333,代表有333个数据是可供分析操作的。
# 解析卧室以及浴室的信息:
def parse_info(row):
if not 'sqft' in row:
br, ba = row.split('•')[0:2]
sqft = np.nan
else:
br, ba, sqft = row.split('•')[0:3]
return pd.Series({
'Baths': ba, 'Beds': br, 'Sqft': sqft})
attr = sucln['propertyinfo_value'].apply(parse_info)
#在propertyinfo_value列上应用.apply函数,返回一个数据框,每个公寓属性成为单独一列
# print(attr)
# #在取值中删除 ba, br,sqft,将新数据框与原始数据框进行拼接
attr_cln=attr.applymap(lambda x: x.strip().split(' ')[0] if isinstance(x,str) else np.nan)
# print(attr_cln)
#将新数据框和原有数据框进行连接,添加邮编(区域)信息,并将数据框减少为感兴趣的数据,即包含租金、卧室、浴室、楼层、邮编信息:
sujnd=sucln.join(attr_cln)
# print(sujnd.T)
# 各数据集狙击在一起,基于各个变量测试公寓价值
# 提取楼层信息,假设一种模式,数字后面跟随字母,数字表示楼层信息===============================================================================================
def parse_addy(r):
so_zip = re.search(', NY(\d+)', r)
so_flr = re.search('(?:APT|#)\s+(\d+)[A-Z]+,', r)
if so_zip:
zipc = so_zip.group(1)
else:
zipc = np.nan
if so_flr:
flr = so_flr.group(1)
else:
flr = np.nan
return pd.Series({
'Zip':zipc, 'Floor': flr})
flrzip = sujnd['routable_link/_text'].apply(parse_addy)
suf = sujnd.join(flrzip)
# print(suf.T)
#将数据减少为感兴趣的列
sudf = suf[['pricelarge_value_prices', 'Beds', 'Baths', 'Sqft', 'Floor','Zip']]
# print(sudf)
##清理列名以及重置索引号
sudf.rename(columns={
'pricelarge_value_prices':'Rent'}, inplace=True)
sudf.reset_index(drop=True, inplace=True)
# print(sudf)
#——————————————————2.2.1分析数据————————————————————
# 进行数据分析和可视化工作:查看简单的统计信息:
# print(sudf.describe())
#数值方可进行分析,将Studio设置为0:
sudf.loc[:,'Beds'] = sudf['Beds'].map(lambda x: 0 if 'Studio' in x else x)
#查看数值类型;
# print(sudf.info())
## 更改数据类型
sudf.loc[:,'Rent'] = sudf['Rent'].astype(int)
sudf.loc[:,'Beds'] = sudf['Beds'].astype(int)
# 浴室为浮点型
sudf.loc[:,'Baths'] = sudf['Baths'].astype(float)
#存在NaNs,需要浮点型,但是首先要将逗号替换掉
sudf.loc[:,'Sqft'] = sudf['Sqft'].str.replace(',','')
sudf.loc[:,'Sqft'] = sudf['Sqft'].astype(float)
sudf.loc[:,'Floor'] = sudf['Floor'].astype(float)
# print(sudf.info())
#查看修改后的数据统计信息:
print(sudf.describe())
# 1107层显然为异常点,剔除:
sudf = sudf.drop([318])
# 透视表
sudf.pivot_table('Rent', 'Zip', 'Beds', aggfunc='mean')
sudf.pivot_table('Rent', 'Zip', 'Beds', aggfunc='count')
#——————————————————2.2.2可视化数据——使用热图————————————————————
#可视化数据,nyc.geojson文件下载有误,未实现
su_lt_two = sudf[sudf['Beds']<2]
#
# import folium#pip install folium
# map = folium.Map(location=[40.748817, -73.985428], zoom_start=13)
#
# map.choropleth(
# geo_data=r'E:/python/ML/nyc.geojson',#需要下载Geojson 地图,nyc.geojson为纽约市行政区地图Geojson 可用esri geometry api进行解析 空间分析
# # 参考https://www.zhihu.com/question/26069397关于县级市的geojson数据格式的查找以及生成方式
# data=su_lt_two,
# columns=['Zip', 'Rent'],
# # key_on='features.Feature.properties.borough',
# threshold_scale=[1700.00, 1900.00, 2100.00, 2300.00, 2500.00,2750.00],
# fill_color='YlOrRd',
# fill_opacity=0.7,
# line_opacity=0.2,
# legend_name='Rent (%)'
#——————————————————2.3数据建模————————————————————
import patsy
import statsmodels.api as sm
f = 'Rent ~ Zip + Beds'#左边Rent是因变量, Zip + Beds是预测变量,及邮编和卧室数量如何影响出租价格
y, X = patsy.dmatrices(f, su_lt_two, return_type='dataframe')
result = sm.OLS(y, X).fit()
print(result.summary())
#运行结果如下:
# 262个样本,R方Adj. R-squared: 0.283, Prob (F-statistic):1.21e-10,表示邮编和卧室数量解释了约三分之一的价格差异
# OLS Regression Results
# ==============================================================================
# Dep. Variable: Rent R-squared: 0.377
# Model: OLS Adj. R-squared: 0.283
# Method: Least Squares F-statistic: 4.034
# Date: Thu, 03 Oct 2019 Prob (F-statistic): 1.21e-10
# Time: 15:42:01 Log-Likelihood: -1856.8
# No. Observations: 262 AIC: 3784.
# Df Residuals: 227 BIC: 3908.
# Df Model: 34
# Covariance Type: nonrobust
#提供自变量的系数、标准误差、t统计量、t统计量的p值,以及95%置信区间
#一个0.05的p值意味着只有5%的可能性是偶然发生的
#截距表示了100001的邮政编码
# ================================================================================
# coef std err t P>|t| [0.025 0.975]
# --------------------------------------------------------------------------------
# Intercept 2737.5000 219.893 12.449 0.000 2304.207 3170.793
# Zip[T.10002] -503.2729 226.072 -2.226 0.027 -948.740 -57.806
# Zip[T.10003] -519.1638 230.290 -2.254 0.025 -972.943 -65.384
# Zip[T.10004] 29.8051 260.334 0.114 0.909 -483.175 542.785
# Zip[T.10005] -221.5000 269.313 -0.822 0.412 -752.174 309.174
# Zip[T.10006] -132.7949 260.334 -0.510 0.610 -645.775 380.185
# Zip[T.10009] -416.4142 227.231 -1.833 0.068 -864.166 31.338
# Zip[T.10010] -646.9746 383.461 -1.687 0.093 -1402.572 108.623
# Zip[T.10011] 4.3813 269.543 0.016 0.987 -526.746 535.508
# Zip[T.10012] -197.7638 235.233 -0.841 0.401 -661.283 265.755
# Zip[T.10013] -215.7045 234.573 -0.920 0.359 -677.924 246.515
# Zip[T.10014] -287.5000 380.867 -0.755 0.451 -1037.986 462.986
# Zip[T.10016] -215.8687 269.543 -0.801 0.424 -746.996 315.258
# Zip[T.10017] -212.6413 287.352 -0.740 0.460 -778.860 353.577
# Zip[T.10019] -348.8560 271.376 -1.286 0.200 -883.594 185.882
# Zip[T.10021] -627.6060 271.376 -2.313 0.022 -1162.344 -92.868
# Zip[T.10022] -567.5000 380.867 -1.490 0.138 -1317.986 182.986
# Zip[T.10023] -372.5707 254.885 -1.462 0.145 -874.814 129.673
# Zip[T.10024] -392.3687 246.100 -1.594 0.112 -877.302 92.564
# Zip[T.10025] -237.5000 380.867 -0.624 0.534 -987.986 512.986
# Zip[T.10026] -145.9746 314.148 -0.465 0.643 -764.994 473.045
# Zip[T.10027] -1095.9746 314.148 -3.489 0.001 -1714.994 -476.955
# Zip[T.10028] -622.5848 261.550 -2.380 0.018 -1137.960 -107.209
# Zip[T.10029] -945.6498 255.640 -3.699 0.000 -1449.382 -441.918
# Zip[T.10033] -1120.9746 383.461 -2.923 0.004 -1876.572 -365.377
# Zip[T.10035] -983.8560 271.376 -3.625 0.000 -1518.594 -449.118
# Zip[T.10036] -321.4831 285.429 -1.126 0.261 -883.912 240.946
# Zip[T.10037] -1130.9746 314.148 -3.600 0.000 -1749.994 -511.955
# Zip[T.10038] -176.8475 240.922 -0.734 0.464 -651.578 297.883
# Zip[T.10040] -1395.9746 383.461 -3.640 0.000 -2151.572 -640.377
# Zip[T.10065] -564.5848 261.550 -2.159 0.032 -1079.960 -49.209
# Zip[T.10075] -529.2373 270.232 -1.958 0.051 -1061.721 3.247
# Zip[T.10280] -19.4915 254.345 -0.077 0.939 -520.670 481.687
# Zip[T.11229] -350.9746 383.461 -0.915 0.361 -1106.572 404.623
# Beds 208.4746 44.528 4.682 0.000 120.734 296.215
# ==============================================================================
# Omnibus: 3.745 Durbin-Watson: 2.039
# Prob(Omnibus): 0.154 Jarque-Bera (JB): 2.546
# Skew: -0.012 Prob(JB): 0.280
# Kurtosis: 2.518 Cond. No. 84.2
# ==============================================================================
#——————————————————2.3.1数据建模@预测————————————————————
X.head()
# #输入用虚拟变量进行编码
# #以下创建自己的输入行进行预测
to_pred_idx = X.iloc [0] .index
to_pred_zeros = np.zeros(len(to_pred_idx))
tpdf = pd.DataFrame (to_pred_zeros, index= to_pred_idx, columns= ['value'])
tpdf
#
# #填入实际值,对一个位于10009区域的,包含一家卧室的公寓进行估价
tpdf.loc['Intercept'] = 1
tpdf.loc['Beds'] = 1
tpdf.loc['Zip[T.10009'] = 1
tpdf
# result.predict(tpdf['value'])
# 预测结果报错,未解决
# ————————————————————————————————————————————————————————————————————————————
# python3.7 更新pip版本的方法
# https://blog.csdn.net/weixin_40271793/article/details/82666597
# 1,使用python -m pip install --upgrade pip升级失败
# 2,使用python -m pip install -U --force-reinstall pip升级失败
# 3,使用pip install --user --upgrade pip升级失败
# 参考https://blog.csdn.net/cxs123678/article/details/80659273
# 删除D:\Program Files\Python37\Lib\site-packages\pip-19.2.1.dist-info,运行python -m pip install --upgrade pip,升级成功
# ————————————————————————————————————————————————————————————————————————————
# 参考https://blog.csdn.net/hhhparty/article/details/54917327
# 抓取EXCEL
# 抓取HTML源文档
# 抓取HTML表单数据
# 抓取Javascript数据