用knn进行汽车目的地预测(python实现)

题目来源
一、预测思路:

  1. 把开始时间,如“20:20:34”,按小时划分为0-23,把日期,如“2018-09-09 ”,按照工作日、休息日、小长假依次划分为0、1、2;
  2. 把训练集的结束位置的经纬度用geohash(python的一个工具包)转化为字符串作为标签;
  3. 把按以上步骤处理好的数据带入knn即可.

二、数据集格式
训练集部分数据

r_key,out_id,start_time,end_time,start_lat,start_lon,end_lat,end_lon
SDK-XJ_609994b4d50a8a07a64d41d1f70bbb05,2016061820000b,2018-01-20 10:13:43,2018-01-20 10:19:04,33.783415000000005,111.60366,33.779810999999995,111.60588500000001
SDK-XJ_4c2f29d94c9478623711756e4ae34cc5,2016061820000b,2018-02-12 17:40:51,2018-02-12 17:58:13,34.810763,115.549264,34.814875,115.549374
SDK-XJ_3570183177536a575b9da67a86efcd62,2016061820000b,2018-02-13 14:52:24,2018-02-13 15:24:33,34.640284,115.539024,34.813136,115.559243

测试集部分数据

r_key,out_id,start_time,start_lat,start_lon
f6fa6b2a1fa250b3_SDK-XJ_eed80f24f496fc9a59f49e031edfe9b8,358962079107966,2018-09-01 15:54:12,43.943356,125.37771799999999
a584728d1eb0fb5b_SDK-XJ_d60de6f0b8121b07383e80c0b176d0fa,358962079111695,2018-09-01 13:16:11,43.886501,125.272971
7308d46abc5ec4d0_SDK-XJ_6dd3f0f118e9813c51ed224ed09444c2,358962079120563,2018-09-01 18:08:36,43.867917,125.30785300000001

三、代码(可直接运行)

# -*- coding: utf-8 -*-
import datetime
import os
import time
from collections import Counter

import geohash
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
from sklearn.utils import shuffle

"""
汽车目的地智能预测大赛_knn
"""


def datetime_to_period(date_str):
    """
    描述:把时间分为24段
    返回:0到23
    """
    time_part = date_str.split(" ")[1]  # 获取时间部分
    hour_part = int(time_part.split(":")[0])  # 获取小时
    return hour_part


def date_to_period(date_str):
    """
    描述:把日期转化为对应的工作日或者节假日
    返回:0:工作日 1:节假日 2:小长假
    """
    holiday_list = ['2018-01-01', '2018-02-15', '2018-02-16', '2018-02-17', '2018-02-18', '2018-02-19',
                    '2018-02-20', '2018-02-21', '2018-04-05', '2018-04-06', '2018-04-07', '2018-04-29',
                    '2018-04-30', '2018-05-01', '2018-06-16', '2018-06-17', '2018-06-18']  # 小长假
    switch_workday_list = ['2018-02-11', '2018-02-24', '2018-04-08', '2018-04-28']  # 小长假补班
    workday_list = ['1', '2', '3', '4', '5']  # 周一到周五
    weekday_list = ['0', '6']  # 周六、周日,其中0表示周日
    date = date_str.split(" ")[0]  # 获取日期部分
    whatday = datetime.datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S').strftime("%w")  # 把日期转化为星期
    if date in holiday_list:
        return 2
    elif date in switch_workday_list:
        return 0
    elif whatday in workday_list:
        return 0
    elif whatday in weekday_list:
        return 1


time_start = time.asctime(time.localtime(time.time()))  # 程序开始时间

# ---删除相关文件---
path = "C:\\Users\\yang\\Desktop\\"  # 文件路径
lst = ['predict', 'predict_result', 'view', 'score', 'train']  # 文件名列表
for file_name in lst:
    file_path = path + file_name + '.csv'
    if os.path.exists(file_path):
        os.remove(file_path)

train_data_path = "C:\\Users\\yang\\Desktop\\train_new.csv"
train_data = pd.read_csv(train_data_path, low_memory=False)
test_data_path = "C:\\Users\\yang\\Desktop\\test_new.csv"
test_data = pd.read_csv(test_data_path, low_memory=False)

n = 0
test_out_id = Counter(test_data['out_id'])
for out_id in test_out_id.keys():
    # ----train_new数据补充字段 begin----
    train = train_data[train_data['out_id'] == out_id]  # 选择出同一个out_id的数据
    train = shuffle(train)  # 打乱顺序
    train['start_code'] = None  # 开始位置的geohash编码
    train['end_code'] = None  # 结束位置的geohash编码
    train['period'] = None  # 时间段编码(0-23)
    train['week_code'] = None  # 工作日和休息日编码
    for i in range(len(train)):
        train.iloc[i, 8] = geohash.encode(train.iloc[i, 4], train.iloc[i, 5], 8)  # 开始geohash编码
        train.iloc[i, 9] = geohash.encode(train.iloc[i, 6], train.iloc[i, 7], 8)  # 结束geohash编码
        train.iloc[i, 10] = datetime_to_period(train.iloc[i, 2])  # 添加时间段
        train.iloc[i, 11] = date_to_period(train.iloc[i, 2])  # 添加工作日、休息日编码
    # ----train_new数据补充字段 end----

    # ----test_new数据补充字段 begin----
    test = test_data[test_data['out_id'] == out_id]
    test = shuffle(test)  # 打乱顺序
    test['period'] = None
    test['week_code'] = None
    test['start_code'] = None
    test['predict'] = None
    for i in range(len(test)):
        test.iloc[i, 5] = datetime_to_period(test.iloc[i, 2])  # 添加时间段
        test.iloc[i, 6] = date_to_period(test.iloc[i, 2])  # 添加工作日、休息日编码
        test.iloc[i, 7] = geohash.encode(test.iloc[i, 3], test.iloc[i, 4], 8)  # 开始geohash编码
    # ----test_new数据补充字段 end----

    # ---knn begin---
    knn = KNeighborsClassifier(n_neighbors=10, weights='distance', algorithm='auto', p=2)
    knn.fit(train[['start_lat', 'start_lon', 'period', 'week_code']], train['end_code'])
    predict = knn.predict(test[['start_lat', 'start_lon', 'period', 'week_code']])
    test['predict'] = predict
    # ---knn end---
    if n == 0:
        test.to_csv("C:\\Users\\yang\\Desktop\\predict.csv", mode='a', encoding='utf-8', index=False,
                    header=True)
    else:
        test.to_csv("C:\\Users\\yang\\Desktop\\predict.csv", mode='a', encoding='utf-8', index=False,
                    header=False)
    if n % 500 == 0:
        print("已运行:" + str(n) + " " + time.asctime(time.localtime(time.time())))
    n = n + 1
print("输出结果:\n")
df = pd.read_csv("C:\\Users\\yang\\Desktop\\predict.csv")  # 预测结果文件
df['end_lat'] = None
df['end_lon'] = None
for i in range(len(df)):
    site = geohash.decode(df.iloc[i, 8])
    df.iloc[i, 9] = site[0]  # 预测横坐标
    df.iloc[i, 10] = site[1]  # 预测纵坐标
    if i % 5000 == 0:
        print("已运行" + str(i))
df = df[['r_key', 'end_lat', 'end_lon']]
df.to_csv("C:\\Users\\yang\\Desktop\\predict_result.csv", encoding='utf-8', index=False)

print('\r程序运行开始时间:', time_start)
print('\r程序运行结束时间:', time.asctime(time.localtime(time.time())))

备注:该代码运行时间约1.5小时

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论
KNN(k最近邻)算法是通过计算新数据点与训练集中各个点的距离,然后选择距离最近的k个点进行预测的算法。基于KNN算法预测各类房型的价格的步骤如下: 1. 数据收集:收集不同房型的各种特征数据,例如面积、房间数量、地理位置等。 2. 数据预处理:对收集的数据进行处理,如缺失值处理、特征缩放等。 3. 训练集与测试集划分:将数据集划分为训练集和测试集,通常将大部分数据作为训练集,少部分用于测试模型性能。 4. 特征选择:选择对价格影响较大的特征进行分析和建模。 5. 计算距离:计算测试集中每个样本与训练集中各个样本之间的距离,常用的距离度量方法有欧氏距离和曼哈顿距离等。 6. k值选择:选择适当的k值,通常通过交叉验证等方法来确定。 7. 预测:根据计算得到的距离,选择距离最近的k个样本,利用这些样本的价格信息进行预测,可以采用加权平均或多数表决等方式来得到预测结果。 8. 评估模型性能:使用测试集中的真实价格与预测价格进行比较,计算评价指标,例如均方误差(MSE)等,评估模型的性能。 9. 调参:根据评估结果,调整模型参数、选择新的特征或调整算法,优化预测效果。 基于KNN算法预测各类房型的价格,可以在数据量较大、特征选择合理、参数调整适当的前提下,得到较为准确的预测结果。然而,KNN算法也有一些局限性,如需要大量的存储空间、计算复杂度高等,因此应根据实际情况综合考虑选择适合的预测算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

适当喝点

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值