您的位置:首页 > 其它

基于FPGrowth挖掘算法的乳腺癌中医症型关联规则挖掘

2018-01-14 23:03 435 查看
挖掘的总体思路:

首先癌症有不同的发展期

不同发展期的癌症有不同的症型

这些症型都处于不同的严重程度。

因此收集病人样本930条,最终挖掘目标是:

找出这些严重程度不同的症型和癌症发展阶段(我们知道癌症有初期,中期,晚期等)之间的关系(也就是找到症状与疾病之间的关联规则)

数据来自书籍《Python数据分析与挖掘实战》的第8章

书籍《Python数据分析与挖掘实战》中使用了Apriori算法来得到结果,

敝文尝试使用另外一种关联规则挖掘算法:FP-Growth 来获得最终的挖掘结果。

敝文的前半部分代码来自《Python数据分析与挖掘实战》,
后半部分代码通过把挖掘算法Apriori修改为FP-Growth而得,

最终实验结果表明:FP-Growth可以获得与Apriori一样的挖掘效果,并且提升了挖掘速度。

挖掘总流程:

一(对应代码1)、

每人的6种症型(症状名字的代号是A~F,分别对应下面data.xls中的各种症型)都处于不同的严重程度,

每种症型按照严重程度高低用具体数字赋值,然后根据症型的严重程度不度,聚类为四个区间,并根据某病人的某种症状的严重程度对应的数值,归类到四个区间中的某一个区间(下面表格中的区间由后面代码中的Kmeans聚类后得到)。各个症型区间表格如下:







表格用法举例:

例如一个人的肝气郁结症型比较严重,我们可以给他A3或者A4,如果比较轻,我们给他A1或者A2

同样的,症型之间我们认为地位是等同的,一个症型就是一个6维矢量中的其中一维,6个症型构成了一个6维矢量,其实也就是数据挖掘算法眼中的集合。

由于每个病人都有六种症状的不同区间(例如A1,A2,A3,A4),因此每个病人都可以由一个6维矢量(矢量中的每一维代表一种症型)来表示,例如(A1,B3,C2,D2,E2,F4)

这些表格中的各个区间的边界数值都是怎么来的呢?由代码1运行时,通过Kmeans聚类而得

代码1:

# -*- coding: utf-8 -*-
'''
聚类离散化,最后的result的格式为:
1 2 3 4
A 0 0.178698 0.257724 0.351843
An 240 356.000000 281.000000 53.000000
即(0, 0.178698]有240个,(0.178698, 0.257724]有356个,依此类推。
'''
from __future__ import print_function
import pandas as pd
from sklearn.cluster import KMeans # 导入K均值聚类算法

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

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

if __name__ == '__main__': # 判断是否主窗口运行,如果是将代码保存为.py后运行,则需要这句,如果直接复制到命令窗口运行,则不需要这句。
for i in range(len(keys)):#每轮循环处理一个症状的聚类和数量统计
print("i=", i)
# 调用k-means算法,进行聚类离散化
print(u'正在进行“%s”的聚类...' % keys[i])
kmodel = KMeans(n_clusters=k, n_jobs=4) # n_jobs是并行数,一般等于CPU数较好
kmodel.fit(data[[keys[i]]].as_matrix()) # 训练模型

r1 = pd.DataFrame(kmodel.cluster_centers_, columns=[typelabel[keys[i]]]) # 聚类中心
print("r1=",r1)
print("label=", typelabel[keys[i]])
#
#
#
r2 = pd.Series(kmodel.labels_).value_counts() # 分类统计
print("r2=",r2)
print("-------------------------------------")
r2 = pd.DataFrame(r2, columns=[typelabel[keys[i]] + 'number']) # 转为DataFrame,记录各个类别的数目
print("r2=", r2)#这一段用来统计聚类中各个类别的数量,并且写入一列中,并改改名字
#
#
#
#
r=pd.concat([r1, r2], axis=1)
print("排序前r=",r)
r=r.sort_values(typelabel[keys[i]])
print("排序后r=",r)
r.index = [1, 2, 3, 4]#index指的是列标签,typelabel[keys[i]]指的是行标签
#
#
#
#
print("----------------------------------------------------")
print("计算均值前的表格r=",r)
r[typelabel[keys[i]]] = pd.rolling_mean(r[typelabel[keys[i]]], 2) # rolling_mean()用来计算相邻2列的均值,以此作为边界点。
r[typelabel[keys[i]]][1] = 0.0 # 这两句代码将原来的聚类中心改为边界点.这里的用法类似于C语言中的r[i][j]
print("计算均值后的表格r=",r)
result = result.append(r.T)#旋转
print("----------------------------------------------------")
#
#
#
#
print("result=",result)
result = result.sort_index() # 以Index排序,即以A,B,C,D,E,F顺序排,A代表症状的名称,BCDE各自代表该症状的严重程度
result.to_excel(processedfile)

运行代码1后得到聚类处理后的文件为data_processed.xls(各种症型的数据统计),得到上面的表格9~14,同时也得到统计结果:

输出的结果是:

 1234
A00.1786975890.25772406430.3518431814
Anumber24035628153
B00.15076622770.29663131310.4897045019
Bnumber32539618029
C00.20214872930.28906113770.4235365546
Cnumber29739420435
D00.17650463630.25711995250.3661899988
Dnumber30937121139
E00.15269780220.25754132230.3748694473
Enumber27331924296
F00.17914337550.26138639440.354642668
Fnumber200237265228
结合输入文件data.xls
由于得到了每种症状的各种严重程度的量化区间,所以把data.xls中的各个参数(例如A症状)转化为A1~A4
转化办法如下:
data.xls中,对每行的首单元进行按行排序,由于data.xls中第一列的各项数据处于data_processed.xls的四个区间中,
分别改为A1~A4,从而得到下一份代码需要的文件data.txt文件(可从百度网盘下载:https://pan.baidu.com/s/1miZgHMo),

举个例子说明data.txt中的的每行数据是什么意思:

例如,data.xls第一行的数据是:

0.175,0.682,0.171,0.535,0.419,0.447

由于Kmeans得到了“症型对应的数值的聚类中心”,得到的结果其实就是上文中的表8-9,8-10,8-11,8-12,8-13,8-14,

根据症型的数值查表,得到由于0.175在区间(0,0.179]中,靠近聚类中心0.179,所以0.175替换为A2,同样地:

0.682查表8-10,归类为B1

0.171查表8-11,归类为C3

0.535查表8-12,归类为D3

0.419查表8-13,归类为E1

0.447查表8-14,归类为F1

以此类推,把6维向量(0.175,0.682,0.171,0.535,0.419,0.447)转化成(A2,B1,C3,D3,E1,F1,H1)

用代码批量转化即可,转化结果为data.txt,可从百度网盘下载:
https://pan.baidu.com/s/1miZgHMo
二(对应代码2)、这里使用FP-Growth算法来进行挖掘,找出不同严重程度的症状和mammary cancer

发展时期之间的联系,也就是说,找出哪些症状(例如A3和B5)极有可能导致乳腺癌之间的某个特定的发展阶段(例如H5),例如,肾脏发炎和肝硬化有较大概率导致乳腺癌(这里只是举个例子,不一定符合真实情况)挖掘结束。

代码2:
#-*- encoding:utf-8 -*-
import sys
reload(sys)
import pyfpgrowth
sys.setdefaultencoding('utf-8')

path='./data.txt'
def read_data(path):
data_lists=[]
f = open(path) # 返回一个文件对象
line = f.readline() # 调用文件的 readline()方法

for line in open(path):
# print type(line)
print line # 后面跟 ',' 将忽略换行符
# print(line, end = '')   # 在 Python 3中使用
lists_cell=line.replace('\n','').split(",")#去掉回车键,以逗号作为分隔符
data_lists.append(lists_cell)
line = f.readline()
f.close()
return data_lists

transactions=read_data(path)
# print "transactions=",transactions
print len(transactions)
print type(transactions)

patterns = pyfpgrowth.find_frequent_patterns(transactions, 56)#2 这个位置的参数代表支持度,也就是说出现数量56次以上
rules = pyfpgrowth.generate_association_rules(patterns, 0.87)#0.7 这个位置的参数代表置信度

print "FPGrowth关联规则挖掘结果:"
for k,v in rules.items():
print k
print v
print"-"*20


代码运行结果:
FPGrowth关联规则挖掘结果:

('A3', 'F4')

(('H4',), 0.8795180722891566)

--------------------

('C3', 'F4')

(('H4',), 0.875)

--------------------

[Finished in 0.1s]

与书上P192结果进行比较,可以发现,虽然书上用的是Apriori,此处使用的是FPGrowth,挖掘得到的关联规则是一致的:



最后解释下实验结果:

顺便解释下基本概念:

下面的support指的是,‘并’的关系

Support(A=>B)=P(AUB)

置信度指的是:条件概率

Confidence(A=>B)=P(B|A)

那么FpGrowth的挖掘结果可以解释为:

当肝气郁结症型系数位于A3区间,并且 肝肾阴虚症型系数位于F4区间,在这两个前提的条件下,处于mammary cancer H4阶段的概率为0.8795180722891566

在总样本中,这种情况发生的概率是0.078495,代码中有个数字是56,设置办法是:930*0.078495=56
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: