ลองนำไฟล์ฐานข้อมูล ICD-10-TM จาก THCC มาต่อยอดให้เหมาะกับโปรแกรมคอมมากขึ้น

เรื่องนี้เริ่มจากผมต้องการทำการสรุปสถิติผู้มารับบริการที่โรงพยาบาล ทุกวันนี้เจ้าหน้าที่ coder ของรพ.ก็ทำการลงรหัส ICD-10 อยู่แล้ว แต่พอนำข้อมูลมาดูจริง ๆ ผมพบว่าข้อมูล ICD-10 ที่รพ.เราใช้อยู่นั้นไม่น่าจะมีความถูกต้อง คือตัวรหัสนั้นอาจจะถูก แต่ term ไม่น่าจะถูก รวมถึงมีการสะกดผิดอยู่เยอะพอสมควร ผมจึงรู้สึกว่าฐานข้อมูลนี้ไม่น่าจะใช้ได้แล้ว ก็เลยต้องหาฐานข้อมูล ICD-10 มาทดแทน

แน่นอนว่าเมื่อจะหาข้อมูลแนวนี้ ก็ต้องเริ่มจากภาครัฐสักแห่ง ค้นไปค้นมาพบว่าทางศูนย์มาตรฐานรหัสและข้อมูลสุขภาพแห่งชาติ (Thai Health Coding Center – THCC) มีการแจกฐานข้อมูล ICD-10 ฉบับ TM (Thai Modification) หรือ ICD-10-TM เวอร์ชั่นปี 2016 ในรูปแบบไฟล์ Excel ที่ในเว็บของเขาครับ ก็เลยลองโหลดมาดูครับ หลังโหลดมาแล้ว ค้นพบว่าไฟล์ดังกล่าวมีความสมบูรณ์น่าประทับใจแล้วครับ (ผมชอบมากที่เขาไม่ให้มี code การปวด Low back pain ระดับคอ ซึ่งมันเป็นไปไม่ได้ไงครับ แต่ฐานข้อมูล ICD-10 ก็ชอบใส่กันมา เพราะมันเป็นผลมาจากการ cross join) แต่มีบางจุดที่อาจยังไม่ตอบโจทย์ผมนัก

ก็เลยพยายามลองหาจากแหล่งอื่น จริง ๆ ในไทยมีคนพยายามทำ ICD-10 browser อยู่ 2-3 แห่งนะครับ แต่ผมก็ไม่มั่นใจในความถูกต้องของข้อมูล สุดท้ายแล้วเลยคิดว่าใช้ของ THCC น่าจะดีที่สุด ก็เลยลองนำไฟล์ดังกล่าวมาต่อยอดครับ ส่วนจุดที่เป็นสาเหตุที่ผมบอกว่ามีบางจุดยังไม่ตอบโจทย์นัก เนื่องจากเหตุผลดังต่อไปนี้ครับ


รวมจุดที่คิดว่าเป็นปัญหาในไฟล์

1) ส่วนที่เป็น Term หลายคำไม่สามารถค้นหาได้โดยง่ายจากระบบคอมพิวเตอร์

อันนี้เป็นเหตุผลหลักเลยที่ทำให้ผมต้องลงมือปรับไฟล์​ ICD-10-TM ชุดนี้ครับ ขอยกตัวอย่างโรคกลุ่มมะเร็งนะครับ จากในไฟล์ใช้ term ว่า "C18.0 caecum" ซึ่งจริง ๆ เป็น term ที่ถูกต้องตามหนังสือแล้วครับ แต่ในหนังสือมันมีกลุ่มรหัสกำกับไงครับ ("C18 Malignant neoplasm of colon") ทำให้เราทราบว่ารหัส C18.0 นี้คือ CA colon ส่วน caecum นะ แต่พอมาอยู่ในระบบคอมพิวเตอร์มันไม่เป็นแบบนั้นไงครับ

ลองนึกภาพครับว่าเราเป็นแพทย์หรือเจ้าหน้าที่ coder ที่ต้องทำการคีย์ข้อมูล ICD-10-TM ดังกล่าวโดยการพิมพ์ term ลงในช่องค้นหา ถึงแม้เราจะพิมพ์ "Malignant neoplasm of colon", "neoplasm of colon", "CA colon", "colon cancer" หรือพิมพ์อะไรก็ตาม ระบบไม่มีทาง filter เอากลุ่มรหัสโรคของ CA colon มาได้เลย (เว้นเสียแต่ว่าระบบการค้นหา term จะไม่ใช่ filter ธรรมดาแต่มีการใช้ relation lookup บางอย่างช่วยหา ซึ่งระบบในไทยส่วนใหญ่ไม่ได้เป็นแบบนั้น)

หรือถึงเราจะรู้ว่าเป็น CA caecum เราพิมพ์ "Caecum" ลงไปในช่องค้นหา ได้ C18.0 Caecum ออกมา เราก็ไม่รู้อยู่ดีว่ารหัสนี้คือ CA caecum จริง ๆ หรือเปล่า มีทางเดียวเท่านั้นที่จะแน่ใจได้ว่าทำถูกก็คือเปิดหนังสืออ้างอิงไปด้วย ซึ่งการทำแบบนั้นก็เป็นการใช้ประโยชน์จากระบบคอมพิวเตอร์ไม่ได้เต็มที่

วิธีการที่จะทำให้ระบบคอมพิวเตอร์ที่ใช้การ filter อย่างง่าย ๆ หาเจอ จริง ๆ คือควรระบุเป็น "C18.0 Malignant neoplasm of colon: Caecum" เป็นต้นครับ

2) ในไฟล์นำมาแต่รหัสที่อนุญาตให้ใช้ แต่ข้อมูลอย่างอื่นจริง ๆ ก็มีประโยชน์

ในไฟล์ไม่มี "C18 Malignant neoplasm of colon" เพราะว่า C18 เป็นรหัสระดับกลุ่มซึ่งมีสมาชิกกลุ่ม ดังนั้นจึงเป็นรหัสที่งดใช้ (เป็นกล่องสีดำในหนังสือ) แต่รหัสนี้ แม้ไม่ให้คีย์แต่ก็ใช้ประโยชน์ได้ เช่นกรณีข้างต้น หากว่าค้นหาเจอ "C18 Malignant neoplasm of colon" อยู่ข้างบนของ "C18.0 Caecum" เราก็อาจจะพอเดาได้ว่า C18.0 นี่มันก็ CA colon ที่เราต้องการนี่แหละ

ไม่เพียงแต่รหัสที่เป็นรหัสกลุ่มเท่านั้น ข้อมูล Chapter, Block, Group สิ่งเหล่านี้ล้วนมีประโยชน์ต่อการไปวิเคราะห์ข้อมูลต่อ เช่น เราอยากทราบว่าสรุปรพ.ของเรามีผู้ป่วยมะเร็งกี่คน แทนที่เราจะมานั่งหาทีละรหัสแล้วรวมผล เราก็สามารถเลือกดูเป็น block แล้ว drill-down ต่อเป็นระดับ group จนถึงระดับรหัสได้เลย

ภาพจากโปรแกรม Power BI แสดงการ drill-down ดูคนไข้กลุ่ม Malignant

3) Format ที่เลือกใช้ในกลุ่มรหัสที่มีกลุ่มย่อย สามารถทำให้ความหมายชัดเจนกว่านี้ได้

ข้อนี้ผมว่าหลายท่านอาจไม่เห็นด้วยกับผม แต่สำหรับผมผมว่ามันชัดเจนกว่าถ้าทำแบบนี้ครับ

ลองดูตัวอย่างนี้ครับ "V79.64 Unspecified bus occupant injured in collision with other and unspecified motor vehicles in traffic accident While resting, sleeping, eating or engaging in other vital activities" ซึ่งจริง ๆ เป็น term ที่เกิดจากการรวมร่างกันของ 3 term คือ รหัสหลัก: "V79 Bus occupant injured in other and unspecified transport accidents" ประกอบร่างกับกลุ่มย่อย: ".6 unspecified bus occupant injured in traffic accident" และ ".4 while resting, sleeping, eating or engaging in other vital activities” แต่จะเห็นได้ว่าพอมารวมกันแล้วนั้นอ่านไม่ค่อยรู้เรื่องครับ

ผมว่าทางที่ดีกว่าคือการแยกส่วนให้ชัดเจนว่า term นี้ประกอบด้วย 3 ส่วน เป็น "V79.64 Bus occupant injured in other and unspecified transport accident: unspecified bus occupant injured in traffic accident: while resting, sleeping, eating or engaging in other vital activities" รวมกันตรง ๆ เลย ไม่ต้องพยายามเชื่อมให้เป็นคำเดียวกัน ไม่ต้องสลับเอาผู้บาดเจ็บมาอยู่หน้า (แม้ว่าจะทำให้สั้นลง) และเลือกใช้อักขระที่ไม่ใช่ “,” ในการเชื่อม term เพราะ “,” นั้นใช้บ่อยมากใน term ต่าง ๆ ทำให้เกิดปัญหาสองประการ

  1. เราต้องใช้ความคิดมากขึ้นว่า “,” ไหนกันแน่ใช้แบ่ง term
  2. เราไม่สามารถใช้โปรแกรม split ด้วย delimiter (เช่น Excel) โดยใช้ “,” ได้ เพราะมันจะไปโดนตัวที่เราไม่ต้องการ ใช้การแบ่งโดยตัวสุดท้ายก็ไม่ได้ เพราะ term ของกลุ่มย่อยบางกลุ่มก็มี “,” ข้างในอีก สรุป logic การ split มันจะซับซ้อนมากครับ แต่ถ้าใช้ “:” ก็เสร็จได้แบบง่าย ๆ เลย ถามว่าแล้วจะ split ไปทำไม เพราะเราอาจจะทำ UX แบบอื่นที่ง่ายกว่านี้ได้ครับ เดี๋ยวกล่าวถึงตอนท้าย ๆ ครับ

ประเด็นนี้เป็นปัญหาในหมวดอื่นเช่นกันนะครับ เช่น "M7900 Rheumatism, unspecified Multiple sites" อันนี้ไม่มีบอกเลยว่าแบ่งตรงก่อนคำว่า Multiple ผมว่าถ้าเขียนเป็น "M7900 Rheumatism, unspecified: multiple sites" แบบนี้ก็ชัดเจนกว่าครับ


วิธีการที่ผมใช้สร้างฐานข้อมูลชุดใหม่

1) คัดลอก ICD-10 มาจากเว็บของหน่วยราชการแห่งหนึ่ง

เนื่องจากไม่สามารถหา Official ICD-10 ที่คิดว่าน่าจะทำไปใช้งานได้เลยโดยไม่ต้องทำอะไร ตอนนั้นจริง ๆ ก็ไม่รู้จะเอาไงต่อเหมือนกันครับ พอดีมีคนแนะนำให้ลองไปดูในเว็บของหน่วยงานแห่งหนึ่งซึ่งน่าเชื่อถือพอสมควร (ขออนุญาตไม่เปิดเผยนะครับ) เขาก็มีฐานข้อมูล ICD-10 เช่นกัน ก็เลยก็อปของเขามาครับ ตอนแรกนึกว่าจะเสร็จแล้ว แต่เปล่า ไฟล์นี้ก็มีปัญหามากเหมือนกัน

2) นำไฟล์ที่โหลดมามาเพิ่มรหัสพวกที่เป็นกลุ่มรหัสเข้าไป แล้วระบุไว้ว่าพวกนี้คือ heading

รหัสและ term ที่ใช้อิงตามหนังสือ ICD-10-TM

3) นำรหัสในไฟล์ที่โหลดมามาเชื่อมโยงกับรหัสที่อยู่ในไฟล์ Excel ของ THCC

อันไหนที่ THCC ไม่มีก็จะระบุไว้ว่าเป็น FALSE ส่วนอันไหนที่มีใน Excel ของ THCC ก็จะระบุว่าเป็น TRUE ในทางตรงกันข้าม ถ้ามีรหัสไหนที่ THCC มี แต่ในไฟล์ไม่มี ก็นำมาเพิ่มเข้าไป การดำเนินการตามขั้นนี้ทำให้รหัสที่เคยเป็น HEADING (รหัสกลุ่ม) ที่ไม่มีสมาชิกกลุ่มกลายเป็นค่า TRUE (เพราะยัง valid และอยู่ในไฟล์ของ THCC)

เท่ากับว่ารหัสที่ใช้งานจริง ก็จะมีแค่รหัสที่อยู่ในไฟล์ Excel ของ THCC เท่านั้น ส่วนรหัส HEADING เอาไว้ใช้ประโยชน์ในแง่การทำข้อมูลเฉย ๆ ส่วนรหัสที่เป็น FALSE จริง ๆ ก็ลบไปเลยก็ได้ครับ แต่ผมก็ใส่ไว้ไปก่อน

4) ทำการเพิ่มข้อมูล Chapter, Block, Group เข้าไป

โดยอิงตามหนังสือ ICD-10-TM เช่นกัน อันไหนไม่มี hierarchy ลงไปถึงระดับ Block หรือ Group ก็เว้นว่างไว้ ผมเลือกเอา text มาลงเลย เพราะไม่อยากต้องทำอีก table นึงเป็น lookup table นะครับ แต่คิดว่าใครอยากทำก็คงแปลงไปเป็นแบบนั้นไม่ยาก

5) ทำการสร้างพวก term หมวดการบาดเจ็บและหมวด musculoskeletal ที่มีรหัสย่อย

โดยการ cross join ของโรคและรหัสย่อยทั้งหมด แล้วขั้นระหว่าง term ด้วย “:” เพื่อให้เป็นรูปแบบเดียวกัน และแก้ปัญหาอ่านเข้าใจยากที่ผมอธิบายข้างต้น หากท่านใดไม่ชอบแนวนี้ หรือเห็นว่าไม่ official สามารถนำ term ในไฟล์ Excel ของ THCC อันเดิมมา replace ได้ครับ

6) ตรวจสอบความถูกต้อง และปรับปรุงข้อมูลให้ทันสมัย

โดยการเช็คพวก term ที่เป็น duplicate จากนั้นโหลดพวกสไลด์สอนเพิ่มเติมมาจาก THCC แล้วดูว่า code ไหนที่เขายกเลิกแล้ว ก็ใส่เป็น FALSE ไป

สุดท้ายแล้วออกมาหน้าตาประมาณนี้ครับ ผมใส่ Excel ของ THCC เข้าไปด้วยใน sheet ที่สองนะครับ


สำหรับท่านที่ต้องการดาวน์โหลดสามารถคลิกลิงค์นี้ได้เลยครับ

Download

หากดาวน์โหลดแล้วพบข้อผิดพลาดประการใดก็คอมเมนต์หรือส่ง pull request เข้ามาได้นะครับ หรือท่านใดจะนำไปต่อยอดเพิ่มเติมก็ยินดีเป็นอย่างยิ่งครับ หรือหากหน่วยงานรัฐอยากให้ยุติการแจกก็บอกผมได้นะครับ

ขอบคุณครับ


เสริม: User Interface ของระบบหา ICD-10 ที่ดีกว่าที่เป็นอยู่

ต้องยอมรับว่าพวกรหัสที่มีรหัสย่อยนี่ ผมว่าจะปรับยังไงคำยาว ๆ ก็อ่านยากเหมือนเดิม วิธีที่ดีกว่าน่าจะทำให้ term สั้นเหมือนเดิม แต่ไปเปลี่ยนที่โปรแกรมแทนครับ ซึ่งผมว่าแบบทำง่ายมีสองแนวครับ คือ 1) ทำเป็น multi-step select หรือ 2) ทำเป็น dropdown แบบมี hierarchy ส่วนแบบทำยากก็ต้องไปสาย AI เหมือน Google search น่ะครับ ที่แสดงผลตามสิ่งที่เราน่าจะต้องการ ซึ่งขอกล่าวถึงเฉพาะแบบทำง่ายนะครับ

Multi-step select ก็คือ กดครั้งนึงเพื่อเลือกหัวข้อ กดอีกครั้งเพื่อเลือก item ย่อย กดไปเรื่อย ๆ จนเจอสิ่งที่ต้องการ อันนี้จะอ่านง่าย dropdown list ไม่ยาว แต่ข้อเสียคือคลิกหลายครั้ง

ถ้าเป็นแบบ dropdown แบบมี hierarchy ก็จะเป็นประมาณในภาพที่สองครับ ข้อสำคัญคือเวลาฟิลเตอร์ถ้าจะเอารหัสลูกมาต้องเอารหัสกลุ่มมาด้วย ไม่งั้นก็จะเกิดปัญหาอ่านไม่เข้าใจดังที่กล่าวไปข้างต้น ข้อเสียของวิธีนี้คือผมว่าเลือกยากกว่าวิธีแรกนะครับ แต่ข้อดีคือคลิกครั้งเดียวได้เลยไม่ต้องหลายคลิก

ก็เสนอเป็นไอเดียไว้ครับ เผื่อนักพัฒนาซอฟต์แวร์ท่านใดนำไป implement

ขอเกริ่นสายทำยากไว้นิดนึงครับ ถ้าใช้ AI เข้ามาช่วย เราอาจสามารถพิมพ์ “คนขับรถบัสขับรถชนรถเก๋ง ผู้โดยสารบาดเจ็บ ขณะนั่งรถไปทำงาน” แล้วระบบ natural language processing ก็แปลงเป็นรหัส ICD-10 ที่ถูกต้องให้เองเลยครับ หรือไม่ก็เราพิมพ์แค่ “Bus occupant” ระบบ recommendation ก็แนะนำรหัสที่เราน่าจะเลือกมาให้เลย อิงจากข้อมูลอื่น ๆ ที่เราเคย train model ไว้ เป็นต้นครับ

ก็จบครับสำหรับ blog นี้

Comments

  1. กรณีcodeที่มี * ต่อท้ายเพื่อบอกให้ทราบว่าจะต้องไปหาcodeขยาย เช่น G02.1* Meningitis in mycoses ซึ่งจะต้องไปหาcodeชื่อเชื้อรามาต่อท้าย แต่ในไฟล์ที่download ไม่มีเครื่องหมาย*ต่อท้าย
    ขอความกรุณาช่วยอธิบายครับ
    ขอบคุณครับ
    นพ.วรวิทย์ กิตติภูมิ

    1. สวัสดีครับอาจารย์ น่าจะเพราะ source ต้นทางที่ผมเอามาไม่ได้ใส่ไว้ครับ อย่างไรก็ดี บทความนี้ก็ค่อนข้างเก่ามากแล้ว หากมีโอกาสเดี๋ยวผมทบทวนใหม่ครับ ขอบคุณที่แจ้งปัญหานะครับ

Leave a Reply

Your email address will not be published. Required fields are marked *