從天津百貨大樓 5 病例「迷局」見新冠病毒傳播路徑

image

天津某百貨大樓內部相繼出現 5 例新冠肺炎確診病例,從起初的 3 個病例來看,彷佛找不到任何流行病學上的關聯性。在這種背景之下,做爲技術人員能夠經過什麼技術來找尋病例之間的聯繫呢?html

摘要

最初,nCoV 新冠病毒的擴散過程是由一我的(節點)向各其餘人(節點)擴散的樹狀結構,但隨着病毒的變異和人員交叉感染、「百家宴」、「聯歡會」、「春運」等人員彙集,疫情擴散爲網狀結構。可使用圖數據庫來存儲相關人員、地理位置、感染時間等數據,本文將使用圖數據庫 Nebula Graph 做爲工具,帶你們一塊兒探討疫情的傳播路徑,並找到相關的疑似病例。git

天津案例簡述

下面用 Usr一、Usr二、Usr三、Usr四、Usr5 來代指這 5 例病例,看一下他們的行爲軌跡:github

Usr1 信息:數據庫

  • Usr1 於 1 月 24 日開始發熱,在 1 月 22 日至 1 月 30 日期間在天津百貨大廈 A 區工做,於 1 月 31 日確診;
  • Usr2 信息:Usr2 爲 Usr1 丈夫,於 1 月 25 日開始出現腹瀉症狀,於 2 月 1 日確診;
  • Usr3 信息:Usr3 於 1 月 18 日接觸過一個疑似病例,然後在天津百貨大廈 B 區工做,於 1 月 24 日開始發熱,於 2 月 1 日確診;
  • Usr4 信息:Usr4 於 1 月 12 日、13 日接觸過疑似病例,然後在天津百貨大廈 C 區工做,於 1 月 21 日開始發熱,於 2 月 1 日確診;
  • Usr5 信息:Usr5 於 1 月 23 日下午 16 點到 23 點到過天津百貨大廈 A、B、C 區,1 月 29 日開始發熱,2 月 2 日確診;

下面咱們來創建一個傳播路徑的模型。bash

nCoV 新冠病的數據分析

以咱們現有的資料顯示,本次 nCoV 的傳播路徑爲人傳人(圖 Demo1),即一個點經過特定訪問路徑鏈接到一個點。單個節點看來傳播路徑爲一個樹形結構(圖 Demo2)——確診病人 A 感染 B,B 再感染 C,C 再感染 D…。根據如今疫情傳播狀況,存在多個確診病人,因此整個傳播鏈路呈網狀結構(圖 Demo3)。而不管是樹形結構仍是網狀結構都很適合用圖(網絡)這種數據結構來存儲、查詢和分析。網絡

image

圖模型

在建模以前咱們須要清楚人和人之間的關係載體是什麼?根據現有的病例信息,咱們知道 A 和 B 會的接觸場景最多見的是:**同一個時間段逗留在某個相同的空間。**這也是本次疫情篩選需隔離人羣的重要指標:是否和確診 / 疑似病例在酒店、火車、超市有過密切接觸。數據結構

image

可見最小模型中有兩類節點 Person 和 Space ,關係爲 stay 。最小模型有了,那麼咱們須要 Person 和 Space 的什麼信息呢?工具

Person 類型節點的屬性:大數據

  • _ID:_Person 的身份證,用來標識人
  • _HealthStatus _:健康狀態,有 2 種狀態
    • Health:健康
    • Sick:生病
  • SickTime:發熱開始時間,能夠用來追溯病人發病的前後次序

Space 類型節點的屬性:人工智能

  • ID:Space ID,用來惟一標識 space
  • Address:space 地址

image

咱們構建完 Person 和 Space 的模型以後,再構建人和位置之間的關係:

在 stay 關係上,記錄有逗留的起始時間終止時間。這樣就能夠幫助咱們判斷兩我的是否有過期間和空間上的交集。

天津案例的建模

構建完最小模型以後,咱們來分析一下天津病例中的信息,將模型應用在這個案例中。並經過圖數據庫 Nebula Graph 構建病例間關係、找尋病例1 的發病緣由——病例1 怎麼被傳染的,及病例1 確診後咱們須要觀察/隔離哪些人

整個模型的示意以下:

image

數據錄入

Usr1:

  • Person 信息:ID 2020020201,HealthStatus:Sick,SickTime:20200124;
  • Stay Time:起始時間 1 月 23 日 12 點,終止時間 18 點;
  • Place 信息:天津百貨大廈 A 區;
  • Stay Time:起始時間 1 月 23 日 18 點,終止時間 24日 8 點;
  • Place 信息:天津市和平區 A 小區;

Usr2:

  • Person 信息:ID 2020020202,HealthStatus:Sick,SickTime:20200125;
  • Stay Time:起始時間 1 月 23 日 12 點,終止時間 23 點;
  • Place 信息:天津市和平區 A 小區;

Usr3:

  • Person 信息:ID 2020020203,HealthStatus:Sick,SickTime:20200125;
  • Stay Time:起始時間 1 月 23 日 15 點,終止時間 19 點;
  • Place 信息:天津百貨大廈 B 區;
  • Stay Time:起始時間 1 月 23 日 12 點,終止時間 23 點;
  • Place 信息:天津市河西區 B 小區;

Usr4:

  • Person 信息:ID 2020020204,HealthStatus:Sick,SickTime:20200121;
  • Stay Time:起始時間 1 月 23 日 11 點,終止時間 20 點;
  • Place 信息:天津南開區某火鍋店;
  • Stay Time:起始時間 1 月 23 日 20 點,終止時間 23 點;
  • Place 信息:天津市濱海區 B 小區;

Usr5:

  • Person 信息:ID 2020020205,HealthStatus:Health,SickTime:NULL(無);
  • Stay Time:起始時間 1 月 23 日 11 點,終止時間 15 點;
  • Place 信息:天津南開區某火鍋店;
  • Stay Time:起始時間 1 月 23 日 16 點,終止時間 23 點;
  • Place 信息:天津百貨大廈 A、B、C 區;

將它導入到 NebulaGraph 中, 創建人和空間之間的關係。這裏以 Usr1 的軌跡爲例,其他幾份病例相似。

-- 插入 Usr1
INSERT VERTEX person(ID, HealthStatus, SickTime) VALUES 1:(2020020201, ‘Sick’, '2020-01-24'); 
-- 插入 位置 「天津百貨大廈 A 區」
INSERT VERTEX place(name) VALUES 101:("天津百貨大廈 A 區")
-- Usr1 到 「天津百貨大廈 A 區」
INSERT EDGE stay (start_time, end_time) VALUES 1 -> 101: ('2020-01-23 12:00:00', '2020-01-23 18:00:00')
-- 插入 位置 「天津市和平區 A 小區」
INSERT VERTEX place(name) VALUES 102:("天津市和平區 A 小區")
-- Usr1 回家
INSERT EDGE stay (start_time, end_time) VALUES 1 -> 102: ('2020-01-23 18:00:00', '2020-01-24 8:00:00')

病例數據分析

數據導入後,讓咱們一步步揭開病例1 被感染之謎:

1. 查詢 Usr1 在 1 月 23 日 15 點至 23 點之間去過哪裏

$PlaceUsr1Goto = GO FROM 1 OVER stay WHERE stay.start_time > '2020-01-23 15:00:00' AND 
stay.start_time < '2020-01-23 23:00:00'
YIELD stay._dst AS placeid

2. 查詢這段時間 Usr1 是否接觸過任何(已發病的)病例

GO FROM $PlaceUsr1Goto OVER stay REVERSELY WHERE $$.person.HealthStatus == 'Sick' 
   AND $$.person.SickTime <= "2020-01-23"

很奇怪,在 Usr1 發病的時候(2020-01-24),他接觸的人羣裏面並無發熱患者。那會不會是這些人又接觸過其餘的患者呢(從而成爲攜帶者),讓咱們繼續分析。

3. 查詢這些人又接觸過誰

$PersonUsr1Meet = GO FROM $PlaceUsr1Goto OVER stay REVERSELY YIELD stay._dst AS id
$PlaceThosePersonGoto = GO FROM $PersonUsr1meet.id OVER stay YIELD stay.start_time AS start
    stay.end_time AS end
GO FROM $PlaceThosePersonGoto.id FROM stay REVERSELY 
    WHERE $$.person.HealthStatus == 'Sick'
    AND $$.person.SickTime <= "2020-01-23"  -- 在此以前已經發病
    stay.start_time > $PlaceTHosePersonGoto.start 
    AND stay.end_time < $PlaceThosePersonGoto.end  -- 而且有過接觸

咱們發現,雖然 Usr1 在 1 月 23 日 12 點到 1 月 24 日 8 點之間接觸的人(Usr2, Usr5)都尚未發熱,可是 Usr5 卻在以前接觸過發熱病人 Usr4。至此,咱們找到了這條傳播鏈路:

Usr4 在 1 月 21 日發病。發病後,他仍前往天津南開區某火鍋店(1 月 23 日 11 點- 20 點)。在這裏,他接觸到(當時健康的)Usr5(1 月 23 日 11 點-15 點)。在接觸過程當中使得 Usr5 成爲一個攜帶者。以後 Usr5 前往天津百貨大廈 A、B、C 區( 1 月 23 日 16 - 23 點),在這段時間內,他將病毒傳染給在 A 區上班的 Usr1(1 月 23 日 12 點 - 18 點)。最終 Usr1 在 1 月 24 日發病。

4. 以後排查須要隔離哪些人

Usr1 確診以後,咱們須要查看她在哪些時候到過哪些地方。而對應這個時間段相同地點內,又有哪些人同她接觸。 咱們判斷這些親密接觸者,須要重點隔離和觀察。

GO FROM 1 OVER stay YIELD stay.start_time AS usr1_start, 
stay.end_time AS usr1_end, stay._dst AS placeid
| GO FROM $placeid OVER stay REVERSELY WHERE 
stay.start_time > usr1_start AND stay.start_time < usr1_end
YIELD $$.person.ID

能夠發現 Usr1 和 Usr2 在天津市和平區 A 小區有過交集,這使得 Usr2 須要被重點觀察。

傳播路徑可視化展現

上面這段分析過程,也可使用圖形化界面的方式來交互分析,這樣更加直觀。

image

固然,若是有很是大批量的關注點(例如上千萬離開湖北的潛在人員和他們的二次三次傳播軌跡),經過批量程序查詢的方式會更加高效。

小結

因爲春節返鄉和一些不可描述的影響,致使冠狀病毒的大面積擴散。從報道和社交媒體上能夠看到,各個社區、村莊、企業都採用了至關嚴格的隔離措施,要求我的每日彙報行蹤和健康狀態,並密切跟蹤從疫區來的人員。這樣十幾億人的隔離和追蹤須要極大的人力物力和動員能力,充分體現了「集中力量辦大事」的制度優越性。

但另一方面,這樣的自我申報和層層統計,很是依賴我的的自覺,也依賴於彙報體系的響應速度。特別是當生死攸關(或者一刀切的歧視政策)的時候,我的反而有很強的動機隱瞞過去的行爲和病史,致使未能獲得及時的隔離和救治,也極大的影響了須要專業分工合做的現代經濟生產活動。

另一方面,隨着大數據技術的發展和智能設備的普及,使得安防、運營商、交通、醫療部門的數據體系已經創建的較爲全面。

在天津這個案例中,只選取了少數幾個病例和場所做爲示意,咱們相信若是可以結合前述數據體系,並經過採用新的大數據和人工智能技術,可以極大提升定位和隔離疑似患者的速度,大大減小各類「有效人傳人」和「超級毒王」的發生,減小一線醫療和社區工做人員的壓力。也能下降全社會的全面隔離時間,儘快恢復經濟活動。

image

image

參考資料

相關文章
相關標籤/搜索