机器学习-5.k-近邻算法(KNN)
Posted wyply115
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习-5.k-近邻算法(KNN)相关的知识,希望对你有一定的参考价值。
1. 定义
- 定义:所谓K近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例(也就是上面所说的K个邻居), 这K个实例的多数属于某个类,就把该输入实例分类到这个类中。
- 白话来讲就是通过你的“邻居”来推断你的类别。
- 上述概念中讲最临近,那如何求最临近?也就是如何求距离?
- 两个样本的距离可通过如下公式进行计算,又叫做欧式距离。
- 比如说,a(a1,a2,a3),b(b1,b2,b3),则:
欧 式 距 离 = ( a 1 − b 1 ) 2 + ( a 2 − b 2 ) 2 + ( a 3 − b 3 ) 2 欧式距离 = \\sqrt(a1-b1)^2 + (a2-b2)^2 + (a3-b3)^2 欧式距离=(a1−b1)2+(a2−b2)2+(a3−b3)2 - 由上述公式看出有平方和平方根,因此在计算距离时需要做标准化处理。
- API:sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm=‘auto’)
- n_neighbors:int,可选(默认=5),k_neighbors查询默认使用的邻居数。
- algorithm:{‘auto’,‘ball_tree’,‘kd_tree’,‘brute’},可选用于计算最近邻居的算法,ball_tree将会使用BallTree;kd_tree将使用KDTree;auto将尝试根据传递给fit方法的值来决定最合适的算法。(不同实现方式影响效率,一般auto即可。)
2. 案例
- 案例:facebook和kaggle推出的一项竞赛题,根据提供的数据预测入驻签到位置。
- 数据可从:https://www.kaggle.com/c/facebook-v-predicting-check-ins/data 中下载test.csv和train.csv。官网上可以看到竞赛最高分数:0.62279。当然这里仅演示knn算法,目的不是如何分析得出高分。
- 数据的结构:
如上,row_id:签入事件的id;x y :坐标; acuracy:定位精度即误差;time:时间戳;place_id:业务id,预测的目标值。 - 分析:row_id 和预测的入住位置没有关系。xy坐标、acuracy精度、时间戳对预测入住位置都会有影响,可以作为特征值。place_id是目标值,有特征值和目标值,可以做监督学习,由于预测目标值是离散数据,属于分类问题。这里讲knn算法,因此在这里就用knn算法了。
- 特征值:xy坐标、acuracy、时间戳(一般需要进行处理,这里处理为年、月、日、周、时分秒,当作新特征)
- 目标值:place_id,类别太多,降低了准确性,可以将制定签到人数的位置删除(比如一个酒店一年就入驻3人,就没必要要了)
- 数据展示如下:
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
import pandas as pd
def knncls():
'''
k近邻预测用户签到位置
开发流程:
1. 数据的基本处理(读取数据、处理数据、分割数据集)
2. 特征工程(标准化)
3. 建立模型(这里演示用knn算法)
4. 模型评估(计算得分)
:return: None
'''
# 读取数据
data = pd.read_csv("./data/train.csv")
# 处理数据
# 1.缩小数据(数据较多,如果运行太慢,为了方便演示可以缩小下数据)
data = data.query("x>1.0 & x<1.25 & y>2.5 & y<2.75")
# 2. 处理时间
train_time_value = pd.to_datetime(data['time'],unit="s") # 返回格式是:1970-01-01 22:25:01
# 3. 把时间转换为字典格式
train_time_value = pd.DatetimeIndex(train_time_value)
# 根据时间戳构造新特征
data['day'] = train_time_value.day
data['hour'] = train_time_value.hour
data['weekday'] = train_time_value.weekday
# 把签到数量少于n个的位置删除,先分组统计数量,然后保留>n个的,最后根据保留的place_id将data里多余的删除
place_count = data.groupby('place_id').count()
tf = place_count[place_count.row_id > 3].reset_index()
data = data[data['place_id'].isin(tf.place_id)]
# 删除无用的特征,时间戳和row_id
data = data.drop(['time'], axis=1) # pandas中1表示列,和sklearn中正好相反
data = data.drop(['row_id'], axis=1)
# 取出数据中的特征值x和目标值y
y = data['place_id']
x = data.drop(['place_id'],axis=1)
# 进行数据的分割成一部分训练集和测试集
# 0.25是测试集的保留比例,返回:训练特征值、测试特征值、训练目标值、测试目标值
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25)
# 特征工程(标准化)
std = StandardScaler()
# 对测试集和训练集的特征值进行标准化
x_train = std.fit_transform(x_train)
x_test = std.fit_transform(x_test)
# 进行算法预测
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(x_train,y_train)
y_predict = knn.predict(x_test) # 预测出的目标值
print("预测的准确率:", knn.score(x_test,y_test))
return None
if __name__ == '__main__':
knncls()
- 输出结果:预测的准确率: 0.474468085106383
3. 总结
- knn算法中的k值取值多少合适,有什么影响?
- k值取很小时:容易受异常点影响
- k值取很大时:容易受k值数量(类别)波动
- knn算法优点:简单易于理解,易于实现,无需估计参数(算法内的参数),无需训练。
- 缺点
- 懒惰算法,对测试样本分类时的计算量大,内存开销大。
- 必须指定k值,k值取值不当时分类精度不能保证。
- 适用场景:小数据场景,几千到几万样本,具体场景具体去测试看效果。
以上是关于机器学习-5.k-近邻算法(KNN)的主要内容,如果未能解决你的问题,请参考以下文章
机器学习实战☛k-近邻算法(K-Nearest Neighbor, KNN)
机器学习经典算法具体解释及Python实现--K近邻(KNN)算法