import pandas as pd features=['accommodates','bathrooms','bedrooms','beds','price','minimum_nights','maximum_nights','number_of_reviews'] dc_listings=pd.read_csv('listings.csv') dc_listings=dc_listings[features] print(dc_listings.shape) dc_listings.head()
运行结果:
K:候选对象个数,近邻数(如找3个和自己最近的样本)
import numpy as np our_acc_value=3#房间数为3个 dc_listings['distance']=np.abs(dc_listings.accommodates-our_acc_value)#为dc_listings新增distance列,用于保存当前房间数与3的差值 dc_listings.distance.value_counts().sort_index()#统计各差值的情况
输出:
0.0 3370 1.0 17967 1.5 2 2.0 3865 3.0 1250 4.0 221 5.0 334 6.0 58 7.0 125 8.0 15 9.0 44 10.0 5 11.0 14 12.0 5 13.0 73 Name: distance, dtype: int64
原始数据统计过程中可能会存在一些规律,一般需要进行洗牌操作,打乱原有秩序(使用sample函数)
dc_listings=dc_listings.sample(frac=1,random_state=0)#洗牌 frac:抽取行的比例,1为100% random_state:0表示不得取重复数据 1表示可以取重复数据 dc_listings=dc_listings.sort_values('distance')#统计差值(房间数-3)的情况 将dc_listings按照distance列排序 将和房间数3最近的放在最前面 dc_listings.price.head()#取前5条的价格 由于数据时乱的,所以id和price均无规律
输出结果:
2732 $129.00 14798 $249.00 27309 $170.00 20977 $169.00 11178 $100.00 Name: price, dtype: object
对价格进行类型转换,去掉$符号,转换成float,然后对前五个价格取均值,用前5个的均值来预测当前房价
dc_listings['price']=dc_listings.price.str.replace("\$|,",'').astype(float) mean_price=dc_listings.price.iloc[:5].mean() mean_price
输出:163.4
拿75%的数据作为训练集,25%的数据作为测试集来进行模型的评估,训练集和测试集不可重复。
dc_listings.drop('distance',axis=1)#删除distance列 train_df=dc_listings.copy().iloc[:20544]#27392*0.75行为训练集 test_df=dc_listings.copy().iloc[20544:]#剩下的作为测试集(27392*0.25)
基于单变量预测价格
#new_listing_value:当前样本的feature_clolumn(如accomodates)列属性取值 #feture_column:计算房租使用的单属性 def predict_price(new_listing_value,feature_column): temp_df=train_df#使用训练集来预测测试集房租结果 dc_listings[feature_column]=train_df[feature_column].astype(float)#统一将格式转换成float否则会报错 temp_df['distance']=np.abs(train_df[feature_column]-new_listing_value) temp_df=temp_df.sort_values('distance') knn_5=temp_df.price.iloc[:5] predict_price=knn_5.mean() return(predict_price)
对测试集的每一条记录使用accomodates属性预测其房租价格
#new_listing_value的值即为accommodates的取值 test_df['predicted_price']=test_df.accommodates.apply(predict_price,feature_column='accommodates') test_df.predicted_price.head()
输出:
14122 134.0 23556 418.0 16317 134.0 26230 134.0 19769 134.0 Name: predicted_price, dtype: float64
得到每个样本的预测值后计算均方根误差用于评估模型(值越小模型越好)
test_df['squared_error']=(test_df['predicted_price']-test_df['price'])**(2) mse=test_df['squared_error'].mean() rmse=mse**(1/2) rmse
输出结果:
348.689169172284
for feature in ['accommodates','bedrooms','bathrooms','number_of_reviews']: test_df['predicted_price']=test_df[feature].apply(predict_price,feature_column=feature) test_df['squared_error']=(test_df['predicted_price']-test_df['price'])**(2) mse=test_df['squared_error'].mean() rmse=mse**(1/2) print("RMSE for the {} column:{}".format(feature,rmse))
输出:
RMSE for the accommodates column:348.689169172284 RMSE for the bedrooms column:344.64855009943 RMSE for the bathrooms column:361.1230782594195 RMSE for the number_of_reviews column:383.4946020709275
注:由于每个测试集中的样本都要与训练集中样本一一比对,所以上述程序运行时间较长,需要耐心等待……
同时使用多个属性——如房间数(个位数)和房间面积(几十甚至上百)进行计算的时候,由于变量取值范围的不同(取值范围大的影响较大)会导致对计算结果的不良影响(如计算欧式距离时,房间面积差值平方计算结果通常较大,而房间数差值平方较小),而各个属性是独立的即它们是同等重要的,所以需要对数据进行标准化,如采用z-score标准化或归一化等手段进行预处理
要求数据总体均值μ=0 标准差σ=1
转换公式如下:
其中μ为原始数据均值,
联系客服