• 机器学习-特征选择:如何使用互信息特征选择挑选出最佳特征?


    一、引言

    特征选择在机器学习中扮演着至关重要的角色,它可以帮助我们从大量的特征中挑选出对目标变量具有最大预测能力的特征。互信息特征选择是一种常用的特征选择方法,它通过计算特征与目标变量之间的互信息来评估特征的重要性。

    互信息是信息论中的一个概念,用于衡量两个随机变量之间的相互依赖程度。在特征选择中,互信息可以用来衡量特征与目标变量之间的相关性。通过计算特征与目标变量之间的互信息,我们可以得到每个特征对目标变量的贡献程度,进而选择最相关的特征。

    本文旨在介绍互信息特征选择的方法和应用。首先,我们将详细解释互信息的概念和计算方法,并阐述特征选择的步骤和原理。然后,我们将展示使用互信息特征选择在实际数据集上挑选出的最佳特征。接下来,我们将对每个最佳特征进行分析和解释,探讨其对目标变量的重要性。随后,我们将使用挑选出的最佳特征训练机器学习模型,并评估模型的性能。最后,我们将总结互信息特征选择的效果和对研究问题的贡献。

    二、户信息特征选择简介

    2.1 互信息的概念和计算方法

    「互信息」是信息论中衡量两个随机变量之间相互依赖程度的指标。它可以用来评估特征与目标变量之间的相关性。互信息的计算方法基于信息熵的概念,它衡量了两个随机变量联合分布与各自边缘分布之间的差异。

    在特征选择中,我们需要计算每个特征与目标变量之间的互信息。互信息的计算可以通过以下公式得到:

    I(X; Y) = ∑∑ p(x, y) * log(p(x, y) / (p(x) * p(y)))

    其中,X表示特征,Y表示目标变量,p(x, y)表示特征X和目标变量Y的联合概率分布,p(x)和p(y)分别表示特征X和目标变量Y的边缘概率分布。

    2.2 特征选择的步骤和原理

    1. 步骤1:计算每个特征与目标变量之间的互信息。对于每个特征X和目标变量Y,使用上述公式计算它们之间的互信息值。
    2. 步骤2:根据互信息值排序特征。将特征按照与目标变量的互信息值从大到小排序,以确定特征的重要性。
    3. 步骤3:选择具有最高互信息值的特征。根据排序结果,选择互信息值最高的特征作为最佳特征。

    特征选择的原理是基于互信息值来衡量特征与目标变量之间的相关性。互信息值越大,表示特征对目标变量的贡献越大,具有更强的预测能力。通过选择互信息值最高的特征,我们可以提取出对目标变量最相关的特征,从而提高机器学习模型的性能。

    三、实例演示

    • 「数据集准备」
    library(survival)
    head(gbsg)
    • 1

    结果展示:

       pid age meno size grade nodes pgr er hormon rfstime status
    1  132  49    0   18     2     2   0  0      0    1838      0
    2 1575  55    1   20     3    16   0  0      0     403      1
    3 1140  56    1   40     3     3   0  0      0    1603      0
    4  769  45    0   25     3     1   0  4      0     177      0
    5  130  65    1   30     2     5   0 36      1    1855      0
    6 1642  48    0   52     2    11   0  0      0     842      1
    • 1
    • 「示例数据集介绍」
    > str(gbsg)
    'data.frame':   686 obs. of  10 variables:
     $ age    : int  49 55 56 45 65 48 48 37 67 45 ...
     $ meno   : int  0 1 1 0 1 0 0 0 1 0 ...
     $ size   : int  18 20 40 25 30 52 21 20 20 30 ...
     $ grade  : int  2 3 3 3 2 2 3 2 2 2 ...
     $ nodes  : int  2 16 3 1 5 11 8 9 1 1 ...
     $ pgr    : int  0 0 0 0 0 0 0 0 0 0 ...
     $ er     : int  0 0 0 4 36 0 0 0 0 0 ...
     $ hormon : int  0 0 0 0 1 0 0 1 1 0 ...
     $ rfstime: int  1838 403 1603 177 1855 842 293 42 564 1093 ...
     $ status : Factor w/ 2 levels "0","1"1 2 1 1 1 2 2 1 2 2 ...

    age:患者年龄
    meno:更年期状态(0表示未更年期,1表示已更年期)
    size:肿瘤大小
    grade:肿瘤分级
    nodes:受累淋巴结数量
    pgr:孕激素受体表达水平
    er:雌激素受体表达水平
    hormon:激素治疗(0表示否,1表示是)
    rfstime:复发或死亡时间(以天为单位)
    status:事件状态(0表示被截尾,1表示事件发生)
    • 1
    • 「互信息特征选择」
    install.packages("FSelector")
    library(FSelector)
    gbsg <- gbsg[,c(-1)]
    # 计算互信息
    weights <- information.gain(status ~ ., data = gbsg)
    print(weights)
    # 这里是截取多少个的意思
    subset <- cutoff.k(weights,5)
    f <- as.simple.formula(subset, "status")
    print(f)
    • 1

    结果展示:

    > print(weights)
            attr_importance
    age          0.00000000
    meno         0.00000000
    size         0.00000000
    grade        0.05222619
    nodes        0.03689316
    pgr          0.85827582
    er           0.11240936
    hormon       0.00000000
    rfstime      0.09209408
    # 这里是截取多少个的意思
    > subset <- cutoff.k(weights,5)
    > f <- as.simple.formula(subset, "status")
    > print(f)
    status ~ pgr + er + rfstime + grade + nodes + age
    0x0000013cbe019f48>
    • 1

    我这里是把信息通量为0的去除了

    • 「划分训练集和测试集」
    # 划分训练集和测试集
    set.seed(123)
    data <- gbsg
    data$meno <- as.factor(data$meno)
    data$hormon <- as.factor(data$hormon)
    data$grade <- as.factor(data$grade)
    train_indices <- sample(x = 1:nrow(data), size = 0.8 * nrow(data), replace = FALSE)
    test_indices <- sample(setdiff(1:nrow(data), train_indices), size = 0.2 * nrow(data), replace = FALSE)
    train_data <- data[train_indices, ]
    test_data <- data[test_indices, ]
    • 1
    • 「拟合模型并进行比较」
    # 未进行特征选择的模型拟合
    library(randomForest)
    library(pROC)
    set.seed(666)
    rf <- randomForest(status~., data=train_data)

    # 获取模型预测的概率
    pred_prob <- predict(rf, newdata = test_data, type = "class")
    # 计算真阳性率和假阳性率
    roc1 <- pROC::roc(test_data$status, pred_prob)

    # 特征选择后的模型拟合
    rf_handle <- randomForest(f, data=train_data)
    pred_prob_handle <- predict(rf_handle, newdata = test_data, type = "class")
    # 计算真阳性率和假阳性率
    roc2 <- pROC::roc(test_data$status, pred_prob_handle)

    plot(roc1,col="#2E9FDF", legacy.axes = TRUE)
    plot.roc(roc2,add=TRUE,col="red")

    abline(h = seq(01, by = 0.1), col = "gray", lty = "dotted")
    legend(0.400.17,  # 图例位置x,y
           bty = "n",   # 图例样式
           legend=c("UnHandle AUC 0.864","handle AUC 0.868"),  # 添加分组
           col=c("#2E9FDF","red"),  # 颜色跟前面一致
           lwd=2,
        border="black")  # 线条粗
    • 1

    从比较结果可以看出来,特征选择过后模型的表现比不处理的要表现的更好,然后模型的复杂度也会下降很多。

    四、结论

    「互信息特征选择是一种常用的特征选择方法,它通过计算特征与目标变量之间的互信息值来评估它们之间的相关性。这种方法的效果和对研究问题的贡献可以总结如下:」

    1. 特征选择效果:互信息特征选择可以帮助我们识别与目标变量高度相关的特征,从而提高模型的预测性能。通过计算互信息值,我们可以确定哪些特征对目标变量具有较高的信息增益,从而更好地理解数据中的关键特征。
    2. 对研究问题的贡献:互信息特征选择可以帮助我们理解数据中的关键特征,并且可以在建模过程中减少特征维度。这样可以提高模型的可解释性、降低模型的复杂度,并且可以加快训练和推理的速度。此外,互信息特征选择还可以帮助我们发现潜在的关联特征,从而为进一步的数据分析和挖掘提供线索。

    「在改进和未来工作方向方面,以下是一些可能的讨论点:」

    1. 特征选择方法的比较:互信息特征选择是特征选择的一种方法,与其他方法(如方差选择、相关性选择、L1正则化等)相比,它的优势和局限性是什么?可以考虑在不同数据集和问题上进行比较研究,以评估互信息特征选择的性能。
    2. 特征选择的稳定性:特征选择结果的稳定性是一个重要的考虑因素。可以通过使用交叉验证或引入随机性来评估互信息特征选择的稳定性,并探索如何提高其稳定性。
    3. 大规模数据和高维数据的处理:互信息特征选择在大规模和高维数据集上的计算效率如何?是否存在改进方法,以便更好地处理这些数据集?
    4. 结合领域知识的特征选择:除了互信息值,是否可以结合领域知识或先验信息来进行特征选择?这样可以更好地解释特征之间的关系,并提高特征选择的准确性。
    5. 非线性关系的建模:互信息特征选择主要基于特征与目标变量之间的线性关系。如何处理非线性关系,并将其纳入特征选择过程中,是一个值得探索的方向。

    总之,互信息特征选择是一种有用的特征选择方法,但仍有改进和深入研究的空间。通过比较不同方法、提高稳定性、处理大规模数据和高维数据、结合领域知识以及处理非线性关系,我们可以进一步提升互信息特征选择的效果,并为更复杂的数据分析和挖掘任务提供更好的支持。

  • 相关阅读:
    实现SSM项目在服务器的自动化部署(包括jdk安装,入门级教程简单易懂)
    powerlevel10k 颜色和图标的自定义设置
    android算法实现房贷计算器
    读懂Json文件[妈妈再也不用担心我不读懂了]
    proemtheus TSL加密认证
    想开发DAYU200,我教你
    第六届物业管理创新发展论坛在深召开,鹏业受邀参加并发表主题演讲
    Vue3使用customRef封装防抖函数
    玩转MyBatis-Plus分页插件一:分页基本使用+方法解释+解析Page对象
    SQLAlchemy学习-3.(懒人专用)sqlacodegen自动同步数据库中表生成model 代码
  • 原文地址:https://blog.csdn.net/weixin_43935907/article/details/134095628