第八章 中医证型关联规则挖掘

8.1 背景与挖掘目标

中医药治疗恶性肿瘤,从整体出发,调整机体气血、阴阳、脏腑功能的平衡,根据不同的临床证候进行辩证论治。确定“先证而治”的方向:即后续证候尚未出现之前,需要截断恶化病情的哪些后续证候。发现中医症状间的关联关系和诸多症状间的规律性,并且依据规则分析病因、预测病情发展以及为未来临床诊治提供有效借鉴。
挖掘目标:
1)借助三阴乳腺癌患者的病理信息,挖掘患者的症状与中医证型之间的关联关系。
2)对截断治疗提供依据,挖掘潜性证素。

8.2 分析方法与过程

由于患者在围手术期、围化疗期、围放疗期和内分泌治疗期等各个病程阶段,基本都会出现特定的临床症状,因此运用中医截断疗法进行治疗。截断扭转的主要观点是强调早期治疗,力图快速控制病情,截断病情邪变深入,扭转阻止疾病恶化。
由于临床病理信息大部分记录在纸张,本章采用问卷调查方式收集数据;运用数据挖掘技术对收集的数据进行数据探索与预处理,形成建模数据;采用关联规则算法,挖掘各中医证素与乳腺癌TNM分期之间的关系,其中乳腺癌TNM分期是乳腺癌分期基本原则,I期较轻,IV期较严重。探索不同分期阶段的三阴乳腺癌患者的中医证素分布规律,以及采用截断病变发展、先期干预的治疗思路,指导三阴乳腺癌的中医临床治疗。
挖掘步骤:
1)以问卷调查的方式对数据进行收集,并将问卷信息整理成原始数据。
2)对原始数据集进行数据预处理,包括数据清洗、属性规约、数据变换。
3)利用步骤2)形成的建模数据,采用关联规则算法,调整模型输入参数,获取各中医证素与乳腺癌TNM分期之间的关系。
4)结合实际业务,对模型结果进行分析,且将模型结果应用到实际业务中,最后输出关联规则结果。

8.2.1 数据获取

采用调查问卷形式的数据获取具体过程如下:
1)拟定调查问卷表并形成原始指标表
2)定义纳入标准与排除标准
3)将收集回来的问卷表整理成原始数据

8.2.2 数据预处理

1.数据清洗

在收回的问卷中剔除无效的问卷,将有效问卷整理成原始数据。

2.属性规约

本案例收集到的数据有73个属性,将其中的冗余属性与挖掘任务不相关属性剔除。选取六种证型得分、TNM分期的属性值构成数据集。

3.数据变换

首先通过属性构造,获得证型系数,然后通过聚类算法对数据进行离散化处理,形成建模数据。

(1)属性构造

为了更好反应出中医证素分布的特征,采用证型系数代替具体单证型的证素得分,证型系数=该证型得分/该证型总分。

python做医学研究统计分析 python医学数据挖掘_python做医学研究统计分析

(2)数据离散化
由于Apriori关联规则算法无法处理连续性数值变量,对数据进行离散化。本案例采用聚类算法对各个证型系数进行离散化处理,将每个属性聚成四类。

import pandas as pd
from sklearn.cluster import KMeans

datafile = './demo/data/data.xls'  # 待聚类的数据文件
processedfile = './demo/tmp/data_processed.xlsx'  # 处理后的文件
typelabel = {'肝气郁结证型系数':'A', '热毒蕴结证型系数':'B', '冲任失调证型系数':'C', '气血两虚证型系数':'D', '脾胃虚弱证型系数':'E',
             '肝肾阴虚证型系数':'F'}
k = 4  # 需要的聚类类别数

# 读取数据并且进行聚类
data = pd.read_excel(datafile)
keys = list(typelabel.keys())
result = pd.DataFrame()

if __name__ == '__main__':  # 判断是否主窗口运行
    '''
    当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;
    当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。
    '''
    for i in range(len(keys)): # 调用k-means算法,进行聚类离散化
        print('正在进行 "%s" 的聚类...' % keys[i])
        kmodel = KMeans(n_clusters=k)
        kmodel.fit(data[[keys[i]]].values)  # 训练模型

        r1 = pd.DataFrame(kmodel.cluster_centers_, columns=[typelabel[keys[i]]])  # 聚类中心
        r2 = pd.Series(kmodel.labels_).value_counts()  # 分类统计
        r2 = pd.DataFrame(r2, columns=[typelabel[keys[i]]+'n'])  # 转为DataFrame,记录各个类别的数目
        r = pd.concat([r1, r2], axis=1).sort_values(by= typelabel[keys[i]])  # 匹配聚类中心和类别数目,并按值排序
        r.index = [1, 2, 3, 4]

        r[typelabel[keys[i]]] = r[typelabel[keys[i]]].rolling(2).mean()  # rolling().mean()用来计算相邻2列的均值,以此作为边界点
        r[typelabel[keys[i]]][1] = 0.0  # 将原来的聚类中心改为边界点
        result = result.append(r.T)

    result = result.sort_index()  # 以index排序,即以ABCDEF排序
    result.to_excel(processedfile)

python做医学研究统计分析 python医学数据挖掘_关联规则_02


原始数据预处理后

import pandas as pd

data = pd.read_excel('./demo/data/data.xls')
print(data)
for i in range(len(data)):
    if data['肝气郁结证型系数'][i] <= 0.179:
        data['肝气郁结证型系数'][i] = 'A1'
    elif data['肝气郁结证型系数'][i] <= 0.258:
        data['肝气郁结证型系数'][i] = 'A2'
    elif data['肝气郁结证型系数'][i] <= 0.35:
        data['肝气郁结证型系数'][i] = 'A3'
    else:
        data['肝气郁结证型系数'][i] = 'A4'

    if data['热毒蕴结证型系数'][i] <= 0.15:
        data['热毒蕴结证型系数'][i] = 'B1'
    elif data['热毒蕴结证型系数'][i] <= 0.296:
        data['热毒蕴结证型系数'][i] = 'B2'
    elif data['热毒蕴结证型系数'][i] <= 0.485:
        data['热毒蕴结证型系数'][i] = 'B3'
    else:
        data['热毒蕴结证型系数'][i] = 'B4'

    if data['冲任失调证型系数'][i] <= 0.201:
        data['冲任失调证型系数'][i] = 'C1'
    elif data['冲任失调证型系数'][i] <= 0.288:
        data['冲任失调证型系数'][i] = 'C2'
    elif data['冲任失调证型系数'][i] <= 0.415:
        data['冲任失调证型系数'][i] = 'C3'
    else:
        data['冲任失调证型系数'][i] = 'C4'

    if data['气血两虚证型系数'][i] <= 0.172:
        data['气血两虚证型系数'][i] = 'D1'
    elif data['气血两虚证型系数'][i] <= 0.251:
        data['气血两虚证型系数'][i] = 'D2'
    elif data['气血两虚证型系数'][i] <= 0.357:
        data['气血两虚证型系数'][i] = 'D3'
    else:
        data['气血两虚证型系数'][i] = 'D4'

    if data['脾胃虚弱证型系数'][i] <= 0.154:
        data['脾胃虚弱证型系数'][i] = 'E1'
    elif data['脾胃虚弱证型系数'][i] <= 0.256:
        data['脾胃虚弱证型系数'][i] = 'E2'
    elif data['脾胃虚弱证型系数'][i] <= 0.375:
        data['脾胃虚弱证型系数'][i] = 'E3'
    else:
        data['脾胃虚弱证型系数'][i] = 'E4'

    if data['肝肾阴虚证型系数'][i] <= 0.178:
        data['肝肾阴虚证型系数'][i] = 'F1'
    elif data['肝肾阴虚证型系数'][i] <= 0.261:
        data['肝肾阴虚证型系数'][i] = 'F2'
    elif data['肝肾阴虚证型系数'][i] <= 0.353:
        data['肝肾阴虚证型系数'][i] = 'F3'
    else:
        data['肝肾阴虚证型系数'][i] = 'F4'

print(data)
data.to_excel('./demo/tmp/data_model.xlsx',index=False)

这里不知道掩码方式怎么处理数据。。就用的最笨的if条件语句

python做医学研究统计分析 python医学数据挖掘_关联规则_03

8.2.3 模型构建

关联规则算法主要用于寻找数据集中项之间的关联关系,其揭示了数据项之间的未知关系,基于样本的统计规律,进行关联规则挖掘。当置信度达到某一阈值时,就可以认为规则成立。
1.中医证型关联规则模型
模型实现步骤:首先设置建模参数最小支持度、最小置信度,输入建模样本数据。然后采用Apriori关联规则算法对建模的样本数据进行分析,以模型参数设置的最小支持度、最小置信度以及分析目标作为条件,如果所有的规则都不满足条件,则需要重新调整模型参数,否则输出关联规则结果。
对于如何设置最小支持度和最小置信度,大部分都是根据业务经验设置初始值,然后经过多次调整,获取与业务相符的关联规则结果。本案例选取模型的输入参数为:最小支持度6%、最小置信度75%。

import pandas as pd
from apriori import *  # 导入自行编写的高效的Apriori函数
import time  # 导入时间库用来计算用时

inputfile = './demo/data/apriori.txt'  # 输入事务集文件
data = pd.read_csv(inputfile, header=None, dtype=object)

start = time.perf_counter()  # 计时开始(新版本不支持clock,用time.perf_counter()替换)
print('\n转换原始数据至0-1矩阵')
ct = lambda x : pd.Series(1, index=x[pd.notnull(x)])  # 转换0-1矩阵的过渡函数,即将标签数据转换为1
b = map(ct, data.values)  # 用map方式执行
data = pd.DataFrame(b).fillna(0)  # 实现矩阵转换,除了1外,其余为空,空值用0填充
end = time.perf_counter()  # 计时结束
print('\n转换完毕,用时:%0.2f秒' % (end-start))
del b  # 删除中间变量b,节省内存

support = 0.06  # 最小支持度
confidence = 0.75  # 最小置信度
ms = '---'  # 连接符,默认'--',用来区分不同元素,如A--B,需要保证原始表格不含有该字符

start = time.perf_counter()  # 计时开始
print('\n开始搜索关联规则')
find_rule(data, support, confidence, ms)
end = time.perf_counter()  # 计时结束
print('\n转换完毕,用时:%0.2f秒' % (end-start))

python做医学研究统计分析 python医学数据挖掘_数据分析_04

2.模型分析

对于关联的结果,我们只关注以H为规则结果的规则。每个关联规则都可以表示成python做医学研究统计分析 python医学数据挖掘_数据_05,其中X表示各个证型系数范围标识组合而成的规则,Y表示TNM分期为H4期。A3表示肝气郁结证型系数处于(0.258,0.35]范围内的数值,B2表示热毒蕴结证型系数处于(0.15,0.296]范围内的数值,C3表示冲任失调证型系数处于(0.288,0.415]范围内的数值,F4表示肝肾阴虚证型系数处于(0.353,0.607]范围内的数值。

python做医学研究统计分析 python医学数据挖掘_关联规则_06


由此分析得到以下结论。

1)python做医学研究统计分析 python医学数据挖掘_python做医学研究统计分析_07 支持度最大,达到7.85%,置信度最大,达到87.96%,说明肝气郁结证型系数处于(0.258,0.35]范围,肝肾阴虚证型系数处于(0.353,0.607]范围内,TNM分期诊断为H4的可能性为87.96%,而这种情况发生的可能性为7.85%。

2)python做医学研究统计分析 python医学数据挖掘_数据分析_08 支持度达到7.53%,置信度达到87.5%,说明冲任失调证型系数处于(0.288,0.415]范围,肝肾阴虚证型系数处于(0.353,0.607]范围内,TNM分期诊断为H4的可能性为87.5%,而这种情况发生的可能性为7.53%。

3)python做医学研究统计分析 python医学数据挖掘_数据_09 支持度达到6.24%,置信度达到79.45%,说明热毒蕴结证型系数处于(0.15,0.296]范围,肝肾阴虚证型系数处于(0.353,0.607]范围内,TNM分期诊断为H4的可能性为79.45%,而这种情况发生的可能性为6.24%。

综上,TNM分期为H4期的三阴乳腺癌患者证型主要为肝肾阴虚证、热毒蕴结证、肝气郁结证和冲任失调,H4期患者肝肾阴虚证和肝气郁结证的临床表现较为突出,其置信度最大达到87.96%、3.模型应用

python做医学研究统计分析 python医学数据挖掘_数据分析_10