本文主要是介绍预测入住酒店位置的案例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一. KNN算法
- 定义:
邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。
kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 kNN方法在类别决策时,只与极少量的相邻样本有关。由于kNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,kNN方法较其他方法更为适合。 - 原理 :
KNN是一种即可用于分类又可用于回归的机器学习算法。对于给定测试样本,基于距离度量找出训练集中与其最靠近的K个训练样本,然后基于这K个“邻居”的信息来进行预测。
在分类任务中可使用投票法,选择这K个样本中出现最多的类别标记作为预测结果;在回归任务中可使用平均法,将这K个样本的实值输出标记的平均值作为预测结果。当然还可以基于距离远近程度进行加权平均等方法。
- 数据:
预测入住酒店的位置
数据下载:
链接:https://pan.baidu.com/s/1w0GRA3bRJJKB2Dze8kzABA
提取码:yd3i - 平台: Pycharm
二. 算法过程
- 先用 pandas 读取数据, 打印数据的信息
- 参数详解:
row_id : 样本序号
x : x 坐标
y : y 坐标
accuracy : 定位的精准度
time : 时间
place_id : 位置 - 选取特征值
row_id , x , y , accuracy , time - 选取目标值( 预测入住酒店的位置 所以选取 place_id 为目标值)
place_id
data = pd.read_csv("../data/train.csv")
print(data.info())
- 利用pandas 中的 query 来缩小数据的范围, 因为我的电脑性能那么好,所以缩小了数据的范围, 里面的范围直接用字符串表示, 不同条件之间 ‘与’ : & ‘或’ : | ‘非’ : !
data = data.query("x > 1.0 & x <1.25 & y > 2.5 & y < 2.75")
- 处理 time 字段, 利用 pandas 中的 to_datatime 方法, 将数据中的 time 格式转换为, pandas 中的时间格式, 为的是以 天, 小时, 周 处理时间
time_value = pd.to_datatime(data["time"],unit='s')
# 把 日期格式 转换为 字典格式
time_value = pd.DatetimeIndex(time_value)
print(time_value)
7. 我们需要在原有的数据中构造一些特征, 构造 天, 小时, 周, 再将 time 列删除
# 添加新的列 day hour weekday
data["day"] = time_value.day
data["hour"] = time_value.hour
data["weekday"] = time_value.weekday
# 将没用的 time 列删除 避免影响预测结果
data = data.drop(['time'], axis=1)
- 大家在选择酒店的时候不可能选择入住人数很少的酒店吧, 所以我们要把 place_id 少于 30 次的酒店的样本删除
# 先通过 groupby 以 place_id 进行分组 行索引为:place_id
place_count = data.groupby('place_id').count()
此时的 row_id 就是每一个酒店 (place_id) 的入住人数,可以通过 row_id 进行筛选, 数据的结构如下图:
tf = place_count[place_count.row_id > 30].reset_index()
这是我们筛选出来的入住酒店次数大于 30 次的数据,再将这个数据与原始的数据进行对比筛选
data = data[data['place_id'].isin(tf.place_id)]
print(data.head(10))
数据中的 row_id 已经没有用了, 这样我们就可以将这一列删除
data = data.drop(['row_id'], axis=1)
- 以上就是数据的处理过程. 下面我们将进行预测分析, 先取出数据中的 特征值 和 目标值
# 将目标值再原有的数据中删除作为我们的特征值, x 为特征值
x = data.drop(['place_id'], axis=1)
# y 为 目标值
y = data['place_id']
- 分割训练集和测试集
# test 参数为测试集的占比, 也就是训练集占 75% 测试集占 25%
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
- 特征工程(将数据标准化),因为我们的数据都是数值类型的, 对于同一个特征,不同的样本中的取值可能会相差非常大,一些异常小或异常大的数据会误导模型的正确训练, 我们可以将特征中的值进行标准差标准化,即转换为均值为0,方差为1的正态分布, 它的计算公式为:标准化数据=(原数据-均值)/标准差
# 特征工程(标准化)
std = StandardScaler()
# 对 训练集和测试集的特征值进行标准化
x_train = std.fit_transform(x_train)
x_test = std.transform(x_test)
- 接下来就开始执行算法 n_neighbors 为 5 个邻近样本为一个区
knn = KNeighborsClassifier(n_neighbors=5)
# 开始训练计算,得出一个预测的模型
knn.fit(x_train, y_train)
# 将测试集输入到模型中进行预测,得出运算结果
y_predict = knn.predict(x_test)
print("预测的目标签到位置为:", y_predict[:5])
# 得出准确率
print("准确率为:", knn.score(x_test, y_test))
三. 算法过程的 API
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
- KNeighborsClassifier:就是KNN算法的API
- pd:就是pandas的API
- train_test_split:这是分割训练集和测试集的API
- StandardScaler:这是特征工程的标准化API
四. 总结
-
算法优点
- KNN可以处理分类问题,同时天然可以处理多分类问题,适合对稀有事件进行分类 。
- KNN还可以处理回归问题,也就是预测。
- 简单,易于理解,易于实现,无需估计参数。
-
算法缺点
- 计算量太大,尤其是特征数非常多的时候。每一个待分类文本都要计算它到全体已知样本的距离,才能得到它的第K个最近邻点。
- 对训练数据依赖度特别大,对训练数据的容错性太差。如果训练数据集中,有一两个数据是错误的,刚刚好又在需要分类的数值的旁边,这样就会直接导致预测的数据的不准确
-
预测结果分析
- 上面的图片的预测率为:57%,可能是缩小数据所导致的,如果你的电脑比较牛掰,你就可以不用缩小数据的范围,直接进行计算分析,当然了 KNN 算法对电脑内存的消耗是挺大的
- 也可能是 n_neighbor 设置的不合理,可以用交叉验证网格搜索的方法来提高预测的准确率
这篇关于预测入住酒店位置的案例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!