R语言机器学习与临床预测模型87--预测模型的特征筛选及构建

R小盐准备介绍R语言机器学习与预测模型的学习笔记

你想要的R语言学习资料都在这里, 快来收藏关注【科研私家菜】


01 什么是特征构建

特征对于预测而言是相当重要的,在预测建模之前的大部分工作都是在寻找特征,没有合适特征的预测模型,就几乎等于瞎猜,对预测目标而言没有任何意义。特征通常是指输入数据中对因变量的影响比较明显的有趣变量或属性。常见的特征提取、特征构建、特征选择三个概念有着本质不同,特征提取是指通过函数映射从原始特征中提取新特征的过程,假设有n个原始特征(或属性)表示为A.,A....An,通过特征提取我们可以得到另外一组特征,表示为B,B...,m(m<m),其中Bi = f(A,A2,...An),i∈[1,m]且f是对应的函数映射,注意到,这里我们用得到的新特征替代了原始特征,最终得到m个特征;而特征构建是从原始特征中推断或构建额外特征的过程,对于原始的n个特征A.2....An.经过特征构建,我们得到m个额外的特征,表示为An+.,7....An+m.所得到的这些特征都是由原始特征定义的,最终得到n+m个特征。特征选择是指从原始的n个特征中选择m(m<n)个子特征的过程,因此特征选择按照某个标准实现了最优简化,即实现了降维,最终得到m个特征(注意特征并没有发生变化,只是总的数量减少了)。
特征的构建与选取在提高预测精度方面越来越受到重视,甚至影响到预测项目的成败。通常初始特征是基于领域经验构建的,比如在预测短期负荷的时候,一般会考虑节假日、气温、历史负荷水平等因素来构建特征。然而这样得到的特征未必能够充分地描述目标变量,因此很有必要基于这些初始特征构建更多更强的特征,从而尽可能地提高预测精度。最近几年这方面的研究也不少,百度等科技巨头企业已经有成熟的特征学习算法,并且应用在相关的业务场景中。


02 特征变换

特征变换通常是指对原始的某个特征通过一定规则或映射得到新特征的方法,主要的方法包括概念分层、标准化、离散化、函数变换以及深入表达。特征变换主要是由人工完成,属于比较基础的特征构建方法。

02.1 概念分层

在数据分析过程中,对于类别过多的分类变量通常使用概念分层的方法变换得到类别较少的变量,比如可以将年龄变量,其值为“1岁”、“12岁”、“38岁"等,变换成更高概念层次的值,如“儿童”、“青年"、“中年”等,其中每个值对应多个年龄,经过这样的处理,类别减少到几类,既避免了程序陷入过拟合,又能提高算法的效率。因此,概念分层是缩减离散变量取值数量的方法。由于取值概念层级更高,这必然会损失一些细节信息,极端情况是取到概念分层的顶层,也就是信息损失最大的取值,这种情况下,对所有的样本,该变量的值都是一样的,因此就失去概念分层的意义。

boysData<-read.csv("orgdata.csv")
#属性说明:
#age:年龄
#hgt:身高
#wgt:体重
#bmi:体重指数
#hc:头围
#gen:发育程度1
#phb:发育程度2
#tv:发育程度3
#reg:所属区域
print(head(boysData))
##     age  hgt   wgt   bmi   hc  gen  phb tv   reg
## 1 0.035 50.1 3.650 14.54 33.7 <NA> <NA> NA south
## 2 0.038 53.5 3.370 11.77 35.0 <NA> <NA> NA south
## 3 0.057 50.0 3.140 12.56 35.2 <NA> <NA> NA south
## 4 0.060 54.5 4.270 14.37 36.7 <NA> <NA> NA south
## 5 0.062 57.5 5.030 15.21 37.3 <NA> <NA> NA south
## 6 0.068 55.5 4.655 15.11 37.0 <NA> <NA> NA south
summary(boysData)
##       age              hgt              wgt              bmi       
##  Min.   : 0.035   Min.   : 50.00   Min.   :  3.14   Min.   :11.77  
##  1st Qu.: 1.581   1st Qu.: 84.88   1st Qu.: 11.70   1st Qu.:15.90  
##  Median :10.505   Median :147.30   Median : 34.65   Median :17.45  
##  Mean   : 9.159   Mean   :132.15   Mean   : 37.15   Mean   :18.07  
##  3rd Qu.:15.267   3rd Qu.:175.22   3rd Qu.: 59.58   3rd Qu.:19.53  
##  Max.   :21.177   Max.   :198.00   Max.   :117.40   Max.   :31.74  
##                   NA's   :20       NA's   :4        NA's   :21     
##        hc          gen        phb            tv           reg     
##  Min.   :33.70   G1  : 56   P1  : 63   Min.   : 1.00   city : 73  
##  1st Qu.:48.12   G2  : 50   P2  : 40   1st Qu.: 4.00   east :161  
##  Median :53.00   G3  : 22   P3  : 19   Median :12.00   north: 81  
##  Mean   :51.51   G4  : 42   P4  : 32   Mean   :11.89   south:191  
##  3rd Qu.:56.00   G5  : 75   P5  : 50   3rd Qu.:20.00   west :239  
##  Max.   :65.00   NA's:503   P6  : 41   Max.   :25.00   NA's :  3  
##  NA's   :46                 NA's:503   NA's   :522
#这里根据BMI指数,将泛化成体重类型的wtype字段
#通过summary的结果得知bmi字段存在21个缺失值与总量748相比远小于5%,这里将其删除
boysData<-boysData[!is.na(boysData$bmi),]
#设置变换规则
typeUp<-c(18.5,24.99,25,28,32,100)
typeDown<-c(0,18.5,20,25,28,32)
typeName<-c("过轻","正常","适中","过重","肥胖","非常肥胖")
boysData$wtype<-typeName[unlist(mapply(function(x){
    tmp<-intersect(which(typeDown<x),which(typeUp>=x))
    #如果同时满足正常和适中,则默认为适中
    return(tmp[length(tmp)])
},boysData$bmi))]
head(boysData)
##     age  hgt   wgt   bmi   hc  gen  phb tv   reg wtype
## 1 0.035 50.1 3.650 14.54 33.7 <NA> <NA> NA south  过轻
## 2 0.038 53.5 3.370 11.77 35.0 <NA> <NA> NA south  过轻
## 3 0.057 50.0 3.140 12.56 35.2 <NA> <NA> NA south  过轻
## 4 0.060 54.5 4.270 14.37 36.7 <NA> <NA> NA south  过轻
## 5 0.062 57.5 5.030 15.21 37.3 <NA> <NA> NA south  过轻
## 6 0.068 55.5 4.655 15.11 37.0 <NA> <NA> NA south  过轻
barplot(table(boysData$wtype),col=rainbow(9),border='gray')

02.2 标准化

在数据分析过程中,通常使用的变量量纲不一致,在确定权重、系数、距离的时候,也会有所
影响,因此要进行数据标准化。标准化对数据进行无量纲处理,使不同量纲的数据可以在同一个数量级上进行横向比较,减少因为数据级差异带来的误差。分成线性标准化和非线性标准化两类。
(1)线性标准化
所谓线性标准化,即是满足y= ax + b的标准化处理过程,其中a、b为常数。常见的线性标准
化方法包括极差标准化、z-score 标准化、小数定标标准化。
(2)非线性标准化
非线性标准化,就是标准化处理过程是非线性,常见的包括对数、倒数标准化。


stdProc<-function(x,isPos)
{
    #(1)线性标准化
    #---极差标准化
    if(max(x)>min(x)){
        if(isPos){
            yExt=(x-min(x))/(max(x)-min(x))
        }else{
            yExt=(max(x)-x)/(max(x)-min(x))
        }
    }else{
        print("最大值与最小值相等,不能进行极差标准化!")
        yExt=NULL
    }
    
    #---z-score标准化
    sd0<-sd(x)
    mean0<-mean(x)
    if(sd0==0){
        print("由于标准差为0,不能进行z-score标准化")
        yZsc=NULL
    }else{
        yZsc=(x-mean0)/sd0
    }
    #---小数定标标准化
    yPot=x/(10^nchar(max(abs(x))))
    
    #(2)非线性标准化
    #---对数标准化
    if(isPos){
        y=log(x-min(x)+1)
        yLog=(1/max(y))*y
    }else{
        y=log(max(x)-x+1)
        yLog=(1/max(y))*y
    }
    #---倒数标准化
    yInv=min(abs(x[x!=0]))/x
    
    return(list(yExt=yExt,yZsc=yZsc,yPot=yPot,yLog=yLog,yInv=yInv))
}

02.3 离散化

离散化通常是对实数而言的,它是将无限的连续值映射到有限分类值中去的方法,并且这些分
类规定了与无限连续值相同的取值空间。比如我们可以将收入金额,取值范围为2000~100000, 离散化成“低等收入”、“中等收入”、“高等收入”等分类值,-般对于这种类型的离散化,得到的是有序分类变量。通过离散化处理,可以简化数据,有助于提高算法的执行效率和模型的可解释性。
常见用于离散化处理的方法主要包括分箱法、熵离散法、ChiMerge法、规则离散法。

(1)分箱法

分箱法是一种将连续数值按照一定规则存放到不同箱中的数据处理方法,箱的宽度表示箱中数
值的取值区间,箱的深度表示箱中数值的数量。通常按箱的等宽、等深的差异将分箱法分成两类,一类是等宽分箱,另一类是等比分箱。
对于数据2、4、7、10、 13、24、26、29、 30、 45、68、89,由于共12个,可以按深度4将数值等比分成3个箱,分别为箱1I: 2、4、7、10;箱2: 13、24、 26、29;箱3: 30、 45、68、89。由于数值介于区间[2,87],可以按宽度44将数值等宽分成2个箱,分别为箱1: 2、4、7、10、13、24、26、29、30、 45;箱2: 68、89。

tmpV=runif(100,10,100)
#1.使用quantile函数进行等比分箱,此处将数据分成4份
newType=c("A1","A2","A3","A4")
q0=quantile(tmpV,probs=seq(0,1,1/4))
v0=rep(newType[1],length(tmpV))
for(i in 2:(length(q0)-1)){
    v0[tmpV>q0[i] & tmpV<=q0[i+1]]=newType[i]
}
#...另外常可通过均值、中位数、最大最小值来平滑数值以生成新的特征
vt0=tmpV[tmpV>=q0[1] & tmpV<=q0[2]]
v_mean=rep(mean(vt0),length(tmpV))
v_median=rep(median(vt0),length(tmpV))
v_max=rep(max(vt0),length(tmpV))
v_min=rep(min(vt0),length(tmpV))
for(i in 2:(length(q0)-1)){
    v_mean[tmpV>q0[i] & tmpV<=q0[i+1]]=mean(tmpV[tmpV>q0[i] & tmpV<=q0[i+1]])
    v_median[tmpV>q0[i] & tmpV<=q0[i+1]]=median(tmpV[tmpV>q0[i] &tmpV<=q0[i+1]])
    v_max[tmpV>q0[i] & tmpV<=q0[i+1]]=max(tmpV[tmpV>q0[i] & tmpV<=q0[i+1]])
    v_min[tmpV>q0[i] & tmpV<=q0[i+1]]=min(tmpV[tmpV>q0[i] & tmpV<=q0[i+1]])
}
#2.使用cut函数进行等宽分箱,此处将数据分成5份
c0=cut(tmpV,breaks=5,labels=c("B1","B2","B3","B4","B5"))
#...另外可通过设置labels为NULL,并通过levles函数查看cut的水平
#...进一步确定各分箱的取值区间
#...可通过均值、中位数、最大最小值来平滑数值以生成新的特征
L0=levels(cut(tmpV,breaks=5))
v2_mean=v2_median=v2_max=v2_min=rep(0,length(tmpV))
for(lvl in L0)
{
    splitval=as.integer(strsplit(strsplit(strsplit(lvl,split='\\(')[[1]][2],
              split='\\]')[[1]],split=',')[[1]])
    subcond=tmpV>splitval[1] & tmpV<=splitval[2]
    subval=tmpV[subcond]
    v2_mean[subcond]=mean(subval)
    v2_median[subcond]=median(subval)
    v2_max[subcond]=max(subval)
    v2_min[subcond]=min(subval)
}

(2)熵离散法

熵离散法是基于信息熵的一种数据离散方法,通常用在分类问题的预测场景中对数值属性或特
征进行离散化处理。这是一种有指导的离散化方法,并且通常进行二元离散化。大致思路是这样的,首先对离散化的数值特征进行排序,然后按顺序将对应数值作为分割点,这样可将该特征分为两类,分别记为VI和V2,假设该特征为V,目标变量为U,则该划分可通过计算相应的熵得到信息增益Gains(U,V) = Ent(U) - Ent(UIV),通过不断地选择分割点,并从得到的所有信息增益中,选取最大值,其对应的分割点即为最终用于离散化的分割点。

#将iris中的Sepal.Length变量排序,并保存在变量sortedSL中
sortedSL=sort(iris$Sepal.Length)
#循环:按顺序以sortedSL中的每个值作为分割点,重建新特征new,默认设置为0
gainsV<-NULL
splitV<-NULL
for(i in 1:NROW(sortedSL))
{
    splitVal=sortedSL[i]
    iris$new=0
    if(sum(iris$Sepal.Length>splitVal)>0)
    {
        iris[iris$Sepal.Length>splitVal,]$new=1
    }
    gainsV<-c(gainsV,gains(iris$Species,iris$new))
    splitV<-c(splitV,splitVal)
}
#分割点为
finalSplitV<-splitV[which.max(gainsV)]
finalSplitV

02.4 函数变换

函数变换指的是使用函数映射将变量或特征变换成另外一个特征的方法。通过函数变换会改变
数据的分布,因此常用于对数据分布比较敏感的模型中。常见的函数变换方法主要包括幂函数变换和对数变换。


关注R小盐,关注科研私家菜(VX_GZH: SciPrivate),有问题请联系R小盐。让我们一起来学习 R语言机器学习与临床预测模型

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

推荐阅读更多精彩内容