数模之Apriori关联算法

news2025/1/20 18:35:39

一、问题

中医证型的关联规则挖掘

背景:

 

        中医药治疗乳腺癌有着广泛的适应证和独特的优势。从整体出发,调整机体气血、阴阳、脏腑功能的平衡,根据不同的临床证候进行辨证论治。确定“先证而治”的方向:即后续证侯尚未出现之前,需要截断恶化病情的哪些后续证侯。找出中医症状间的关联关系和诸多症状间的规律性,并且依据规则分析病因、预测病情发展以及为未来临床诊治提供有效借鉴。能够帮助乳腺癌患者手术后体质的恢复、生存质量的改善,有利于提高患者的生存机率。

        目前,中医治疗一般都是采用中医辨证的原则,结合临床医师的从医经验和医学指南进行诊断,然而此方法也存在一定的缺陷。同一种疾病的辨证分型,往往都有不同见解,面对临床症状不典型的患者,初学者很难判断。

        因此,找到一种能够根据数据间的关系判断病症的方法显得格外重要。

目的:

  1. 借助三阴乳腺癌患者的病理信息,找出患者的症状与中医证型之间的关联关系;
  2. 对截断治疗提供依据,找出潜性证素。

数据概览:

二、为什么选择Apriori算法

Apriori算法,是关联规则最常用也是最经典的挖掘频繁项集的算法,其核心思想是通过连接产生候选项及其支持度然后通过剪枝生成频繁项集。

三、算法原理

算法依据

频繁项集的子集也是频繁项集。(迭代的思想)

名词解释

  • 频繁项集:同一属性不同的值
  • 支持度计数:不同值的个数
  • 支持度:不同值的概率
  • 置信度:在A发生的条件下发生B的概率

算法实现步骤

  1. 确定C1(支持度,一个元素),根据最小支持度进行剪枝,得到L1。
  2. L1项集随机组合得到元素个数为2的项集,计算C2支持度,根据最小支持度,得到满足条件的L2项集,依次类推,直至所有项集都不满足条件。
  3. 支持度处理完毕后,对留下来的项集计算置信度。根据置信度公式以及最小置信度进行筛选,最终得到满足条件的项集,即是最终的结果。

算法缺点

Apriori算法的在确定置信度和支持度时需要多次扫面事务数据集,这使得该算法在面对巨大的数据量时,效率降低。

四、问题解决

1、问题分析

本题探究TNM分期与病症之间的关联程度,则以TNM分期和各病症属性为C1项集,剔除小于最小支持度的项集得到L1。以TNM分期为起始点,构建HiXi二项集,计算置信度得到包含Hi的2项集,一次类推,得到最终的项集。再计算置信度,不断剪枝得到符合条件的项集。

2、代码实现

"""
每一行作为一个项集
data概览:A--F都有四种,
目标:确定TNM分期:H1--H4
"""
# 建立项集,读取data文件
# 逐行读取csv文件
import csv
lines = []
with open("中医证型关联规则.csv",'r') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        # print(row)
        lines.append(row)

# 执行连接步操作,确定频繁项集
ll_A = {}
ll_H = {}
all_data = []
for i in lines:
    all_data.append(i['肝气郁结证型系数'])
    all_data.append(i['热毒蕴结证型系数'])
    all_data.append(i['冲任失调证型系数'])
    all_data.append(i['气血两虚证型系数'])
    all_data.append(i['脾胃虚弱证型系数'])
    all_data.append(i['肝肾阴虚证型系数'])
    all_data.append(i['TNM分期'])
# 计数
for k in range(1,5):
    ll_A['A {}'.format(k)] =all_data.count('A {}'.format(k))
    ll_A['B {}'.format(k)] = all_data.count('B {}'.format(k))
    ll_A['C {}'.format(k)] = all_data.count('C {}'.format(k))
    ll_A['D {}'.format(k)] = all_data.count('D {}'.format(k))
    ll_A['E {}'.format(k)] = all_data.count('E {}'.format(k))
    ll_A['F {}'.format(k)] = all_data.count('F {}'.format(k))
    ll_H['H {} '.format(k)] = all_data.count('H {} '.format(k))
print(ll_A)

# 计算支持度
print("支持度大于最小支持度的数据")
all_len = ll_A['A 1'] + ll_A['A 2'] + ll_A['A 3'] + ll_A['A 4']
# print(all_len)
suppot_l = []
nonsupport_l = []
suppot_l_name = []
for j in ll_A.keys():
    if ll_A[j]/all_len >= 0.06:
        print("{}  {}".format(j,ll_A[j]/all_len))
        suppot_l.append(ll_A[j]/all_len)
        suppot_l_name.append(j)
    else:
        nonsupport_l.append(j)
print("小于支持度0.06的参数")
print(nonsupport_l)
# 各个证型与H 的关系,构建C2只需考虑两个因素
# H的支持度
print('H的支持度')
for j in ll_H.keys():
    print("{}  {}".format(j, ll_H[j] / all_len))
print("H与x的支持度")
llc2 = {}
for j in ll_H.keys():
    for k in suppot_l_name:
        lllo = []
        lllo.append(j)
        lllo.append(k)
        nc1 = k+j
        a = 0
        for l in lines:
            # 判断集合lllo是否为集合l的子集
            if set(lllo).issubset(list(l.values())):
                a+=1
        kk = a/all_len
        if kk>0.06:
            llc2[nc1] = kk
print(llc2)
print("二项集的长度为{}".format(len(llc2)))
print("构建HXX支持度")
pop = 0
lllc3 = {}
for l in llc2.keys():
    for k in suppot_l_name:
        llc3 = []
        llc3.append(l[0:3])
        llc3.append(l[3:]+"")
        if k not in llc3:
            llc3.append(k)
            b = 0
            for line in lines:
                p = list(line.values())
                if set(llc3).issubset(set(p)):
                    b+=1
            dc3 = b/all_len
            pop+=b
            if dc3>0.06:
                lllc3[l+k] = dc3
print(lllc3)
print("三项集的长度为{}".format(len(lllc3)))
print("构建HXXX")

lllc4 = {}
print(lllc3)
for l in lllc3.keys():
    for k in suppot_l_name:
        llc4 = []
        llc4.append(l[0:3])
        llc4.append(l[3:7])
        llc4.append(l[7:])
        if k not in llc4:
            llc4.append(k)
            c = 0
            for line in lines:
                p = list(line.values())
                if set(llc4).issubset(set(p)):
                    c+=1
            dc4 = c/all_len
            if dc4>0.06:
                lllc4[l+k] = dc4
print("四项集的长度为{}".format(len(lllc4)))

# 计算置信度
print("计算置信度")

dop = {}
sud = 0
for k in lllc3.keys():
    p1 = k[0:3]
    p2 = k[7:]
    kko = 0
    for l in lines:
        if p1 in l.values() and p2 in l.values():
            kko+=1
    lklk = lllc3[k]*all_len/kko
    if lklk >0.75:
        dop[k] = lklk
print("最终结果")
print("  病症   TNM分期     支持度                置信度")
# print(dop.keys())
dop.pop('C 3H 4 F 3')
dop.pop('F 3H 4 A 4')
for k in dop.keys():
    print(k[0:3]+k[7:],"  ",k[3:6],"  ",lllc3[k],"  ",dop[k])




五、欢迎大家批评指正,莫小凡会持续更新算法知识,大家一起进步呀!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/522860.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前后端分离博客】学习笔记04 --- 文件上传-策略模式

一、思路 我们定义一个接口(就比如接下来要实现的文件上传接口)我们定义所需要实现的策略实现类 A、B、C、D(也就是项目中所使用的四种策略阿里云Oss上传、腾讯云Cos上传、七牛云Kodo上传、本地上传)我们通过策略上下文来调用策略…

基础IO(一)

基础IO(一) 1.文件基础概念2.C语言接口回顾3.系统接口4.文件系统调用5.三个标准6.输出缓冲区 🌟🌟hello,各位读者大大们你们好呀🌟🌟 🚀🚀系列专栏:【Linux的…

股票K线基础知识2

光头光脚阳线 光头光脚阳线形态与特征描述 光头光脚阳线表示股票的最高价与收盘价相同,最低价与开盘价一样。光头光脚阳线上下不带影线,表明从一开盘买方就积极进攻,中间也可能出现买方与卖方的斗争,但买方发挥了最大力量。始终占…

18.JAVA之三大框架Spring、IOC和DI、拦截器、MVC项目、Mybatis持久层、动态SQL、SSM

一、Spring框架 1.1概述 其中最核心的是:IoC控制反转、DI依赖注入、Bean工厂、SpringAOP面向切面编程、事务控制。 Spring是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。 SpringMVC框架用来接受浏览器的请求和给浏览器做出响应 Mybatis…

C++:设计一个线程安全的队列

文章目录 1. 目的2. 实现?验证!makefileQueue 类的 public 成员单元测试 3. 实现 Queue 类的方案 1. 目的 串行的程序只用到单个 CPU 核心, 希望加速整个程序, 考虑使用多线程加速。典型情况下可以找到生产者、消费者&#xff0c…

基于ESP或ESP8266 单通道Lorawan网关硬件制作

软件代码设计资料下载链接》》 基于 Comresult PCB 的单通道网关 介绍 这是 ESP8266 LoRa 网关的最新版本。基于 ESP8266 mcu 的 LoRa 网关在过去几年里有了很大的发展。您想构建一个小型网关并保持尽可能多的 GPIO 引脚可用,Hallard 板是无与伦比的。另一种解决…

C++多态练习题

文章目录 1.虚函数的调用过程2.虚函数例题例题一例题二例题三例题四例题四 1.虚函数的调用过程 从汇编上面来看: []代表指针解引用操作 1.op指向test对象的首地址(存放vptr),并存放在eax里面; 2.将eax所指之物(虚表…

使用不同的梯度下降法优化算法

本篇将使用以下几个梯度下降算法进行对比: 不使用任何的优化算法(即整批数据集作为一次迭代更新梯度,也叫batch梯度下降,BGD) mini-batch梯度下降法(Mini-batchGD) 使用具有动量的梯度下降算法&…

无标签背景图(负样本)的拼图代码

训练目标检测模型有个很令人头疼的问题,就是有些特征与要训练的特征较为相似的背景区域也被误检出来(作为本应不该检测出来的负样本却被误检出为正样本的FP)。 根据这一问题的解决办法,除了可以对正样本特征较为模糊或者有歧义的样…

Intel SGX学习笔记(2):用数组向Enclave传递5个数实现自增操作

写在前面 1、实现一个简单的Intel SGX的应用:非安全区定义初始化一个数组,数组里面存储5个数,然后向安全区(enclave)传入,在安全区中进行加减乘除,然后返回。 2、Intel SGX开发初学整体思路&a…

代码随想录算法训练营day39 | 62.不同路径,63. 不同路径 II

代码随想录算法训练营day39 | 62.不同路径,63. 不同路径 II 62.不同路径解法一:动态规划解法二:深度搜索(明天补充)解法三:数论(明天补充) 63. 不同路径 II解法一:动态规…

RuoYi-Vue下载与运行

一、源码下载 若依官网:RuoYi 若依官方网站 鼠标放到"源码地址"上,点击"RuoYi-Vue 前端分离版"。 跳转至Gitee页面,点击"克隆/下载",复制HTTPS链接即可。 源码地址为:https://gitee.…

左值引用、右值引用,std::move() 的汇编解释

1:左值引用 引用其实还是指针,但回避了指针这个名字。由编译器完成从地址中取值。以vs2019反汇编: 如图,指针和引用的汇编代码完全一样。但引用在高级语言层面更友好,对人脑。比如可以少写一个 * 号和 -> 。 &…

F280049C实现Simulink调制,以及多个PWM实例之间的同步

文章目录 前言基本概念调制发波载波同步问题 前言 最近作实验碰到了载波不同步的问题,以前也有碰到过这个问题,现在终于解决了,做个记录。 为了以示区分,实例指ePWMx,x1,2,3,4,5,6,7,8;通道指ePWMxA/B&am…

如何使用jmeter进行压测

目录 1.概述 2.测试计划、线程组、取样器 3.调试运行 4.请求默认值 5.流量录制 6.模拟时间间隔 7.压力测试 8.报表 1.概述 一款工具,功能往往是很多的,细枝末节的地方也很多,实际的测试工作中,绝大多数场景会用到的也就是…

看大老如何用Postman+Jmeter实现接口实例

一、接口基础 为什么要单独测试接口? 1. 程序是分开开发的,前端还没有开发,后端已经开发完了,可以提前进入测试 2. 接口直接返回的数据------越底层发现bug,修复成本是越低的 3. 接口测试能模拟功能测试不能测到的异常…

数十位高级测工联合讲解Selenium自动化测试框架工作原理

一、Selenium是什么?   用官网的一句话来讲:Selenium automates browsers. Thats it!简单来讲,Selenium是一个用于Web应用程序自动化测试工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作浏览器一样。支持…

uvm寄存器模型

一、基础知识 前门访问与后门访问是两种寄存器的访问方式。 所谓前门访问, 指的是通过模拟cpu在总线上发出读指令, 进行读写操作。 在这个过程中, 仿真时间( $time函数得到的时间) 是一直往前走的。而后门访问是与前门访问相对的概念。 它并不通过总线进行读写操作, 而是…

2023/5/14周报

目录 摘要 论文阅读 1、标题和现存问题 2、准备知识 3、模型结构 4、实验准备 5、实验结果 深度学习 1、大气数据和水质数据 2、数据清洗 3、项目框架设定 总结 摘要 本周在论文阅读上,阅读了一篇时空图卷积网络:交通预测的深度学习框架的论文。文章的时…

oracle使用with as创建临时表

一、业务需求 在oracle项目的开发过程中,使用sql编写好对应的分析报表内容后,由于sql分析报表涉及到的一些线别丢失,导致呈现的报表分类统计时固定用醒目颜色标识的统计行数据显示错位;因此需要修复分析报表填充完整的线别。 二、…