R语言判别分析

article/2025/9/16 22:46:45

本文首发于公众号:医学和生信笔记,完美观看体验请至公众号查看本文。


文章目录

    • Fisher判别分析
    • Bayes判别分析

判别分析(discriminant analysis)是根据判别对象若干个指标的观测结果判定其属于哪一类的统计方法。经典的判别分析方法有Fisher判别和贝叶斯判别分析。当分类很确定时,判别分析可以有效替代logistic回归,但是如果自变量和因变量关系很复杂时,判别分析表现不如logistic回归。

Fisher判别分析

Fisher判别又称为典型判别(canonical discriminant)分析,适用于两类和多分类判别。

Fisher判别使用贝叶斯定理确定每个观测属于某个类别的概率。如果你有两个类别,比如良性和恶性,判别分析会分别计算属于两个类别的概率,然后选择概率大的类别作为正确的类别。

线性判别分析假设每个类中的观测服从多元正态分布,并且不同类别之间的协方差相等。二次判别假设观测服从正态分布,每种类别都有自己的协方差。

使用孙振球版《医学统计学》第4版例20-1的数据。电子版及配套数据已上传到QQ群,需要的加群下载即可。

收集了22例肝硬化患者的3个指标,其中早期患者(用1表示)12例,晚期患者(用2表示),试做判别分析。

df <- read.csv("../000统计学/例20-1.csv")psych::headTail(df)
##      id  x1  x2  x3   y
## 1     1  23   8   0   1
## 2     2  -1   9  -2   1
## 3     3 -10   5   0   1
## 4     4  -7  -2   1   1
## ... ... ... ... ... ...
## 19   19  -9 -20   3   2
## 20   20  -7  -2   3   2
## 21   21  -9   6   0   2
## 22   22  12   0   0   2

这个数据集中id是编号,x1,x2,x3是自变量,y是因变量。

线性判别分析可以通过MASS包中的lda函数实现:

library(MASS)fit <- lda(y ~ x1+x2+x3, data = df)
fit
## Call:
## lda(y ~ x1 + x2 + x3, data = df)
## 
## Prior probabilities of groups:
##         1         2 
## 0.5454545 0.4545455 
## 
## Group means:
##   x1 x2 x3
## 1 -3  4 -1
## 2  4 -5  1
## 
## Coefficients of linear discriminants:
##           LD1
## x1  0.0395150
## x2 -0.1265698
## x3  0.1792631

Prior probabilities of groups是先验概率,类别1的概率是0.5454545,类别2是0.4545455。

然后给出了每个组在不同类别中的均值。

最下面给出了线性判别系数,如果你的结果变量是3个类别,会给出两组判别系数,这里我的结果变量只有2分类,所以结果只有1组。

结果可以画出来:

plot(fit,type="both")

plot of chunk unnamed-chunk-3

上图是判别分析结果的直方图和密度图,可以看出组间有重合,说明有些分组分错了。

下面用predict提取判别分析的分类结果。

predict用于判别分析可以得到3种类型的结果,class是类别,posterior是概率,x是线性判别评分。

pred <- predict(fit)$class
table(df$y, pred)
##    pred
##      1  2
##   1 11  1
##   2  2  8

可以看到有3个分类分错了,结果还是可以的。

可以查看每个患者的后验概率:

# 查看概率
predict(fit)$posterior
##             1           2
## 1  0.62566758 0.374332416
## 2  0.95508370 0.044916302
## 3  0.89600449 0.103995511
## 4  0.51330556 0.486694443
## 5  0.95464457 0.045355435
## 6  0.88314148 0.116858515
## 7  0.77454260 0.225457398
## 8  0.99508599 0.004914013
## 9  0.89391137 0.106088634
## 10 0.84899794 0.151002059
## 11 0.31960372 0.680396284
## 12 0.64144092 0.358559076
## 13 0.14903037 0.850969632
## 14 0.57026493 0.429735074
## 15 0.13106732 0.868932682
## 16 0.26925350 0.730746503
## 17 0.03911397 0.960886034
## 18 0.04332382 0.956676176
## 19 0.01115243 0.988847571
## 20 0.35826933 0.641730670
## 21 0.90954200 0.090457999
## 22 0.37480490 0.625195100

上面的图我们也可以用ggplot2画出来。

df.plot <- data.frame(LD1 = predict(fit)$x[,1],y = factor(df$y,labels = c("早期患者","晚期患者")))library(ggplot2)ggplot(df.plot, aes(x=LD1, fill=y))+geom_histogram()+facet_wrap(~ y, ncol = 1)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

plot of chunk unnamed-chunk-6

如果你想用这个模型预测新的数据,只需要predict(fit, newdata = xxx)即可。比如我们新建一个数据:

tmp <- data.frame(x1 = c(-9,-7,-9),x2 = c(-18,-2,6),x3 = c(3,3,1))predict(fit, newdata = tmp)
## $class
## [1] 2 2 1
## Levels: 1 2
## 
## $posterior
##            1         2
## 1 0.01736557 0.9826344
## 2 0.35826933 0.6417307
## 3 0.87974275 0.1202573
## 
## $x
##          LD1
## 1  2.4580167
## 2  0.5119296
## 3 -0.9381851

这样就得到新的结果。

我们再用一个iris鸢尾花数据集演示下线性判别分析的结果可视化,这个结果变量是3分类的。

str(iris)
## 'data.frame':	150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...

拟合模型:

library(MASS)fit <- lda(Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width, data = iris)
fit
## Call:
## lda(Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width, 
##     data = iris)
## 
## Prior probabilities of groups:
##     setosa versicolor  virginica 
##  0.3333333  0.3333333  0.3333333 
## 
## Group means:
##            Sepal.Length Sepal.Width Petal.Length Petal.Width
## setosa            5.006       3.428        1.462       0.246
## versicolor        5.936       2.770        4.260       1.326
## virginica         6.588       2.974        5.552       2.026
## 
## Coefficients of linear discriminants:
##                     LD1         LD2
## Sepal.Length  0.8293776  0.02410215
## Sepal.Width   1.5344731  2.16452123
## Petal.Length -2.2012117 -0.93192121
## Petal.Width  -2.8104603  2.83918785
## 
## Proportion of trace:
##    LD1    LD2 
## 0.9912 0.0088

可视化结果:

iris$LD1 <- predict(fit)$x[,1]
iris$LD2 <- predict(fit)$x[,2]library(ggplot2)ggplot(iris, aes(LD1,LD2))+geom_point(aes(color=Species),size=3)

plot of chunk unnamed-chunk-10

ggplot(iris, aes(x=LD1, fill=Species))+geom_histogram()+facet_wrap(~ Species, ncol = 1)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

plot of chunk unnamed-chunk-11

二次判别分析和线性判别分析用法一样。

fit <- qda(y ~ x1+x2+x3, data = df)
fit
## Call:
## qda(y ~ x1 + x2 + x3, data = df)
## 
## Prior probabilities of groups:
##         1         2 
## 0.5454545 0.4545455 
## 
## Group means:
##   x1 x2 x3
## 1 -3  4 -1
## 2  4 -5  1

结果不含判别系数,查看分类结果:

pred <- predict(fit)$class
table(df$y, pred)
##    pred
##      1  2
##   1 10  2
##   2  1  9

也是3个分错了。

Bayes判别分析

贝叶斯判别也是根据概率大小进行判别,要求各类近似服从多元正态分布。当各类的协方差相等时,可得到线性贝叶斯判别函数,当各类的协方差不相等时,可得到二次贝叶斯判别函数。

欲用4个标化后的影像学指标鉴别脑囊肿(1)、胶质瘤(2)、转移瘤(3),收集了17个病例,试建立判别贝叶斯函数。

df <- read.csv("../000统计学/例20-4.csv")df$y <- factor(df$y)psych::headTail(df)
##       x1    x2  x3  x4    y
## 1      6 -11.5  19  90    1
## 2    -11 -18.5  25 -36    3
## 3   90.2   -17  17   3    2
## 4     -4   -15  13  54    1
## ...  ...   ... ... ... <NA>
## 14    10   -18  14  50    1
## 15    -8   -14  16  56    1
## 16   0.6   -13  26  21    3
## 17   -40   -20  22 -50    3

使用klaR包实现贝叶斯判别分析:

library(klaR)fit <- NaiveBayes(y ~ ., data = df)
fit
## $apriori
## grouping
##         1         2         3 
## 0.4117647 0.2352941 0.3529412 
## 
## $tables
## $tables$x1
##        [,1]     [,2]
## 1 -14.42857 38.26163
## 2   0.80000 78.10779
## 3  -6.65000 19.78017
## 
## $tables$x2
##        [,1]     [,2]
## 1 -17.34286 4.103599
## 2 -17.42500 3.085855
## 3 -17.33333 4.143268
## 
## $tables$x3
##       [,1]     [,2]
## 1 12.71429 4.990467
## 2 17.50000 2.081666
## 3 20.16667 6.493587
## 
## $tables$x4
##        [,1]     [,2]
## 1  31.14286 44.03948
## 2   0.00000 30.75711
## 3 -15.00000 35.83295
## 
## 
## $levels
## [1] "1" "2" "3"
## 
## $call
## NaiveBayes.default(x = X, grouping = Y)
## 
## $x
##        x1    x2 x3  x4
## 1     6.0 -11.5 19  90
## 2   -11.0 -18.5 25 -36
## 3    90.2 -17.0 17   3
## 4    -4.0 -15.0 13  54
## 5     0.0 -14.0 20  35
## 6     0.5 -11.5 19  37
## 7   -10.0 -19.0 21 -42
## 8     0.0 -23.0  5 -35
## 9    20.0 -22.0  8 -20
## 10 -100.0 -21.4  7 -15
## 11 -100.0 -21.5 15 -40
## 12   13.0 -17.2 18   2
## 13   -5.0 -18.5 15  18
## 14   10.0 -18.0 14  50
## 15   -8.0 -14.0 16  56
## 16    0.6 -13.0 26  21
## 17  -40.0 -20.0 22 -50
## 
## $usekernel
## [1] FALSE
## 
## $varnames
## [1] "x1" "x2" "x3" "x4"
## 
## attr(,"class")
## [1] "NaiveBayes"

获取预测结果,并查看混淆矩阵:

pred <- predict(fit)$class
table(pred, df$y)
##     
## pred 1 2 3
##    1 7 0 1
##    2 0 3 0
##    3 0 1 5

只有两个分错了。

如果要预测新的数据,只需要predict(fit, newdata = xxx)即可。


本文首发于公众号:医学和生信笔记,完美观看体验请至公众号查看本文。



http://chatgpt.dhexx.cn/article/9QSYr3XF.shtml

相关文章

R 判别分析

判别分析 1. 数据描述2. 调入数据3.Fisher线性判别3.1 计算Fisher线性判别函数3.2 根据线性判别模型对原数据进行预测&#xff0c;并分析预测结果。3.3 对新的数据&#xff08;CF_TD0.31,NI_TA0.06, CA_CL4.23, CA_NS0.62&#xff09;进行判定。 4.距离判别&#xff08;协方差矩…

16种常用的数据分析方法-判别分析

判别分析又称为线性判别分析&#xff08;Linear Discriminant Analysis&#xff09;。产生于20世纪30年代&#xff0c;是利用已知类别的样本建立判别模型&#xff0c;为未知类别的样本判别的一种统计方法。 ​ 判别分析方法目的与特点 目的 判别分析的目的是对已知分类的数据建…

SPSS(十六)SPSS之判别分析(图文+数据集)

SPSS&#xff08;十六&#xff09;SPSS之判别分析&#xff08;图文数据集&#xff09; 判别分析又称“分辨法”&#xff0c;是在分类确定的条件下&#xff0c;根据某一研究对象的各种特征值判别其类型归属问题的一种多变量统计分析方法。 聚类分析与判别分析的区别与联系 都是…

HTML5清除浮动方式,多种方式CSS清除浮动

以下展示了四种方式进行清除浮动 先看一段代码 css .box { border: 1px solid #f00; } .fl { float: left; width: 50px; height: 50px; background: #0f0; margin: 5px; } html 下面是结果 效果展示 因为没有清除浮动&#xff0c;所以子元素没有将父元素撑开&#xff0c;出现上…

清除浮动的四种方式及其原理

前言&#xff1a; 什么是浮动&#xff0c;浮动给我们造成了什么困扰&#xff0c;我们该使用什么方式来解决它。下面会介绍到为什么要清除浮动以及清除浮动的四种方式。 目录: 前言&#xff1a;一、为什么要清除浮动二、清除浮动的第一种方式---给父级盒子添加高度三、清除浮动…

清除浮动的五种方法详解

前言&#xff1a;   在非IE浏览器&#xff08;如Firefox&#xff09;下&#xff0c;当容器的高度为auto&#xff0c;且容器的内容中有浮动&#xff08;float为left或right&#xff09;的元素&#xff0c;在这种情况下&#xff0c;容器的高度不能自动伸长以适应内容的高度&…

清除浮动的几种方法

浮动的布局比标准流高了半个层级&#xff0c;因此它并不占标准流下&#xff0c;如果子元素浮动了&#xff0c;父元素又没有设置高度&#xff0c;此时子元素无法撑开盒子&#xff0c;就如同下面这种情况 没加浮动之前 给son加上浮动之后 可以看到&#xff0c;父元素pink的颜色消…

BFC以及清除浮动四种方式

什么是BFC 先了解常见的三种定位方案&#xff1a; bfc是普通流&#xff1a; 可以将bfc看作是一个属性 2.如何触发bfc 1&#xff0e;根元素() 2&#xff0e;浮动元素(元素的float不是none) 3.绝对定位元素(元素的position为absolute 或 fixed) 4.display为inline-block、tabl…

html清除浮动有几种方法,HTML中清除浮动的几种方法

清除float的常见几种方式: 清除浮动方法(1)在浮动元素后面使用一个空的自身清除浮动的元素。 例如 实例:清除容器中子元素的浮动,让父元素塌陷的高度恢复。 CSS代码: .content{width:100px; border:1px dotted red; } .div-test{width:100px; height:100px; border:1px dot…

css清除浮动的几种方式

前言&#xff1a; CSS 的 Float&#xff08;浮动&#xff09;&#xff0c;会使元素向左或向右移动&#xff0c;其周围的元素也会重新排列。 Float&#xff08;浮动&#xff09;&#xff0c;往往是用于图像&#xff0c;但它在布局时一样非常有用。 css浮动 但是使用了 float …

清除浮动的4种方式

为什么要清除浮动&#xff1f; 清除浮动主要是为了解决&#xff0c;父元素因为子级元素浮动引起的内部高度为0的问题 如下: 给父盒子设置一个boder&#xff0c;内部放两个盒子一个big 一个small&#xff0c;未给big和small设置浮动&#xff0c;则他们会默认撑开父盒子。 当我给…

左联,右联和内联的区别(图示)

感谢midy&#xff01; 转载于:https://www.cnblogs.com/0633shj/archive/2008/05/12/1193660.html

左联接、右联接、内联接、自然联接

前几日面试。面试小哥问我左联接、右联接是什么。一时语塞。好像根本没用到过&#xff0c;也就没在意过&#xff0c;一直都是简单的自然连接。 左联接&#xff1a;也叫左外联接。就是以左表为主&#xff0c;右表为辐&#xff0c;ON 后跟的条件对右表生效。结果中包含全部左表数…

SQL的左联,右联,内联的关系

相信很多人在刚开始使用数据库的INNER JOIN、LEFT JOIN和RIGHT JOIN时&#xff0c;都不太能明确区分和正确使用这三种JOIN操作&#xff0c;本文通过一个简单的例子通俗易懂的讲解这三者的区别&#xff0c;希望对大家能带来帮助。 首先&#xff0c;我们创建示例数据库和表。同时…

sql语句中内联左联右联的区别?

内联查询&#xff1a; inner join ... on ... &#xff0c;不以谁为主&#xff0c;列出满足条件的查询结果集&#xff1b; 左联查询&#xff1a;left join .... on ... &#xff0c; 以昨表为主&#xff0c;列出满足条件的结果集&#xff1b; 右联查询&#xff1a;right join…

SQL内联、左联、右联、全联查询语法

概述&#xff1a;   联合查询效率较高&#xff0c;举例子来说明联合查询&#xff1a;内联inner join 、左联left outer join 、右联right outer join 、全联full outer join 的好处及用法。   联合查询效率较高&#xff0c;以下例子来说明联合查询(内联、左联、右联、全联…

mysql多表左联分组查询

在做项目的时候需要实现一个多表左联加分组查询的逻辑。 下图是前端要显示的数据&#xff1a; 数据来源于三张表&#xff1a; ETC表&#xff1a;cap_etc车辆表&#xff1a;cap_vehicleETC消费表&#xff1a;cap_etc_record 下图是后台的三张数据表&#xff1a; cap_etc: ca…

左联右联内联

left join &#xff08;左连接&#xff09;&#xff1a;返回包括左表中的所有记录和右表中连接字段相等的记录。 right join &#xff08;右连接&#xff09;&#xff1a;返回包括右表中的所有记录和左表中连接字段相等的记录。 inner join &#xff08;等值连接或者叫内连接…

uniapp使用scroll-view实现菜单的左联右和右联左

左联右 <!-- 左 菜品分类--><view class"order-left"><scroll-view scroll-y"true" class"scroll-Hei" :scroll-with-animation"true" :enhanced"true":show-scrollbar"false"><block v-fo…

join操作-内联,左外联,右外联,交叉联,全联

在数据库中新建三张表格&#xff1a; T1 T2 T3 普通查询&#xff1a; select * from T1, T3 where T1.user_id T3.user_id 结果&#xff1a; --------------------------------------------------------------- join就是把两张表格等效当做一张表来查 内联(inner join)&a…