预测建模常用的数据预处理方法

面向医学生/医生的实用机器学习教程系列推文

数据预处理对获得表现良好的模型有非常重要的作用!

是金子总会发光,一个未经雕琢的数据,本身的价值也难以得到体现,通过数据预处理,可以让数据展现真正的价值;另外,不同的模型对数据有不同的要求,通过预处理可以让数据符合算法的要求,这样也能提高模型的预测能力。这就是数据预处理的重要作用!

但是,一个本身就没有什么价值的数据,再好的模型也得不出理想的结果,这就是我常说的:鸭子是不会变成天鹅的!

这样一个雕琢数据,精细打磨的过程有一个专门的名字:特征工程。

但是要注意,数据预处理不是单纯的数字操作,一定要结合自己的实际情况!

今天的推文给大家介绍一些临床预测模型和机器学习常用的数据预处理方法。

最有效的数据预处理的方法来自于建模者对数据的理解,而不是通过任何数学方法。

本期目录:

中心化和标准化可以解决这样的问题。

中心化是将所有变量减去其均值,其结果是变换后的变量均值为0;标准化是将每个变量除以其自身的标准差,标准化迫使变量的标准差为1。

R语言中scale()函数可实现中心化和标准化,就不多做介绍了。

无偏分布类似我们常说的正态分布,有偏分布又分为右偏和左偏,分别类似正偏态分布和负偏态分布。

一个判断数据有偏的黄金标准:如果最大值与最小值的比例超过20,那么我们认为数据有偏。

可以通过计算偏度统计量来衡量偏度。如果预测变量分布是大致对称的,那么偏度将接近于0,右偏分布偏度大于0,越大说明偏的越厉害;左偏分布偏度小于0,越小说明偏的越厉害。

计算偏度的包很多。

使用e1071包查看变量的偏度

library(e1071)#查看偏度skewness(segData$AngleCh1)##[1]-0.02426252#查看每一列的偏度skewValues<-apply(segData,2,skewness)head(skewValues)##AngleCh1AreaCh1AvgIntenCh1AvgIntenCh2AvgIntenCh3AvgIntenCh4##-0.024262523.525107452.959185240.848160332.202342141.90047128也可以通过psych包查看:

psych::skew(segData$AngleCh1)#偏度##[1]-0.02426252psych::kurtosi(segData$AngleCh1)#峰度##[1]-0.8594789通过对数据进行变换可以一定程度解决偏度的问题,常用的方法有:取对数(log),平方根,倒数,Box&Cox法等。

log、平方根、倒数这些很简单,就不演示了,下面演示下BoxCox变换。

#准备对数据进行BoxCox变换Ch1AreaTrans<-BoxCoxTrans(segData$AreaCh1)Ch1AreaTrans##Box-CoxTransformation####1009datapointsusedtoestimateLambda####Inputdatasummary:##Min.1stQu.MedianMean3rdQu.Max.##150.0194.0256.0325.1376.02186.0####Largest/Smallest:14.6##SampleSkewness:3.53####EstimatedLambda:-0.9#进行变换AreaCh1_transed<-predict(Ch1AreaTrans,segData$AreaCh1)#查看变换前、后的数据head(segData$AreaCh1)##[1]819431298256258358head(AreaCh1_transed)##[1]1.1084581.1063831.1045201.1035541.1036071.105523这里可以看到caret对数据预处理的方式,首先是选择方法,然后使用predict()函数把变换应用到具体的变量上。这是caret的基本操作,大家一定要记住!

对于变换前后的数据变化,只看数字没有直观的感受,下面给大家画图演示。

psych::skew(AreaCh1_transed)##[1]0.0976087下面是BoxCox变换的一点点扩展,不看也影响不大。

BoxCox变换需要一个参数lambda,这个参数需要我们计算并指定,如上使用caret进行变换时,它会自动帮我们处理好,其中一句代码显示EstimatedLambda:-0.9,也就是lambda=0.9。

还有很多R包可以实现BoxCox变换,其中比较简单的是forecast,简单演示如下:

library(forecast)##RegisteredS3methodoverwrittenby'quantmod':##methodfrom##as.zoo.data.framezoobest.lambda<-BoxCox.lambda(segData$AreaCh1)#计算lambdabest.lambda##[1]-0.9999264AreaCh1.transformed<-BoxCox(segData$AreaCh1,lambda=best.lambda)#变换head(AreaCh1.transformed)##[1]0.99885190.99775220.99671630.99616550.99619580.9972789y0<-InvBoxCox(AreaCh1.transformed,lambda=best_lambda)#还原##ErrorinInvBoxCox(AreaCh1.transformed,lambda=best_lambda):object'best_lambda'notfound解决离群值离群值其实是有明确定义的,通常我们会选择直接删除离群值,但是还是要根据实际情况来看,有的离群值是非常有意义的,这样的离群值不能直接删除。

有些模型对离群值很敏感,比如线性模型,这样是需要处理的,一个常见的方法是空间表示变换,该变换将预测变量取值映射到高纬的球上,它会把所有样本变换到离球心相等的球面上。在caret中可以实现。关于它的具体数学运算过程,感兴趣的自己了解即可,我不太感兴趣。

在进行空间表示变换前,最好先进行中心化和标准化,这也和它的数学计算有关,我也不太感兴趣。

对数据进行PCA变换之前,最好先解决偏度问题,然后进行中心化和标准化,和它的数学计算过程有关,感兴趣的自己了解。

可视化前后不同:

这里的过滤和解决共线性,其实部分属于特征选择的范围,就是大家常见的自变量选择问题,这个问题在以后的推文中还会详细介绍。

冗余的变量通常增加了模型的复杂度而非信息量

如果一个变量只有1个值,那么这个变量的方差为0;如果一个变量只有少量不重复的取值,这种变量称为近零方差变量;这2种变量包含的信息太少了,应当过滤;

检测近零方差变量的准则是:

移除共线变量的方法如下:

caret可以轻松实现以上过程。

使用mdrr数据集演示。其中一列nR11大部分都是501,这种变量方差是很小的!

data(mdrr)table(mdrrDescr$nR11)#大部分值都是0####012##501423sd(mdrrDescr$nR11)^2#方差很小!##[1]0.1731787使用nearZeroVar()找出零方差和近零方差变量,结果中会给出zeroVar和nzv两列,用逻辑值表示是不是近零方差变量或者零方差变量。

nzv<-nearZeroVar(mdrrDescr,saveMetrics=TRUE)nzv[nzv$nzv,][1:10,]##freqRatiopercentUniquezeroVarnzv##nTB23.000000.3787879FALSETRUE##nBR131.000000.3787879FALSETRUE##nI527.000000.3787879FALSETRUE##nR03527.000000.3787879FALSETRUE##nR08527.000000.3787879FALSETRUE##nR1121.782610.5681818FALSETRUE##nR1257.666670.3787879FALSETRUE##D.Dr03527.000000.3787879FALSETRUE##D.Dr07123.500005.8712121FALSETRUE##D.Dr08527.000000.3787879FALSETRUE去掉近零方差变量:

ltfrDesign<-matrix(0,nrow=6,ncol=6)ltfrDesign[,1]<-c(1,1,1,1,1,1)ltfrDesign[,2]<-c(1,1,1,0,0,0)ltfrDesign[,3]<-c(0,0,0,1,1,1)ltfrDesign[,4]<-c(1,0,0,1,0,0)ltfrDesign[,5]<-c(0,1,0,0,1,0)ltfrDesign[,6]<-c(0,0,1,0,0,1)ltfrDesign##[,1][,2][,3][,4][,5][,6]##[1,]110100##[2,]110010##[3,]110001##[4,]101100##[5,]101010##[6,]101001findLinearCombos()可以通过算法给出需要去除的变量,关于具体的方法可以官网查看。

comboInfo<-findLinearCombos(ltfrDesign)comboInfo##$linearCombos##$linearCombos[[1]]##[1]312####$linearCombos[[2]]##[1]6145######$remove##[1]36结果给出了需要去除的变量是第3列和第6列。

这里介绍下独热编码(one-hotencoding),和哑变量编码稍有不同,哑变量是变成k-1个变量,独热编码是变成k个变量。

使用以下数据进行演示

data("cars",package="caret")head(cars)##PriceMileageCylinderDoorsCruiseSoundLeatherBuickCadillacChevy##122661.052010564100100##221725.011345762110001##329142.713165542111000##430731.942247942100000##533358.771759042111000##630315.172363542100000##PontiacSaabSaturnconvertiblecoupehatchbacksedanwagon##100000010##200001000##301010000##401010000##501010000##601010000type<-c("convertible","coupe","hatchback","sedan","wagon")cars$Type<-factor(apply(cars[,14:18],1,function(x)type[which(x==1)]))carSubset<-cars[sample(1:nrow(cars),20),c(1,2,19)]#上面是数据生成过程,不重要,记住下面这个数据的样子即可!!head(carSubset)##PriceMileageType##62120902.1029649sedan##15417675.845131coupe##57327703.2024738sedan##60113106.9021910coupe##36117119.4618277sedan##43032501.2517508sedanlevels(carSubset$Type)#Type是一个因子型变量##[1]"convertible""coupe""hatchback""sedan""wagon"现在把Type这个变量进行独热编码。

使用dummyVars构建虚拟变量:

simpleMod<-dummyVars(~Mileage+Type,#用mileage和Type对价格进行预测data=carSubset,levelsOnly=TRUE)#从列名中移除因子变量的名称simpleMod##DummyVariableObject####Formula:~Mileage+Type##2variables,1factors##Factorvariablenameswillberemoved##Alessthanfullrankencodingisused接下来就可以使用predict和simpleMod对训练集进行生成虚拟变量的操作了:

predict(simpleMod,head(carSubset))##Mileageconvertiblecoupehatchbacksedanwagon##6212964900010##154513101000##5732473800010##6012191001000##3611827700010##4301750800010可以看到Type变量没有了,完成了虚拟变量的转换。

假如你认为车型和里程有交互影响,则可以使用:表示:

withInteraction<-dummyVars(~Mileage+Type+Mileage:Type,data=carSubset,levelsOnly=TRUE)withInteraction##DummyVariableObject####Formula:~Mileage+Type+Mileage:Type##2variables,1factors##Factorvariablenameswillberemoved##Alessthanfullrankencodingisused应用于新的数据集:

predict(withInteraction,head(carSubset))##MileageconvertiblecoupehatchbacksedanwagonMileage:Typeconvertible##62129649000100##1545131010000##57324738000100##60121910010000##36118277000100##43017508000100##Mileage:TypecoupeMileage:TypehatchbackMileage:TypesedanMileage:Typewagon##62100296490##1545131000##57300247380##60121910000##36100182770##43000175080区间化预测变量主要是为了好解释结果,比如把血压分为高血压1级、2级、3级,把贫血分为轻中重极重等,这样比如你做logistic回归,可以说血压每增高一个等级,因变量的风险增加多少,但是你如果说血压值每增加1mmHg,因变量增加多少倍,这就有点扯了。

在caret中是通过preProcess()函数里面的method参数实现的,把不同的预处理步骤按照顺序写好即可。

以上就是数据预处理的一般过程,一个caret包可以解决上面所有的问题,有兴趣的小伙伴可以自行学习。

数据预处理是一个非常系统且专业的过程,如同开头说的那样:最有效的编码数据的方法来自于建模者对数据的理解,而不是通过任何数学方法,在对数据进行预处理之前,一定要仔细理解自己的数据哦,结果导向的思维是不对的哦!

THE END
1.大数据——数据预处理有效的数据预处理能够清洗和转换原始数据,使其适合用于机器学习模型训练。它可以帮助去除噪声、处理缺失值和异常数据,从而提升模型的准确性和稳定性。同时,数据预处理也是数据挖掘中一个热门的研究方面,毕竟现实世界中的数据几乎都是“脏数据”,需要通过预处理来提高数据挖掘模式的质量。 https://blog.csdn.net/lyl040215/article/details/143290489
2.什么是数据预处理数据预处理简介数据预处理是指在进行数据分析和建模前,对原始数据进行清洗、转换、集成、规范化等一系列处理过程。数据预处理旨在减少数据分析和建模过程中的错误和偏差,提高数据的质量和可靠性。https://cloud.tencent.com/developer/techpedia/1719
3.数据预处理为何重要?数据预处理方法与工具推荐!在数据科学和机器学习领域,数据预处理是数据分析过程中至关重要的步骤之一。它涉及将原始数据进行清洗、转换和准备,以确保数据的质量、一致性和适用性。本文将深入探讨数据预处理的概念,以及常用的数据预处理方法。 一、数据预处理的定义 数据预处理是数据科学和机器学习领域中的一个关键步骤,它指的是在进行数据分析、https://www.fanruan.com/bw/data-sjycl
4.数据预处理数据预处理的主要任务有: 1.数据清洗2.数据集成3.数据转换4.数据归约 下面一个个地分析。 1.数据清洗 现实世界的数据一般是不完整的、有噪声的和不一致的。数据清理例程试图填充缺失的值,光滑噪声并识别离群点,纠正数据中的不一致。 (1)缺失值处理 https://www.douban.com/note/128949687/
5.数据预处理的方法有哪些数据处理的工作时间占整个数据分析项目的70%以上,因此,数据的质量直接决定了分析模型的准确性。那么,数据预处理的方法是什么呢?例如数据清理、数据集成、数据规范、数据转换等,其中最常用的是数据清理和数据集成,下面中琛魔方将来详细介绍一下这2种方法。 https://www.qianjia.com/zhike/html/2020-08/12_27673.html
6.数据预处理的方法有哪些数据预处理在数据挖掘中至关重要,旨在提升原始数据的品质与可用性。其主要任务涵盖去除冗余、数据清洗、格式转换,以及处理异常值。此外,通过消除变量间的相关性,数据预处理增强了数据的代表性和可解释性,为后续的数据分析和挖掘奠定坚实基础。 在数据预处理缺失值时,通常有两种策略:一是删除缺失值,用新数据替换;二是https://www.yueshu.com.cn/posts/Data-preprocessing%20-method
7.[名词解释]数据预处理百度试题 题目[名词解释] 数据预处理 相关知识点: 试题来源: 解析 用各种方法对数据进行变换、加工,以便使它适于存储、管理及进一步分析和应用。预处理的主要内容包括几何纠正、数据压缩、数据规范化和数据匹配。反馈 收藏 https://easylearn.baidu.com/edu-page/tiangong/bgkdetail?id=419ac4373968011ca30091b4&fr=search
8.如何进行数据清洗和预处理?有时候,数据集中会有重复的记录,这可能会影响分析和建模的准确性。因此,需要进行去重处理,保留唯一的记录。 数据预处理 数据预处理是指在清洗完数据之后,进一步对数据进行加工和转化,以便于后续分析和建模。以下是一些常见的数据预处理步骤: 1.特征选择 https://www.cda.cn/bigdata/202679.html
9.数据分析中的数据预处理包括哪些步骤数据预处理包括数据清洗、数据集成、数据转换和数据规约四个步骤。数据预处理是数据分析的重要阶段,通过对原始数据进行处理和清洗,可以提高数据分析的准确性和可靠性。 一、数据清洗 数据清洗是数据预处理的第一步,主要是为了处理原始数据中存在的错误、缺失、重复、异常等问题。具体步骤如下: https://www.linkflowtech.com/news/1073
10.spss数据预处理包括哪些内容spss数据预处理怎么做在进行数据分析时,数据预处理是一个至关重要的步骤。SPSS软件作为一款广泛应用的统计分析软件,提供了一系列强大的数据预处理功能。本文将详细介绍SPSS数据预处理包括哪些内容,以及SPSS数据预处理怎么做的内容,帮助您更好地利用软件功能,提高数据分析的准确性和效率。 一、 SPSS数据预处理包括哪些内容 在SPSS中,数据预https://spss.mairuan.com/jiqiao/spss-djxklq.html
11.数据挖掘预处理数据挖掘预处理的目的数据预处理的方法包括:数据清理、数据集成和转换、数据归约。 数据清理可以去掉数据中的噪音,纠正不一致。数据集成将数据由多 个源合并成一致的数据存储,如数据仓库或数据方。数据变换(如规范化)也可以使用。例如,规范化可以改进涉及距离度量的挖掘算法的精度和有效性。数据归约可以通过聚集、删除冗余特征或聚类等方法https://blog.51cto.com/u_13416/9239111
12.数据预处理方法和步骤使用MATLAB,可以将五种常见的数据预处理方法应用于此原始太阳辐射度数据集。 数据预处理方法MATLAB 图 应对离群值 遥测数据中的异常值显示为离群值。使用filloutliers删除离群值。您可以指定确定离群值的方法,以及用来估计替换离群数据点的值的填充方法。 https://ww2.mathworks.cn/discovery/data-preprocessing.html
13.数据分析:数据预处理缺失值处理(三)上一篇数据分析:数据预处理--标准化方法优劣了解(二)讲了两类常用标准化方法,但没涉及到如何处理缺失数据。 标准化 全局校正(global adjustment)标准化是蛋白质组学中常用的方法之一,它将log化的intensity数据的中心转换成一个常数,这个常数可以是mean、median或者其它数学测量指标。比如Zscore就是将数据中心的mean转换https://www.jianshu.com/p/023f9b241e95
14.Pythonscikitlearn数据预处理常见方法和步骤python数据预处理是数据准备阶段的一个重要环节,主要目的是将原始数据转换成适合机器学习模型使用的格式,数据预处理可以显著提高机器学习模型的性能和准确度,本文给大家介绍了Python数据预处理常见方法和步骤,需要的朋友可以参考下+ 目录 数据预处理常见方法和步骤 数据预处理是数据准备阶段的一个重要环节,主要目的是将原始数据https://www.jb51.net/python/321454h37.htm
15.数据挖掘读书笔记1——数据预处理sillypudding数据挖掘读书笔记1——数据预处理 此为读《数据挖掘概念与技术》一书的随手摘抄,方便以后查阅。 数据清理 3.2.1 遗漏值 1.忽略元组:当类标号缺少时通常这样做(假定挖掘任务涉及分类或描述)。除非元组有多个属 性缺少值,否则该方法不是很有效。当每个属性缺少值的百分比很高时,它的性能非常差。https://www.cnblogs.com/sillypudding/archive/2013/04/11/2893538.html