Feature Engineering

作者: Abyssal_Fish | 来源:发表于2018-08-24 18:45 被阅读1次

    介绍如何在R语言中进行特征工程(未完待续)
    建议在R语言中亲自实践


    总述

    特征工程可以帮助我们提升模型的表现,但是这是一个有些玄学的东西,因为没有一种具体的、结构性强的处理方法。很多人都有一些秘而不宣的小技巧。我的体会是,对于数据比赛和发论文来说,这是一个利器。但是对于商业应用来说有些鸡肋,因为不太符合成本收益分析。

    有一点要特别强调,当你的数据量不够多时,特征工程非常重要。一旦数据量足够大以后,它就不那么重要了,这是因为像神经网等模型充分训练以后可以充分提取特征。

    尽管这是一个玄之又玄的东西,我们还是要掌握一些常规的方法。通常情况下,特征工程总是伴随着可视化,于是我们的ggplot2可以派上用场了。

    数据准备

    我们的数据来源于kaggle竞赛https://www.kaggle.com/c/mercedes-benz-greener-manufacturing/data,可以自由下载。

    我们观察数据,会发现这个数据集由0-1数据和类别数据(x0-x8)构成。把他们分离。

    library(tidyverse)
    dir_train <- 'F:/Mine/R/FE/test.csv'
    dir_test <- 'F:/Mine/R/FE/test.csv'
    train <- read_csv(dir_train)
    test <- read_csv(dir_test)
    # 我们用read_csv()读入tibble格式,此时文件路径不能含有中文,否则会报错。而传统的read.csv()则是可以的。
    data_all <- rbind(train, test)
    categorical_vars = paste0('X', c(0,1,2,3,4,5,6,8))
    categorical_data <- df_all %>% select(one_of(categorical_vars))
    # one_of(): variables in character vector ; select(): choose columns
    binary_data <- data_all %>% select(-one_of(categorical_vars))
    

    Missing Data

    这个数据集很完整,不需要处理数据缺失,我们将在另外的文档中展示这一功能。为保证特征工程的完整性,我们暂且加上它。

    One-hot encoding

    首先说一说什么是热独码。这是一种把种类数据转换为0-1矩阵的方法,很常见。

    使用one-hot encoding前:

    代码实现如下:

    library(caret)
    # perform one-hot encoding 
    dmy <- dummyVars(~., data = categorical_data)
    ohe_features <- data.frame(predict(dmy, newdata = categorical_data))
    
    data_all <- cbind(data_all, ohe_features)
    binary_data <- cbind(binary_data, ohe_features)
    binary_data_train <- binary_data[1:nrow(train), ]
    binary_data_test <- binary_data[(nrow(train)+1):nrow(binary_data),]
    
    成果:

    同时,我们还可以给0-1矩阵画图,以下代码实现了这一功能:

    image(as.matrix(ohe_features), col=c("white", "black"))
    # 主要的画图函数,横坐标是样本,纵坐标是所有的类别。被映射到[0,1]上。
    n_levels <- apply(categorical_df, 2, function(x){length(unique(x))}) 
    # 计算类的数量
    n_levels <- n_levels/sum(n_levels)
    # 归一化
    abline(h=cumsum(n_levels), col="red")
    text(0.05, cumsum(n_levels)-.025, names(n_levels), col="red")
    # 标定类
    abline(v=0.5, col="darkgreen")
    # 0.5表示训练集和测试集五五开,应视实际情况选取
    text(0.22, 0.025, "Train", col="darkgreen")
    text(0.72, 0.025, "Test", col="darkgreen")
    
    图像示例
    解读:在这个例子中,X5值得我们关注。这表明观察结果也许不是随机选择的。X5可能是一个测试参数,在几次连续的测试运行中保持不变。这表明观察的时间顺序。
    这样,我们完成了one-hot encoding。

    Hierarchical Clustering(分层聚类)

    这里聚合0-1变量并使用不同聚类索引作为新特征。使用Jaccard的距离。

    library(proxy)
    # compute distance matrix  
    jdist <- proxy::dist(binary_data, method = "Jaccard")
    # perform hierarchical clustering
    hc <- hclust(jdist)
    # get all clusterings with 2 up to max_k clusters
    max_k <- 50
    clusters <- data.frame(sapply(2:max_k, function(k){ cutree(hc,k) }))
    # 聚类的信息都储存在clusters中
    colnames(clusters) <- paste0("hc_group_", 2:max_k)
    # add lines for each cut in the dendrogram 
    plot(hc, hang = -1, labels = FALSE, xlab = "", ann=FALSE)
    cuts <- sort(hc$height, decreasing = TRUE)[2:max_k]
    abline(h=cuts, col=alpha("red",0.3))
    
    聚类结果

    这样,我们把类作为新的特征即可。有关聚类的更多细节,我们会专题学习。

    Principal Component Analysis (PCA)

    PCA也是烂大街的一种方法,具体说来就是把高维度特征精华一下,浓缩到相对低维,而又不损失太多信息。这种方法听起来不错,用起来就差强人意。不过还是比没有强那么一些。

    # perform pca
    res_pca <- prcomp(binary_data_train)
    pca_features <- predict(res_pca, newdata = binary_data)
    # proportion of explained variance 
    importance_pca <- summary(res_pca)$importance
    

    结果如下:


    可以画成这种,用ggplot2自己完成即可。



    注:
    参数的意义依次为标准差、方差贡献率、累计方差贡献率。

    Logistic PCA

    用于0-1数据降维的更合适的方法称为Logistic PCA。与普通PCA不同,Logistic PCA最大化伯努利对数似然函数而不是变量线性组合的方差。

    对Logistic PCA更详细的解释在“Dimensionality Reduction for Binary Data through the Projection of Natural Parameters”这篇论文中,下载地址为https://arxiv.org/pdf/1510.06112.pdf或者参照https://cran.r-project.org/web/packages/logisticPCA/vignettes/logisticPCA.html

    library(logisticPCA)
    library(rARPACK)
    
    # Find the appropriate values for k and m. 
    # > logsvd_model = logisticSVD(binary_data, k = 20)
    # 8418 rows and 368 columns
    # Rank 20 solution
    # 95.6% of deviance explained
    # 397 iterations to converge
    #
    # > logpca_cv = cv.lpca(binary_data, ks = 20, ms = 1:10)
    #      m
    #  k       1        2      3        4        5        6        7        8        9       10
    #  20 400428 261586.6 185985 143663.3 118547.4 102668.9 92638.51 85579.33 80440.14 76707.54
    
    k <- 20
    m <- 12
    logpca_model = logisticPCA(binary_df_train, k = k, m = m)
    logpca_features <- predict(logpca_model, newdata=binary_df)
    colnames(logpca_features) <- paste0("LPC", 1:k)
    

    这个算法计算量比较大,速度慢一些。

    ICA

    MCA

    总结

    最后我们把做好的特征组合起来,喂给我们的模型。这样,通常来说你会得到一个好于直接把数据丢给模型更好的结果。当然,有一点需要铭记:这是经验占据主导地位的一个领域。

    参考文献

    https://www.kaggle.com/msp48731/feature-engineering-and-visualization/notebook

    相关文章

      网友评论

        本文标题:Feature Engineering

        本文链接:https://www.haomeiwen.com/subject/lpwbiftx.html