← All posts

Joint Model: หนึ่ง Likelihood สำหรับสองกระบวนการ

Clinical Epidemiology ResearchUniqcret doctor knowledges THMethodology and Research Design THPrognosis [Methodology] TH
Joint Model: หนึ่ง Likelihood สำหรับสองกระบวนการ
On this page

Read the English version

บทคัดย่อ

ในการศึกษาติดตามผู้ป่วยทางคลินิก เรามักวัด biomarker เช่น serum creatinine ซ้ำ ๆ ในขณะที่ผู้ป่วยก็มีความเสี่ยงต่อ event เช่นการเสียชีวิตไปพร้อมกัน และสองกระบวนการนี้แทบไม่เคยเป็นอิสระต่อกัน ผู้ป่วยที่แย่ที่สุดจะทรุดเร็วที่สุดและเสียชีวิตเร็วที่สุด บันทึก longitudinal ของเขาจึงหยุดลงเพราะ outcome นั่นเอง informative dropout แบบนี้ทำให้การวิเคราะห์ trajectory เพียงอย่างเดียวมี bias เพราะวิธี two-stage ที่ fit mixed model ก่อนแล้วค่อยเสียบ trajectory ที่ประมาณได้เข้าไปใน Cox hazard นั้นได้ล็อก trajectory ไว้ก่อนที่ข้อมูล survival จะย้อนกลับมาแก้ได้ joint model แก้ปัญหานี้ด้วยการวาง fixed effects และ random effects ชุดเดียวกันไว้ทั้งใน longitudinal submodel และ survival submodel แล้วประมาณค่าทั้งหมดจาก likelihood ร่วมเพียงอันเดียว เวลาของการเกิด event จึงป้อนกลับเข้าไปปรับ trajectory ผ่าน shared random effects โดยมี association parameter alpha เป็นตัวกำหนดความแข็งแรงของการเชื่อม และเมื่อ alpha เป็นศูนย์ likelihood ก็แยกออกเป็นสองแบบจำลองที่ต่างหากจากกัน บทความนี้อธิบายทีละสมการว่า likelihood เดียวเชื่อมสองกระบวนการเข้าด้วยกันได้อย่างไร และเหตุใดจึงเหนือกว่าการวิเคราะห์แต่ละ model แยกกัน


Visual summary · ภาพสรุป

Joint Models · ตอนที่ 1 จาก 2. ตอนต่อไป: Joint Model กับ Stacking [[joint-model-vs-stacking]].

คำถามที่ joint model ถูกสร้างขึ้นมาเพื่อตอบ

ลองนึกถึง cohort ของผู้ป่วยโรคไตเรื้อรัง ทุกครั้งที่มาตรวจ เราบันทึกค่า serum creatinine ผู้ป่วยแต่ละคนจึงมีค่าที่วัดซ้ำ ๆ เรียงต่อกันไปตามเวลา และเรายังบันทึกอีกสิ่งหนึ่งด้วยคือ เวลาจนกระทั่งเสียชีวิต (time to death) ข้อมูลสองชุดนี้ไม่ได้เป็นอิสระต่อกัน ผู้ป่วยที่ creatinine พุ่งเร็วที่สุดคือคนที่มักเสียชีวิตเร็วที่สุด และทันทีที่เขาเสียชีวิต ชุดค่า creatinine ของเขาก็ หยุด ลงเฉย ๆ ผู้ป่วยที่แย่ที่สุดจึงเป็นกลุ่มที่หลุดออกจากบันทึก longitudinal ก่อนใคร ไม่ได้หลุดแบบสุ่ม แต่หลุด เพราะ สิ่งเดียวกับที่ทำให้เขาป่วยหนักนั่นเอง

นี่คือปรากฏการณ์ informative dropout ที่ค่อย ๆ บ่อนทำลายการวิเคราะห์ใด ๆ ที่มองแค่ trajectory ของ creatinine อย่างเงียบ ๆ ถ้าผู้ป่วยที่แย่ที่สุดหายไปก่อน ค่า creatinine ที่เหลืออยู่ก็จะเอนเข้าหากลุ่มที่สุขภาพดี ทำให้แนวโน้มเฉลี่ยดูค่อยเป็นค่อยไปกว่าความจริงทางชีววิทยามาก joint model คือเครื่องมือที่สร้างมาเพื่อสถานการณ์นี้โดยเฉพาะ มันสร้างแบบจำลองของ creatinine ที่วัดซ้ำและเวลาจนเสียชีวิต พร้อมกัน เพื่อให้ข้อเท็จจริงของการเสียชีวิตก่อนเวลาสามารถให้ข้อมูลย้อนกลับมาบอกได้ว่า trajectory จริงของผู้ป่วยควรเป็นอย่างไร แนวคิดทั้งหมดสรุปได้ในวลีเดียวว่า likelihood เดียวสำหรับสองกระบวนการ และบทความส่วนที่เหลือจะค่อย ๆ คลี่ให้เห็นว่ามันให้อะไรกับเราบ้าง

เริ่มจากวิธี two-stage ก่อน

ก่อนจะเห็นคุณค่าว่า "joint" เปลี่ยนอะไร ลองดูวิธีที่ตรงไปตรงมาและใช้งานได้จริงถ้าไม่มี joint model นั่นคือวิธี two-stage ขั้นที่หนึ่ง fit แบบจำลองของ trajectory ของ creatinine ขั้นที่สอง ป้อน trajectory ที่ fit ได้เข้าไปใน survival model ราวกับว่ามันเป็นตัวแปรร่วมอีกตัวหนึ่ง

ขั้นที่หนึ่งคือ linear mixed model ของค่า creatinine ที่สังเกตได้ $Y_{ij}$ ของผู้ป่วย $i$ ในการตรวจครั้งที่ $j$:

$$Y_{ij} = \beta_0 + \beta_1 t_{ij} + b_{0i} + b_{1i} t_{ij} + \epsilon_{ij}$$

จากนั้นเราอ่านค่า trajectory ที่ประมาณได้ของผู้ป่วยแต่ละคนออกมา:

$$\hat m_i(t) = \hat\beta_0 + \hat\beta_1 t + \hat b_{0i} + \hat b_{1i} t$$

ขั้นที่สอง เสียบเส้นโค้งที่ประมาณได้เข้าไปใน hazard แบบ Cox โดยมี association parameter $\alpha$ เป็นตัวบอกว่าระดับ creatinine ผลักดันความเสี่ยงต่อการเสียชีวิตแรงแค่ไหน:

$$h_i(t) = h_0(t)\,\exp\{\gamma X_i + \alpha\, \hat m_i(t)\}$$

ลำดับเป็นแบบทางเดียวอย่างเคร่งครัด: creatinine model $\rightarrow \hat m_i(t) \rightarrow$ survival model คุณจำเป็นต้องมีข้อมูล creatinine ก่อนจริง ๆ และนั่นไม่ใช่เรื่องผิด ปัญหาอยู่ที่จุดที่ละเอียดกว่านั้น เมื่อขั้นที่หนึ่งเสร็จและ $\hat m_i(t)$ ถูกล็อกไว้แล้ว survival outcome ไม่มีทางย้อนกลับมาแก้ trajectory ได้อีก ถ้าการเสียชีวิตก่อนเวลาของผู้ป่วยคือสัญญาณดัง ๆ ว่า creatinine จริงของเขากำลังพุ่งเร็วกว่าที่ค่าที่วัดได้อันบางตาจะบอก วิธี two-stage ก็จะหูหนวกต่อสัญญาณนั้น เพราะ trajectory ถูกแช่แข็งไปก่อนที่การเสียชีวิตจะถูกนำมาพิจารณาด้วยซ้ำ

joint เปลี่ยนอะไรจริง ๆ

joint model ยังคงเก็บ submodel ทั้งสองไว้ แต่ปฏิเสธที่จะแช่แข็งอันแรก แทนที่จะแทนค่าด้วยเส้นโค้งที่ ประมาณได้ มันเขียน trajectory จริง ที่อยู่เบื้องล่างของผู้ป่วย

$$m_i(t) = \beta_0 + \beta_1 t + b_{0i} + b_{1i} t$$

ลงไปใน hazard โดยตรง:

$$h_i(t) = h_0(t)\,\exp\left[\gamma X_i + \alpha\left(\beta_0 + \beta_1 t + b_{0i} + b_{1i} t\right)\right]$$

ลองดูให้ดีว่าเกิดอะไรขึ้น พารามิเตอร์ชุดเดียวกันเป๊ะ — fixed effects $\beta_0, \beta_1$ และ random effects เฉพาะรายผู้ป่วย $b_{0i}, b_{1i}$ — ตอนนี้ปรากฏอยู่ใน submodel ทั้งสอง พร้อมกัน แบบจำลองสองอันจึงไม่ได้เชื่อมกันด้วยตัวเลขที่เสียบเข้าไปอีกต่อไป แต่ถูกเชื่อมแน่นเข้าด้วยกันด้วย shared latent trajectory $m_i(t)$ หรือจะพูดให้เทียบเท่ากันก็คือด้วย shared random effects $b_{0i}, b_{1i}$ เพราะพารามิเตอร์เหล่านี้ต้องทำให้ทั้งข้อมูล creatinine และข้อมูล survival พอใจไปพร้อม ๆ กัน ข้อมูลจึงไหลได้ทั้งสองทิศทาง การขยับเชิงโครงสร้างเพียงจุดเดียวนี้ — การที่ $\beta$ และ $b$ ชุดเดียวกันอยู่ในสองสมการ — คือความต่างทั้งหมดระหว่าง two-stage กับ joint

longitudinal submodel โดยละเอียด

เรามาช้าลงและอ่าน submodel แต่ละอันตามเนื้อของมันเอง เริ่มจาก longitudinal ก่อน:

$$Y_{ij} = \beta_0 + \beta_1 t_{ij} + b_{0i} + b_{1i} t_{ij} + \epsilon_{ij}$$

ทุกสัญลักษณ์มีที่ทางของมัน:

สิ่งที่เราสนใจจริง ๆ ไม่ใช่ค่าที่วัดได้ค่าใดค่าหนึ่งซึ่งมี noise ปน แต่คือ trajectory ที่อยู่เบื้องล่าง

$$m_i(t) = \beta_0 + \beta_1 t + b_{0i} + b_{1i} t$$

ซึ่งเป็นค่าประมาณที่ดีที่สุดของแบบจำลองสำหรับเส้นโค้ง creatinine จริงของผู้ป่วย หลังจากลอก measurement error ออกไปแล้ว นี่คือการมองใหม่ที่สำคัญ: $m_i(t)$ คือเส้น latent ที่ราบเรียบ ไม่ใช่จุดข้อมูล เมื่อ survival model เอื้อมไปหา "creatinine" มันเอื้อมไปหา trajectory ที่ปลอด noise อันนี้ ไม่ใช่ค่าล่าสุดดิบ ๆ

survival submodel โดยละเอียด

submodel อันที่สองคือ hazard ของเวลาจนเสียชีวิต:

$$h_i(t) = h_0(t)\,\exp\{\gamma X_i + \alpha\, m_i(t)\}$$

เครื่องหมายและขนาดของ $\alpha$ อ่านได้เหมือน log hazard ratio เป๊ะ ๆ $\alpha>0$ หมายความว่า creatinine ที่สูงขึ้นหรือแย่ลงเดินคู่ไปกับ hazard ที่สูงขึ้น เป็นรูปธรรมคือ $\alpha=\log(1.5)$ หมายความว่า creatinine เบื้องล่างที่เพิ่มขึ้น 1 mg/dL จะคูณ hazard ด้วยราว ๆ $1.5$ — เท่ากับอัตรา (hazard) การเสียชีวิตแบบทันทีสูงขึ้นประมาณ 50% ต่อการเพิ่มขึ้น 1 mg/dL ของ creatinine เบื้องล่าง ทั้งนี้ขึ้นกับหน่วยและโครงสร้างของแบบจำลอง $\alpha$ คือจุดที่เรื่องเล่าทางคลินิกว่า "ไตวายฆ่าคน" ได้ตัวเลขติดตัวมาในที่สุด

likelihood เดียว ไม่ใช่สองขั้น

ทีนี้มาถึงวลีที่เป็นชื่อบทความ ในโลกของ two-stage มีปัญหา optimisation แยกกันสองปัญหาจริง ๆ ที่ทำเรียงตามลำดับ:

$$\hat\beta,\hat b = \arg\max L_{\text{long}}$$ $$\hat\alpha,\hat\gamma=\arg\max L_{\text{surv}}(\hat\beta,\hat b)$$

ค่าประมาณ longitudinal ถูกหาก่อนและถูกล็อก จากนั้นค่อย maximise survival likelihood โดยรับ $\hat\beta,\hat b$ เป็น input ที่ตายตัวและขยับไม่ได้ ข้อมูล survival ไม่เคยได้ออกเสียงเรื่อง trajectory เลย

joint model ยุบสองปัญหานั้นให้เหลือ likelihood เดียว ที่ข้อมูลทั้งสองชนิดต้องทำให้พอใจไปพร้อมกัน:

$$L_{\text{joint}} = \prod_i \int L_{\text{long},i}\, L_{\text{surv},i}\, f(b_i)\, db_i$$

เขียนขยายให้เห็นส่วนประกอบทุกตัว:

$$L_{\text{joint}} = \prod_i \int p(Y_i\mid b_i,\beta,\sigma)\; p(T_i,\delta_i\mid b_i,\beta,\gamma,\alpha)\; p(b_i\mid D)\, db_i$$

ในที่นี้ $Y_i$ คือชุดค่า creatinine ทั้งหมด, $T_i$ คือเวลาของ event หรือ censoring, $\delta_i$ คือ event indicator, $b_i$ คือ random effects, $\beta$ คือพารามิเตอร์ของ trajectory, $\sigma$ คือ ส่วนเบี่ยงเบนมาตรฐานของ measurement error, $\alpha$ คือ association ระหว่าง trajectory กับ event, $\gamma$ คือผลของ survival predictors และ $D$ คือ covariance ของ random effects อินทิกรัลบน $b_i$ คือสิ่งที่เย็บ likelihood สองอันเข้าด้วยกัน เพราะ $p(Y_i\mid b_i,\beta)$ และ $p(T_i,\delta_i\mid b_i,\beta,\gamma,\alpha)$ ใช้ $b_i$ ตัวเดียวกัน (และบ่อยครั้งใช้ $\beta$ ตัวเดียวกัน) การ maximise joint likelihood จึงบังคับให้ทุกพารามิเตอร์ fit ข้อมูลทั้งสองชนิดในคราวเดียว

คำว่า "simultaneous" ไม่ได้แปลว่า "คำนวณเสร็จในชั่วพริบตาเดียว" กลไกจริงเป็นแบบวนซ้ำ — ลูปแบบ EM หรือ Newton ที่เริ่มจากค่าประมาณหยาบ ๆ ใช้ข้อมูล creatinine ปรับ trajectory ใช้ข้อมูลการเสียชีวิตและ censoring ตรวจว่า trajectory นั้นสอดคล้องกับคนที่เสียชีวิตจริงหรือไม่ แล้วปรับ $b_i, \beta, \alpha, \gamma$ และทำซ้ำจนกว่า joint likelihood จะหยุดดีขึ้น มันไม่ได้ขนานกัน แต่มันเป็น joint เพราะพารามิเตอร์ที่ออกมาคือชุดที่อธิบายข้อมูลทั้งสองสายได้ดีที่สุดไปพร้อมกัน ไม่ใช่ทำอันหนึ่งแล้วค่อยทำอีกอัน

ข้อมูล event ป้อนกลับเข้าไปแก้ trajectory อย่างไร

การป้อนกลับนี้สัมผัสได้ง่ายที่สุดผ่านผู้ป่วยสมมติสองคนที่ค่า creatinine ที่ วัดได้ เหมือนกันทุกประการ (ตัวเลขเพื่อการอธิบายเท่านั้น):

เวลา ผู้ป่วย A (mg/dL) ผู้ป่วย B (mg/dL)
เดือนที่ 0 1.2 1.2
เดือนที่ 1 1.5 1.5
เดือนที่ 2 1.8 1.8

ถ้าดูจากตัวเลขที่บันทึกไว้ A กับ B แยกจากกันไม่ออกเลย แต่ ผู้ป่วย A เสียชีวิตที่เดือนที่ 3 ในขณะที่ ผู้ป่วย B รอดถึงเดือนที่ 12 การวิเคราะห์แบบ longitudinal อย่างเดียวจะประมาณ trajectory ของทั้งคู่ออกมาเกือบเหมือนกัน เพราะมันเห็นแค่ค่าวัดสามค่าที่ตรงกัน แต่ joint model รู้มากกว่านั้น: trajectory ที่แย่ลงย่อมมี hazard สูงขึ้น ดังนั้นการเสียชีวิตก่อนเวลาของ A จึงเป็น หลักฐานเพิ่มเติม เกี่ยวกับ latent trajectory ของ A — หลักฐานที่บอกว่า creatinine จริงของ A น่าจะกำลังพุ่งชันกว่าที่จุดสามจุดนั้นตามลำพังจะบอกได้ การเสียชีวิตไม่ได้ผลิตค่า creatinine ใหม่ขึ้นมา แต่มันบอกแบบจำลองว่าในบรรดา trajectory หลาย ๆ เส้นที่เข้ากันได้กับจุดสามจุดนั้น เส้นไหนสอดคล้องกับข้อมูล ทั้งหมด ของผู้ป่วยมากที่สุด

กลไกนี้เห็นได้ในบรรทัดความน่าจะเป็นเพียงบรรทัดเดียว เมื่อมีแต่ข้อมูล longitudinal random effects ของผู้ป่วยถูกกำหนดด้วย creatinine เพียงอย่างเดียว:

$$p(b_i\mid Y_i) \propto p(Y_i\mid b_i)\,p(b_i)$$

ใน joint model ข้อมูล event เข้ามาอยู่ใน posterior เดียวกัน:

$$p(b_i\mid Y_i,T_i,\delta_i) \propto p(Y_i\mid b_i)\,p(T_i,\delta_i\mid b_i)\,p(b_i)$$

ตอนนี้ random effects ขึ้นกับทั้ง $Y_i$ และ $(T_i,\delta_i)$: เวลาของการเกิด event ปรับรูป trajectory ที่ประมาณได้โดยตรง นี่คือสิ่งที่ทำให้ joint model เป็นอะไรที่มากกว่า "แบบจำลองสองอันที่ train บนชุดข้อมูลเดียวกัน" อย่างแท้จริง — เทอม event $p(T_i,\delta_i\mid b_i)$ กำลังทำงานจริงอยู่ภายในค่าประมาณของ $b_i$

ประโยคที่ว่า "trajectory ขับเคลื่อน hazard" ทำให้ชัดเจนได้มากกว่าหนึ่งวิธี การเลือก association structure เป็นการตัดสินใจเชิงแบบจำลอง และสามทางเลือกมาตรฐานตอบคำถามทางคลินิกที่ต่างกันเล็กน้อย

Current value. ความเสี่ยงขึ้นกับตำแหน่งที่ trajectory อยู่ ณ ตอนนี้:

$$h_i(t)=h_0(t)\exp\{\gamma X_i + \alpha\, m_i(t)\}$$

Current slope. ความเสี่ยงขึ้นกับทั้งระดับและความเร็วในการเปลี่ยนแปลง:

$$h_i(t)=h_0(t)\exp\{\gamma X_i + \alpha_1 m_i(t) + \alpha_2 m_i'(t)\}$$

โดยที่ $m_i'(t)=dm_i(t)/dt$ นี่คือโครงสร้างที่แยกผู้ป่วยสองคนซึ่งมี creatinine ปัจจุบันเท่ากัน แต่เส้นโค้งชี้ไปคนละทิศ: คนที่ระดับกำลังพุ่งเร็วมีความเสี่ยงสูงกว่าคนที่ระดับราบนิ่ง แม้ ณ ขณะนี้ทั้งคู่จะอ่านได้ตัวเลขเดียวกันเป๊ะ

Shared random effects. การเชื่อมพุ่งตรงผ่าน intercept และ slope รายบุคคล:

$$h_i(t)=h_0(t)\exp\{\gamma X_i + \alpha_0 b_{0i} + \alpha_1 b_{1i}\}$$

ในที่นี้ลักษณะ latent ของผู้ป่วย — ว่าเขาเริ่มต้นที่ไหนและกำลังมุ่งไปชันแค่ไหน — ป้อนเข้า hazard โดยตรง โดยไม่ต้องผ่าน $m_i(t)$ เป็นตัวกลาง

alpha คือความแข็งแรงของการเชื่อม

กลไกทั้งหมดนี้แขวนอยู่บนพารามิเตอร์ตัวเดียว ลองถามว่าจะเกิดอะไรขึ้นถ้า survival model ตัด trajectory ทิ้งไปทั้งหมด — เอา $m_i(t)$ และ $b_i$ ออกจาก hazard แล้วคุณจะเหลือ

$$h_i(t)=h_0(t)\exp\{\gamma X_i\}$$

และ joint likelihood ก็จะแยกตัวประกอบออกจากกันง่าย ๆ:

$$L_{\text{joint}} = L_{\text{long}}\times L_{\text{surv}}$$

เมื่อไม่มีพารามิเตอร์ร่วม สองซีกก็แยกออกจากกันเป็นแบบจำลองต่างหาก — มันไม่ใช่ joint model อีกต่อไปเลย สิ่งเดียวกันนี้เกิดขึ้นทันทีที่คุณตั้ง $\alpha=0$: trajectory ของ creatinine หยุดเกี่ยวข้องกับ hazard และสองกระบวนการก็หลุดออกจากกัน ดังนั้น $\alpha$ จึงไม่ใช่แค่สัมประสิทธิ์อีกตัวหนึ่ง แต่เป็นบานพับที่โครงสร้างทั้งหมดหมุนอยู่บนมัน:

$$\boxed{\alpha \text{ is the parameter that measures the strength of the join.}}$$

ทำไมมันถึงสำคัญ

กลับไปที่จุดเริ่มต้น ผู้ป่วยที่ป่วยหนักมาก creatinine พุ่งเร็วและเสียชีวิตเร็ว หลังเสียชีวิตก็ไม่มีค่า creatinine อีกต่อไป การขาดหายจึงไม่ใช่แบบสุ่มอย่างชัดเจน (not random) — เพราะการเสียชีวิตเป็น terminal event ตัว trajectory ไม่ได้เพียงแค่ไม่ถูกสังเกต แต่หยุดมีอยู่จริง ซึ่งเป็นเหตุผลว่าทำไม event time จึงให้ข้อมูลเกี่ยวกับ latent path จนถึงเวลาเสียชีวิตได้มากนัก การวิเคราะห์แบบ longitudinal อย่างเดียวเสียผู้ป่วยที่แย่ที่สุดไปก่อน และเมื่อขาดค่าที่ชันที่สุดของพวกเขา ก็รายงานแนวโน้ม creatinine ที่ดูดีกว่าความจริง joint model ปฏิเสธ bias นั้น: มันใช้ ทั้ง การเปลี่ยนแปลงของ creatinine และเวลาของการเสียชีวิต ประมาณสองกระบวนการจาก likelihood เดียว การเสียชีวิตก่อนเวลาจึงถูกนับเป็นข้อมูลเกี่ยวกับ trajectory แทนที่จะหายไปเงียบ ๆ จากมัน

วิธีที่สะอาดที่สุดในการเก็บความต่างนี้ไว้ในหัวคือภาพลูกศรคู่หนึ่ง two-stage เป็น pipeline คือ $Y \rightarrow \hat m_i(t) \rightarrow T$: fit creatinine ก่อน แล้วดันค่าประมาณลงไปตามน้ำ ส่วน joint model เป็นสาเหตุร่วม คือ $Y_i \leftarrow m_i(t) \rightarrow T_i$ หรือจะพูดให้เทียบเท่ากันก็คือ $\boxed{Y_i \leftarrow b_i \rightarrow T_i}$ — latent trajectory และ random effects ชุดเดียวกันอธิบายทั้ง creatinine ที่สังเกตได้และเวลาของ event joint model ไม่เคยอ้างว่าคุณไม่ต้องมี creatinine ก่อน มันอ้างว่าคุณไม่ควร ล็อก creatinine model ก่อน survival model แต่ควรปล่อยให้ข้อมูลทั้งสองแหล่งร่วมกันกำหนด trajectory, random effects และ association ในการประมาณครั้งเดียว

ประเด็นสำคัญ

0
ถึงนักอ่านชาวไทยและต่างชาติทำความเข้าใจบริบททางการแพทย์ของผมอ่านต่อ →ถึงนักอ่านชาวไทยและต่างชาติทำความเข้าใจเนื้อหาของผมที่นอกเหนือจากการแพทย์อ่านต่อ →

ความคิดเห็น

ยังไม่มีความคิดเห็น มาเป็นคนแรกกันเลย

เข้าสู่ระบบเพื่อแสดงความคิดเห็น