最近,公司想嘗試一下利用機器學習進行航班的延誤預測,於是將調研任務交給了博主。一開始的傾向是使用GBDT算法,使用了在scikit-learn上的腫瘤數據作爲初步模型測試,使用網格搜索後發現,其預測結果僅僅只有50%不到,還不如KNN——《機器學習之Knn算法》。
後來在網上看到了XGBOOST算法,於是常識了一波,準確率可以達到90%,比knn要強出5%以上,所以在模型的選擇上,博主決定使用XGBOOST。
對於GBDT和XGBOOST的原理,以及各超參的控制機理,博主這邊還只是初步嘗試,後面會較深入的去琢磨一番,然後完善博客,但是工具的使用還是簡單的,問題在於數據集。
一、航班數據集
1.1 蒐集數據
國內的航班數據幾乎沒有,也沒有免費的公開網站,而公司的數據幾乎不可用,因爲只有航線、航司、出發、到達、計劃時間等,沒有博主需要的實際時間、天氣狀況、航班號等。
爲此博主花了一整天時間蒐羅各大網站,終於發現了這個國外網站——stat-computing.org,貌似需要翻牆。可以查詢到美國的航空公司航班準點率數據,博主選取的是2016年的。
此外,還有這位博主,提供的數據也被博主參考了進來——找不到鏈接,後期補上。
但是唯一遺憾就是缺少天氣數據,經過不斷的搜索,博主發現了一個美國氣象局,可以查到2016年的歷史天氣數據——ATL亞特蘭大國際機場天氣狀況
亞特蘭大國際機場2016年1月部分數據 |
---|
本想通過爬蟲進行爬取數據,但實際情況不允許。不過博主也是講table標籤數據copy下來,然後利用python進行數據的整理與合併。
經過分析,博主個人認爲風速和降水量,由於變化幅度大,可以作爲影響航班的主要因素,隱藏只提取這兩個因素作爲天氣指數。
1.2 天氣數據處理和合並
由於是調研,選取的是美國大型航空公司——DL達美,並選取了五個機場:ATL(佐治亞州亞特蘭大:哈茨菲爾德-傑克遜亞特蘭大國際機場)、DTW(底特律韋恩縣國際機場)、JFK(紐約:約翰·F·肯尼迪國際機場)、MSP(明尼蘇達州明尼阿波利斯:明尼阿波利斯聖保羅國際機場)、SEA(華盛頓州:西雅圖/塔科馬國際機場)
由兩個文件,一個是USA_fightDataSet.xlsx
,這個Excel文件記錄的是起飛時間、機場、計劃飛行時間、實際飛行實際、航班號等數據;另一個是由機場和月份組成的60個txt文件,裏面是html的table標籤數據。
博主要做的就是將table標籤裏的當天的天氣情況,即風速和降水量,插入到表格相應的位置,代碼如下:
## 獲取天氣數據的類方法
import pandas as pd
import numpy as np
np.set_printoptions(threshold=np.inf)
# 獲取數據
def getData(url, airport, mon):
# 讀取配置文件
table = pd.read_html(url);
# 數據行數
dayOfMonth = np.array(table[1])[1:, 0]
size = dayOfMonth.size
# 選取最後一個元素進行判斷,因爲爬取的數據有時候最後一個又從1號開始,這裏進行判斷排除處理
ele = dayOfMonth[size-1]
if ele == '1':
dayOfMonth = np.array(table[1])[1:size, 0]
wsp_data = np.array(table[5])[1:size, 1]
precipitation_data = table[7].values[1:size, 0]
else :
# 讀取數據,這裏將header刪掉,取數據
# 日
dayOfMonth = np.array(table[1])[1:, 0]
# windSpeed的平均值
wsp_data = np.array(table[5])[1:, 1]
# 降水量
precipitation_data = table[7].values[1:, 0]
# 填充月份
size = dayOfMonth.size
month = np.array([mon for i in range(size)])
# 填充機場
airport = np.array([airport for i in range(size)])
# 輸出結果
return np.vstack([month, dayOfMonth, airport, wsp_data, precipitation_data]).T
# 迭代合併數組,從2開始
def fibonacci(n, airport):
if n==2 :
url1 = "D:\\File\\航班預測\\天氣數據\\"+airport+"\\table" + str(1) + ".txt"
url2 = "D:\\File\\航班預測\\天氣數據\\"+airport+"\\table" + str(2) + ".txt"
return np.concatenate([getData(url1, airport, 1), getData(url2, airport, 2)])
else :
url = "D:\\File\\航班預測\\天氣數據\\"+airport+"\\table" + str(n) + ".txt"
return np.concatenate([fibonacci(n-1, airport), getData(url, airport, n)])
# 將各機場數據拼接
def getWeatherData():
result1 = fibonacci(12, 'ATL')
result2 = fibonacci(12, 'DTW')
result3 = fibonacci(12, 'JFK')
result4 = fibonacci(12, 'MSP')
result5 = fibonacci(12, 'SEA')
return np.concatenate([result1, result2, result3, result4, result5])
##
## 調用上面的天氣數據包,然後與USA_fightDataSet.xlsx表格數據進行合併
import weatherData.getWeatherData as gd
import numpy as np
import openpyxl
np.set_printoptions(threshold=np.inf)
# 獲取天氣數據結果
result = gd.getWeatherData()
# 獲取FlightData表格數據
wb = openpyxl.load_workbook('D:\\File\\航班預測\\天氣數據\\USA_fightDataSet.xlsx')
sheet = wb['FlightData_DL']
# 獲取fightData的行數,必須+1,因爲後面的for循環判斷是<判斷
rows = sheet.max_row+1
# 獲取天氣數據的行數
rows_weather = result.shape[0]
# 外層fightData數據
for i in range(3, rows):
# 獲取月份/日期/出發和到達機場名字
# 注意,openpyxl讀取的數據是從1開始計數的
month = sheet.cell(row=i, column=3).value
# 表格讀取的數據莫名其妙不是字符串,導致後面判斷總是false,需要轉一下
dayOfMonth = str(sheet.cell(row=i, column=4).value)
ori_airport = sheet.cell(row=i, column=9).value # 出發機場
dest_airport = sheet.cell(row=i, column=13).value # 到達機場
# 內層循環天氣數據
for j in range(0, rows_weather):
# 獲取天氣行數據
weather_row = result[j]
# 獲取天氣的各數據
w_month = weather_row[0]
w_dayOfMonth = weather_row[1]
w_airport = weather_row[2]
w_wsp = weather_row[3] # 風速
w_precipitation = weather_row[4] # 降水量
# 循環對比,如果月份/日期/機場名字都對應,則將風速和降水量插入表格
if month == w_month and dayOfMonth == w_dayOfMonth and ori_airport == w_airport:
sheet.cell(row=i, column=10).value = w_wsp
sheet.cell(row=i, column=11).value = w_precipitation
if month == w_month and dayOfMonth == w_dayOfMonth and dest_airport == w_airport:
sheet.cell(row=i, column=14).value = w_wsp
sheet.cell(row=i, column=15).value = w_precipitation
# 保存操作
wb.save('D:\\jdFile\\航班預測\\天氣數據\\USA_fightDataSet.xlsx')
最終的表格部分數據 |
---|
1.3 數據集處理
To Be Continued……