banner
朝闻道

朝闻道

做个知行合一的人
email

統一的標準太重要了(預先解決無形的問題)

用 Python 挖掘事故報告中的死亡人數#

今天用 Python 寫一個函數,用來識別土木行業事故報告中的死亡人數。我的設計思路如下:

  1. 經過觀察,80% 的事故報告中有關死亡人數的記錄是有規律的,即「XX 人死亡」,其中 XX 可能是漢語數字也可能是阿拉伯數字。
  2. 於是我設計出一個正則表達式,pattern_death = r'([\d\w]+)(人死亡|名工人死亡)' 用以識別出這種模式。
  3. 對安徽省的幾份調查報告的測試中,我發現這種識別模式會將「XX 人死亡」之前的文字也提取出來,比如「該工程有 5 人死亡」,直到遇到標點符號,因為 ([\d\w]+) 的含義是提取任意數量的漢字或數字。
  4. 於是我又設計出第二個正則表達式,pattern_death_num = r'(\d+|[零一二兩三四五六七八九十百千萬]+)(人死亡|名工人死亡)' ,用以識別出上一種模式識別出的句子中的數字(無論是中文還是阿拉伯的)。
  5. 之後我又下載一個第三方庫 cn2an ,將中文數字轉換為數學數字。
  6. 將識別到的數字存放到字典中,沒有識別到數字但文本中識別出「死亡」的做標記「待確認」。

雖然我在這裡描述的似乎很輕鬆,但是你無法知道的是,我從最開始的起點走到這個目的地用了多久,以及為了識別條件、避免報錯、存放識別出的數據等而為函數設計的邏輯化了多久時間。

在報了許多次錯誤、迭代了多次之後,這個程序基本上能運行起來了,這個思路已經可以從 393 個事故報告中提取 393-56 份 死亡人數了。

你可能會好奇,圖上顯示的分明是 57 份文件「待確認」,那麼已提取到數據的數量不應該是 383-57 嗎?

沒錯,這缺少的一份就是今天我要談論的主角。

一字之差的工作量#

這一份數據一直在報錯,我不得不在每個省份的文件之間依次測試,找出有問題的文件。

我發現出錯的原因是:程序的確識別出了「X 人死亡」,並且將「X」提取了出來,但報錯的那份文件用的不是「二人死亡」,而是是「兩人死亡」。cn2an 這個專門將表示數字的中文轉化為阿拉伯數字的庫,它只能識別「二」,無法識別「兩」

於是我又要設計出一個新的邏輯語句,如果識別出了「兩」,就將它改為「二」,然後再用 cn2an 將其轉化為阿拉伯數字。

我找到這個導致錯誤的原因並寫出解決問題的語句,花了近半個小時。僅僅是一個字的偏差,為了使程序能夠適應這種情況,卻需要大量的測試。

我並非一個計算機專業的學生,我比較好奇的是,也許「大量時間花費在解決報錯上」就是軟件開發的常態?

言歸正傳,這是我們提取數據中很簡單的一步,為了適配所有可能性,它的工作量並不小。

如果是從文本中提取「事故性質」這樣的數據,也許描述「事故性質」的方式有多種多樣(暫時我們不確定),不過它一定比數字要複雜,並且上下文可能沒有特殊的格式,如果真是這樣,單憑正則表達式可能已經無法完成目的了。

如果正則表達式無法解決這個問題,根據我目前掌握的信息來看,我們就需要複雜的 NLP 技術去識別出命名實體的詞語、語義邏輯關係等,讓機器理解句子,再將事故原因做分類。而這套規則,需要預設已知的數據庫使代碼能夠理解。

如果我們真的使用 NLP 技術去提取所有事故報告中的「事故原因」,那麼為了做出一個適配所有情況的程序,其工作量一定非常大。

為什麼這麼費勁#

我們之所以在提取數據時這麼費勁,是什麼原因呢?

答案顯而易見,事故報告中大部分信息的記錄方式都沒有統一的格式,如果格式能夠統一,如果每個事故報告中都有一個統一的清單,那麼每一種數據只需要一個正則表達式就能夠提取出來了,並且對所有文件適配。

只可惜,在事故報告的格式上,沒有像秦始皇統一六國的偉大節點。

現在 ChatGPT-4 應該可以自動提取出你所需的數據,只是需要充錢。而我們老師想讓我們做一個自動識別的程序,只能說有點難,哈哈。

秦始皇統一六國#

秦始皇建立了中國歷史上第一個統一的中央集權的封建國家,他不僅僅同意了中國,更重要的是他使書同文、車同軌、行同輪,統一文字、貨幣。

這些統一,不僅有利於信息的傳遞、規格的統一,也有助於我們中華文化的傳承和發揚。

今天在寫代碼中遇到了這個「兩」字引起的報錯,以及對提取「事故性質」的工作量的思考,是否可以說明 ——統一的標準能在無形中解決許多問題呢?

我認為答案是肯定的。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。