(這里只是做分析,不提供源代碼,畢竟是一個比賽)
題目分析
賽題詳情
構建一個模型,根據天氣,交通,區域里面的各種設施,以往歷史數據,預測未來的某個時間點,某個區域里,打車需求的缺口。整個算法其實就是一個有監督的機器學習的過程。
數據整理
下載后的整個壓縮數據包575M,其中包括的訂單數據大約900萬條。(其他Master表數據量很小,這里忽略不計)
使用MongoDB存儲的話,大概使用2GB的空間,全部導入之后,工作用計算機十分卡頓。MongoCola管理軟件失去響應。所以,這里的訂單按照日期導入。(訓練的時候,按照天來訓練)注意:官方的訂單數據的 訂單號 OrderID是主鍵重復的。這里以第一次出現的訂單號的數據為准。
由於數據量非常龐大,所以這里建議將中間的計算結果也放入數據庫中備用。
訂單數據整理
訂單數據整理,主要是整理出各個時段,各個地域的訂單數據。
- 時間段
- 地域編號
- 需求數
- 缺口
- 缺口比例
數據整理盡量使用LINQ進行處理,MONGODB查詢是消耗時間的!!!,這里數據庫只是用作數據的存儲不做計算
private void btnImportDB_Click(object sender, EventArgs e)
{
string rootFolder = txtRootDir.Text;
//Order: Root + "\order_data"
foreach (var filename in Directory.GetFiles(rootFolder + "\\order_data"))
{
if (!filename.Contains("._"))
{
string strDate = filename.Substring(filename.LastIndexOf("_") + 1);
var colname = "Order_" + strDate;
Database.Clear(colname);
var orderlist = new List<Order>();
var read = new StreamReader(filename);
while (!read.EndOfStream)
{
var o = Order.Gernerate(read.ReadLine());
orderlist.Add(o);
}
orderlist = orderlist.Distinct(x => x.order_id).ToList();
Database.InsertRecBatch(orderlist, colname);
var orderGaplist = new List<OrderGap>();
Database.Clear("OrderGap_" + strDate);
for (int time = 1; time < 144 + 1; time++)
{
for (int area = 1; area < 66 + 1; area++)
{
var m = new OrderGap() { DistrictId = area,TimeSlient = time};
m.Total = orderlist.Count((x) => { return x.DistrictID == area && x.TimeSlient == time; });
m.Gap = orderlist.Count((x) => { return x.DistrictID == area && x.TimeSlient == time && x.driver_id == "NULL" ; });
m.GapPercent = m.Total == 0 ? 0 : Math.Round(((double)m.Gap / m.Total) * 100, 2);
orderGaplist.Add(m);
}
}
Database.InsertRecBatch(orderGaplist, "OrderGap_" + strDate);
//暫時只分析一天數據
break;
}
}
}
利用Excel,可視化數據
以下是2016-01-01的數據分析。藍色的是GAP缺口數,紅色的是Total數。
一天24個小時整體需求分布可以看個大概了。
擬合
Gap的預測,是建立在一個擬合函數上的。也有一些機器學習的味道。
總的Gap函數 = 函數(時間,地區)
- TimeID : 時間片編號
- DistricID:地區編號
- Traffic:交通流量
- Weather:天氣
- POI:設施數
交通流量和時間有關,一個地方的擁堵程度和時間有關系
不同的地區,各種設施配置不同。
天氣和時間有關。
Gap函數 = 函數(交通擁擠度函數(時間,地區編號),POI函數(地區編號),天氣函數(時間))
這里可以認為,一個地方的打車人數,交通越堵,則打車的GAP越大。天氣不好,打車的人則越多,GAP也越大。設施越多的地方,打車的需求也越多,GAP可能也越大。但是這一切都只是可能性。
(題外話,其實真實的情況也要考慮節假日的問題,在節假日的時候,GAP可能會變大。當然這是一個人文的考量了)
算法
交通擁堵函數:
這里的交通擁堵函數是使用4個等級表示的。
- LV1 20條路 權重8
- LV2 10條路 權重4
- LV3 15條路 權重2
- LV4 05條路 權重1
那么擁堵指數怎么計算呢?這里應該是對每個擁堵喲一個權重,等級越高,權重越大。
擁擠度 = SUM(權重 * 數量)
當然權重也是一個需要訓練和擬合的。
(設施數和天氣差不多,也是同樣考慮的。)
這里有三個指標,每種指標對於整體的影響程度也是需要訓練的。
本博文將在 http://www.codesnippet.info/Article/Index?ArticleId=00000038 進行實時更新。
任何疑問,討論,請移步 http://www.codesnippet.info/Article/Index?ArticleId=00000038
本文不求大部分關注,只求算法愛好者的參與。