สัปดาห์ที่ ๑: บทนำสู่สารสนเทศสุขภาพและการเตรียมข้อมูล
สารสนเทศสุขภาพ (Health Informatics) คือศาสตร์และการปฏิบัติงานที่เกี่ยวข้องกับการจัดการข้อมูลสุขภาพเพื่อให้เกิดข้อมูลและสารสนเทศที่มีความหมาย (Data plus Meaning) โดยมีเทคโนโลยีทำหน้าที่สนับสนุนเพื่อช่วยในการตัดสินใจทางการแพทย์อย่างรอบคอบ
นิยามโดย Greenes & Shortliffe (1990) ชี้ว่าศาสตร์นี้เน้นกระบวนการคิดทางปัญญา การประมวลผลข้อมูล และงานด้านการสื่อสาร
ให้ความสำคัญกับการนำสถิติและข้อมูลดิบมาสกัดความหมายเพื่อปรับปรุงการรักษารายบุคคล
มุ่งใช้ข้อมูลเพื่อปรับปรุงระบบดูแลสุขภาพ งานสาธารณสุข และขับเคลื่อนงานวิจัยชีวการแพทย์ระดับสูง
ระบบสารสนเทศสุขภาพที่มีประสิทธิภาพจำต้องคำนึงถึง พฤติกรรมมนุษย์และบริบทขององค์กร (Human and Organization Behavior) เสมอ เนื่องจากบุคลากรการดูแลสุขภาพเป็นแกนหลักในการใช้งานจริงระดับปฏิบัติงาน
ศึกษาพฤติกรรมความพร้อมและอุปสรรคในการใช้งานระบบคอมพิวเตอร์ของแพทย์และพยาบาล
สิ่งที่ส่งผลต่อประสิทธิภาพการรับเอาและยอมรับระบบสารสนเทศในสภาพแวดล้อมทางคลินิก
การพิจารณาความสอดคล้องกับพฤติกรรมในองค์กรเพื่อเพิ่มความร่วมมือในการทำงาน
หัวใจหลักของปฏิบัติการสารสนเทศสุขภาพคือการบูรณาการระบบเพื่อสร้างความรอบรู้ (Informed) และการช่วยเหลือ (Assisted) ในระบบรักษาพยาบาล
การจัดสรรข้อมูลสุขภาพที่ถูกต้องให้กับผู้ใช้ในเวลาที่เหมาะสมและในรูปแบบที่เป็นประโยชน์
ตัวอย่าง: แพทย์เห็นประวัติแพ้ยาและประวัติยาเดิมของผู้ป่วยทันทีก่อนการสั่งใช้ยาเพื่อป้องกันความผิดพลาด
การนำเทคโนโลยีมาช่วยทุ่นแรงหรือลดความเสี่ยงในการดำเนินงาน
ตัวอย่าง: แอปพลิเคชันบนมือถือที่คอยแจ้งเตือนผู้ป่วยให้รับประทานยาตามนัดเพื่อเพิ่มอัตราการปฏิบัติตามแผนการรักษา
ทิศทางการทำงานด้านสารสนเทศสุขภาพครอบคลุมตั้งแต่ระดับรายบุคคล กลุ่มประชากร ไปจนถึงระบบสาธารณสุขขนาดใหญ่
นำข้อมูลมาสนับสนุนเครื่องมือวินิจฉัย การรักษาพยาบาล และระบบคัดกรองผู้ป่วยของแพทย์ (เช่น ระบบเวชระเบียนอิเล็กทรอนิกส์ EHRs, ระบบสั่งการรักษาโดยแพทย์ CPOE, และระบบตัดสินใจทางคลินิก CDSS )
การวิเคราะห์ข้อมูลระบาดวิทยาเพื่อติดตามการแพร่ระบาด และการเฝ้าระวังโรคภัยคุกคามในระดับประชากร
การสนับสนุนสารสนเทศแก่ตัวผู้ป่วยโดยตรงเพื่อให้เข้าใจและรักษาสุขภาพของตนเอง เช่น ประวัติสุขภาพส่วนบุคคล PHRs และอุปกรณ์สวมใส่
องค์การอนามัยโลก (WHO) ชี้ว่าระบบข้อมูลสุขภาพที่ถูกต้องและทันท่วงที คือหัวใจสำคัญของการวางนโยบายและโปรแกรมการดูแลสุขภาพให้มีประสิทธิภาพสูงสุด
ลดภาระงานเอกสารและลดระยะเวลารอตรวจของคนไข้ (เช่น ระบบการจองคิวนัดหมายและเตือนอัตโนมัติ )
ตรวจวินิจฉัยโรคได้รวดเร็วและแม่นยำยิ่งขึ้น (เช่น การนำโมเดล AI มาร่วมคัดกรองและวิเคราะห์ภาพถ่ายเอกซเรย์เพื่อตรวจหาโรคมะเร็งในระยะเริ่มต้น )
แม้จะมีเทคโนโลยีที่ก้าวหน้า แต่ในเชิงปฏิบัติจริงยังมีปัญหาความล้มเหลวที่มักพบบ่อยครั้งในการเตรียมและจัดการข้อมูลสุขภาพ
แม้จะมีการรวบรวมข้อมูลดิบจำนวนมหาศาลจากเซ็นเซอร์หรือเฝ้าระวังโรค แต่ข้อมูลกลับถูกกองทิ้งไว้โดยไม่นำมาวิเคราะห์หาข้อมูลเชิงลึก
ปัญหาระดับบันทึกข้อมูล หากการป้อนข้อมูลระเบียนสุขภาพล่าช้า มีจุดบกพร่อง หรือกรอกข้อมูลผิดพลาด คุณภาพของผลลัพธ์การวิเคราะห์และการตัดสินใจก็จะถูกลดทอนลงทันที (Garbage In, Garbage Out)
ในการจัดการข้อมูลสุขภาพ ปัญหาหลักคือการติดตั้งโปรแกรมและไลบรารีเวอร์ชันที่ไม่ตรงกัน
เราจะเปลี่ยนมาใช้ Modern Developer Toolchain ที่มีประสิทธิภาพสูง รวดเร็ว และล็อกเวอร์ชันเพื่อป้องกันความเสียหายเชิงระบบ
ระบบติดตั้งแพ็กเกจ Command Line สำหรับ Windows ช่วยเลี่ยงการรันไฟล์ติดตั้ง .exe แบบเดิมๆ
เครื่องมือจัดการโปรเจกต์ Python ยุคใหม่ (Rust-based) ที่ทำงานรวดเร็วและสร้างสภาพแวดล้อมจำลอง (Virtual Environment) ได้ในตัว
สภาพแวดล้อมและไลบรารีหลักสำหรับการจัดเตรียมและวิเคราะห์ข้อมูลตารางผู้ป่วยในวิชานี้
เปิดโปรแกรม Windows PowerShell เพื่อทำการตั้งค่าระบบและติดตั้งตัวจัดการแพ็กเกจ Scoop
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
irm get.scoop.sh | iex
scoop --version เพื่อทดสอบความถูกต้อง
เราจะทำการติดตั้ง Git เพื่อใช้ดาวน์โหลดข้อมูล และติดตั้ง uv สำหรับควบคุมเวอร์ชันของ Python โครงงาน
scoop install git uv
เพื่อใช้ในการเรียกดูและดาวน์โหลดไฟล์ชุดข้อมูลทางการแพทย์สาธารณะและ template งานปฏิบัติการต่าง ๆ ได้สะดวก
เพราะ uv ทำงานเร็วกว่า pip/conda ถึง 10-100 เท่า และจัดการติดตั้งเวอร์ชัน Python ให้เหมาะสมกับสเปคเครื่องออฟไลน์โดยอัตโนมัติ
การสร้างสภาพแวดล้อมที่สะอาดและเป็นระบบ เพื่อแยกชุดข้อมูลและไลบรารีออกจากตัวเครื่องคอมพิวเตอร์หลัก
# 1. ย้ายตำแหน่งการทำงานไปที่ไดรฟ์ D: D: # 2. สร้างและเข้าไปยังไดเรกทอรีโครงการ mkdir health-informatics cd health-informatics # 3. เริ่มต้นระบบโครงงาน Python ด้วย uv uv init
pyproject.toml — ไฟล์สำหรับกำหนดค่าการตั้งค่าโครงงานmain.py — ไฟล์ Python ตัวอย่างสำหรับการทดสอบระบบรันโค้ดทำการระบุตัวแปรเพื่อดาวน์โหลดและติดตั้งเครื่องมือแก้ไขรหัสคำสั่ง (JupyterLab) และไลบรารีจัดการข้อมูลผู้ป่วย (pandas) ลงในโครงการ
uv add jupyterlab pandas faker
🔒 ความปลอดภัยและความยั่งยืนของข้อมูล (Reproducibility):
คำสั่ง uv add จะสร้างไฟล์ uv.lock ขึ้นมา เพื่อทำหน้าที่ล็อกเวอร์ชันของแพ็กเกจให้เหมือนกันสำหรับนักศึกษาทุกคน
ทำให้เมื่อนำโปรเจกต์นี้ไปรันที่เครื่องอื่นหรือส่งอาจารย์ผู้สอน โค้ดที่เขียนจะยังคงรันได้ปกติโดยไม่มีปัญหาเรื่องเวอร์ชันชนกัน
เปิดสภาพแวดล้อมการเขียนโปรแกรมและการทำ Pre-processing ข้อมูลสุขภาพเพื่อเตรียมการฝึกปฏิบัติการประจำสัปดาห์
uv run jupyter lab
🚀 สิ่งที่จะเกิดขึ้นถัดไป:
http://localhost:8888 โดยอัตโนมัติmain.py และไฟล์อื่น ๆ ของโครงการ .ipynb) และเริ่มต้นเขียนโปรแกรมวิเคราะห์ไฟล์ CSV/JSON เพื่อเริ่มงาน Homework 1 ได้ทันที! ในระบบสารสนเทศสุขภาพเชิงคลินิก ข้อมูลมีทั้งแบบตารางที่มีโครงสร้างชัดเจน และแบบกึ่งมีโครงสร้างที่ยืดหยุ่นสูง
เป็นข้อมูลตาราง (Tabular format) จัดเก็บแถวและคอลัมน์ชัดเจน เช่น ข้อมูลผลตรวจแล็บ สัญญาณชีพ หรือประวัติผู้ป่วยพื้นฐาน
ตัวอย่าง: MIMIC-IV Clinical Tablesเป็นข้อมูลกึ่งมีโครงสร้าง (Semi-structured) ในรูปแบบคู่กุญแจ-มูลค่า (Key-Value) เหมาะกับการซ้อนข้อมูลซับซ้อนและการส่งข้ามระบบ
ตัวอย่าง: มาตรฐาน HL7 FHIR Resourcesเครื่องมือที่สำคัญที่สุดในการจัดการข้อมูลแบบตารางขนาดใหญ่ใน Python คือไลบรารี pandas
import pandas as pd
# 1. โหลดข้อมูลผู้ป่วยจากไฟล์ CSV
df = pd.read_csv('patients_data.csv')
# 2. ตรวจสอบมิติข้อมูล (แถว, คอลัมน์) และหัวตาราง
print(f"ขนาดชุดข้อมูล: {df.shape}")
df.head(5) # แสดงข้อมูล 5 แถวแรก
df.shape แสดงโครงสร้างข้อมูลในรูป (จำนวนผู้ป่วย, จำนวนตัวแปรตรวจวัด) df.dtypes ช่วยวิเคราะห์ประเภทตัวแปรว่ามีลักษณะเป็นตัวเลขหรือตัวอักษร ระเบียนสุขภาพดิจิทัลสมัยใหม่ เช่น มาตรฐาน HL7 FHIR มักเก็บในรูปแบบ JSON ที่มีโครงสร้างซ้อนกัน
import json
# 1. โหลดไฟล์ JSON ของเวชระเบียนผู้ป่วย
with open('patient_fhir_demo.json', 'r') as file:
record = json.load(file)
# 2. การสืบค้นข้อมูลเชิงลึกในโครงสร้าง Dictionary แบบซ้อน (Nested Key)
patient_name = record['resource']['name']['given']
birth_date = record['resource']['birthDate']
print(f"ผู้ป่วย: {patient_name} | วันเกิด: {birth_date}")
การเข้าถึงข้อมูล JSON จำเป็นต้องอาศัยการเขียนโปรแกรมเชิงโครงสร้างดิกชันนารี (Dictionary Map) เพื่อไล่เรียงหาตำแหน่งตัวแปรที่แท้จริง
ในการวิเคราะห์ผู้ป่วยทั้งกลุ่ม (Cohort Analysis) เราจำต้องแปลงโครงสร้างซ้อนของ JSON ให้กลายเป็นตารางแบนราบเพื่อการคำนวณที่ง่ายขึ้น
# แปลงโครงสร้างแบบซ้อน (Nested JSON) ให้เป็นตารางแบนเรียบง่ายแบบอัตโนมัติ
df_patients = pd.json_normalize(
record,
record_path=['entry'],
meta=['id', 'resourceType']
)
df_patients.head()
ฟังก์ชัน pd.json_normalize จะช่วยลดเวลาในการเขียนโค้ดสกัดกิ่งข้อมูลซับซ้อนออกเป็นตารางสถิติกลุ่มในทันที
ข้อมูลทางการแพทย์และจีโนมิกส์มีขนาดที่เติบโตแบบก้าวกระโดด เราต้องเรียนรู้วิธีบริหารจัดการทรัพยากรหน่วยความจำอย่างคุ้มค่า
ไม่โหลดข้อมูลรูปภาพ (DICOM) หรือสัญญาณชีพขนาดใหญ่เข้ามาเก็บในตาราง DataFrame โดยตรงเพื่อความปลอดภัยของระบบ
ควรใช้วิธีจัดเก็บค่าระบุตำแหน่งไฟล์พิกัดและ deterministic path แทนการฝังไฟล์แบบออฟไลน์ (เทียบเคียงโครงสร้างท่อส่งข้อมูลสากลของ MIMIC-IV)
ดึงข้อมูลเฉพาะคอลัมน์และช่วงระยะเวลาที่จำเป็นเพื่อความประหยัดของหน่วยประมวลผล (RAM)
ชุดข้อมูลสุขภาพในโลกความเป็นจริงมักมี "สัญญาณรบกวน" (Real-world noise) เช่น การพิมพ์ผิด ช่องข้อมูลว่าง หรือค่าที่บันทึกผิดพลาดทางชีววิทยา ซึ่งอาจทำให้แบบจำลอง AI ทางการแพทย์ทำงานผิดพลาดและส่งผลกระทบต่อความปลอดภัยของคนไข้
เกิดจากกระบวนการตรวจรักษาที่ไม่ได้ทำกับผู้ป่วยทุกคน หรือข้อผิดพลาดในการดึงและจัดเก็บข้อมูล ส่งผลให้ข้อมูลขาดความสมบูรณ์ (Incompleteness)
ข้อมูลที่มีค่าสูงหรือต่ำผิดปกติเกินกว่าค่าทางสรีรวิทยาของมนุษย์ หรือการบันทึกเครื่องมือแพทย์ที่ผิดพลาด ซึ่งจำเป็นต้องคัดกรองและกำจัดออกก่อนนำไปวิเคราะห์ต่อ
เราใช้ไลบรารี pandas ในการระบุปริมาณข้อมูลที่ว่าง และใช้กลวิธีแก้ไขจุดบกพร่องตามระดับความสำคัญ
# 1. นับจำนวนค่าว่างในแต่ละคอลัมน์ของข้อมูลผู้ป่วย print(df.isnull().sum()) # 2. การคัดทิ้ง (Drop) แถวที่ไม่มีข้อมูลแล็บสำคัญ เช่น 'HbA1c_level' df_cleaned = df.dropna(subset=['HbA1c_level']) # 3. การแทนค่าว่าง (Imputation) ด้วยค่าเฉลี่ยสถิติของกลุ่มคนไข้ mean_bp = df['systolic_bp'].mean() df['systolic_bp'] = df['systolic_bp'].fillna(mean_bp)
💡 ข้อตระหนักเชิงระบบ: การคัดทิ้งข้อมูล (dropna) อาจทำให้เสียขนาดตัวอย่างวิจัย ในขณะที่การแทนค่าด้วยค่าเฉลี่ย (fillna) ช่วยคงขนาดกลุ่มผู้ป่วยไว้ได้ แต่ต้องพิจารณาไม่ให้ขัดต่อหลักสถิติระบาดวิทยา
การทำความสะอาดทางคลินิก ต้องอาศัยหลักการ Validity Checks (การตรวจสอบความสมเหตุสมผล) และสรีรวิทยาพื้นฐานร่วมด้วย
# 1. การลบข้อมูลอายุที่ติดลบ (ความผิดพลาดทางอายุ) หรือลบคนไข้ที่อายุ > 89 เพื่อจำกัดความเสี่ยง re-identification df = df[(df['Age'] >= 0) & (df['Age'] <= 89)] # 2. การตัดค่าสถิตินอกช่วงเปอร์เซ็นไทล์ (Outlier Thresholding) # ลบแถวที่คอลัมน์ข้อมูลความดันสูงเกินเปอร์เซ็นไทล์ที่ 99 (อาจเกิดจากสัญญานหลุด) threshold_bp = df['systolic_bp'].quantile(0.99) df = df[df['systolic_bp'] <= threshold_bp]
🔬 ตัวอย่าง Validity Check: ผู้ป่วยไม่สามารถมีอายุติดลบได้ หรือ วันที่ให้ผู้ป่วยออกจากจากโรงพยาบาล (Discharge Date) ต้องไม่เป็นวันก่อนวันที่รับผู้ป่วยเข้าโรงพยาบาล (Admission Date) เด็ดขาด
ทักษะสกัดกลุ่มผู้ป่วยเฉพาะโรคหรือกลุ่มที่มีความเสี่ยงสูง (Prioritizing patients at risk) เพื่อวินิจฉัยและวางแนวทางรักษารายบุคคล
# 1. กรองเฉพาะผู้ป่วยเบาหวานสูงอายุที่มีความเสี่ยงสะสม (Age > 60 ปี และมีระดับน้ำตาล HbA1c > 7.0 %)
high_risk_diabetic = df[
(df['Age'] > 60) &
(df['HbA1c_level'] > 7.0)
]
print(f"จำนวนผู้ป่วยกลุ่มเสี่ยงสูงสุด: {high_risk_diabetic.shape} ราย")
high_risk_diabetic.head()
ตัวแปรประเภท Boolean Array ทำหน้าที่เสมือนหน้าต่างคัดกรอง (Mask) ซึ่งกรองหาแถวที่มีเงื่อนไขเป็น True
ขึ้นมาเป็นตารางใหม่สำหรับดำเนินงานต่อในทันที
ในขั้นตอนวิเคราะห์ข้อมูลสุขภาพ ความผิดพลาดมักเกิดจากการระบุชนิดข้อมูลคอลัมน์ไม่ตรงกับลักษณะแท้จริงของค่าที่บันทึก
# 1. ตรวจสอบชนิดข้อมูลของ DataFrame print(df.dtypes) # 2. แปลงอายุจากทศนิยมให้เป็นจำนวนเต็มเพื่อการวิเคราะห์ทางสถิติ (Discrete Variable) df['Age'] = df['Age'].astype(int) # 3. แปลงคอลัมน์วันที่สมัครจากการเป็น 'ตัวหนังสือ (object)' ไปเป็น 'วันเวลา (Datetime)' df['admission_date'] = pd.to_datetime(df['admission_date']) print(df['admission_date'].dtypes) # แสดงผลเป็น datetime64[ns]
💡 ความสำคัญของ Datetime: หากเราไม่แปลงประเภทวันที่เป็น Datetime ก่อน ตัวแปรนั้นจะทำหน้าที่เพียงตัวหนังสือ (String) ทำให้เราไม่สามารถนำวันที่ไปคำนวณหามิติทางเวลาหรือนำไปหาช่วงเวลารักษา (Length of Stay) ได้อย่างถูกต้อง
ในกระบวนการทำงานข้อมูลสุขภาพ (Health Data Lifecycle) เมื่อเราจัดการเตรียมและทำความสะอาดข้อมูลดิบแล้ว
การบันทึกสถานะของชุดข้อมูลที่สะอาด (Cleaned Intermediate State) เป็นขั้นตอนที่สำคัญมากทางวิทยาการข้อมูล
ป้องกันการรันโปรเซสทำความสะอาดข้อมูลขนาดใหญ่ที่ซับซ้อนซ้ำหลายรอบ ช่วยลดภาระหน่วยประมวลผล (RAM)
เมื่อทำความสะอาดข้อมูลเสร็จแล้ว เราจะใช้ฟังก์ชันดั้งเดิมของ pandas บันทึกตารางกลับไปเป็นไฟล์ CSV หรือส่งต่อเป็นโครงสร้าง JSON
# 1. ส่งออกตารางสะอาดเป็นไฟล์ CSV (โดยไม่เซฟดัชนีแถว)
df_cleaned.to_csv('cleaned_patients_data.csv', index=False)
# 2. ส่งออกเป็นไฟล์ข้อมูล JSON เพื่อเตรียมส่งผ่านเครือข่ายสากล
df_cleaned.to_json('cleaned_patients_records.json', orient='records', indent=4)
index=False ในไฟล์ CSV จะป้องกันการสร้างคอลัมน์ดัชนีเปล่าที่ไม่มีชื่อเมื่อเปิดอ่านไฟล์ในครั้งถัดไป
สัปดาห์แรก มุ่งเน้นการวางรากฐานทางความคิดควบคู่ไปกับทักษะวิชาชีพเชิงปฏิบัติการจัดการข้อมูลดิบ
ไม่ใช่แค่เรื่องเครื่องคอมพิวเตอร์ แต่เป็นกระบวนการจัดแจงข้อมูลและการประมวลผลอย่างเป็นระบบ (Data + Meaning) เพื่อเพิ่มความปลอดภัยและยกระดับระบบบริการทางการแพทย์
การติดตั้งระบบจัดการแบบล็อกเวอร์ชัน (Scoop, uv และ lockfiles) จะช่วยขจัดปัญหาระบบพังในภายหลัง ทำให้นักศึกษาสามารถทำซ้ำผลลัพธ์การทดลองได้อย่างน่าเชื่อถือ
ทักษะการตรวจสอบความถูกต้องของข้อมูล (Validity Checks) เช่น การกรองอายุที่ขัดแย้งทางชีววิทยา และการจัดการกับระเบียนสูญหายด้วย Pandas ก่อนนำข้อมูลไปป้อนเข้าโมเดล AI
การบ้านประจำสัปดาห์ เพื่อประเมินผลสัมฤทธิ์ CLO2
raw_patients.csvHbA1c_level โดยการแทนที่ด้วย ค่าเฉลี่ยสถิติ (Mean Imputation)student_id_homework1.csv และอัปโหลดไฟล์ .ipynb บนระบบ📅 กำหนดการส่งงาน: ก่อนเริ่มคาบเรียนปฏิบัติการสัปดาห์ถัดไป (สัปดาห์ที่ ๒)
ช่องทางการการเรียนรู้เพิ่มเติม
ดร.วิชิต สมบัติ
📧 wichit.s@ubu.ac.th | 📞 ๐๙๘-๐๙๗-๓๓๒๖