数量生态学笔记||聚类外部验证

对每一种聚类算法的结果我们都会遇到一个真实的问题:就是这个结果能否反映真实的生态情况。我们已经看到内部准则(如轮廓法或其他聚类质量指数) 都仅仅是依赖物种数据,还不足以选择最佳聚类结果。选择最终的聚类结果有时也需要基于生态学解释。生态学解释可视为样方聚类的外部验证。

利用外部独立的解释变量验证聚类结果(作为响应数据)可以用判别式分析。当然也可以将样方分组当做因子对解释变量(作为响应数据)进行方差分析,了解解释变量在各组间是否有显著差异。

# 加载所需的程序包
library(ade4)
library(vegan)  # 应该先加载ade4后加载vegan以避免冲突
library(gclus)
library(cluster)
library(RColorBrewer)
library(labdsv)
library(mvpart)
library(MVPARTwrap) # MVPARTwrap这个程序包必须从本地zip文件安装
# 导入CSV格式的数据

rm(list = ls())
setwd("D:\\Users\\Administrator\\Desktop\\RStudio\\数量生态学\\DATA")

spe <- read.csv("DoubsSpe.csv", row.names=1)
env <- read.csv("DoubsEnv.csv", row.names=1)
spa <- read.csv("DoubsSpa.csv", row.names=1)
# 删除无物种数据的样方8
spe <- spe[-8,]
env <- env[-8,]
spa <- spa[-8,]
# 物种多度数据:先计算样方之间的弦距离矩阵,然后进行单连接聚合聚类
# **************************************************************
spe.norm <- decostand(spe, "normalize")
spe.ch <- vegdist(spe.norm, "euc")
spe.ch.single <- hclust(spe.ch, method="single")
# 预转化后物种数据k-均值划分
# ****************************
spe.kmeans <- kmeans(spe.norm, centers=4, nstart=100)

下面的案例展示一样方聚类簇为因子去对解释变量进行方差分析。首先检验某一环境变量是否符合方差分析假设(残差正态性和方差齐性),然后用传统的单因素方差分析或非参数的Kruskal-Wallis检验解释变量在组间是否有显著差异。

# 基于k-均值划分结果(分4组)的样方聚类簇与4个环境变量的关系
# *************************************************************
attach(env)
# 定量环境变量箱线图
# 海拔、坡度、氧含量和铵浓度
par(mfrow=c(2,2))
boxplot(sqrt(alt) ~ spe.kmeans$cluster, main="海拔", las=1, 
  ylab="sqrt(alt)", col=2:5, varwidth=TRUE)
boxplot(log(pen) ~ spe.kmeans$cluster, main="坡度", las=1, 
  ylab="log(pen)", col=2:5, varwidth=TRUE)
boxplot(oxy ~ spe.kmeans$cluster, main="氧含量", las=1, 
  ylab="oxy", col=2:5, varwidth=TRUE)
boxplot(sqrt(amm) ~ spe.kmeans$cluster, main="铵浓度", las=1, 
  ylab="sqrt(amm)", col=2:5, varwidth=TRUE)
> # 检验方差分析的假设
> # 检验残差的正态性
> shapiro.test(resid(lm(sqrt(alt) ~ as.factor(spe.kmeans$cluster))))

    Shapiro-Wilk normality test

data:  resid(lm(sqrt(alt) ~ as.factor(spe.kmeans$cluster)))
W = 0.96238, p-value = 0.3756

> shapiro.test(resid(lm(log(pen) ~ as.factor(spe.kmeans$cluster))))

    Shapiro-Wilk normality test

data:  resid(lm(log(pen) ~ as.factor(spe.kmeans$cluster)))
W = 0.95182, p-value = 0.204

> shapiro.test(resid(lm(log(pen) ~ as.factor(spe.kmeans$cluster))))

    Shapiro-Wilk normality test

data:  resid(lm(log(pen) ~ as.factor(spe.kmeans$cluster)))
W = 0.95182, p-value = 0.204

> shapiro.test(resid(lm(oxy ~ as.factor(spe.kmeans$cluster))))

    Shapiro-Wilk normality test

data:  resid(lm(oxy ~ as.factor(spe.kmeans$cluster)))
W = 0.93941, p-value = 0.09674

> shapiro.test(resid(lm(sqrt(amm) ~ as.factor(spe.kmeans$cluster))))

    Shapiro-Wilk normality test

data:  resid(lm(sqrt(amm) ~ as.factor(spe.kmeans$cluster)))
W = 0.95398, p-value = 0.2319

> #检验结果表明sqrt(alt)、log(pen)、oxy和sqrt(amm)的残差是正态分布。
> #也尝试为其他的环境变量寻找好的标准化转化。
> # 检验方差齐性
> bartlett.test(sqrt(alt), as.factor(spe.kmeans$cluster))

    Bartlett test of homogeneity of variances

data:  sqrt(alt) and as.factor(spe.kmeans$cluster)
Bartlett's K-squared = 16.953, df = 3, p-value = 0.0007227

> bartlett.test(log(pen), as.factor(spe.kmeans$cluster))

    Bartlett test of homogeneity of variances

data:  log(pen) and as.factor(spe.kmeans$cluster)
Bartlett's K-squared = 2.9832, df = 3, p-value = 0.3942

> bartlett.test(oxy, as.factor(spe.kmeans$cluster))

    Bartlett test of homogeneity of variances

data:  oxy and as.factor(spe.kmeans$cluster)
Bartlett's K-squared = 1.8258, df = 3, p-value = 0.6093

> bartlett.test(sqrt(amm), as.factor(spe.kmeans$cluster))

    Bartlett test of homogeneity of variances

data:  sqrt(amm) and as.factor(spe.kmeans$cluster)
Bartlett's K-squared = 5.7203, df = 3, p-value = 0.126

> #变量sqrt(alt)的方差不齐,所以参数检验的方差分析不适用
> #可被参数检验的变量的方差分析 
> summary(aov(log(pen) ~ as.factor(spe.kmeans$cluster)))
                              Df Sum Sq Mean Sq F value  Pr(>F)   
as.factor(spe.kmeans$cluster)  3  18.05   6.018   7.283 0.00114 **
Residuals                     25  20.66   0.826                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
> summary(aov(oxy ~ as.factor(spe.kmeans$cluster)))
                              Df Sum Sq Mean Sq F value   Pr(>F)    
as.factor(spe.kmeans$cluster)  3 103.54   34.51   26.27 6.75e-08 ***
Residuals                     25  32.84    1.31                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
> summary(aov(sqrt(amm) ~ as.factor(spe.kmeans$cluster)))
                              Df Sum Sq Mean Sq F value   Pr(>F)    
as.factor(spe.kmeans$cluster)  3 2.6126  0.8709   49.55 1.15e-10 ***
Residuals                     25 0.4394  0.0176                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
> #坡度、含氧量和铵浓度在不同聚类簇之间是否差异显著?
> # 变量alt的Kruskal-Wallis检验
> kruskal.test(alt ~ as.factor(spe.kmeans$cluster))

    Kruskal-Wallis rank sum test

data:  alt by as.factor(spe.kmeans$cluster)
Kruskal-Wallis chi-squared = 21.526, df = 3, p-value = 8.186e-05

> #海拔在不同聚类簇之间是否有显著差异?
> detach(env)
双类型比较(列联表分析)
> # 两种聚类的列联表 
> # ******************
> # 基于环境变量(见第2章)的样方聚类
> env2 <- env[,-1]
> env.de <- vegdist(scale(env2), "euc")
> env.kmeans <- kmeans(env.de, centers=4, nstart=100)
> env.KM.4 <- env.kmeans$cluster
> # 比较两种聚类的结果
> table(as.factor(spe.kmeans$cluster), as.factor(env.kmeans$cluster))
   
    1 2 3 4
  1 0 4 7 1
  2 1 0 0 2
  3 5 3 0 0
  4 0 4 2 0
> #两种聚类结果是否相同?
> # 用卡方检验分析两种聚类之间的差异 
> chisq.test(as.factor(spe.kmeans$cluster), as.factor(env.kmeans$cluster))

    Pearson's Chi-squared test

data:  as.factor(spe.kmeans$cluster) and as.factor(env.kmeans$cluster)
X-squared = 30.227, df = 9, p-value = 0.0004014

Warning message:
In chisq.test(as.factor(spe.kmeans$cluster), as.factor(env.kmeans$cluster)) :
  Chi-squared近似算法有可能不准
> # 改用置换的方法进行卡方检验分析 
> chisq.test(as.factor(spe.kmeans$cluster), as.factor(env.kmeans$cluster), 
+   simulate.p.value=TRUE)

    Pearson's Chi-squared test with simulated p-value (based on 2000 replicates)

data:  as.factor(spe.kmeans$cluster) and as.factor(env.kmeans$cluster)
X-squared = 30.227, df = NA, p-value = 0.0004998

> # k-均值样方聚类簇平均多度
> # ***********************
> groups <- as.factor(spe.kmeans$cluster)
> as.factor(spe.kmeans$cluster)
 1  2  3  4  5  6  7  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 
 1  1  1  1  4  1  1  4  1  1  1  1  1  1  4  4  4  4  3  3  3  2  2  2  3  3  3  3  3 
Levels: 1 2 3 4
> as.factor(env.kmeans$cluster)
 1  2  3  4  5  6  7  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 
 4  3  3  3  3  3  3  3  3  2  2  2  2  3  2  2  2  2  2  2  2  4  1  4  1  1  1  1  1 
Levels: 1 2 3 4
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容