RETAIN เป็นแบบจำลองการคาดการณ์ที่สามารถตีความได้สำหรับการใช้งานด้านการดูแลสุขภาพ จากบันทึกผู้ป่วย ทำให้สามารถคาดการณ์ในขณะที่อธิบายว่ารหัสทางการแพทย์แต่ละรหัส (รหัสการวินิจฉัย รหัสยา หรือรหัสขั้นตอน) ในการนัดตรวจแต่ละครั้งมีส่วนช่วยในการทำนายอย่างไร การตีความเป็นไปได้เนื่องจากการใช้กลไกความสนใจของระบบประสาท
เมื่อใช้ RETAIN คุณสามารถคำนวณได้ว่ารหัสทางการแพทย์แต่ละรหัส (การวินิจฉัย ยา หรือรหัสขั้นตอน) ในการนัดตรวจที่แตกต่างกันมีส่วนทำให้เกิดคะแนนสุดท้ายในเชิงบวก/เชิงลบอย่างไร ในกรณีนี้ เรากำลังคาดการณ์ว่าผู้ป่วยจะได้รับการวินิจฉัยว่าเป็นภาวะหัวใจล้มเหลว (HF) หรือไม่ คุณจะเห็นว่ารหัสที่เกี่ยวข้องอย่างมากกับ HF นั้นมีส่วนสนับสนุนในเชิงบวก RETAIN ยังเรียนรู้ที่จะให้ความสำคัญกับข้อมูลใหม่มากกว่าข้อมูลเก่า คุณจะเห็นว่าภาวะหัวใจเต้นผิดจังหวะ (CD) มีส่วนช่วยมากขึ้นเมื่อเกิดขึ้นในการนัดตรวจครั้งล่าสุด
RETAIN ใช้อัลกอริทึมที่แนะนำในเอกสารต่อไปนี้:
RETAIN: An Interpretable Predictive Model for Healthcare using Reverse Time Attention Mechanism
Edward Choi, Mohammad Taha Bahadori, Joshua A. Kulas, Andy Schuetz, Walter F. Stewart, Jimeng Sun,
NIPS 2016, pp.3504-3512
เอกสาร RETAIN จะกำหนดแบบจำลองว่าสามารถคาดการณ์ในแต่ละช่วงเวลาได้ (เช่น พยายามคาดการณ์ว่าผู้ป่วยจะได้รับการวินิจฉัยแบบใดในการนัดตรวจแต่ละครั้ง) และดำเนินการจำแนกลำดับ (เช่น จากบันทึกผู้ป่วย เขาจะได้รับการวินิจฉัยว่าเป็นภาวะหัวใจล้มเหลวใน อนาคต?) เป็นกรณีพิเศษ เนื่องจากการจำแนกลำดับจะทำให้การทำนายในช่วงเวลาสุดท้ายเท่านั้น
อย่างไรก็ตาม รหัสนี้ถูกนำมาใช้เพื่อดำเนินงานการจำแนกลำดับ ตัวอย่างเช่น คุณสามารถใช้รหัสนี้เพื่อคาดการณ์ว่าผู้ป่วยที่ระบุเป็นผู้ป่วยภาวะหัวใจล้มเหลวหรือไม่ หรือคุณสามารถคาดเดาได้ว่าผู้ป่วยรายนี้จะกลับเข้ามาใหม่ในอนาคตหรือไม่ RETAIN เวอร์ชันทั่วไปเพิ่มเติมจะเปิดตัวในอนาคต
ขั้นตอนที่ 1: การติดตั้ง
ติดตั้ง python, Theano เราใช้ Python 2.7, Theano 0.8 Theano สามารถติดตั้งได้อย่างง่ายดายใน Ubuntu ตามที่แนะนำที่นี่
หากคุณวางแผนที่จะใช้การคำนวณ GPU ให้ติดตั้ง CUDA
ดาวน์โหลด/โคลนรหัส RETAIN
ขั้นตอนที่ 2: วิธีที่รวดเร็วในการทดสอบ RETAIN ด้วย MIMIC-III
ขั้นตอนนี้อธิบายวิธีการฝึกอบรม RETAIN ด้วยจำนวนขั้นตอนขั้นต่ำโดยใช้ MIMIC-III เพื่อคาดการณ์การเสียชีวิตของผู้ป่วยโดยใช้บันทึกการนัดตรวจ
ก่อนอื่นคุณจะต้องขอสิทธิ์เข้าถึง MIMIC-III ซึ่งเป็นบันทึกสุขภาพอิเล็กทรอนิกส์ที่เปิดเผยต่อสาธารณะซึ่งรวบรวมจากผู้ป่วย ICU ในช่วง 11 ปี
คุณสามารถใช้ "process_mimic.py" เพื่อประมวลผลชุดข้อมูล MIMIC-III และสร้างชุดข้อมูลการฝึกอบรมที่เหมาะสมสำหรับ RETAIN วางสคริปต์ในตำแหน่งเดียวกับที่มีไฟล์ CSV MIMIC-III และเรียกใช้สคริปต์ คำสั่งดำเนินการคือ python process_mimic.py ADMISSIONS.csv DIAGNOSES_ICD.csv PATIENTS.csv <output file>
เรียกใช้ RETAIN โดยใช้ไฟล์ ".seqs" และ ".morts" ที่สร้างโดย process_mimic.py ไฟล์ ".seqs" มีลำดับการนัดตรวจของผู้ป่วยแต่ละราย การนัดตรวจแต่ละครั้งประกอบด้วยรหัสวินิจฉัยหลายรหัส อย่างไรก็ตาม เราขอแนะนำให้ใช้ไฟล์ ".3digitICD9.seqs" แทน เนื่องจากผลลัพธ์จะสามารถตีความได้ง่ายกว่ามาก (หรือคุณอาจใช้ซอฟต์แวร์จำแนกประเภทคลิคัลระดับเดียวสำหรับ ICD9 เพื่อลดจำนวนรหัสให้เหลือสองสามร้อยรหัส ซึ่งจะปรับปรุงประสิทธิภาพให้ดียิ่งขึ้นไปอีก) ไฟล์ ".morts" มีลำดับป้ายกำกับการเสียชีวิตสำหรับผู้ป่วยแต่ละราย คำสั่งคือ python retain.py <3digitICD9.seqs file> 942 <morts file> <output path> --simple_load --n_epochs 100 --keep_prob_context 0.8 --keep_prob_emb 0.5
942
คือจำนวนของรหัส ICD9 3 หลักทั้งหมดที่ใช้ในชุดข้อมูล
หากต้องการทดสอบแบบจำลองสำหรับการตีความ โปรดดูขั้นตอนที่ 6 โดยส่วนตัวแล้วฉันพบว่า โรคดีซ่านปริกำเนิด (ICD9 774) มีความสัมพันธ์กับการเสียชีวิตสูง
แบบจำลองถึง AUC ที่สูงกว่า 0.8 ด้วยคำสั่งข้างต้น แต่การตีความยังไม่ชัดเจนนัก คุณสามารถปรับแต่งไฮเปอร์พารามิเตอร์ได้ แต่ฉันสงสัยว่าสิ่งต่างๆ จะดีขึ้นอย่างมาก ท้ายที่สุด มีผู้ป่วยเพียง 7,500 รายที่เข้ารับการรักษาในโรงพยาบาลมากกว่าหนึ่งครั้ง และส่วนใหญ่มีการเข้ารับการตรวจเพียงสองครั้งเท่านั้น
ขั้นตอนที่ 3: วิธีเตรียมชุดข้อมูลของคุณเอง
ชุดข้อมูลการฝึกอบรมของ RETAIN จะต้องเป็นรายการ Python cPickled ของรายการ รายการที่อยู่ชั้นนอกสุดสอดคล้องกับผู้ป่วย ลำดับขั้นกลางถึงลำดับการนัดตรวจที่ผู้ป่วยแต่ละรายทำ และรายการชั้นในสุดของรหัสทางการแพทย์ (เช่น รหัสการวินิจฉัย รหัสยา รหัสขั้นตอน ฯลฯ) ที่เกิดขึ้นในการนัดตรวจแต่ละครั้ง ขั้นแรก รหัสทางการแพทย์จะต้องแปลงเป็นจำนวนเต็ม จากนั้นการเข้าชมครั้งเดียวสามารถเห็นได้เป็นรายการจำนวนเต็ม จากนั้นจะเห็นผู้ป่วยเป็นรายการนัดตรวจ ตัวอย่างเช่น [5,8,15] หมายความว่าผู้ป่วยได้รับรหัส 5, 8 และ 15 ในการนัดตรวจแต่ละครั้ง หากผู้ป่วยมาตรวจสองครั้ง [1,2,3] และ [4,5,6,7] สามารถแปลงเป็นรายการ [[1,2,3], [4,5,6,7] ]]. ผู้ป่วยหลายรายสามารถแสดงเป็น [[[1,2,3], [4,5,6,7]], [[2,4], [8,3,1], [3]]] ซึ่งหมายถึง มีผู้ป่วยสองราย โดยผู้ป่วยรายแรกมาตรวจสองครั้ง และผู้ป่วยรายที่สองมาตรวจสามครั้ง รายการของรายการนี้จะต้องดองโดยใช้ cPickle เราจะเรียกไฟล์นี้ว่า "ไฟล์เยี่ยมชม"
ต้องใช้รหัสทางการแพทย์ที่ไม่ซ้ำกันทั้งหมดเพื่อเรียกใช้ RETAIN ตัวอย่างเช่น หากชุดข้อมูลใช้รหัสวินิจฉัย 14,000 รหัสและรหัสขั้นตอน 11,000 รหัส จำนวนทั้งหมดจะเป็น 25,000
ชุดข้อมูลป้ายกำกับ (ให้เราเรียกสิ่งนี้ว่า "ไฟล์ป้ายกำกับ") จะต้องเป็นรายการ Python cPickled แต่ละองค์ประกอบสอดคล้องกับฉลากที่แท้จริงของผู้ป่วยแต่ละราย ตัวอย่างเช่น 1 อาจเป็นผู้ป่วยรายกรณี และ 0 อาจเป็นผู้ป่วยควบคุม หากมีผู้ป่วยสองรายโดยที่ผู้ป่วยรายแรกเป็นเคสเท่านั้น เราก็ควรจะได้ [1,0]
"ไฟล์เยี่ยมชม" และ "ไฟล์ป้ายกำกับ" จำเป็นต้องมี 3 ชุดตามลำดับ: ชุดการฝึก ชุดการตรวจสอบ และชุดการทดสอบ นามสกุลไฟล์ต้องเป็น ".train", ".valid" และ ".test" ตามลำดับ
ตัวอย่างเช่น หากคุณต้องการใช้ไฟล์ชื่อ "my_visit_sequences" เป็น "visit file" RETAIN จะพยายามโหลด "my_visit_sequences.train", "my_visit_sequences.valid" และ "my_visit_sequences.test"
สิ่งนี้ก็เป็นจริงสำหรับ "ไฟล์ป้ายกำกับ" เช่นกัน
คุณสามารถใช้ข้อมูลเวลาที่เกี่ยวกับการเยี่ยมชมเป็นแหล่งข้อมูลเพิ่มเติมได้ ให้เราเรียกสิ่งนี้ว่า "ไฟล์เวลา" โปรดทราบว่าข้อมูลเวลาอาจเป็นอะไรก็ได้: ระยะเวลาระหว่างการเข้าชมติดต่อกัน จำนวนวันสะสมนับตั้งแต่การเข้าชมครั้งแรก ฯลฯ "ไฟล์เวลา" จะต้องเตรียมเป็นรายการ Python cPickled รายการที่อยู่ชั้นนอกสุดสอดคล้องกับผู้ป่วย และข้อมูลเวลาที่อยู่ชั้นในสุดของการนัดตรวจแต่ละครั้ง ตัวอย่างเช่น ให้ "ไฟล์เยี่ยมชม" [[[1,2,3], [4,5,6,7]], [[2,4], [8,3,1], [3]]] "ไฟล์เวลา" ที่เกี่ยวข้องอาจมีลักษณะดังนี้ [[0, 15], [0, 45, 23]] หากเราใช้ระยะเวลาระหว่างการเข้าชมติดต่อกัน (แน่นอนว่าตัวเลขนั้นเป็นของปลอม และฉันได้ตั้งระยะเวลาสำหรับการเข้าชมครั้งแรกไว้ที่ศูนย์) ใช้ตัวเลือก --time_file <path to time file>
เพื่อใช้ "time file" โปรดจำไว้ว่า ".train", ". กฎที่ถูกต้อง", ".test" ยังใช้กับ "ไฟล์เวลา" ด้วยเช่นกัน
เพิ่มเติม: การใช้การรับรองรหัสทางการแพทย์ของคุณเอง
RETAIN เรียนรู้การแสดงเวกเตอร์ของรหัสทางการแพทย์ภายในขณะฝึกอบรม เวกเตอร์เหล่านี้เริ่มต้นด้วยค่าสุ่มแน่นอน
อย่างไรก็ตาม คุณสามารถใช้รหัสทางการแพทย์ของคุณเองได้ ถ้ามี (สามารถฝึกได้โดยใช้อัลกอริธึมแบบ Skip-gram โปรดดู Med2Vec หรือนี่สำหรับรายละเอียดเพิ่มเติม) หากคุณต้องการให้การแสดงรหัสทางการแพทย์ จะต้องเป็นรายการของรายการ (โดยพื้นฐานแล้วเป็นเมทริกซ์) ของแถว N และ คอลัมน์ M โดยที่ N คือจำนวนรหัสที่ไม่ซ้ำกันใน "ไฟล์เยี่ยมชม" ของคุณ และ M คือขนาดของการแสดงรหัส ระบุเส้นทางไปยังไฟล์การแสดงโค้ดของคุณโดยใช้ --embed_file <path to embedding file>
นอกจากนี้ แม้ว่าคุณจะใช้การแสดงรหัสทางการแพทย์ของคุณเอง คุณก็สามารถฝึกใหม่ได้ (หรือปรับแต่งอย่างละเอียด) ขณะที่คุณฝึก RETAIN ใช้ตัวเลือก --embed_finetune
เพื่อทำสิ่งนี้ หากคุณไม่ได้ให้การรับรองรหัสทางการแพทย์ของคุณเอง RETAIN จะใช้รหัสที่เริ่มต้นแบบสุ่ม ซึ่งเห็นได้ชัดว่าต้องใช้กระบวนการปรับแต่งอย่างละเอียดนี้ เนื่องจากค่าเริ่มต้นคือการใช้การปรับแต่งแบบละเอียด คุณจึงไม่ต้องกังวลกับเรื่องนี้
ขั้นตอนที่ 4: เรียกใช้ RETAIN
อินพุตขั้นต่ำที่คุณต้องใช้ในการเรียกใช้ RETAIN คือ "ไฟล์การเยี่ยมชม" จำนวนรหัสทางการแพทย์ที่ไม่ซ้ำกันใน "ไฟล์การเยี่ยมชม" "ไฟล์ฉลาก" และเส้นทางเอาต์พุต เส้นทางผลลัพธ์คือที่ที่น้ำหนักที่เรียนรู้และบันทึกจะถูกบันทึกไว้
python retain.py <visit file> <# codes in the visit file> <label file> <output path>
การระบุตัวเลือก --verbose
จะพิมพ์กระบวนการฝึกอบรมหลังจากแต่ละมินิแบทช์ 10 ชุด
คุณสามารถระบุขนาดของ W_emb ที่ฝัง ขนาดของเลเยอร์ที่ซ่อนอยู่ของ GRU ที่สร้างอัลฟ่า และขนาดของเลเยอร์ที่ซ่อนอยู่ของ GRU ที่สร้างเบต้า คำสั่งที่เกี่ยวข้องคือ --embed_size <integer>
, --alpha_hidden_dim_size <integer>
และ --beta_hidden_dim_size <integer>
ตัวอย่างเช่น --alpha_hidden_dim_size 128
จะบอกให้ RETAIN ใช้ GRU ที่มีเลเยอร์ที่ซ่อนอยู่ 128 มิติเพื่อสร้างอัลฟ่า
การออกกลางคันใช้กับสองตำแหน่ง: 1) กับการฝังอินพุต 2) กับเวกเตอร์บริบท c_i อัตราการออกกลางคันตามลำดับสามารถปรับได้โดยใช้ --keep_prob_embed {0.0, 1.0}
และ --keep_prob_context {0.0, 1.0}
ค่าที่ออกกลางคันจะส่งผลต่อประสิทธิภาพ ดังนั้นจึงแนะนำให้ปรับแต่งค่าเหล่านี้สำหรับข้อมูลของคุณ
การทำให้เป็นมาตรฐาน L2 สามารถนำไปใช้กับ W_emb, w_alpha, W_beta และ w_output
สามารถระบุตัวเลือกเพิ่มเติมได้ เช่น ขนาดของขนาดแบตช์ จำนวนยุค ฯลฯ ข้อมูลโดยละเอียดสามารถเข้าถึงได้โดย python retain.py --help
คำแนะนำส่วนตัวของฉัน: ใช้การทำให้เป็นมาตรฐานเล็กน้อย (0.0001 ~ 0.001) กับน้ำหนักทั้งสี่ และใช้การออกกลางคันปานกลางกับเวกเตอร์บริบทเท่านั้น แต่ทั้งหมดนี้ขึ้นอยู่กับข้อมูลของคุณ ดังนั้นคุณจึงควรปรับแต่งไฮเปอร์พารามิเตอร์สำหรับตัวคุณเองเสมอ
ขั้นตอนที่ 5: รับผลลัพธ์ของคุณ
RETAIN จะตรวจสอบ AUC ของชุดการตรวจสอบความถูกต้องหลังจากแต่ละยุค และหากสูงกว่าค่าก่อนหน้าทั้งหมด ระบบจะบันทึกโมเดลปัจจุบัน ไฟล์โมเดลถูกสร้างขึ้นโดย numpy.savez_compressed
ขั้นตอนที่ 6: ทดสอบโมเดลของคุณ
เมื่อใช้ไฟล์ "test_retain.py" คุณสามารถคำนวณการมีส่วนร่วมของรหัสทางการแพทย์แต่ละรายการในการนัดตรวจแต่ละครั้ง ก่อนอื่นคุณต้องมีโมเดลที่ผ่านการฝึกอบรมซึ่งบันทึกไว้โดย numpy.savez_compressed โปรดทราบว่าคุณจำเป็นต้องทราบการกำหนดค่าที่คุณฝึก RETAIN (เช่น การใช้ --time_file
การใช้ --use_log_time
)
ขอย้ำอีกครั้งว่าคุณต้องเตรียม "ไฟล์เยี่ยมชม" และ "ไฟล์ป้ายกำกับ" ในลักษณะเดียวกัน อย่างไรก็ตาม ในครั้งนี้ คุณไม่จำเป็นต้องปฏิบัติตามกฎ ".train", ".valid", ".test" สคริปต์ทดสอบจะพยายามโหลดชื่อไฟล์ตามที่กำหนด
คุณต้องมีข้อมูลการจับคู่ระหว่างรหัสทางการแพทย์สตริงจริงกับรหัสจำนวนเต็ม (เช่น "Hypertension" ถูกแมปเป็น 24) ไฟล์นี้ (ขอเรียกว่า "ไฟล์การแมป") จะต้องเป็นพจนานุกรม Python cPickled โดยที่คีย์เป็นรหัสสตริงทางการแพทย์และค่าเป็น intergers ที่สอดคล้องกัน (เช่น ไฟล์แผนที่ที่สร้างโดย process_mimic.py คือไฟล์ ".types") ไฟล์นี้จำเป็นสำหรับการพิมพ์รหัสทางการแพทย์แต่ละรหัสในรูปแบบที่ใช้งานง่าย
สำหรับตัวเลือกเพิ่มเติม เช่น --time_file
หรือ --use_log_time
คุณควรใช้การกำหนดค่าเดียวกันกับที่คุณฝึกโมเดลทุกประการ สำหรับข้อมูลโดยละเอียดเพิ่มเติม ให้ใช้ตัวเลือก "--help"
อินพุตขั้นต่ำในการรันสคริปต์ทดสอบคือ "ไฟล์โมเดล", "ไฟล์เยี่ยมชม", "ไฟล์ป้ายกำกับ", "ไฟล์การแมป" และ "ไฟล์เอาต์พุต" "ไฟล์เอาต์พุต" คือที่ที่ผลงานจะถูกจัดเก็บ python test_retain.py <model file> <visit file> <label file> <mapping file> <output file>