周一至周五 | 9:00—22:00

期刊论文网 > 医学论文 > 皮肤病学论文 > 最新皮肤病论文 红斑鳞状皮肤病类型的判定

最新皮肤病论文 红斑鳞状皮肤病类型的判定

2018-12-19 15:48:00来源:组稿人论文网作者:婷婷

  摘 要

  皮肤疾病是儿童和成人常会发生的疾病。红斑鳞状皮肤病作为皮肤病的典型代表,其诊断更是皮肤病科的一个难题,由于红斑鳞状皮肤病特征之间的相似性,选择对医疗诊断有意义的特征是一个至关重要的环节,而由于病理情况的复杂性,选择更为准确的方法也是极其重要的。本研究通过使用UCI中的真实数据,将最常见的六种皮肤疾病作为研究主题,利用病症和病理之间的关系,应用决策树,K最近邻,支持向量机算法4种方法,分别建立数学模型,对红斑鳞状皮肤病的特征做分类分析,最后选择最有效的分类方法。

  由于该皮肤病在不同时期的表现形式并不一致,所以,我们考虑两种情况:第一种情况将样本数据先按年龄分段,再对每个年龄段进行分析,分别获取训练集和测试集,由此建立判别模型,得出判定结果。第二种情况将年龄作为普通变量,再进行建立数学模型得出判定结果。最后根据不同的判定结果与临床表现的结果数据做对比,最后得出将年龄作为一个变量时模型拟合效果更好,而且支持向量机方法的效果在这两种情况中的表现相比较来说都是最好。

  虽然近年来资讯科技进步,已有许多技术方法应用在医学辅助上,对医学诊断有极大的帮助。但在仍然存在某些医学仪器诊断有困难或无法完全解释疾病,或诊断正确率不高的问题,此时使用机器学习方法与技术就可以挖掘一些隐性或未知的资讯,可作为辅助诊断的一种新的医疗工具。

  关键词:K最近邻;决策树;随机森林;支持向量机;机器学习

  1 引 言

  皮肤是保护我们身体的第一道防线,可以防止外在的细菌及一些危害物质,使它们不能够轻易地入侵到我们的体内,并且能防止体内水分散失。如果没有皮肤,我们根本就不能生存。皮肤作为人体的第一道生理防线和最大的器官,时刻参着机体的功能活动,维持着机体和自然环境的对立统一,机体的异常情况也可以在皮肤表面反映出来。

  红斑鳞状皮肤病是以红斑鳞状为主要特征的皮肤,是皮肤科常见的一类疾病。在临床上主要包括银屑病、玫瑰糠疹、扁平苔藓、毛发红糠疹、脂溢性皮炎、慢性皮炎六类,在实际诊断中,通过活组织切片检查是必要的手段,但是红斑鳞状皮肤病病种及成因很复杂,他们的外在表现都是皮肤出现红斑、红斑部位萎缩和皮肤脱落,并且都有许多相同的临床特征和病理学特征,往往在疾病初期呈现为一种疾病的特征,而在接下来的几个阶段又显现为其他疾病所具有的特征。由于该疾病共享许多难以区分的临床特征,增加了医生对红斑鳞状皮肤病诊断的难度,对该疾病的精确诊断是皮肤病科的一个难题。医疗诊断过程是医生根据临床经验对病人进行推理诊断的决策过程,诊断失误有可能付出严重的生命代价,而这在很大程度上依据于医生的经验,同时决策过程也容易受到主观倾向和外界的干扰,容易做出偏差较大的诊断。

  4 数据概况

  该数据集有34个特征,366个皮肤疾病案例样本,其中有9个样本有缺失数据,这9个数据的缺失表现为年龄变量上出现“0”和“?”,这显然是错误数据。由于9个样本占总体样本的比例较小,因此我们考虑直接删除这些缺失数据。

  4.1 原始数据展示

  在样本数据中,0表示没有表现此特征,3表示重度表现,1、2表示表现程度相对中间值,这里变量名称用Xi(i=1,2,…,35)表示。

  4.2 数据处理

  筛选出年龄缺失情况,以及一个0岁的样本,不列入研究范围,因缺失值较少,故采用直接删除缺失值的方法,本实验中剔除了这些有特征缺失的样本,实际使用了357个样本。

  5 方法原理

  1.K最近邻法(KNN法)

  如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性,该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。

  KNN方法在类别决策时,只与极少量的相邻样本有关。由于kNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。

  2.决策树

  决策树是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解法。由于这种决策分支画成图形很像一棵树的枝干,故称决策树。此方法将初始的包含大量信息的数据集,按照一定的划分条件逐层分类至不可再分或不需再分,充分形成树。其中的分类树类型是针对于目标变量时离散型的情况,即最终目标是预测各样本的所属类型。下图是一个决策树的示例,树的内部结点表示对某个属性的判断,该结点的分支是对应的判断结果;叶子结点代表一个类标。

  3.随机森林

  随机森林是一种比较新的机器学习模型。经典的机器学习模型是神经网络,有半个多世纪的历史了。神经网络预测精确,但是计算量很大。上世纪八十年代Breiman等人发明分类树的算法(Breiman et al. 1984),通过反复二分数据进行分类或回归,计算量大大降低。2001年Breiman把分类树组合成随机森林(Breiman 2001a),即在变量(列)的使用和数据(行)的使用上进行随机化,生成很多分类树,再汇总分类树的结果。随机森林在运算量没有显著提高的前提下提高了预测精度。随机森林对多元共线性不敏感,结果对缺失数据和非平衡的数据比较稳健,可以很好地预测多达几千个解释变量的作用(Breiman 2001b),被誉为当前最好的算法之一。

  通过自助法重采样技术,从原始训练样本集中有放回的随机重复抽取k个样本生成新的训练集样本集合,然后根据自助样本集生成k个决策树组成的随机森林,新数据的分类结果按决策树投票多少形成的分数而定。实质是对决策树算法的一种改进,将多个决策树合并在一起,每棵树的建立依赖于一个独立抽取的样本,森林中的每棵树具有相同的分布,分类误差取决于每棵决策树的分类能力和它们之间的相关性。

  随机森林的构建过程:

  4.支持向量机

  支持向量机(Support Vector Machine)是Cortes和Vapnik于1995年首先提出的,它在解决小样本、非线性及高维模式识别中表现出许多特有的优势,并能够推广应用到函数拟合等其他机器学习问题中。

  支持向量机方法是建立在统计学习理论的VC 维理论和结构风险最小原理基础上的,根据有限的样本信息在模型的复杂性(即对特定训练样本的学习精度,Accuracy)和学习能力(即无错误地识别任意样本的能力)之间寻求最佳折衷,以期获得最好的推广能力(或称泛化能力)。

  支持向量机的定义是:根据给定的训练集

  其中, ,X称为输入空间,输入空间中的每一个点由n个属性特征组成, , 。寻找 上的一个实值函数 ,以便用分类函数

  推断任意一个模式x相对应的y的值的问题为分类问题。

  支持向量机(SVM,也称支持矢量网络)是与相关的学习算法有关的监督学习模型,可以分析数据,识别模式,用于分类和回归分析以及模型的识别、概率密度估计。通过寻求结构风险最小化来实现实际风险的最小化,追求在有限信息的条件下得到最优结果。给定一组训练样本,每个标记为属于两类,一个SVM训练算法建立了一个模型,分配新的实例为一类或其他类,使其成为非概率二元线性分类。一个SVM模型的例子,如在空间中的点,映射,使得所述不同的类别的例子是由一个明显的差距是尽可能宽划分的表示。新的实施例则映射到相同的空间中,并预测基于它们落在所述间隙侧上属于一个类别。

  6 模型求解过程及分析

  6.1 按年龄分组的建模过程

  说明:由于不同分组的样本抽样方式以及生成和预测训练集与测试集的方式均相同,考虑到由于篇幅问题,故在本文中只对少年组具体解释,其他分组只对输出结果进行解释,其余具体操作程序包含在附件中。

  读取数据集:

  > data=read.table("D:\\DATA\\数据集.txt",header=T)#读取数据集

  > head(data) #查看数据集x的前若干条数据

  > dim(data)#显示维度

  [1] 357 35 #样本数据共357行,35列

  6.1.1 K最近邻法

  对数据按年龄进行分组程序解释及运行结果如下:

  >install.packages(sampling)

  > library(sampling) #安装并加载sampling软件包

  > x=data[,34]

  > A=data[which(x<=17),]

  > B=data[which(17

  > C=data[which(x>40),]

  #按年龄分段,小于等于17岁为少年组,用A表示,17-40岁为青壮年组,用B表示,大于40岁为中年组,用C表示

  >nrow(A);nrow(B);nrow(C)#显示每个年龄段包含的样本数

  [1] 37 #少年组37人

  [1] 182 #青壮年组182人

  [1] 138 #中年组138人

  (1)少年组(7-17岁):

  按疾病类型进行分层抽样,确保每种疾病都有被抽到的样本,确定每层的抽样个数,并将抽到的样本作为训练集。

  > a1=round(2/3*sum(A$"group"=="第1类"))

  > b1=round(2/3*sum(A$"group"=="第2类"))

  > c1=round(2/3*sum(A$"group"=="第3类"))

  > d1=round(2/3*sum(A$"group"=="第4类"))

  > e1=round(2/3*sum(A$"group"=="第5类"))

  > f1=round(2/3*sum(A$"group"=="第6类"))

  #以上是按皮肤病的种类进行分层,并以训练集和测试集的比例为2:1抽取样本

  > a1;b1;c1;d1;e1;f1 #显示每种皮肤病应抽取的样本数

  [1] 3

  [1] 3

  [1] 1

  [1] 2

  [1] 3

  [1] 13

  分析:由输出结果知六类皮肤病应该分别抽取3,3,1,2,3,13个样本构成测试集。

  为了保证实验结果的可信度,设置随机种子,以保持每次抽取样本一致:

  >set.seed(0)

  > A=A[order(A$group),]

  >CY_A=strata(A,stratanames=c("group"),size=c(a1,b1,c1,d1,e1,f1),method="srswor") #对六种皮肤病进行分层抽样

  > CY_A #显示抽取的样本

  > data_train_A=A[CY_A$ID_unit,] #生成训练data_train

  > data_test_A=A[-CY_A$ID_unit,] #生成测试data_test

  > nrow(data_train_A);nrow(data_test_A) #显示训练集、测试集行数,检查其比例是否为2:1

  [1] 25

  [1] 12

  >install.packages("class")

  > library(class)#安装并加载class软件包

  ###按照次序向knn()函数中一次放入训练集中各属性变量(除第35个变量"group")、测试集(除第35个变量“group”)、训练集中的判别变量(第35个变量“group”),并首先取K的默认值1进行判别

  对训练集进行K最近邻分类:

  >fit_knn_A=knn(data_train_A[,-35],data_train_A[,-35],cl=data_train_A[,35])#建立K最近邻判别规则,并对测试集样本进行预测

  > table(data_train_A$group,fit_knn_A)#生成“group”真实值与预测值的混淆矩阵

  fit_knn_A

  第1类 第2类 第3类 第4类 第5类 第6类

  第1类 3 0 0 0 0 0

  第2类 0 3 0 0 0 0

  第3类 0 0 1 0 0 0

  第4类 0 0 0 2 0 0

  第5类 0 0 0 0 3 0

  第6类 0 0 0 0 0 13

  >error_knn_A=sum(as.numeric(as.numeric(fit_knn_A)!=as.numeric(data_train_A$group)))/nrow(data_train_A)#计算错误率

  > error_knn_A #输出错误率

  [1] 0

  对测试集进行K最近邻分类:

  >fit_knn_A1=knn(data_train_A[,-35],data_test_A[,-35],cl=data_train_A[,35]) #建立K最近邻判别规则,并对测试集样本进行预测

  > table(data_test_A$group,fit_knn_A1)#生成“group”真实值与预测值的混淆矩阵

  fit_knn_A1

  第1类 第2类 第3类 第4类 第5类 第6类

  第1类 1 0 0 0 0 1

  第2类 0 0 0 1 0 0

  第3类 0 0 0 0 0 0

  第4类 0 0 0 1 0 0

  第5类 0 0 0 0 2 0

  第6类 0 0 0 0 0 6

  >error_knn_A1=sum(as.numeric(as.numeric(fit_knn_A1)!=as.numeric(data_test_A$group)))/nrow(data_test_A)#计算错误率

  > error_knn_A1 #输出错误率

  [1] 0.1666667

  分析:由混淆矩阵得出在训练集上分类全部判定正确,在测试集上第一类和第二类皮肤病分类错误,错误率为0.1666667,且无第三类。

  (2)青壮年组(18-40岁):

  训练集:

  > table(data_train_B$group,fit_knn_B)

  #生成“group”真实值与预测值的混淆矩阵

  fit_knn_B

  第1类 第2类 第3类 第4类 第5类 第6类

  第1类 36 0 0 0 0 0

  第2类 0 23 0 0 0 0

  第3类 0 0 24 0 0 0

  第4类 0 0 0 21 0 0

  第5类 0 0 0 0 17 0

  第6类 0 0 0 0 0 1

  > error_knn_B #输出错误率

  [1] 0

  测试集:

  > table(data_test_B$group,fit_knn_B1)#生成“group”真实值与预测值的混淆矩阵

  fit_knn_B1

  第1类 第2类 第3类 第4类 第5类 第6类

  第1类 18 0 0 0 0 0

  第2类 0 7 0 4 0 0

  第3类 0 0 12 0 0 0

  第4类 0 4 0 5 1 0

  第5类 0 0 0 1 8 0

  第6类 0 0 0 0 0 0

  > error_knn_B1 #输出错误率

  [1] 0.1666667

  分析:青壮年组的测试集出现分类错误更多,而且无第六类。

  (3)中年组(40岁以上):

  训练集:

  > table(data_train_C$group,fit_knn_C)#生成“group”真实值与预测值的混淆矩阵

  fit_knn_C

  第1类 第2类 第3类 第4类 第5类 第6类

  第1类 34 0 0 0 0 0

  第2类 0 15 0 0 0 0

  第3类 0 0 23 0 0 0

  第4类 0 0 0 9 0 0

  第5类 0 0 0 0 11 0

  第6类 0 0 0 0 0 0

  > error_knn_C #输出错误率

  [1] 0

  测试集:

  > table(data_test_C$group,fit_knn_C1)#生成“group”真实值与预测值的混淆矩阵

  fit_knn_C1

  第1类 第2类 第3类 第4类 第5类 第6类

  第1类 15 0 0 0 2 0

  第2类 0 5 0 2 0 0

  第3类 0 0 11 0 0 0

  第4类 0 2 0 3 0 0

  第5类 0 0 0 0 6 0

  第6类 0 0 0 0 0 0

  > error_knn_C1 #输出错误率

  [1] 0.1304348

  分析:由以上使用K最近邻方法的实验结果可以看出,此方法在三个年龄组的训练集上的错误率均为0,在测试集上错误率为0.1666667;青壮年组在测试集上的错误率为0.1666667;中年组在测试集上的错误率为0.1304348,且体现在第一、二、四、五类皮肤病的分类上,也无第六类。

  6.1.2 决策树

  训练集和测试集抽取方式与K最近邻方法相同。

  程序及运行结果

  #安装并加载rpart、rpart.plot二个软件包:

  >install.packages("rpart")

  >library(rpart)

  > install.packages("rpart.plot")> library(rpart.plot)

  (1)少年组

  > formula_data_A=group~. #设定模型公式

  > rp_data_A=rpart(formula_data_A,data_train_A,method="class") #按公式对训练集构建分类树

  > print(rp_data_A) #导出分类树的基本信息

  n= 25

  node), split, n, loss, yval, (yprob)

  * denotes terminal node

  1) root 25 12 第6类 (0.12 0.12 0.04 0.08 0.12 0.52)

  2) x7< 0.5 12 9 第1类 (0.25 0.25 0.083 0.17 0.25 0) *

  3) x7>=0.5 13 0 第6类 (0 0 0 0 0 1) *

  > rpart.plot(rp_data_A,type=4) #绘制分类树

  分析:由决策树可以直观的看到,在7-17岁的患者中只有第1类和第六类皮肤病。

  训练集预测:

  > table(data_train_A$group,pre_data_A) #获取混淆矩阵

  pre_data_A

  第1类 第2类 第3类 第4类 第5类 第6类

  第1类 3 0 0 0 0 0

  第2类 3 0 0 0 0 0

  第3类 1 0 0 0 0 0

  第4类 2 0 0 0 0 0

  第5类 3 0 0 0 0 0

  第6类 0 0 0 0 0 13

  >(p=sum(as.numeric(pre_data_A!=data_train_A$group))/nrow(data_train_A)) #计算错误率

  [1] 0.36

  分析:在混淆矩阵中可看到,在少年段决策树对疾病的分类并不理想,第2类,第3类,第4类,第5类皮肤病均有判定错误,且错误率较高。

  测试集预测:

  > pre_data_A=predict(rp_data_A,data_test_A,type="class") #对测试集中观测样本的“group”变量进行预测

  > table(data_test_A$group,pre_data_A)#获取混淆矩阵

  pre_data_A

  第1类 第2类 第3类 第4类 第5类 第6类

  第1类 2 0 0 0 0 0

  第2类 1 0 0 0 0 0

  第3类 0 0 0 0 0 0

  第4类 1 0 0 0 0 0

  第5类 1 0 0 0 0 1

  第6类 0 0 0 0 0 6

  >(p=sum(as.numeric(pre_data_A!=data_test_A$group))/nrow(data_test_A))#计算错误率

  [1] 0.3333333

  分析:相对于训练集,在测试集上的错误率有一定的下降,但仍然较高。

  (2)青壮年组

  > rpart.plot(rp_data_B,type=4) #绘制分类树

  分析:由青壮年组的分类树可以直观的看出在18-40岁的患者中并不存在第六类皮肤病。

  > table(data_train_B$group,pre_data_B) #获取混淆矩阵

  pre_data_B

  第1类 第2类 第3类 第4类 第5类 第6类

  第1类 35 1 0 0 0 0

  第2类 0 22 0 1 0 0

  第3类 0 0 24 0 0 0

  第4类 0 5 0 16 0 0

  第5类 0 0 0 0 17 0

  第6类 0 1 0 0 0 0

  >(p=sum(as.numeric(pre_data_B!=data_train_B$group))/nrow(data_train_B)) #计算错误率

  [1] 0.06557377

  分析:由混淆矩阵可以看出,在训练集上对于第一类,第二类,第三类,第五类的分类效果较好,并没有错误判定,但是对于第四类和第六类的判定上均出现了错误,但错误率相对于少年组有所降低。

  测试集:

  > table(data_test_B$group,pre_data_B)#获取混淆矩阵

  pre_data_B

  第1类 第2类 第3类 第4类 第5类 第6类

  第1类 18 0 0 0 0 0

  第2类 0 11 0 0 0 0

  第3类 0 0 12 0 0 0

  第4类 0 2 0 8 0 0

  第5类 0 0 0 0 9 0

  第6类 0 0 0 0 0 0

  >(p=sum(as.numeric(pre_data_B!=data_test_B$group))/nrow(data_test_B))#计算错误率

  [1] 0.03333333

  分析:由混淆矩阵可以看出,在测试集上的判定效果更好了,只有第四类出现两个判定错误,且错误率较训练集上有降低。

  (3)中年组

  > rpart.plot(rp_data_C,type=4) #绘制分类树

  分析:由中年组的分类决策树可直观的看到,在17-40岁的青壮年患者中也不存在第6种皮肤病。

  训练集预测:

  > table(data_train_C$group,pre_data_C) #获取混淆矩阵

  pre_data_C

  第1类 第2类 第3类 第4类 第5类 第6类

  第1类 33 1 0 0 0 0

  第2类 0 15 0 0 0 0

  第3类 0 0 23 0 0 0

  第4类 0 1 0 8 0 0

  第5类 0 0 0 0 11 0

  第6类 0 0 0 0 0 0

  >(p=sum(as.numeric(pre_data_C!=data_train_C$group))/nrow(data_train_C)) #计算错误率

  [1] 0.02173913

  分析:由在训练集上的预测结果混淆矩阵可以看出只有第4类病有分类错误,但相对于少年组,错误率大大降低。

  测试集预测:

  > table(data_test_C$group,pre_data_C)#获取混淆矩阵

  pre_data_C

  第1类 第2类 第3类 第4类 第5类 第6类

  第1类 17 0 0 0 0 0

  第2类 1 6 0 0 0 0

  第3类 0 0 11 0 0 0

  第4类 0 1 0 4 0 0

  第5类 1 0 0 0 5 0

  第6类 0 0 0 0 0 0

  >(p=sum(as.numeric(pre_data_C!=data_test_C$group))/nrow(data_test_C))#计算错误率

  [1] 0.06521739

  分析:由结果可知,在测试集上的预测结果并不理想,判定结果出现更多错误,且错误率较训练集上升很多。由决策树方法的结果可以看出,虽然仍存在不少判定错误,但相比较于K最近邻法在青壮年组和中年组的错误率已经降低很多了。

  6.1.3 支持向量机

  支持向量机的训练集和测试集抽取方式与前两种方法相同。

  #安装并加载e1071软件包

  >install.packages(e1071)

  > library("e1071")

栏目分类