用随机森林算法进一步筛选差异表达基因

前言

很多时候,我们分析完差异表达基因后,发现会得到一大堆差异基因,常见的做法有降低Pvalue的阈值,挑选fold-change最大的基因,做通路富集然后挑重要通路上的基因。本文主要讲述在差异基因表达分析后,用随机森林的方法进一步找出差异基因里面,对表型影响最大的基因,作为我们的下游研究。

本文主要参考下列文章

对方向扔了一个赤果果的生信分析SCI思路
机器学习之随机森林(R)randomFordom算法案例
机器学习算法之随机森林的R语言实现-表达芯片示例

本文思路

TCGA下载乳腺癌数据,把病人分成生存时间小于三年生存时间大于五年两组,两组进行差异表达分析,然后用随机森林找出最重要的几个基因。

分析步骤

数据下载

library(TCGAbiolinks)
library(dplyr)
library(DT)
library(SummarizedExperiment)

#数据下载
#下面填入要下载的癌症种类
# if (!requireNamespace("BiocManager", quietly=TRUE))
#   install.packages("BiocManager")
# BiocManager::install("TCGAbiolinks")
# 
# 
# if (!requireNamespace("BiocManager", quietly=TRUE))
#   install.packages("BiocManager")
# BiocManager::install("TCGAbiolinksGUI", dependencies = TRUE)
# 
request_cancer=c("BRCA")
for (i in request_cancer) {
  cancer_type=paste("TCGA",i,sep="-")
  print(cancer_type)
  #下载临床数据
  clinical <- GDCquery_clinic(project = cancer_type, type = "clinical")
  write.csv(clinical,file = paste(cancer_type,"clinical.csv",sep = "-"))
  
  #下载rna-seq的counts数据
  query <- GDCquery(project = cancer_type, 
                    data.category = "Transcriptome Profiling", 
                    data.type = "Gene Expression Quantification", 
                    workflow.type = "HTSeq - Counts")
  
  GDCdownload(query, method = "api")
  expdat <- GDCprepare(query = query)
  count_matrix=assay(expdat)
  write.csv(count_matrix,file = paste(cancer_type,"Counts.csv",sep = "-"))
  
}

用DESeq2包进行差异分析分析

#载入包,并启用8核并行运算
library(DESeq2)
library(BiocParallel)
register(MulticoreParam(8))
#clinical=read.csv("TCGA-BRCA-clinical.csv",header = T,row.names = 1)
#count_matrix=read.table("TCGA-BRCA-Counts.csv",row.names = 1,sep=",")


#首先对病人进行分组
poor_OS_patients=clinical[clinical$days_to_death <= 1095 & clinical$vital_status == "dead" & is.na(clinical$days_to_death) == F ,]
poor_OS_patients[,1]=gsub("-",".",poor_OS_patients[,1])
good_OS_patients=clinical[clinical$days_to_death >= 1825 | clinical$vital_status == "alive",]
good_OS_patients[,1]=gsub("-",".",good_OS_patients[,1])

#处理表达矩阵
count_matrix_t=as.data.frame(t(count_matrix))
#去掉normal的数据
count_matrix_t1=cbind(row.names(count_matrix_t),count_matrix_t)
count_matrix_t1=count_matrix_t1[substr(count_matrix_t1[,1],14,15) < 10,]
#分割成两个矩阵
count_matrix_t2=cbind(count_matrix_t1[,1],count_matrix_t1)
colnames(count_matrix_t2)[1]=colnames(poor_OS_patients)[1]
count_matrix_t2[,1]=substr(count_matrix_t2$submitter_id,1,12)
poor_matrix=merge(count_matrix_t2,poor_OS_patients,by=colnames(poor_OS_patients)[1])
good_matrix=merge(count_matrix_t2,good_OS_patients,by=colnames(poor_OS_patients)[1])

#构建差异分析矩阵

database=cbind(t(poor_matrix),t(good_matrix))[2:56717,]
patients_barcode=database[1,]
colnames(database)=patients_barcode
database=database[-1,]
mode(database)="numeric"
condition <- factor(c(rep("poor_OS",length(poor_matrix[,1])),rep("good_OS",length(good_matrix[,1]))))
coldata <- data.frame(row.names = colnames(database), condition)
dds <- DESeqDataSetFromMatrix(countData=database, colData=coldata, design=~condition)
nrow(dds)
dds <- dds[ rowSums(counts(dds)) > 1, ]
nrow(dds)
dds <- DESeq(dds,parallel = T)
res <- results(dds)
summary(res) 
#提取FDR<0.01且|logFC|>1的差异表达基因
table(res$padj<0.01 & abs(res$log2FoldChange)>1)
res <- res[order(res$padj),]
resdata <- merge(as.data.frame(res), as.data.frame(counts(dds, normalized=TRUE)),by="row.names",sort=FALSE)
signresdata<-na.omit(resdata[resdata$padj<0.01 & abs(resdata$log2FoldChange) > 1,])

对以上得到的差异基因进行随机森林分类

#随机森林
# install.packages("randomForest")
# install.packages("ROCR")
# install.packages("Hmisc")
# source("http://bioconductor.org/biocLite.R")
# biocLite("genefilter")

library(randomForest)
library(ROCR)
library(genefilter)
library(Hmisc)
#对差异基因表格进行处理
signres_norm_matrix=signresdata[,-2:-7]
row.names(signres_norm_matrix)=signres_norm_matrix[,1]
signres_norm_matrix=signres_norm_matrix[,-1]
signres_norm_matrix_forest=as.data.frame(t(signres_norm_matrix))

#制作性状表格
trait=as.data.frame(row.names(signres_norm_matrix_forest))
trait=cbind(trait,substr(trait$`row.names(signres_norm_matrix_forest)`,1,12))
colnames(trait)[2]="barcode"
good_trait=cbind(good_OS_patients[,1],rep("good",length(good_OS_patients[,1])))
poor_trait=cbind(poor_OS_patients[,1],rep("poor",length(poor_OS_patients[,1])))
merge_trait=as.data.frame(rbind(good_trait,poor_trait))
colnames(merge_trait)[1]="barcode"
trait=merge(trait,merge_trait,by="barcode")
trait=trait[,-1]
colnames(trait)[1]="barcode"
# barcode=as.character(trait$barcode)
# status=trait$V2
# trait=data.frame(barcode,status)
forest_trait=cbind(row.names(signres_norm_matrix_forest),signres_norm_matrix_forest)
colnames(forest_trait)[1]="barcode"
forest_trait=merge(trait,forest_trait,by="barcode")
colnames(forest_trait)[2]="trait"
row.names(forest_trait)=forest_trait[,1]
forest_trait=forest_trait[,-1]
#将数据集分为2/3训练集和1/3测试集,并查看数据集基本属性。
ind=sample(2,nrow(forest_trait),replace=TRUE, prob=c(0.67,0.33))
train=forest_trait[ind==1,]
test=forest_trait[ind==2,]
#选取mtry节点值,选择误差最小时对应的i值
#每次都set.seed一下,保证数据的可重复性
errset=1:(length(names(train))-1)
for (i in 1:length(names(train))-1){
  set.seed(350)
  mtry_fit=randomForest(trait ~ .,train,mtry=i)
  err=mean(mtry_fit$err.rate)
  print(err)
  errset[i]=err
}
best_mtry=which(errset==min(errset),arr.ind=TRUE)
#选择ntree,选择图像趋于稳定时的树值
set.seed(350)
model <- randomForest(trait~., train, mtry=best_mtry[1], ntree = 1000)
plot(model)
#大约400棵树比较稳定了

#训练集进行随机森林
set.seed(350)
rf <- randomForest(trait~., train, mtry=best_mtry[1], ntree = 400, importance = TRUE)

#查看变量的重要性
importance <- importance(x=rf)

#绘制变量的重要性图
varImpPlot(rf)

#最后验证并预测

pred1<-predict(rf,data=train)
Freq1<-table(pred1,train$trait)
sum(diag(Freq1))/sum(Freq1)
plot(margin(rf,test$trait))
#全体数据用于训练集
set.seed(350)
rf_output=randomForest(trait ~ ., forest_trait, importance = TRUE, mtry=best_mtry[1], ntree = 400, proximity=TRUE)

#查看变量的重要性
importance <- importance(x=rf_output)

#绘制变量的重要性图
varImpPlot(rf_output)

image.png

最后得到的结果,左边是基于精确度的重要性排序,右边是基于基尼系数的重要性排序,最右上的重要性最高。附:重要性的表格

按精确度排序

image.png

按基尼系数排序

image.png

后续待做的工作

以全部数据作为训练集弄出来重要的基因以后,还需要寻找合适的数据,作为测试集,去验证我们的分析是否具有普适性。数据我现在懒得找。

总结

本文的矩阵处理过程略显捉急,自己都觉得有点蠢,不过能够达到目的就行了,反正我也不要求代码简洁,也不要求运行效率多高,出来正确的结果就行。
另外,我只是依样画葫芦,对真正的随进森林算法的理解非常浅薄,还要日后恶补统计学知识,准备抽空看一下《统计学完全教程》,据说很不错。

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