{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":71549,"databundleVersionId":8561470,"sourceType":"competition"}],"dockerImageVersionId":30715,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"=========================================================================================================================","metadata":{}},{"cell_type":"markdown","source":"# GOAL\nMục tiêu của cuộc thi này là tạo ra các mô hình có thể được sử dụng để hỗ trợ trong việc phát hiện và phân loại các tình trạng thoái hóa cột sống bằng cách sử dụng hình ảnh MRI cột sống thắt lưng. Các thí sinh sẽ phát triển các mô hình mô phỏng hiệu suất của bác sĩ chẩn đoán hình ảnh trong việc chẩn đoán các tình trạng cột sống.","metadata":{}},{"cell_type":"markdown","source":"# Metric overview (Tổng quan về chỉ số)\nChúng ta cần dự đoán xác suất của hẹp ống sống cho mỗi trong năm đốt sống được ký hiệu là L1/L2, ..., cũng như một xác suất tổng thể của bất kỳ hẹp ống sống nào trong cột sống thắt lưng.\nBài nộp sẽ được đánh giá bằng cách sử dụng trung bình của mất mát log có trọng số mẫu và dự đoán any_severe_spinal được tạo ra bởi thước đo\n\nCác trọng số mẫu như sau:\n\n1.  cho bình thường/nhẹ\n2.  cho trung bình\n3.  cho nặng","metadata":{}},{"cell_type":"markdown","source":"# Anatomical overview(Tổng quan về giải phẫu)","metadata":{}},{"cell_type":"markdown","source":"<center>\n<img src=\"https://i.postimg.cc/0jvKk9qL/maxresdefault.jpg\" width=500>\n</center>","metadata":{}},{"cell_type":"markdown","source":"C1-C7: Các đốt sống cổ (Cervical vertebrae)\nTh1-Th12: Các đốt sống ngực (Thoracic vertebrae)\nL1-L5: Đốt sống thắt lưng (Lumbar vertebrae)\nOS sacrum: Đây là xương cùng (Sacrum), một xương lớn hình tam giác nằm ở gốc cột sống, nối với các đốt sống thắt lưng phía trên và xương cụt phía dưới.\nCoccyx: Đây là xương cụt (Coccyx), phần cuối cùng của cột sống.\n\n`Cervical vertebrae`: Các đốt sống cổ, có nhiệm vụ hỗ trợ và di chuyển đầu\n\n`Thoracic vertebrae`: Các đốt sống ngực, kết nối với xương sườn và hỗ trợ lồng ngực.\n\n`Lumbar vertebrae`: Các đốt sống thắt lưng, chịu trọng lực nhiều nhất và hỗ trợ phần dưới của lưng.\n\n`Sacrum`: Xương cùng, nối cột sống với xương chậu và đóng vai trò trong việc hỗ trợ trọng lượng cơ thể khi đứng và ngồi.\n\n`Coccygeal vertebrae`: Các đốt sống của xương cụt.\n\n--------------------------------------------------\n`Cervical curve`: Đường cong của đốt sống cổ.\n\n`Thoracic curve`: Đường cong của đốt sống ngực.\n\n`Lumbar curve`: Đường cong của đốt sống thắt lưng.\n\n`Sacral curve`: Đường cong của xương cùng và xương cụt.\n","metadata":{}},{"cell_type":"markdown","source":"# MRI overview","metadata":{}},{"cell_type":"markdown","source":"### Axial T2:\n* Axial (cắt ngang) T2 là một chuỗi MRI trọng T2 theo mặt phẳng ngang của cột sống.\n* Hình ảnh trọng T2 hữu ích trong việc phát hiện các bệnh lý như phù nề, viêm hoặc tổn thương, những điều này xuất hiện với độ tín hiệu cao (sáng hơn) so với các mô bình thường.\n\n### Sagittal T1:\n* Mô tả: Sagittal (cắt dọc giữa) T1 là một chuỗi MRI trọng T1 theo mặt phẳng dọc của cột sống.\n* Hình ảnh trọng T1 cung cấp chi tiết giải phẫu tốt và sự tương phản giữa các mô mềm khác nhau.\n\n###  Sagittal T2/STIR\n Sagittal T2/STIR có thể là một chuỗi T2 theo mặt phẳng dọc, nhạy cảm trong việc phát hiện các tổn thương, phù nề và các bệnh lý khác xuất hiện với độ tín hiệu cao. STIR (Short Tau Inversion Recovery) là một chuỗi trọng T2 có ức chế mỡ, giúp làm nổi bật các tổn thương và phù nề bằng cách ức chế tín hiệu sáng của mỡ.\n \n \n ### Sự khác biệt giữa Axial và Sagittal:\n`Axial` :\n* Hướng cắt: Theo mặt phẳng ngang, cắt qua cơ thể từ trên xuống dưới.\n* Ứng dụng: Tốt cho việc xem các cấu trúc theo chiều ngang của cơ thể, bao gồm cả cột sống.\n\n`Sagittal`:\n* Hướng cắt: Theo mặt phẳng dọc, cắt qua cơ thể từ trước ra sau.\n* Ứng dụng: Tốt cho việc xem các cấu trúc theo chiều dọc, đặc biệt là cột sống và não.","metadata":{}},{"cell_type":"markdown","source":"\n<center>\n<img src=\"https://i.postimg.cc/jqBkh94B/CT-Image-Planes.jpg\" width=500>\n</center>\n","metadata":{}},{"cell_type":"markdown","source":"# Difference between T1 and T2","metadata":{}},{"cell_type":"markdown","source":"<center>\n<img src=\"https://i.postimg.cc/GmFxw3sn/Diagram-shows-the-signal-intensity-of-various-tissues-at-T1-and-T2-weighted-imaging.png\" width=700>\n</center>","metadata":{}},{"cell_type":"markdown","source":"Hình ảnh `T1-Weighted` cung cấp chi tiết giải phẫu tốt và sự tương phản giữa các mô mềm khác nhau. Mô mỡ và các sản phẩm máu (methemoglobin) xuất hiện sáng trong hình ảnh T1.\n\nHình ảnh `T2-Weighted` nhạy cảm với nước và phát hiện các bệnh lý như phù nề, viêm hoặc tổn thương. Mô chứa nhiều nước như dịch não tủy (CSF) và mô nước tự do cao xuất hiện sáng trong hình ảnh T2.","metadata":{}},{"cell_type":"markdown","source":"# Dataset overview\nTập dữ liệu của cuộc thi sử dụng bao gồm khoảng 2000 nghiên cứu MR. Các chuyên gia X quang cột sống đã cung cấp các chú thích để chỉ ra sự hiện diện, mức độ đốt sống và vị trí của bất kỳ chứng hẹp cột sống thắt lưng nào.","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n\nimport os\nimport time\n\nimport matplotlib.pyplot as plt\nfrom matplotlib import animation, rc\nimport plotly.express as px\nimport seaborn as sns\nimport plotly.express as px\nimport cv2\n\nimport pydicom as dicom\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\n\nimport warnings\nwarnings.filterwarnings('ignore')\nimport glob\nimport json\nimport collections\n","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:24.084786Z","iopub.execute_input":"2024-06-14T06:09:24.085267Z","iopub.status.idle":"2024-06-14T06:09:28.685248Z","shell.execute_reply.started":"2024-06-14T06:09:24.085230Z","shell.execute_reply":"2024-06-14T06:09:28.683735Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path = '../input/rsna-2024-lumbar-spine-degenerative-classification/'\n\ndf_train_main  = pd.read_csv(path + 'train.csv')\ndf_train_label = pd.read_csv(path + 'train_label_coordinates.csv')\ndf_train_desc  = pd.read_csv(path + 'train_series_descriptions.csv')\ndf_test_desc   = pd.read_csv(path + 'test_series_descriptions.csv')\ndf_sub         = pd.read_csv(path + 'sample_submission.csv')","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:28.688080Z","iopub.execute_input":"2024-06-14T06:09:28.688897Z","iopub.status.idle":"2024-06-14T06:09:28.900890Z","shell.execute_reply.started":"2024-06-14T06:09:28.688854Z","shell.execute_reply":"2024-06-14T06:09:28.899432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_main.info()","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:28.902377Z","iopub.execute_input":"2024-06-14T06:09:28.902781Z","iopub.status.idle":"2024-06-14T06:09:28.948224Z","shell.execute_reply.started":"2024-06-14T06:09:28.902748Z","shell.execute_reply":"2024-06-14T06:09:28.946867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(df_train_main)","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:28.950019Z","iopub.execute_input":"2024-06-14T06:09:28.950419Z","iopub.status.idle":"2024-06-14T06:09:28.960281Z","shell.execute_reply.started":"2024-06-14T06:09:28.950387Z","shell.execute_reply":"2024-06-14T06:09:28.958981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_main.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:28.964858Z","iopub.execute_input":"2024-06-14T06:09:28.965302Z","iopub.status.idle":"2024-06-14T06:09:29.006151Z","shell.execute_reply.started":"2024-06-14T06:09:28.965256Z","shell.execute_reply":"2024-06-14T06:09:29.004832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_label.info()","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:29.007988Z","iopub.execute_input":"2024-06-14T06:09:29.008392Z","iopub.status.idle":"2024-06-14T06:09:29.035419Z","shell.execute_reply.started":"2024-06-14T06:09:29.008360Z","shell.execute_reply":"2024-06-14T06:09:29.034042Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_label.head()\n# instance_number: số thứ tự lát cắt trong loạt ảnh","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:29.037396Z","iopub.execute_input":"2024-06-14T06:09:29.037953Z","iopub.status.idle":"2024-06-14T06:09:29.057955Z","shell.execute_reply.started":"2024-06-14T06:09:29.037904Z","shell.execute_reply":"2024-06-14T06:09:29.056629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(df_train_label['x'].max())\nprint(df_train_label['y'].max())","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:29.059922Z","iopub.execute_input":"2024-06-14T06:09:29.060490Z","iopub.status.idle":"2024-06-14T06:09:29.072663Z","shell.execute_reply.started":"2024-06-14T06:09:29.060440Z","shell.execute_reply":"2024-06-14T06:09:29.071163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for f in ['instance_number','condition','level']:\n    print(df_train_label[f].value_counts())\n    print('-'*50);print();","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:29.074848Z","iopub.execute_input":"2024-06-14T06:09:29.075414Z","iopub.status.idle":"2024-06-14T06:09:29.116784Z","shell.execute_reply.started":"2024-06-14T06:09:29.075366Z","shell.execute_reply":"2024-06-14T06:09:29.115184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.crosstab(df_train_label.condition, df_train_label.level)","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:29.118612Z","iopub.execute_input":"2024-06-14T06:09:29.119137Z","iopub.status.idle":"2024-06-14T06:09:29.172473Z","shell.execute_reply.started":"2024-06-14T06:09:29.119091Z","shell.execute_reply":"2024-06-14T06:09:29.171155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# join 2 bảng đầu tiên\ndf_train_step1 = pd.merge(left = df_train_label, right = df_train_main, how = \"left\", on =\"study_id\").reset_index(drop = True)\ndf_train_step1.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:29.174320Z","iopub.execute_input":"2024-06-14T06:09:29.174876Z","iopub.status.idle":"2024-06-14T06:09:29.341377Z","shell.execute_reply.started":"2024-06-14T06:09:29.174820Z","shell.execute_reply":"2024-06-14T06:09:29.340150Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_desc","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:29.343023Z","iopub.execute_input":"2024-06-14T06:09:29.343726Z","iopub.status.idle":"2024-06-14T06:09:29.358573Z","shell.execute_reply.started":"2024-06-14T06:09:29.343683Z","shell.execute_reply":"2024-06-14T06:09:29.357149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# join 3 bảng\ndf_train = pd.merge(left = df_train_step1, right = df_train_desc, how = 'left', on = ['study_id', 'series_id']).reset_index(drop =True)\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:29.360787Z","iopub.execute_input":"2024-06-14T06:09:29.361299Z","iopub.status.idle":"2024-06-14T06:09:29.505707Z","shell.execute_reply.started":"2024-06-14T06:09:29.361256Z","shell.execute_reply":"2024-06-14T06:09:29.504300Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.study_id = df_train.study_id.astype('category')\ndf_train.series_id = df_train.series_id.astype('category')\ndf_train.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:29.509833Z","iopub.execute_input":"2024-06-14T06:09:29.510298Z","iopub.status.idle":"2024-06-14T06:09:29.546885Z","shell.execute_reply.started":"2024-06-14T06:09:29.510263Z","shell.execute_reply":"2024-06-14T06:09:29.545637Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Coordinates distributions","metadata":{}},{"cell_type":"code","source":"sns.scatterplot(data=df_train, x='x', y='y', c = 'black', s = 20, alpha = 0.2);\nplt.grid(True)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:29.548278Z","iopub.execute_input":"2024-06-14T06:09:29.548672Z","iopub.status.idle":"2024-06-14T06:09:30.045747Z","shell.execute_reply.started":"2024-06-14T06:09:29.548639Z","shell.execute_reply":"2024-06-14T06:09:30.044460Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Phân phối màu theo condition\nc = ['#4600c0',  '#00a419', '#111111', '#ffff00', '#ff0000']\nplt.figure(figsize = (5,5))\nsns.scatterplot(data = df_train, x='x', y='y', hue='condition', palette = c, s = 20, alpha=0.2)\nplt.legend(bbox_to_anchor=(1.2,1), loc = 2, prop={'size':10}, markerscale = 2, framealpha=0.8, facecolor='White')\nplt.grid()\nplt.xlim([0, df_train['x'].max()])\nplt.ylim([0, df_train['y'].max()])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:09:30.047436Z","iopub.execute_input":"2024-06-14T06:09:30.047853Z","iopub.status.idle":"2024-06-14T06:09:32.173354Z","shell.execute_reply.started":"2024-06-14T06:09:30.047820Z","shell.execute_reply":"2024-06-14T06:09:32.171918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Mật Độ xy của Các Trường Hợp Hẹp Ống Sống Chia Theo Loại Bệnh Lý\nfeatures = ['Left Neural Foraminal Narrowing',\n            'Right Neural Foraminal Narrowing',\n            'Left Subarticular Stenosis',\n            'Right Subarticular Stenosis',\n            'Spinal Canal Stenosis']\ngs = 150\nn = 2\na = 0\nk = 1\n\nplt.figure(figsize = (13,5))\nfor i in features:\n    d = df_train[df_train.condition == i]\n    plt.subplot(1,n,k)\n    plt.hexbin(data = d, x='x', y='y', gridsize = gs, cmap='CMRmap',bins = 'log', alpha =1)\n    plt.colorbar().set_label(label='count in bin', size = 10, color ='grey')\n    \n    plt.tick_params(axis='x', labelsize=10)\n    plt.tick_params(axis='y', labelsize=10)\n    \n    plt.xlim([0, df_train.x.max()])\n    plt.ylim([0, df_train.y.max()])\n    \n    plt.title(f'{i}', color = 'black', fontsize = 20)\n    k=k+1\n    if k == (n+1):\n        k = 1\n        plt.show()\n        plt.figure(figsize=(13,5))\n    ","metadata":{"execution":{"iopub.status.busy":"2024-06-14T06:12:30.900053Z","iopub.execute_input":"2024-06-14T06:12:30.900526Z","iopub.status.idle":"2024-06-14T06:12:35.032756Z","shell.execute_reply.started":"2024-06-14T06:12:30.900490Z","shell.execute_reply":"2024-06-14T06:12:35.031390Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}