Facebook V Results: Predicting Check Ins 是Facebook在Kaggle上的一个机器学习工程竞赛数据集。
K-近邻实战分析
1. 数据集介绍及下载
这项比赛的目的是预测一个人想签到哪个地方。为了实现这一目的,Facebook创建了一个人工世界,由10公里乘10公里的正方形中的100,000多个地方组成。对于给定的一组坐标,程序员的任务是返回最可能的位置的排名列表。数据经过伪造,类似于来自移动设备的位置信号,使您有一种处理真实数据(复杂的数值和嘈杂的值)所需的风味。不一致和错误的位置数据可能会破坏Facebook Check In等服务的体验。
训练和测试数据集是根据时间划分的,测试数据中的公共/私人排行榜是随机划分的。 此数据集中没有人的概念。 所有row_id都是事件,而不是人员。
数据特征
row_id: id of the check-in event 标记事件的id
x y: coordinates 用户的位置
accuracy: location accuracy 定位准确性
time: timestamp
place_id: id of the business, this is the target you are predicting
数据集下载:百度网盘
提取码:4h5k
2. 代码分析
首先我们导入本次实战所要用到的库
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
我使用pandas来进行数据的写入,由于数据是以csv的格式存放的。所以我采用了pandas.read_csv函数来进行写入操作。
# 读取数据
data = pd.read_csv("./train.csv/train.csv")
第一次输入数据时,需要对数据进行处理以提高最后模型的预测的准确率。
由于时间是以时间戳的格式输入的,所以我们将时间转换为年月日的格式方便后续计算。并将日、时、周作为特征值构造新的特征。
# 处理数据
# 1.缩小数据
data = data.query('x>1.0 & x<1.25 & y>2.5 & y<2.75')
# 2.转换时间戳为年月日格式
time_value = pd.to_datetime(data['time'],unit='s')
# 把日期格式转换为字典数据
time_value = pd.DatetimeIndex(time_value)
# 3.构造特征
data['day'] = time_value.day
data['hour'] = time_value.hour
data['weekday'] = time_value.weekday
由于很多地方签到的数量都很少,删除一些签到数量很少的地方可以减少计算负荷,加快效率。
# 4.把签到数量少于n个的目标位置删除
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)]
# 5.删除无用的特征
data = data.drop(['row_id', 'time','accuracy'], axis=1)
这时,我们将处理好的数据输出可以看到,此时的数据是:
x y place_id day hour weekday
600 1.2214 2.7023 6683426742 1 18 3
957 1.1832 2.6891 6683426742 10 2 5
4345 1.1935 2.6550 6889790653 5 15 0
4735 1.1452 2.6074 6822359752 6 23 1
5580 1.0089 2.7287 1527921905 9 11 4
... ... ... ... ... ... ...
29100203 1.0129 2.6775 3312463746 1 10 3
29108443 1.1474 2.6840 3533177779 7 23 2
29109993 1.0240 2.7238 6424972551 8 15 3
29111539 1.2032 2.6796 3533177779 4 0 6
29112154 1.1070 2.5419 4932578245 8 23 3
[16918 rows x 6 columns]
这时,我们要在特征的层面上对数据进一步处理,也就是做特征工程。
K-近邻算法一定要做特征标准化处理,因为K-NN算法在计算时是采用欧氏距离来测量每一个点之间在特征空间的距离。要采用标准化来降低某几个大特征对最后结果的影响。
# 特征工程(标准化)
std = StandardScaler()
# 对训练集和测试集的特征值进行标注化
x_train = std.fit_transform(x_train)
x_test = std.transform(x_test)
特征工程处理完后,在进行算法建模之前,我们要将数据分割为数据集和测试集。来进行模型评估。
# 数据分割
y = data['place_id'] # 获取数据的标签
x = data.drop(['place_id'],axis=1) # 获取数据的特征值
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.25)
最后使用K-NN算法来建立模型,进行预测。
# KNN算法
knn = KNeighborsClassifier(n_neighbors=5)
# 输入数据拟合模型
knn.fit(x_train,y_train)
# 得到预测结果
y_predict = knn.predict(x_test)
# 得出准确率
print("准确率: ",knn.score(x_test,y_test))
最后,我们得到的准确率为:
准确率: 0.4949408983451537
3.总结
K-NN算法非常简单,但是K-NN算法的性能有一定的局限。当计算一个点时,要计算该点与特征空间其他所有点的距离才能找到几个距离最近的点,所以K-NN算法的时间复杂度是非常大的。
虽然我们还可以通过一些调参的手段又优化模型,提高准确率。但那都是治标不治本。在Kaggle上,榜单前十的大神选手的准确率也不过60-62这个程度,再难得以提升。