变量选择

 

作者:Pablo Casas

翻译来源:Data Science Live Book—General Aspects in Selecting Best Variables

变量选择

主要内容

本章包括以下主题:

  • 常规机器学习算法(预测或聚类)的最佳变量排名。
  • 选择具有和不具有预测模型变量的规则。
  • 变量在群体中的作用(直觉和信息理论)。
  • 用R探索在实践中最好的变量子集.

选择最佳变量也称为特征选择,选择最重要的预测因子,选择最佳预测因子等。
dark_matter_simulation
图像:是神经网络吗?不。来自“千年模拟项目”的黑暗物质。

导言

选择最好的变量就像做一个故事的总结,我们要关注那些最能概括我们谈论内容的细节。我们要取得在关于不必要的细节谈论太多(过度拟合)和关于故事的本质谈论太少(拟合不足)两者之间的平衡。

另一个例子可能是购买新笔记本电脑的决定过程: 我们最关心的是什么功能?价格,颜色和运输方式?颜色和电池寿命?还是只是价格?

信息理论的角度来看,机器学习的关键点在于,我们正在研究的数据具有(混沌)。当我们选择变量时,我们正在通过添加信息来减少我们系统的熵。

什么是“最好的”选择?

这章说“最好”,但我们最好首先提出一个概念点,一般来说,没有唯一的最佳变量选择。

从这个观点出发是很重要的,因为在探索许多根据预测能力对变量进行排序的算法时,我们可以找到不同的和相似的结果。比如:

  • 算法1选择了最佳变量var_1,其次是var_5var_14
  • 算法2做了这个排名:var_1var_5var_3

我们可以假设,基于算法1,精度为80%,而基于算法2的精度为78%。考虑到每个模型都有内在的差异,结果可以看作是一样的。

这个观点可以帮助我们缩短追求完美变量选择的时间。

然而,在极端情况下,会有一组变量在许多算法中排名很高,对于那些没有预测能力的变量也是如此。经过几次运行,最可靠的变量将迅速出现,所以:

结论 :如果结果不好,重点应该是改进和检查数据预处理步骤。下一节将举例说明。

深入变量排名

给一个特定指标的变量排名在文献和算法中是一个常见的单变量分析问题。

我们将创建两个模型:随机森林和梯度提升机(GBM),使用R包caret来对数据进行交叉验证。如下,我们将比较每个模型返回的最佳变量排名。

library(caret)
library(funModeling)
library(dplyr)

## Excluding all NA rows from the data, in this case, NAs are not the main issue to solve, so we'll skip the 6 cases which have NA (or missing values).
heart_disease=na.omit(heart_disease)

## Setting a 4-fold cross-validation
fitControl = trainControl(method = "cv",
                           number = 4,
                           classProbs = TRUE,
                           summaryFunction = twoClassSummary)

## Creating the random forest model, finding the best tuning parameter set
set.seed(999)
fit_rf = train(x=select(heart_disease, -has_heart_disease, -heart_disease_severity),
             y = heart_disease$has_heart_disease,
             method = "rf",
             trControl = fitControl,
             verbose = FALSE,
             metric = "ROC")

## Creating the gradient boosting machine model, finding the best tuning parameter set
fit_gbm = train(x=select(heart_disease, -has_heart_disease, -heart_disease_severity),
             y = heart_disease$has_heart_disease,
             method = "gbm",
             trControl = fitControl,
             verbose = FALSE,
             metric = "ROC")

现在我们可以进行比较。
importance_rfimportance_gbm这两列代表着每个算法测量的权重。基于每个度量,有着代表权重序列的rank_rfrank_gbm,最终rank_diff(rank_rf-rank_gbm) 代表每个算法对变量排序的不同。

## Here we manipulate to show a nice the table described before
var_imp_rf=data.frame(varImp(fit_rf, scale=T)["importance"]) %>% dplyr::mutate(variable=rownames(.)) %>% dplyr::rename(importance_rf=Overall) %>% dplyr::arrange(-importance_rf) %>% dplyr::mutate(rank_rf=seq(1:nrow(.))) 

var_imp_gbm=as.data.frame(varImp(fit_gbm, scale=T)["importance"])  %>% dplyr::mutate(variable=rownames(.)) %>% dplyr::rename(importance_gbm=Overall) %>% dplyr::arrange(-importance_gbm) %>% dplyr::mutate(rank_gbm=seq(1:nrow(.)))

final_res=merge(var_imp_rf, var_imp_gbm, by="variable")

final_res$rank_diff=final_res$rank_rf-final_res$rank_gbm

# Printing the results!
final_res

ranking_best_vars_comparison

可以看到有在两个模型(fasting_blood_sugar)中都不重要的变量。另有一些变量保持在权重的前列,比如chest_painthal.

根据该特定模型,不同的预测模型实现方式有自己判断什么是最佳特征的标准。这种不同算法的排名不​​同。有关内部重要性度量的更多信息,请参见caret documnetation

更重要的是,在诸如GBM和随机森林这样的基于树的模型中,有一个择取变量的随机组件,选择时的权重基于构建树时的先验和自动变量。每个变量的权重还依赖于其他因素,而不仅仅取决于其独立的贡献:变量在组中作用。我们将在稍后回到此部分内容。

虽然排名会因算法而异,但一般来说,我们之前提到的所有这些结果之间存在相关性。

结论:每个排名都不是“最后的真相” ,它给了我们信息的相对位置。

选择的规则

做变量选择有两种主要方法:

预测模型依赖 :

像我们以前看到的那样,这是最常见的。该模型将根据一个精确度的内在度量来对变量进行排序。在树型模型中,诸如信息增益,基尼指数,节点杂质等指标。参考文献[4],[5]。

非预测模型依赖 :

有趣的是这些方法不像其他方法那样流行,但它们被证明在与基因组数据相关的领域表现非常出色。它们主要用于寻找与某些疾病相关的相关基因(输入变量),如癌症(目标变量)。

来自这个领域的数据的特点是拥有大量的变量(数千个),比其他领域的问题要大得多。

执行此操作的一种算法是mRMR ,最小冗余最大相关特征选择(Minimum Redundancy Maximum Relevance Feature Selection)的缩写。它在mRMRe包中有自己的R实现。

改进变量

变量可以通过对它们进行处理来增加预测能力。

这本书现在包括:

还有更多即将推出……

依据专业领域知识进行清理

它与算法程序无关,而是与数据所属的领域有关。

想象一下来自调查的数据。这次调查有一年的历史,前三个月没有良好的过程控制。插入数据时,用户可以输入任何想要的内容。这段期间的变量可能是虚假的。

如果数据在给定的时间段内变量为空,为零或极端值时,那么会很容易识别。

我们应该问自己一个问题:

这个数据是否可靠? 请记住,预测模型将像一个孩子一样学习,它不会判断数据,只是从中学习。如果数据在给定的时间内是虚假的,那么我们应该删除这些输入。

在这一点上更进一步,我们应该进行更深入的探索性数据分析。不管是从数字上还是图形上。

变量集体发挥作用

variable_groups
在选择最佳变量时,主要目的是获取那些携带关于目标、结果和因变量的信息最多的变量。

预测模型将根据其从1到’N’的输入变量找到其权重或参数。

在解释事件时变量通常不是孤立工作的。引用亚里士多德的话:

“The whole is greater than the sum of its parts.”

在选择最佳特征时同样如此:

使用两个变量构建预测模型可能会比仅使用单变量构建的模型具有更高的精度。

例如:构建基于变量var_1的模型可以导致总体准确度达到60%。另一方面,构建基于var_2的模型可以达到72%的精度。但是当我们组合var_1var_2这两个变量时,我们可以达到80%以上的精度。

R中的示例:集体发挥作用的变量

aristotle
以下代码可以作为例子说明亚里士多德在多年前说的话:

  • 模型1基于输入变量max_heart_rate
  • 模型2基于输入变量chest_pain
  • 模型3基于输入变量max_heart_ratechest_pain每个模型返回指标ROC,结果要同时考虑两个变量做出的改进,而不是将每个变量隔离。
library(caret)
library(funModeling)
library(dplyr)

## setting cross-validation 4-fold
fitControl = trainControl(method = "cv",
                          number = 4,
                          classProbs = TRUE,
                          summaryFunction = twoClassSummary)

create_model<-function(input_variables) {
  ## create gradient boosting machine model based on input variables
  fit_model = train(x=select(heart_disease, one_of(input_variables)),
              y = heart_disease$has_heart_disease,
              method = "gbm",
              trControl = fitControl,
              verbose = FALSE,
              metric = "ROC")

  # returning the ROC as the performance metric
  max_roc_value=max(fit_model$results$ROC)
  return(max_roc_value)
}

roc_1=create_model("max_heart_rate")
roc_2=create_model("chest_pain")
roc_3=create_model(c("max_heart_rate", "chest_pain"))

avg_improvement=round(100*(((roc_3-roc_1)/roc_1)+((roc_3-roc_2)/roc_2))/2,2)
avg_improvement_text=sprintf("Average improvement: %s%%", avg_improvement)

results=sprintf("ROC model based on 'max_heart_rate': %s.; based on 'chest_pain': %s; and based on both: %s", round(roc_1,2), round(roc_2,2), round(roc_3, 2))

# printing the results!
cat(c(results, avg_improvement_text), sep="\n\n")
## ROC model based on 'max_heart_rate': 0.74.; based on 'chest_pain': 0.76; and based on both: 0.82
## 
## Average improvement: 8.93%

一个小例子(基于信息理论)

考虑以下大型数据表,有4行,2个输入变量(var_1var_2)和一个结果(target):
variables_work_in_gropus
如果我们只建立一个基于var_1的预测模型,会发现什么? a的值与输出变量bluered以相同的比例相关(50%):

  • 如果var_1='a'则target =’red’的可能性为50%(第1行)
  • 如果var_1='b'则target =’blue’的可能性为50%(第2行)

var_2会得到同样的分析结果。

当相同的输入与不同的结果相关时,它被定义为噪声 。就和一个人告诉我们: “明天会下雨的!“另一个说: ”明天肯定不会下雨“ 是一样的。

我们会想… “OMG!我需要伞吗?“

由 Editor 于 2017 年 12 月 06 日 发布在 数据科学 栏目