目录
- 前言
- 总体设计
- 系统整体结构图
- 系统流程图
- 运行环境
- Python环境
- Pycharm 环境
- Scikit-learnt
- 模块实现
- 1. 数据预处理
- 1)加载数据集
- 2)时间划分与保存
- 3)处理天气预报数据
- 4)增加特征
- 5)合并特征值
- 相关其它博客
- 工程源代码下载
- 其它资料下载
前言
本项目的核心是利用百度地图API获取步行时间和借助GBDT(梯度提升决策树)模型进行排队时间的预测。它旨在为用户提供一种自主选择多个目的地的功能,然后系统会输出最佳路线规划的结果,并根据用户的选择提供智能化的建议。
首先,项目利用百度地图API,能够获取到步行时间信息。这些信息包括从一个地点到另一个地点所需的预计步行时间。这个步骤确保了系统具有地理位置感知能力,可以理解用户的出行需求。
接下来,项目使用GBDT模型,这是一种强大的机器学习模型,用于预测排队时间。GBDT模型会考虑多个因素,如交通状况、目的地之间的距离、历史排队数据等,来预测用户在不同地点排队的时间。
一旦获取了这些信息,系统可以让用户自主选择多个目的地。用户可以输入他们的出发点和多个目标地点,然后系统会根据百度地图API的步行时间和GBDT模型的排队时间预测,计算出最佳路线规划。这个规划考虑了用户的时间限制、排队时间、步行时间等因素,以确保用户能够在最短的时间内到达所有目的地。
最后,系统还可以根据用户的选择,提供智能化的建议。例如,如果用户希望优先选择最短排队时间的目的地,系统可以相应地调整路线规划。
总的来说,这个项目结合了地图数据和机器学习技术,为用户提供了一个方便的自主选择多个目的地并获取最佳路线规划的工具。这对于城市出行和旅游规划非常有用,可以帮助用户更高效地安排行程。
总体设计
本部分包括系统整体结构图和系统流程图。
系统整体结构图
系统整体结构如图所示。
系统流程图
系统流程如图所示。
路径规划流程如图所示。
计算路径耗时流程,如图所示。
运行环境
本部分包括 Python 环境、Pycharm 环境和Scikit-learn环境。
Python环境
需要Python 3.6及以上配置,在Windows环境下推荐下载Anaconda完成Python所需环境的配置,下载地址为https://www.anaconda.com/,也可下载虚拟机在Linux环境下运行代码。
Pycharm 环境
PyCharm下载地址为http://www.jetbrains.com/pycharm/download/#section=windows,进入网站后单击Comminity版本下的DOWNLOAD下载安装包,下载完成后安装。单击Create New Project创建新的项目文件,Location为存放工程的路径,单击project附近的三角符号,可以看到PyCharm已经自动获取Python 3.6,单击create完成。
Scikit-learnt
安装CPU版本的Scikit-learn
: pip install -U --ignore-installed scikit-learn
, 或者从Anaconda环境中直接搜索 scikit-learn包进行下载、安装。
模块实现
本项目包括6个模块:数据预处理、客流预测、百度地图API调用、GUI界面设计、路径规划和智能推荐,下面分别给出各模块的功能介绍及相关代码。
1. 数据预处理
数据集链接地址为: https://pan.baidu.com/s/1S6xZmEryGQgmv3_z8MjG2A?pwd=f4ui 提取码: f4ui
乘车刷卡交易数据表train_data
使用城市: use_city
、线路名称: line_ name、刷卡终端ID: terminal_id
、卡片ID: card_id
、发卡地: create_city
、 交易时间: deal_time
、卡类型: card_type
。
公交线路信息表line_desc
, 线路名称: line_name
、线路站点数量: stop_cnt
、 线路类型: _line_type
。
广州市天气状况信息表weather_report
, 日期: data_time
、天气状况: weather
、 气温: temperature
、 风向风力:wind_direction_force
。
1)加载数据集
使用DealTrainData.py
程序加载数据集,初步查看数据集中所有项,以便后续选择需要的项作为特征,相关代码如下:
import pandas as pd
#乘车刷卡交易数据表
train_data = pd.read_csv('C:/Users/99509/Desktop/信息系统设计/data/gd_train_data.txt',header=None,names=['use_city','line_name','terminal_id','card_id','create_city','deal_time','card_type'])
#公交线路信息表
line_desc = pd.read_csv('C:/Users/99509/Desktop/信息系统设计/data/gd_line_desc.txt',header=None,names=['line_name','stop_cnt','line_type'])
#广州市天气状况信息表
weather_report = pd.read_csv('C:/Users/99509/Desktop/信息系统设计/data/gd_weather_report.txt',header=None,names=['data','weather','temperature','wind_direction_force'])
#虽然公交线路数据表中有21条线路,但是数据集只包含2条线路的详细数据
初始train_data
数据,如图所示。
print(train_data)
初始line_desc数据如图所示。
print(line_desc)
初始weather_report
数据,如图所示。
print(weather_report)
2)时间划分与保存
将deal_time按小时划分并保存,程序为DealTrainData.py
,分别将线路6和线路11按小时划分,并保存至表格,相关代码如下:
for i in ['线路6', '线路11']:
train_data_lineX = train_data[train_data['line_name'] == i]
#取原始乘车表中对应线路符合的数据
#把交易数据的日期和小时分成两个字段
train_data_lineX['date'] = train_data_lineX['deal_time'].apply(lambda x: str(x).split(' ')[0]) #日期
train_data_lineX['time'] = train_data_lineX['deal_time'].apply(lambda x: int(str(x).split(' ')[1].split(':')[0])) #小时
train_data_lineX_date_time = train_data_lineX.drop('deal_time', axis=1, inplace=False) #删除原始交易时间元素
#取交易时间在6~21点之间的数据
train_data_lineX_date_time_06 = train_data_lineX_date_time[6 <= train_data_lineX_date_time['time']]
train_data_lineX_date_time_06_21 = train_data_lineX_date_time_06[train_data_lineX_date_time_06['time'] <= 21]
#数据按小时划分并累计单位小时内客流量
lineX_passenger_hour = DataFrame(train_data_lineX_date_time_06_21.groupby(['date', 'time']).count()['card_id']).reset_index()
#保存最终所需数据
if i == '线路6':
lineX_passenger_hour.to_csv('C:/Users/99509/Desktop/信息系统设计/data/line6_passenger_hour.csv', header=1, index=0, encoding='utf-8')
if i == '线路11':
lineX_passenger_hour.to_csv('C:/Users/99509/Desktop/信息系统设计/data/line11_passenger_hour.csv', header=1, index=0, encoding='utf-8')
按小时划分后的客流数据如图所示。
3)处理天气预报数据
使用程序DealWeatherData.py
将天气预报数据集中的天气weather
、温度temperature
、风力风向wind_direction_force
数字标准化。
将天气按照以下方式划分并一一映射:晴: 0,多云:1,阴: 2,小雨: 3,小到中雨: 4,中雨: 5,中到大雨:6,大雨:7,大到暴雨:8,霾:9,阵雨:10,雷阵雨:11,取平均值作为特征。
将风力风向按照以下方式映射:无持续风向≤3级: 0,无持续风向微风转3-4级: 1,北风微风转3-4级:1,东北风3-4级: 2,北风3-4级: 2,东南风3-4级: 2,东风4-5级: 3, 北风4-5级: 3,求平均值作为特征。
相关代码如下:
#日期标准化 eg:'10/10'转换为'10','10' '1/1'转换为'01','01'
def changeDate(date):
dateList = date.split('/')
if int(dateList[1]) < 10:
month = '0' + dateList[1]
else:
month = dateList[1]
if int(dateList[2]) < 10:
day = '0' + dateList[2]
else:
day = dateList[2]
return dateList[0] + month + day
#转换天气预报数组中的日期格式
weather_report['datestr'] = weather_report['date'].apply(lambda x: changeDate(x))
#将相应字段分开
weather_report['weather_d'] = weather_report['weather'].apply(lambda x: x.split('/')[0]) #白天
weather_report['weather_n'] = weather_report['weather'].apply(lambda x: x.split('/')[1]) #晚上
weather_report['temperature_h'] = weather_report['temperature'].apply(lambda x: int(re.sub(r'\D', '', x.split('/')[0]))) #最高温
weather_report['temperature_l'] = weather_report['temperature'].apply(lambda x: int(re.sub(r'\D', '', x.split('/')[1]))) #最低温
weather_report['wind_direction_force_d'] = weather_report['wind_direction_force'].apply(lambda x: x.split('/')[0])
#白天风向、风力
weather_report['wind_direction_force_n'] = weather_report['wind_direction_force'].apply(lambda x: x.split('/')[1])
#晚上风向、风力
weather_report['temperature_average'] = (weather_report['temperature_h'] + weather_report['temperature_l']) / 2.0 #平均温度
weather_report['temperature_abs'] = abs(weather_report['temperature_h'] - weather_report['temperature_l']) #温差
#降低风向影响,着重考虑风力影响,按照以下将风力、风向数字化
print(pd.concat([weather_report['wind_direction_force_d'], weather_report['wind_direction_force_n']],ignore_index=True).drop_duplicates()) #数组合并去冗余、得到所有的风力、风向种类
windmap = {'无持续风向≤3级': 0, '无持续风向微风转3-4级': 1, '北风微风转3-4级': 1, '东北风3-4级': 2, '北风3-4级': 2, '东南风3-4级': 2, '东风4-5级': 3,'北风4-5级': 3} #划分
weather_report['wind_direction_force_d_map'] = weather_report['wind_direction_force_d'].map(windmap) #将原始数据替换为标准化数据
weather_report['wind_direction_force_n_map'] = weather_report['wind_direction_force_n'].map(windmap) #将原始数据替换为标准化数据
weather_report['wind_average'] = (weather_report['wind_direction_force_d_map'] + weather_report['wind_direction_force_n_map']) / 2.0 #做风力、风向平均值
weather_report['wind_abs'] = abs(weather_report['wind_direction_force_d_map'] - weather_report['wind_direction_force_n_map']) #做风力、风向差
#将天气按照以下形式数字化
print(pd.concat([weather_report['weather_d'], weather_report['weather_n']], ignore_index=True).drop_duplicates())
#数据组合并去冗余,得到所有天气种类
weathermap = {'晴': 0, '多云': 1, '阴': 2, '小雨': 3, '小到中雨': 4, '中雨': 5, '中到大雨': 6, '大雨': 7, '大到暴雨': 8, '霾': 9, '阵雨': 10,'雷阵雨': 11}
#划分
weather_report['weather_d_map'] = weather_report['weather_d'].map(weathermap) #将原始数据替换为标准化数据
weather_report['weather_n_map'] = weather_report['weather_n'].map(weathermap) #将原始数据替换为标准化数据
weather_report['weather_average'] = (weather_report['weather_d_map'] + weather_report['weather_n_map']) / 2.0 #做天气平均值
weather_report['weather_abs'] = abs(weather_report['weather_d_map'] - weather_report['weather_n_map']) #做天气差
#去除多余项,留下标准化日期、风力风向、风力风向均值、风力风向差、天气、天气均值、天气差
weather_report_result = weather_report.drop(['date', 'weather', 'temperature', 'wind_direction_force', 'weather_d', 'weather_n', 'wind_direction_force_d','wind_direction_force_n'], axis=1, inplace=False)
#输出
weather_report_result = weather_report_result.reset_index(drop=True)
#重置索引
print(weather_report_result)
for i in range(len(weather_report_result)):
weather_report_result.loc[i, 'datestr'] = pd.to_datetime(weather_report_result.loc[i, 'datestr'],format='%Y%m%d').strftime('%Y-%m-%d') #将时间格式化为year-month-day
weather_report_result.to_csv('C:/Users/99509/Desktop/信息系统设计/data/weather_report_result.csv', header=0, index=0, encoding='utf-8')
天气预报处理后的数据如图所示。
4)增加特征
使用程序TestDataResult.py
增加是否为节假日和星期几的特征,相关代码如下:
weather_report_data = pd.read_csv('C:/Users/99509/Desktop/信息系统设计/data/weather_report_result.csv', header=None,names=['date', 'temperature_h', 'temperature_l', 'temperature_average', 'temperature_abs', 'wind_d_map', 'wind_n_map', 'wind_average', 'wind_abs', 'weather_d_map', 'weather_n_map', 'weather_average', 'weather_abs'])
holiday = pd.read_csv('C:/Users/99509/Desktop/信息系统设计/data/date_holiday.txt', header=None, names=['date', 'isholiday'])
#日期,是否是假期
testdate = pd.date_range('2014-12-25', '2014-12-31') #测试集日期范围:2014.12.25-2014.12.31
#获得测试机完整日期时间范围
datetimelist = []
for idate in testdate:
datetime = pd.date_range(str(idate) + ' 6:00', str(idate) + ' 21:00', freq='H') #测试集时间范围:6:00~21:00
datetimelist.append(DataFrame(datetime))
datetimeDf = pd.concat(datetimelist, ignore_index=True) #忽略索引连接数组
datetimeDf.columns = ['datetime'] #修改列名为datetime
datetimeDf['date'] = datetimeDf['datetime'].apply(lambda x: str(x).split(' ')[0]) #分离出日期
datetimeDf['time'] = datetimeDf['datetime'].apply(lambda x: int(str(x).split(' ')[1].split(':')[0])) #分离出时间
datetimeDf_date_time = datetimeDf.drop('datetime', axis=1, inplace=False) #保存测试所有时间段:7天*15小时
#判断是否为节假日,数据预处理
for i in ['6', '11']:
lineX_passenger_hour_path = "C:/Users/99509/Desktop/信息系统设计/data/line%s_passenger_hour.csv" % i
#得到线路6/11的训练集中每小时客流量的路径(因为%s在字符串中,所以%i表示用i替换s)
lineX_passenger_hour = pd.read_csv(lineX_passenger_hour_path)
#得到线路6或11训练集中每小时的客流量
train_passenger_test = pd.concat([lineX_passenger_hour, datetimeDf_date_time], ignore_index=True)
#连接测试集和训练集中线路6或11的每小时客流量
#取线路6或11的交集(得到完整数据:日期、最高温、最低温、平均温度、温差、标准化白天风力风向、标准化夜晚风力风向、平均风力风向、风力风向差、标准化白天天气、标准化夜晚天气、平均天气、天气差、客流量)
test_data_weather = pd.merge(train_passenger_test, weather_report_data, on='date', how='left')
test_data_weather_holiday = pd.merge(test_data_weather, holiday, on='date', how='left') #测试集中节假日的数据
test_data_weather_holiday['dayofweek'] = test_data_weather_holiday['date'].apply(lambda x: pd.to_datetime(x).dayofweek) #添加是否为周末元素至测试集
5)合并特征值
使用程序finaldata.py
数据预处理最后一步, 得到7项特征值(平均温度temperature_average
、平均风力风向wind_average
、平均天气weather_average
、 单位时间客流card_id
、时间time
、 是否是节假日isholiday
、 星期几dayofweek
) 将所有特征值放入一个表格内。相关代码如下:
weather_report_data = pd.read_csv('C:/Users/99509/Desktop/信息系统设计/data/weather_report_result.csv', header=None,names=['date', 'temperature_h','temperature_l','temperature_average','temperature_abs', 'wind_d_map','wind_n_map','wind_average','wind_abs','weather_d_map','weather_n_map','weather_average','weather_abs']) #读取数据8.1~1.31
line6_weather = weather_report_data[:146] #读取数据8.1~12.24 (天)
line6_dateinfo = pd.read_csv('C:/Users/99509/Desktop/信息系统设计/data/line6_train_data_no_dum_scale.csv',header=None,names=['card_id','date','time','temperature_h','temperature_l','temperature_average','temperature_abs', 'wind_d_map','wind_n_map','wind_average','wind_abs','weather_d_map','weather_n_map','weather_average','weather_abs', 'isholiday','dayofweek' ])
#读取数据8.1~12.24 (小时)
#print(line6_dateinfo)调试代码
line6_weather_date = pd.DataFrame()
line6_weather_date['card_id']=line6_dateinfo['card_id'].drop(0)
line6_weather_date['time']=line6_dateinfo['time']
line6_weather_date['date']=line6_dateinfo['date']
line6_weather_date['isholiday']=line6_dateinfo['isholiday']
line6_weather_date['dayofweek']=line6_dateinfo['dayofweek']
line6_weather_date_f=pd.merge(line6_weather,line6_weather_date)
line6_weather_date_final=line6_weather_date_f.drop(['date', 'temperature_h','temperature_l','temperature_abs','wind_d_map','wind_n_map','wind_abs','weather_d_map','weather_n_map','weather_abs'], axis=1,inplace=False)
line6_weather_date_final.to_csv('C:/Users/99509/Desktop/信息系统设计/修改/line6_weather_date_final.csv',header=1, index=0, encoding='utf-8')
所有特征数据如图所示。
相关其它博客
基于GBDT+Tkinter+穷举法按排队时间预测最优路径的智能导航推荐系统——机器学习算法应用(含Python工程源码)+数据集(二)
基于GBDT+Tkinter+穷举法按排队时间预测最优路径的智能导航推荐系统——机器学习算法应用(含Python工程源码)+数据集(三)
基于GBDT+Tkinter+穷举法按排队时间预测最优路径的智能导航推荐系统——机器学习算法应用(含Python工程源码)+数据集(四)
工程源代码下载
详见本人博客资源下载页
其它资料下载
如果大家想继续了解人工智能相关学习路线和知识体系,欢迎大家翻阅我的另外一篇博客《重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载》
这篇博客参考了Github知名开源平台,AI技术平台以及相关领域专家:Datawhale,ApacheCN,AI有道和黄海广博士等约有近100G相关资料,希望能帮助到所有小伙伴们。