机器学习算法之K近邻算法

K近邻算法的核心思想:衡量一个数据周围邻居的权重,而把它归为(或分配)到权重更大的那一类。既可以做分类也可以做回归!

所谓K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例(也就是上面所说的K个邻居), 这K个实例的多数属于某个类,就把该输入实例分类到这个类中.

如下图所示,有两类不同的样本数据,分别用蓝色的小正方形和红色的小三角形表示,而图正中间的那个绿色的圆所标示的数据则是待分类的数据。也就是说,现在, 我们不知道中间那个绿色的数据是从属于哪一类(蓝色小正方形or红色小三角形),下面,我们就要解决这个问题:给这个绿色的圆分类。

  • 如果K=3,绿色圆点的最近的3个邻居是2个红色小三角形和1个蓝色小正方形,少数从属于多数,基于统计的方法,判定绿色的这个待分类点属于红色的三角形一类。
  • 如果K=5,绿色圆点的最近的5个邻居是2个红色三角形和3个蓝色的正方形,还是少数从属于多数,基于统计的方法,判定绿色的这个待分类点属于蓝色的正方形一类。

选取关注的特征,并把数据导进来

import pandas as pd

features = ['accommodates','bedrooms','bathrooms','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(2)

数据特征:

  • accommodates: 可以容纳的旅客            bedrooms: 卧室的数量
  • bathrooms: 厕所的数量                           beds: 床的数量
  • price: 每晚的费用                                     minimum_nights: 客人最少租了几天
  • maximum_nights: 客人最多租了几天       number_of_reviews: 评论的数量

欧式距离:指在n维空间中两个点之间的真实距离,或者向量的自然长度(即该点到原点的距离)

d为两条信息之间的欧式距离,其中Q1到Qn是一条数据的所有特征信息,P1到Pn是另一条数据的所有特征信息。n个特征可以看成是n维空间。

import numpy as np
import pandas as pd
data = {'x':[1,2],
        'y':[3,4]}
df = pd.DataFrame(data)
print(df)
d1=np.sqrt(np.sum([np.square(x-y)]))
print('欧式距离=%f' %d1)

如果只看所有数据中某一个特征的距离,则不能用上面的公式,可以直接求数据间这个特征的差值,并取绝对值

import numpy as np

our_acc_value = 3#假设我们待定价的房子房间数量是3

dc_listings['distance'] = np.abs(dc_listings.accommodates - our_acc_value)#只求房间数量这一个特征的距离
dc_listings.distance.value_counts().sort_index()

dc_listings = dc_listings.sample(frac=1,random_state=0)#对数据进行洗牌,防止数据呈现某种规律(主要是由于距离为0的数据大于K),而影响评估
dc_listings = dc_listings.sort_values('distance')#按照距离从小到大排序
dc_listings.price.head()#取距离为0的前5条数据
dc_listings['price'] = dc_listings.price.str.replace('\$|,','').astype(float)#转换字符串为数值

mean_price = dc_listings.price.iloc[:5].mean()#取前5个价格
mean_price#得到的平均价格,就是我们房间大致的价格

模型评估

首先制定好训练集和测试集

dc_listings = dc_listings.sample(frac=1,random_state=0)#给数据洗牌
dc_listings=dc_listings.drop('distance',axis=1)#去掉距离这一列,由于后面还有代码,所以drop之后一定要赋值给dc_listings,否则dc_listings的值不会改变
train_df = dc_listings.copy().iloc[:2792]
test_df = dc_listings.copy().iloc[2792:]

基于单变量预测价格

def predict_price(new_listing_value,feature_column):#定义了通过给定一个房间的数量new_listing_value(比如:1),来求其预测的价格
    temp_df = train_df
    temp_df['distance'] = np.abs(dc_listings[feature_column] - new_listing_value)
    temp_df = temp_df.sort_values('distance')
    knn_5 = temp_df.price.iloc[:5]
    predicted_price = knn_5.mean()
    return(predicted_price)
test_df['predicted_price'] = test_df.accommodates.apply(predict_price,feature_column='accommodates')
#predict_price和apply函数实现:1.计算每条测试集数据的房间数和训练集所有数据房间数的距离,取距离最小前5个数据,并求它们房间价格的平均值;
#2.通过apply函数来对测试集中的每一条数据的房间数预测价格,这里的new_listing_value在每次执行的时候就是当前条数据的房间数,对所有训练集数据的房间数差值

这样我们就得到了测试集数据所有房子的预测价格了

root mean squared error (RMSE)均方根误差(计算实际价格和预测价格误差的平方,再取平均值,开根号)这个值越小越好,越小表明预测值与实际值越接近!


test_df['squared_error'] = (test_df['predicted_price'] - test_df['price'])**(2)
mse = test_df['squared_error'].mean()
rmse = mse ** (1/2)
rmse

output: 121.03516084641325

评估不同的单变量的效果

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))
output:
RMSE for the accommodates column: 121.03516084641325
RMSE for the bedrooms column: 113.1281586488065
RMSE for the bathrooms column: 110.92780323047147
RMSE for the number_of_reviews column: 121.5656270317295





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值