K近邻算法是机器学习最简单的基础算法之一,可以用作分类和回归,是一个不需要学习,仅通过邻近样本来判断数据属性的算法之一。本文学习并参考以下ShowMeAI知识社区的代码,实现房价预测,由于本人未下载参考所指的数据集,为此本文在https://medium.com/下载了新的数据集,需要可在我主页下载。
import pandas as pd
import numpy as np
from scipy.spatial import distance#用于计算欧式距离
from sklearn.preprocessing import StandardScaler#用于对数据进行标准化操作
from sklearn.neighbors import KNeighborsRegressor#KNN算法
from sklearn.metrics import mean_squared_error#用于计算均方根误差
#导入数据并提取目标字段
path = r'../word_data/archive (1)/rental_apps_colombia_v2_wo_outlres.csv'
file = open(path, encoding = 'gb18030', errors = 'ignore')
dc_listings = pd.read_csv(file)
features = ['rent_price','area','build_area','rooms','baths','garages']
dc_listings = dc_listings[features]
#数据初步清洗
dc_listings = dc_listings.dropna()
#数据标准化
dc_listings[features] = StandardScaler().fit_transform(dc_listings[features])
normalized_listings = dc_listings
#取得训练集和测试集
norm_train_df = normalized_listings[:2000]
norm_test_df = normalized_listings[20001:]
#用python方法做多变量KNN模型
def predict_price_multivariate(new_listing_value, feature_columns):
temp_df = norm_train_df
#distance.cdist计算两个集合的距离
temp_df['distance'] = distance.cdist(temp_df[feature_columns], [new_listing_value[feature_columns]])
temp_df = temp_df.sort_values('distance')#temp_df按distance排序
knn_5 = temp_df.rent_price.iloc[:5]
predicted_price = knn_5.mean()
return predicted_price
cols = ['area','build_area','rooms','baths','garages']
norm_test_df_pr = norm_test_df.copy()
norm_test_df_pr.loc[:, 'predicted_price'] = norm_test_df[cols].apply(predict_price_multivariate, feature_columns=cols, axis=1)
norm_test_df_pr.loc[:, 'squared_error'] = (norm_test_df_pr['predicted_price'] - norm_test_df['rent_price']) ** 2
mse = norm_test_df_pr['squared_error'].mean()
rmse = mse ** (1/2)
print(rmse)
#利用sklearn完成KNN
col = ['area','build_area','rooms','baths','garages']
knn = KNeighborsRegressor()
#将自变量和因变量放入模型训练,并用测试数据测试
knn.fit(norm_train_df[cols], norm_train_df['rent_price'])
two_features_predictions = knn.predict(norm_test_df[cols])
#计算预测值与实际值的均方根误差
two_features_mse = mean_squared_error(norm_test_df['rent_price'], two_features_predictions)
two_features_rmse = two_features_mse ** (1/2)
print(two_features_rmse)