目录
第1关:数据探索和预处理
实验任务
目前,应用中医药治疗恶性肿瘤已成为公认的综合治疗方法之一,且中医药治疗乳腺癌有着广泛的适应证和独特的优势。从整体出发,调整机体气血、阴阳、脏腑功能的平衡,根据不同的临床证候进行辩证论治。确定“先证而治”的方向:即后续证候尚未出现之前,需要截断恶化病情的哪些后续证候。发现中医症状间的关联关系和诸多症状间的规律性,并且依据规则分析病因、预测病情发展以及为未来临床诊治提供有效借鉴。
本案例使用处于各病程阶段的某疾病患者的病理信息,采用关联规则算法,挖掘各个中医证素与该疾病分期之间的关系,其中I期较轻,IV期较严重。探索不同分期阶段的中医证素分布规律,以及采用截断病变发展、先期干预的治疗思路,指导该疾病的中医临床治疗。
实验数据
使用问卷调查的形式从某省中医院以及肿瘤医院等收集到1253位处于各病程阶段的患者的病理信息数据,对收回的问卷进行有效性条件筛选,将有效问卷整理成原始数据,共计930条记录。之后,选取其中6种证型得分、TNM分期的属性值构成数据集,并对证型得分进行归一化处理获得证型系数。经过以上步骤,得到了本案例中所使用的数据集。
数据集中包含930个样本,每一个患者的病理信息包含7个特征,如下所示:
肝气郁结证
热毒蕴结证
冲任失调证
气血两虚证
脾胃虚寒证
肝肾阴虚证
TNM分期
数据集文件路径为 data/data.xls。
样例数据如下:
本关任务
本实训中,实验内容为完成数据探索和预处理,根据提示,在右侧编辑器补充代码,完成如下四个任务:
使用pandas库的read_excel方法读入实验数据集;
使用 info()函数, 观察数据属性类型并判断是否符合算法要求;
若不符合要求,请选择合适的策略对数据进行离散化处理,即将六种类型数据分别标记为'ABCDEF',再使用等频离散进行离散化。
测试说明
平台会对你编写的代码进行测试,通过正确的输出处理之后的数据进行验证,所以请勿修改函数返回内容。
代码
import pandas as pd
def Task():
# 使用pandas库的read_excel方法读入数据中医数据
#*************** BEIGN ******************
data = pd.read_excel('data/data.xls')
answer_1 = data.head(5)
#**************** END *******************
#*************** BEIGN ******************
#观察数据属性类型是否符合算法要求
info = data.info()
answer_2 = info
#**************** END *******************
#*************** BEIGN ******************
# 使用合适的策略对数据进行离散化处理
typelabel = dict(zip(data.columns[:-1], 'ABCDEF'))
#**************** END *******************
keys = list(typelabel.keys())
answer_3 = keys
# 等频离散
k = 4
datas = list()
#*************** BEIGN ******************
for j in keys:
label = [typelabel[j]+str(i+1) for i in range(k)]
d = pd.qcut(data[j], k, labels=label)
datas.append(d)
#**************** END *******************
datas.append(data['TNM分期'])
# 经过离散化处理后的数据集
datas = pd.DataFrame(datas).T
answer_4 = datas.head(5)
#将离散化后的数据集存储到apriori.txt文件中
filepath = 'data/apriori.txt'
datas.to_csv(filepath, header=0, index=0, sep=',')
return answer_1, answer_2, answer_3, answer_4
第2关:FP增长树算法调用
任务描述
本关的实验任务为:
调用根据提供的FP增长树算法;
实现寻找频繁项集(代码见文件)
FP-growth 实现代码
下面的(1)-(4)包含 FP-growth实现代码,可以直接调用。
(1) FP树节点类
FP-growth算法将数据存储在一种称为FP树的紧凑数据结构中。由于FP树比其他树更加复杂,因此需要一个类来保存树的每一个节点。首先,定义FP树的节点类。
代码如下:
class FPNode(object):
"""FP树中的节点"""
def __init__(self, tree, item, count=1):
self._tree = tree
self._item = item
self._count = count
self._parent = None
self._children = {}
self._neighbor = None
def add(self, child):
"""将给定的fp'孩子'节点添加为该节点的子节点"""
if not isinstance(child, FPNode):
raise TypeError("Can only add other FPNodes as children")
if not child.item in self._children:
self._children[child.item] = child
child.parent = self
def search(self, item):
"""
检查此节点是否包含给定项的子节点。
如果是,则返回该节点; 否则,返回None
"""
try:
return self._children[item]
except KeyError:
return None
def __contains__(self, item):
return item in self._children
@property
def tree(self):
"""出现此节点的树"""
return self._tree
@property
def item(self):
"""此节点中包含的项"""
return self._item
@property
def count(self):
"""与此节点项相关的计数。"""
return self._count
def increment(self):
"""增加与此节点项相关联的计数。"""
if self._count is None:
raise ValueError("Root nodes have no associated count.")
self._count += 1
@property
def root(self):
"""如果此节点是树的根,则为true;否则为false"""
return self._item is None and self._count is None
@property
def leaf(self):
"""如果此节点是树中的叶子,则为true;否则为false"""
return len(self._children) == 0
@property
def parent(self):
"""父节点"""
return self._parent
@parent.setter
def parent(self, value):
if value is not None and not isinstance(value, FPNode):
raise TypeError("A node must have an FPNode as a parent.")
if value and value.tree is not self.tree:
raise ValueError("Cannot have a parent from another tree.")
self._parent = value
@property
def neighbor(self):
"""
节点的邻居;在树中具有相同值的“右边”
"""
return self._neighbor
@neighbor.setter
def neighbor(self, value):
if value is not None and not isinstance(value, FPNode):
raise TypeError("A node must have an FPNode as a neighbor.")
if value and value.tree is not self.tree:
raise ValueError("Cannot have a neighbor from another tree.")
self._neighbor = value
@property
def children(self):
"""该节点的子节点"""