高雄市 1999 提供了至少 7 年的歷史資料,我們是否可以透過分析這些資料,供未來進行快速分案呢?

繼上一次的 高雄市 1999 市政儀表板:用 Open1999 開放資料做視覺化 後,我們在同一個比賽中其實還做了智慧分案系統:終極目標是案件受理人員只要把案件描述打下來,系統就可以自動分案,把案件分派到適當的局處。

predict

下載、預處理 1999 歷史資料

在高雄市政府資料開放平臺中,有從 100 年到 106 年度的歷史派工資料,首先我們透過平臺上的 CKAN API 搜尋並下載下來,這邊使用的是 node.js 中的 axios 套件。之後再透過 concat-files 套件把所有的檔案(CSV 格式)結合成同一個檔案,以供後續進行分析。

觀察這些檔案格式後,由於我們透過案件描述來預測局處,所以我們主要會分析 BeforeDesc 欄位及 UnitName 欄位。

預處理的部分,一開始我們先將 BeforeDesc 中的描述斷詞,當然是使用 jieba 套件。在這裡我們還把一些可能會影響預測的贅詞去掉,像是受理人員會記錄的「渠反映該處......」、「......建請會同查處」等等,另外我們也把車牌去掉了。斷詞後會得到這樣的資料:

有人 放鞭 鞭炮 放鞭炮
民 眾 施放 鞭炮 妨礙 安寧
施 方 鞭炮 妨礙 安寧
*   渠 反映 該 業者 音樂 樂聲 音樂聲 大 , 妨害 安寧
擴音 擴音器 聲 大 擾民
一間 PUB 音樂 樂聲 音樂聲 過 大 , 妨礙 安寧
多名 青少 少年 青少年 在 施放 放煙 煙火 放煙火 施放煙火 , 妨礙 安寧
店家 客人 喧鬧 , 車輛 紅線 違停
渠 反映 該 業者 歡唱 音量 過 大 , 妨害 安寧
店家 冷氣 水塔 聲 大 擾民
音樂 樂聲 音樂聲 大 擾民
......

其實在這種資料裡出現車牌似乎有點不應該,大概是沒注意到這裡也要去識別化吧?

接著要將這些詞彙整理出來,並計算出現的次數:

路燈 121218
不亮 116759
故障 110524
反映 96978
一盞 59342
路面 55458
噪音 42758
坑洞 40246
號誌 38908
......

訓練預測模型

預處理完資料後,接著就是要開始訓練模型了。樣本數目大概有 52 萬筆資料,整理出來大概兩萬個詞彙吧,我們在這裡選擇使用類似貝式分類的方法來訓練模型。

我們將每一個詞彙在不同局處出現的機率記下來,例如路燈這個詞在各個局處的機率:

養工處 0.8995116236862513
環保局 0.029484070022603903
警察局 0.000057747199260835846
水利局防洪維護科 0.002656371165998449
交通局 0.0005362239931363329
台電公司 0.001229190384266363
養工處2 0.04199046346252207
觀光局 0.0013199359831048195
民政局 0.00006599679915524098
區公所 0.0011384447854279067
工務局 0.00014024319820488707
動物保護處 0.00006599679915524098
自來水公司 0.000008249599894405122

不亮這個詞:

養工處 0.8247843849296413
交通局 0.11998218552745399
水利局防洪維護科 0.0046677343930660595
養工處2 0.036476845468015315
台電公司 0.0004967497152253788
警察局 0.000008564650262506531
民政局 0.000034258601050026125
觀光局 0.002192550467201672
區公所 0.0013360854409510188
工務局 0.00005138790157503918

以此類推,我們將每個詞彙在不同局處的機率都算出來並存下來。

我們並沒有深入了解派工的邏輯,所以不清楚為什麼有些事件會派給大樹區公所、大寮區公所等等公所。為了簡化計算,我們將所有區公所統一用「區公所」來計算;此外,我們也沒有去深入了解為什麼會有養工處和養工處2。

使用、評估預測模型

有了這個機率模型後,之後輸入新的句子,一樣都會先透過結巴斷詞,分解出各個詞彙。透過剛剛的預測模型算出每個詞彙在不同局處的機率,並將不同局處的機率相乘起來(若該詞彙沒有紀錄,則忽略不計)。

例如當輸入「路燈不亮」這個詞,首先會被斷為「路燈 / 不亮」,接著透過剛剛的模型算出兩個詞在各個局處的機率,並相乘而得到:

養工處 0.7419031412791277
環保局 0.029484070022603903
養工處2 0.0015316796468527608
動物保護處 0.00006599679915524098
交通局 0.0000643373266287557
水利局防洪維護科 0.000012399235052279951
自來水公司 0.000008249599894405122
觀光局 0.0000028940262564327704
台電公司 6.105999733420899e-7
......

如此我們便能預測「路燈不亮」應該交給養工處、環保局或養工處2。由於輸入的句子越長,斷開的詞就會越多,機率就會越乘越小,在這裡我們只選出最大(或前幾大)的局處當作候選局處。

把他丟回這 7 年度的資料預測看看,可以看到模型準確率和案件量呈正向關係,前幾名大概如下:

部門 案件量 預測準確量 準確率
養工處 200,888 197,833 98%
環保局 171,650 163,704 95%
交通局 36,779 33,891 92%
水利局防洪維護科 44,868 38,988 87%
警察局 24,679 19,276 78%
動物保護處 9,220 5,409 59%

由於我們使用 100~106 年度的資料訓練,所以我們改拿 107 年 1 月到 107 年 4 月底的資料來做評估。前幾名如下:

部門 案件量 預測準確量 準確率
養工處 12,550 12,290 98%
環保局 13,590 13,037 95%
交通局 2,456 2,907 85%
水利局防洪維護科 3,216 2,669 83%
警察局 1,883 1,196 64%
動物保護處 904 505 56%

結語

最後將這模型做成 API 以供分案系統直接在線上呼叫使用,一樣把成品丟出來放在這裡:https://work1999.noob.tw

predict

最後做出來的智慧分案系統看起來很厲害,也實際能操作,不過某些某些描述丟進去還是沒辦法準確預測;像剛剛說的 107 年資料丟進去,完全命中的機率大概有 78%,而考慮前三名的局處的話命中機率有 90%。雖然還不能完全取代真人判斷,但至少可以協助判斷,是個還算堪用的模型了。未來是否有人能建議該怎麼改善或用不同方法算算看呢?也許可以考慮看看 NN?

噢,你說比賽結果如何?

我們得銀質獎啦(),輸給區塊鏈啦()。

相關連結