Python机器学习实践指南-第二章

本文详细介绍了如何使用Python和pandas库对房地产列表数据进行清洗和格式化,包括处理缺失值、格式化卧室和浴室信息、提取楼层和邮编数据。并通过数据透视和热图进行初步分析,最终构建线性回归模型预测公寓租金。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

# # -*- coding:utf-8 -*-
#准备数据
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"D:/python机器学习+数据分析/Python机器学习实践指南(中文版带书签)、原书代码、数据集/PMLB Datasets/PMLB Datasets/PMLB Datasets copy/magic.csv"
df = pd.read_csv(CSV_PATH)
# print(df.columns)   #输出列标题
# print(df.head())
# print(df.describe())
# print(df.T)
# print(df.T.ix[:,1:2])
# nn = df[df['routable_link/_text'].str.contains('203 Rivington')|df['routable_link/_text'].str.contains('280 E 2nd')]
# print(nn[:2].T)
#有上面代码输出结果可以看到,有不少缺失值
#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))  #161
# print(len(su))  #339

"""
大多数房源属于单一单元的类型。需要将数据格式化为标准结构,例如卧室数、浴室数等准备一列。
"""
# print(su['propertyinfo_value'])

#以上数据看出,包含卧室和浴室,也有的数据包含年份

#检查没有包含‘bd'或者’Studio的行数
num=len(su[~(su['propertyinfo_value'].str.contains('Studio')|su['propertyinfo_value'].str.contains('bd'))])
# print(num)  #0
# #检查有没有包含ba的行数
# print(len(su[~(su['propertyinfo_value'].str.contains('ba'))]))   #6
#显示有6条数据,看来有几行缺少浴室数量的数据。需要填充或者插补这些缺失的数据点。

"""
缺失数据的处理,是建模过程的一个关键步骤之一。
"""

#选择拥有浴室的房源
no_baths = su[~(su['propertyinfo_value'].str.contains('ba'))]


#再排除那些缺失了浴室信息的房源
sucln = su[~su.index.isin(no_baths.index)]

#使用项目符号进行切分,解析卧室和浴室的信息
def parse_info(row):
    if not 'sqft' in row:
        br,ba = row.split('•')[:2]
        sqft = np.nan
    else:
        br,ba ,sqft=row.split('•')[:3]
    return pd.Series({'Beds':br,'Baths':ba,'Sqft':sqft})
attr = sucln['propertyinfo_value'].apply(parse_info)
# print(attr)

#在取值中将字符串删除
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)

"""
数据基本出来了。可以基于浴室、卧室的数量和面积,测试公寓的价值。
"""
"""
如果可能,尝试提取楼层的信息。假设一个模式,其中一个数字后面跟随一个字母,
该字母就表示建筑的楼层。
"""
#parse out zip,floor
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)
# print(flrzip)
# print(len(flrzip[~flrzip['Floor'].isnull()]))
# print(len(flrzip[~flrzip['Zip'].isnull()]))
suf = sujnd.join(flrzip)
# print(suf.T)


"""
当楼层和邮编信息出现的时候,从333个房源中获得320个带有邮编的房源和164个带有楼层信息的房源,
"""
#将数据减少为所感兴趣的那些列
sudf = suf[['pricelarge_value_prices','Beds','Baths','Sqft','Floor','Zip']]
#清理奇怪的列名,并重置索引
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)

#解决了上面的问题,还有一个问题,统计数据的列必须是数值型的。
# print(sudf.info())

#解决列中数据类型的问题
sudf.loc[:,'Rent'] = sudf['Rent'].astype(int)
sudf.loc[:,'Beds'] = sudf['Beds'].astype(int)
#存在半浴室的情况,使用浮点型
sudf.loc[:,'Baths'] = sudf['Baths'].astype(float)

#存在NAN的,需要浮点型,但是要首先将逗号替换掉
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())

#索引标号318是有问题的房源,可以放弃此数据
sudf = sudf.drop([318])
# print(sudf.describe())

"""
使用数据透视查看数据。首先看邮政编码和卧室数量来检查价格
"""
# print(sudf.pivot_table('Rent','Zip','Beds',aggfunc='mean'))
"""
以上结果可以根据邮编查看结果。随着房间数量的增加,看到越来越少的房源。nan值就是最好的证明。
"""
#基于房源数量进行透视
# print(sudf.pivot_table('Rent','Zip','Beds',aggfunc='count'))
"""
由结果可知,数据是稀疏的。没关系,还可以继续分析。
"""

#2.2.2可视化数据

"""
由于目前的数据是基于邮政编码的,最好使用热图作为可视化数据的方法。使用folium的python库来实现。
"""

#由于缺少包含两到三间卧室的公寓,可以先缩减数据,聚焦到工作室和一间卧室的房源。
su_lt_two = sudf[sudf['Beds']<2]

# import folium
# map = folium.Map(location=[40.748817,-73.985428],zoom_start=13)
# map.geo_json(geo_path=r'D:/python机器学习+数据分析/Python机器学习实践指南(中文版带书签)、原书代码、数据集/PMLB Datasets/PMLB Datasets/PMLB Datasets copy/nyc_boroughs.geojson',
#              data=su_lt_two,
#              columns=['Zip','Rent'],
#              key_on ='feature.properties.postalCode',
#              threshold_scale=[1700.00,1900.00,2100,2300.00,2500.00,2750.00],
#              fill_color='YlOrRd',fill_opacity=0.7,line_opacity=0.2,
#              legend_name='Rent(%)',reset=True
#              )
# map.create_map(path='nyc.html')

"""
对数据建模
"""
import patsy
import statsmodels.api as sm
f = 'Rent~Zip + Beds'  #Rent是因变量,Zip+Beds是预测变量。邮编和卧室数量如何影响价格
"""
将公式和包含相应列名的数据放一起,传递给patsy.dmatrices().
然后设置patsy,返回一个数据框,其中X矩阵由预测变量组成,而y向量由响应变量组成。
传递给sm.OLS(),之后调研fit()运行模型。
"""
y,X = patsy.dmatrices(f,su_lt_two,return_type='dataframe')
results = sm.OLS(y,X).fit()
"""
  打印结果分析:看到模型包含262个观测样本,调整后的R2位0.282,F值尾1.21e-10,具有统计显示性。
显著性质所建模型,仅仅使用卧室数量和邮政编码,就已经能够解释约三分之一的价格差异。
  看看中间一大堆数据吧。中间部分提供了模型中每个自变量的有关信息。从左至右,看到有变量、变量在模型中的系数。
标准误差,t统计值,t统计值的p值,及置信区间。
  如果看P值这一列,可以确定独立变量从统计的角度来看是否具有意义。在回归模型中具有统计学意义,
意味着一个独立变量和响应变量之间的关系不太可能偶然发生。通常,统计学家使用0.05的p值来确定。
一个0.05的p值意味着看到的结果只有5%的几率是偶然发生的。从结果看,卧室的数量显然有意义。
   邮编会有什么影响呢?截距代表了10001的邮编。建立线性回归模型的时候,是需要截距。
截距就是回归线和y轴交叉的地方。Statsmodels会自动选择一个预测变量作为截距。
   卧室的数量,截距是显著的。邮编并不显著。显著的几个10001,10029和10035,具有很高的负置信区间。
"""
# print(results.summary())

"""
2.3.1预测
"""
# print(X.head())
"""
结果看出,输入是用所谓的虚拟变量进行编码。由于邮编不是胡数字的,为了表示这个特征,
系统使用了虚拟编码。如果某个公寓在10003中,那么该列将被编码为1,而其他编码都是0.
卧室是数值型的,系统根据实际的数字进行编码。
"""
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'])
# print(tpdf)
"""
刚刚使用了X矩阵索引,并用0填充数据。现在填充一些实际的值,比如对10009区域的、包含一间卧室的公寓估价。
"""
tpdf.loc['Intercept']=1
tpdf.loc['Beds']=1
tpdf.loc['Zip[T.10009]']=1
# print(tpdf)  #截距10009邮政编码已经被设置为1了。卧室数量’Beds也变成1了。

#已经将特征设置为适当的值,现在使用该模型返回一个预测。
# print(results.predict(tpdf['value']))  #2529.56

#results是保存模型的变量名。这个模型对象有一个.predict()方法,使用自己的输入值调用该方法。

#如果想要增加一间卧室怎么办?
tpdf['value'] = 0
tpdf.loc['Intercept'] = 1
tpdf.loc['Beds'] =2
tpdf.loc['Zip[T.10009]'] = 1
# print(tpdf)  #卧室数量更新为2

# print(results.predict(tpdf['value']))   #2378.035。可以看出,增加一间卧室,大概多花200美元。
#如果地区选择在10002的话,会是什么情况呢?
tpdf['value'] = 0
tpdf.loc['Intercept'] = 1
tpdf.loc['Beds'] = 2
tpdf.loc['Zip[T.10002]']=1
print(results.predict(tpdf['value']))  #2651.176 .10002地区比10009地区稍微便宜点呢。

"""
目前,只检视了邮政编码、卧室和出租价格之间的关系。虽然有一定的解释能力,但是数据量太小,特征太少,
无法充分的观测房地产估值。
也可以添加更多的特征和数据。
"""

"""
本章,学习了如何获取房地产列表的数据,利用pandas的功能操作和清洗数据,通过热图检视数据,最后,
构建并使用回归模型预估公寓价格。
目前只是接触了机器学习的表层,下面继续探索深层算法和应用。
"""


Key Features, Put machine learning principles into practice to solve real-world problemsGet to grips with Python's impressive range of Machine Learning libraries and frameworksFrom retrieving data from APIs to cleaning and visualization, become more confident at tackling every stage of the data pipeline, Book Description, Machine Learning is transforming the way we understand and interact with the world around us. But how much do you really understand it? How confident are you interacting with the tools and models that drive it?, Python Machine Learning Blueprints puts your skills and knowledge to the test, guiding you through the development of some awesome machine learning applications and algorithms with real-world examples that demonstrate how to put concepts into practice., You’ll learn how to use cluster techniques to discover bargain air fares, and apply linear regression to find yourself a cheap apartment – and much more. Everything you learn is backed by a real-world example, whether its data manipulation or statistical modelling., That way you’re never left floundering in theory – you’ll be simply collecting and analyzing data in a way that makes a real impact., What you will learn, Explore and use Python's impressive machine learning ecosystemSuccessfully evaluate and apply the most effective models to problemsLearn the fundamentals of NLP - and put them into practiceVisualize data for maximum impact and clarityDeploy machine learning models using third party APIsGet to grips with feature engineering, About the Author, Alexander T. Combs is an experienced data scientist, strategist, and developer with a background in financial data extraction, natural language processing and generation, and quantitative and statistical modeling. He is currently a full-time lead instructor for a data science immersive program in New York City., Table of Contents, The Python Machine Learning EcosystemBuild an App to Find Underpriced ApartmentsBuild an App to Find Cheap AirfaresForecast the IPO Market using Logistic RegressionCreate a Custom NewsfeedPredict whether Your Content Will Go ViralForecast the Stock Market with Machine LearningBuild an Image Similarity EngineBuild a ChatbotBuild a Recommendation Engine
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值