Redian新闻
>
【手撕代码】医学影像报告自动生成(2) 数据探索性分析及可视化

【手撕代码】医学影像报告自动生成(2) 数据探索性分析及可视化

公众号新闻

大家好,我是鑫仔。上一期的手撕代码专栏,鑫仔带大家完成了X-ray影像数据及报告数据集下载、影像报告数据预处理、X-ray影像数据预处理、数据集划分等工作(【手撕代码】X-ray影像报告自动生成(1) 数据预处理及数据集划分)。
有同学私信我说,手把手的教学虽然比较详细,不过全部都是代码和注释,没有花花绿绿的图片,学起来还是些点枯燥呀。所以呢,在模型构建之前,我们一起来对上一期得到的数据进行一些探索性分析

一、准备工作

向上滑动阅览

# 导入相关库
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from nltk.corpus import stopwords
from wordcloud importWordCloud, STOPWORDS
import matplotlib.image as mpimg
import warnings
warnings.filterwarnings('ignore')
         
# 设置工作路径
path_1 ='/home/jinlimed/Downloads/X_ray_report_generation/ecgen-radiology'
path_2 ='/home/jinlimed/Downloads/X_ray_report_generation/NLMCXR_png'
path_3 ='/home/jinlimed/Downloads/X_ray_report_generation/data'
         
# 读取dataframe
# 在上一期推文中,经预处理后的影像报告文件final_df.csv被保存在了path_1中
os.chdir(path_1)
df = pd.read_csv('final_df.csv',  encoding='gbk')
ds
       

我们发现,这是一个3851行,4列的DataFrame,列包括:

1.Image(患者影像ID)

2.Indication (患者症状描述)

3.Findings (影像提供信息)

4.Impression (诊断)


下面我们就来逐列对数据进行探索。

二、indication列feature分析


寻找indication列中的独有句子和重复句子

向上滑动阅览


def unique_words_features(data):
    '''
    Input  =  pandas dataframe 或 numpy arrays
    Output =  数据集中某一列数据的独有词数量和重复词数量的条形图
    '''
 
    # data.tolist()将numpy数组或pandas DataFrame对象中的数据转换为Python列表,以便进行进一步的数据处理或可视化
    # 所有词汇的长度
    len_findings = len(data.tolist())
 
    # 独有词的长度
    unique_findings = len(np.unique(data.tolist()))
   
    # 定义x轴和y轴
    x =['Repeated Values','Unique Values']
    y =  [len_findings, unique_findings]
 
    # 定义图尺寸
    plt.figure(figsize=(10,8))
 
    # 绘制x,y轴,定义颜色马尔斯绿
    plt.barh(x, y, color=['#2E8B57'])
 
    # 显示独有句子和重复句子的数量
    for index,valuein enumerate(y):
        plt.text(value, index, str(value))
   
    # y轴标签
    plt.ylabel('Counts')
    # 定义title
    plt.title('Unique Words in Feature')
    plt.show()
         
# 显示figure
unique_words_features(df.indication)

         
indication列中句子长度的频数分布直方图

向上滑动阅览


# 统计indication列行句子中有多少个单词
# 利用 df.indication.str.split().str.len() 将每个句子按空格分割,返回单词的数目
length_indication = df.indication.str.split().str.len()
 
# 图片尺寸
plt.figure(figsize =(8,8))
 
# seaborn库中的distplot()方法绘制直方图
# 直方图的横轴表示单词长度:每个句子的单词长度
# 纵轴表示单词出现的数量相对值
# bins参数指定直方图的柱子数量
# color参数指定直方图的颜色
sns.distplot(length_indication, hist=True, kde=True,bins=40,color ='Darkgreen')
 
# 设置标题和横纵轴
plt.title('Histogram of Indication feature Word length')
plt.xlabel('Words length')
plt.show()


indication列中句子的出现频率

向上滑动阅览


# 统计indication列中出现频率最高的句子
# 并将前50个频率最高的句子绘制成条形图
# 说白了就是统计医生诊断的最常见的适应症有哪些
counts = df.indication.value_counts()[:50]
 
plt.figure(figsize=(12,8))
 
# 绿色比较护眼
plt.bar(counts.index, counts.values, color ='Darkgreen')
 
plt.ylabel('Counts')
plt.title('Frequent Words in Feature')
plt.xticks(rotation=90, fontsize='x-large')
plt.show()



句子长度的累积概率分布直方图(CDF)

向上滑动阅览


# 设置图形尺寸
plt.figure(figsize =(8,6))
 
# 利用Seaborn库中的displot函数绘制频数累积分布直方图
# hist_kws和kde_kws参数将分布图转换为CDF图
# hist_kws参数中的cumulative=True表示绘制累积直方图
# density=True表示对y轴进行标准化,使其表示累积概率密度而不是计数
# kde_kws参数中的cumulative=True表示绘制累积分布函数曲线
sns.distplot(length_indication, hist_kws={'cumulative':True,'density':True}, kde_kws={'cumulative':True}, color ='Darkgreen')
 
# 添加titile及格栅grid
plt.title('Number of words per indication')
plt.grid()
plt.show()


横轴表示适应症词长度的分布范围
纵轴表示累积概率密度,我们看到indication长度在0-6个词之间分分布占总体的80%左右
         
寻找最常出现的词 & 词云图绘制

向上滑动阅览


# 定义停用词
stopwords =(stopwords.words('english'))
 
# 定义词云图函数
def show_wordcloud(data, title =None):
    wordcloud =WordCloud(
        background_color='white',
        # 过滤掉介词,冠词等无意义的停用词
        stopwords=stopwords,
        max_words=1000,
        max_font_size=110,
        scale=3,
        random_state=1# 选择固定的随机数种子,控制停用词云图每次输出相同
    ).generate(str(data))# 生成云图
 
    fig = plt.figure(1, figsize=(18,18))
    plt.axis('off')
     if title:
        fig.suptitle(title, fontsize=20)
        fig.subplots_adjust(top=2.3)
   
    # 绘制云图
    plt.imshow(wordcloud)
    plt.show()
         
show_wordcloud(df['indication'], title = 'Word-Cloud of Indication Feature')


结果显示:year, old, chest, male, indication, tb, positive, female等词出现频率较高。
下面,我们完全可以用相同的方法对findings列和impression列进行分析。


二、findings列和impression列的feature分析


寻找findings和impression列中的独有句子和重复句子
Findings列:
# 由于之前已经定义好了函数,直接将dataframe的列带入函数就可以了
# 便于区分,我改一下色号 #FFFFCC
unique_words_features(df.findings)


Impression列:
# 将impression列的色号改为#FFB6C1
unique_words_features(df.impression)

         
Findings 和impression列中句子长度的频数分布直方图
Findings列:

向上滑动阅览


length_findings = df.findings.str.split().str.len()
 
 
plt.figure(figsize =(8,8))
     
 
sns.distplot(length_findings, hist=True, kde=True,bins=40,color ='#FFCC00')
 
 
plt.title('Histogram of findings feature Word counts')
plt.xlabel('Words Counts')
plt.show()

Impression列:

向上滑动阅览


length_impression = df.impression.str.split().str.len()
 
plt.figure(figsize =(8,8))
     
sns.distplot(length_impression, hist=True, kde=True,bins=40,color ='#FFB6C1')
 
 
plt.title('Histogram of Impression feature Word len')
plt.xlabel('Words len')
plt.show()
         
         
findings列与impression列中句子的出现频率
findings列:

向上滑动阅览


counts = df.findings.value_counts()[:50]
 
plt.figure(figsize=(12,8))
 
plt.bar(counts.index, counts.values,color ='#FFCC00')
plt.ylabel('Counts')
plt.title('Frequent Words in Feature')
plt.xticks(rotation=90, fontsize='x-large')
plt.show()

impression列:

向上滑动阅览


counts = df.impression.value_counts()[:50]
 
plt.figure(figsize=(12,8))
 
plt.bar(counts.index, counts.values, color ='#FFB6C1')
plt.ylabel('Counts')
plt.title('Frequent Words in Feature')
plt.xticks(rotation=90, fontsize='x-large')
plt.show()

         
句子长度的累积概率分布直方图(CDF)
Findings列:

向上滑动阅览


plt.figure(figsize =(8,6))
 
 
sns.distplot(length_findings, hist_kws={'cumulative':True,'density':True}, kde_kws={'cumulative':True},color ='#FFCC00')
 
 
plt.title('Number of words per findings')
plt.grid()
plt.show()

impression列:

向上滑动阅览

plt.figure(figsize =(8,6))
 
sns.distplot(length_impression, hist_kws={'cumulative':True,'density':True}, kde_kws={'cumulative':True},color ='#FFB6C1')
 
plt.title('Number of words per impression')
plt.grid()
plt.show()

寻找最常出现的词 & 词云图绘制
Findings列:
show_wordcloud(df['findings'], title = 'Word-Cloud of findings Feature')


结果显示:Silhouette, mediastinum, within, normal, lungs, cardiomediastinal 等词出现较多
         
Impression列:
show_wordcloud(df['impression'], title = 'Word-Cloud of Impression Feature')


结果显示:Acute, disease, abnormality, cardiopulmonary, normal等词出现频率较高


三、image列的Feature分析


向上滑动阅览

# str.split()方法将df.image字符串按照逗号分隔成由多个字符串组成的list
# 使用len()函数计算字列表中字符串个数
image_count = df.image.str.split(',').str.len()
image_count
# 统计受试者对应的X片数目
image_count.value_counts()
plt.figure(figsize=(10,8))
# countplot函数绘制拥有相同数据量影像患者的条形图
sns.countplot(= image_count)
plt.title('Count Images per Patient')
plt.show()


条形图比较直观的显示,拥有两张影像的患者占大多数,我们根据此图可以确定X-ray影像数据处理方案。


四、影像原始数据的查看


向上滑动阅览

# 设置影像文件的路径
os.chdir(path_2)
 
# 使用NumPy库的random.randint()方法生成16个1到100之间的随机整数,作为图片的索引
ix = np.random.randint(low=1, high=100, size=16)
 
# 使用listdir函数列出该目录下的所有文件和子目录,并将其保存在images列表中
images = os.listdir()
 
# 使用Matplotlib库的subplots()方法创建一个4x4的子图,设置子图的大小为15x10
fig, ax = plt.subplots(4,4, figsize =(15,10))
 
# 使用ax.flatten()方法将ax变量展开为一维数组,以便后续对每个子图进行操作
axs = ax.flatten()             
for i,in zip(axs, ix):
    img = mpimg.imread(images[x])
    i.imshow(img)


         
好啦,至此,一些影像可视化和数据可视化的探索性分析方式就介绍完毕了。给大家留个小作业,可以尝试利用数据可视化的方式对上期划分训练集测试集验证集的均衡性进行分析~
在下一期,就将要动手构建第一个影像报告生成模型了,我们不见不散~

参考材料
https://tankmitesh29.medium.com/medical-report-predication-with-deep-learning-2e3e40289fc3

END

撰文丨鑫    仔

排版丨顶    顶

【手撕代码】X-ray影像报告自动生成(1) 数据预处理及数据集划分

·
我知道你在看

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
五问「ChatGPT+医学影像」:新一代的AI能否成为放射科医生的一把利器?大导演是怎样炼成的?【手撕代码】当我让深度学习模型吃下一本医学书后,他竟学会了如何“看病”!超强大的 Nginx 可视化管理平台 Nginx-Proxy-Manager 中文入门指南45张第一眼会看错的照片,每一张都是错觉,无法相信自己的眼睛美国版权局:通过ChatGPT、Midjourney等AI自动生成的作品,不受版权法保护基于 Vue 和 Canvas,轻舟低代码 Web 端可视化编辑器设计解析 | 低代码技术内幕从加减乘除到机器学习:Github/知乎数学可视化大神全角度拆解“数学要素”【手慢无】这套大奖绘本,版权到期,特价清库存,先到先得!MyBatis-Plus 可视化代码生成器来啦,让你的开发效率大大提速!!人生算数:好的数据可视化什么样?平方差公式的可视化演示...(待会删)yyds!网易内部PPT数据可视化学习资源,请低调使用!新一代基线资料表R包,10min学会精美可视化结果!数字疗法开启千亿脑抗衰赛道,数丹医疗探索性临床实验数据披露美国版权局:ChatGPT自动生成作品,不受版权法保护​勇往直前!新的风暴已经出现,ChatGPT+医学影像=顶刊新玩法?秘密花园根茎生长可视化套装,全景透明容器,直观感受大自然神奇变化低阶到高阶的数据分析图表如何做?内含100套数据可视化模板…高端的数据可视化如何做?限时薅羊毛课程来了!还在手动配置Nginx?太LOW了,这个超强大的 Nginx 可视化管理工具太牛逼了!京东开源:一款高效的企业级表格可视化搭建解决方案!点燃你对医学的热情!分享你的经验,获取特别奖励金!与最优秀的医学同行一起,探索医学界的未来!可视化液体“精油仓”驱蚊手环!不挑蚊子品种,持久有效240天!现代社会,现代汉语、中国现代化与日本、日语【手办新品】BINDing 狐之女神,Vibrastar 冒失娘女仆开订!人工智能AI再次升级,可以自动生成视频了~!使用这些 Python 工具可视化地探索数据 | Linux 中国细说拍过的冬季照片数据可视化:基于 Echarts + SpringBoot 的动态实时大屏银行监管系统【源码】nexttrace: 一款开源的全能可视化网络路由追踪工具一脉阳光医学影像,来自江西,递交招股书,拟香港IPO上市设计界的ChatGPT 来了!1000 组包装设计1 小时自动生成,还这么养眼?直播预告:大模型在多维多组学MDMM靶点开发中的应用和生成式医学影像智能报告系统ReportGPT高血压的困惑
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。