K近邻算法介绍
K近邻算法应该算是机器学习中最基本、最入门的算法了。
K近邻算法既可以用于分类,也可以用于回归(预测具体的值)。
对测试集中的每一个样本:
已知许多房子的条件和房价,现在知道自己的房子的条件,估计自己的房子房价
算法原理:找数据中和自己相似条件的样本(这就是近邻的定义),根据它们的房价标签,定自己的房价,如果有几个样本,他们与我的房子的相似程度并列No.1, 但是他们的房价各不相同,该怎么办呢?我们取其中k个,取它们的平均值,将其作为自己的房价(这就是k的定义)
k更一般化的定义是,取与自己条件最相近的k个样本,取它们标签的平均值。
比方说,如果只看房间个数这一个条件的话,那么房间数相等的房子自然是最相近。如果这类房子有3个,但是我们非要取k=4的话,那么就只好再取房间数次相近的房子了。然后,我们将这4个房子的房价取平均值,就可以得到自己的估计房价。
显然,算法核心是:如何定义"条件相近",即如何定义"距离"。
常用的距离定义:欧氏距离。
欧氏距离公式如下:
其中,q1,q2…为我房间的特征值,p1,p2…为用于比对的样本的对应特征值。
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 = dc_listings[features]
print('shape:{}'.format(dc_listings.shape))
print(dc_listings.head())
#距离的定义
import numpy as np
our_acc_value = 3 #房间数
dc_listings['distance'] = np.abs(dc_listings.accommodates - our_acc_value) #添加一列距离
其实,sklearn为我们提供了欧氏距离模块,直接调用过来就行(虽然直接写也不复杂)
代码如下:
print(dc_listings.distance.value_counts().sort_index()) #对距离先进行值统计,再根据索引排序
### 用sample进行洗牌
```python
dc_listings = dc_listings.sample(frac=1,random_state=0)
dc_listings = dc_listings.sort_values('distance') #表格按照距离从小到大排序
print(dc_listings.price.head())
#标签数据转换(将字符串转换为float)
dc_listings['price'] = dc_listings.price.str.replace("\$|,",'').astype(float)
mean_price = dc_listings.price.iloc[:5].mean() #对排过序的表格前五个房价取平均
print(mean_price)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
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 = dc_listings[features]
print('shape:{}'.format(dc_listings.shape))
print(dc_listings.head())
#距离的定义
import numpy as np
our_acc_value = 3 #房间数
dc_listings['distance'] = np.abs(dc_listings.accommodates - our_acc_value) #添加一列距离
print(dc_listings.distance.value_counts().sort_index()) #对距离先进行值统计,再根据索引排序
#用sample进行洗牌
dc_listings = dc_listings.sample(frac=1,random_state=0)
dc_listings = dc_listings.sort_values('distance') #表格按照距离从小到大排序
print(dc_listings.price.head())
#标签数据转换(将字符串转换为float)
dc_listings['price'] = dc_listings.price.str.replace("\$|,",'').astype(float)
mean_price = dc_listings.price.iloc[:5].mean() #对排过序的表格前五个房价取平均
print(mean_price)
预处理操作有:
对样本进行洗牌,去除样本拿来时样本间的内在联系。
格式转换。可能标签中含有单位(¥符号),这时候标签是object类型,需要将符号去除并转为float类型。
预测出结果后,为了知道结果的正确性,需要对结果进行评估。
评估方法,将测试集输入程序(未输入标签),得到的预测房价和测试集的标签进行比对。
注意,不能直接把训练集输入程序用于评估,因为它已经不纯净了,已经被程序“看”过了。程序是朝着训练集的方向走的,如果用训练集评估的话,得出的吻合程度会偏高。这就如同将平常给学生的练习题当做期末考试题一样,无法反应学生的真实水平。
因此需要对我们拿到手的数据集进行切分,一部分作为训练集,一部分作为测试集。通常二者比例为3:1,即训练集占75%,测试集占25%,也可以训练集占80%,测试集占20%
模型评估的好坏的指标是什么?是RMSE,均方根误差。
actual为真实值,predicted为预测值,n为测试集样本个数。
毫无疑问,RMSE越低越好。
原始数据集中,有些数字天生就比较大(如居住时长),但是有些数字撑死了也很小(如房间数),他们用的却是同一个评估方法,即RMSE,那些较大数值的变量得到的RMSE肯定会大很多,这样就不公平了。我们需要对其进行归一化或者标准化。
接下来考虑多个变量。
考虑多个变量时,距离该如何计算呢?
![涉及到多个变量时的距离计算公式](https://img-blog.csdnimg.cn/20190417221231338.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9jeHp6ZXJvLmJsb2cuY3Nkbi5uZXQ=,size_16,color_FFFFFF,t_70
KNN的缺点:
计算复杂度高,空间复杂度高,效率太低
优点:
无需训练模型,拿过来之间用
预估房价