【问题标题】:svd imputation Rsvd 插补 R
【发布时间】:2016-06-10 23:39:51
【问题描述】:

我正在尝试使用 bcv 包中的 SVD 插补,但所有插补值都相同(按列)。

这是缺少数据的数据集 http://pastebin.com/YS9qaUPs

#load data
dataMiss = read.csv('dataMiss.csv')
#impute data
SVDimputation = round(impute.svd(dataMiss)$x, 2)
#find index of missing values
bool = apply(X = dataMiss, 2, is.na)
#put in a new data frame only the imputed value
SVDImpNA = mapply(function(x,y) x[y], as.data.frame(SVDimputation), as.data.frame(bool))
View(SVDImpNA)

head(SVDImpNA)
        V1   V2   V3
[1,] -0.01 0.01 0.01
[2,] -0.01 0.01 0.01
[3,] -0.01 0.01 0.01
[4,] -0.01 0.01 0.01
[5,] -0.01 0.01 0.01
[6,] -0.01 0.01 0.01

我哪里错了?

【问题讨论】:

    标签: r svd imputation


    【解决方案1】:

    impute.svd 算法的工作原理如下:

    1. 用对应的列均值替换所有缺失值。

    2. 计算估算矩阵的秩-k 近似值。

    3. 将估算位置中的值替换为步骤 2 中计算的 rank-k 近似值中的相应值。

    4. 重复步骤 2 和 3,直到收敛。

    在您的示例代码中,您正在设置k=min(n,p)(默认值)。然后,在步骤 2 中,rank-k 近似值正好等于插补矩阵。该算法在 0 次迭代后收敛。也就是说,该算法将所有估算条目设置为列均值(或者如果存在数值错误,则非常接近此值)。

    如果您想做的不是用列均值估算缺失值,您需要为k 使用较小的值。以下代码使用您的示例数据演示了这一点:

    > library("bcv")
    > dataMiss = read.csv('dataMiss.csv')
    

    k=3

    > SVDimputation = impute.svd(dataMiss, k = 3,  maxiter=10000)$x
    > table(round(SVDimputation[is.na(dataMiss)], 2))
    
    -0.01  0.01 
    531  1062 
    

    k=2

    > SVDimputation = impute.svd(dataMiss, k = 2,  maxiter=10000)$x
    > table(round(SVDimputation[is.na(dataMiss)], 2))
    
    -11.31  -6.94  -2.59  -2.52  -2.19  -2.02  -1.67  -1.63 
        25     23     61      2     54     23      5     44 
     -1.61   -1.2  -0.83   -0.8  -0.78  -0.43  -0.31  -0.15 
        14     10     13     19     39      1     14     19 
     -0.14  -0.02      0   0.01   0.02   0.03   0.06   0.17 
        83     96     94     77     30     96     82     28 
      0.46   0.53   0.55   0.56   0.83   0.91   1.26   1.53 
         1    209     83     23     28    111     16      8 
      1.77   5.63   9.99  14.34 
       112     12     33      5 
    

    请注意,对于您的数据,默认的最大迭代次数 (100) 太低(我收到一条警告消息)。为了解决这个问题,我设置了maxiter=10000

    【讨论】:

      【解决方案2】:

      您描述的问题可能会发生,因为 impute.svd 最初将所有 NA 值设置为等于列均值,然后在收敛时不会更改这些值。

      这取决于您首先使用 SVD 插补的原因,但如果您很灵活,解决此问题的一个好方法可能是通过将 k 设置为来切换 SVD 调用的等级,例如, 1. 目前,k 自动设置为 min(n, p),其中 n = nrow,p = ncol,对于您的数据,这意味着 k = 3。例如,如果您将其设置为 1(如在impute.svd 函数文档中的示例),则不会出现此问题:

      library(bcv) 
      dataMiss = read.csv("dataMiss.csv") 
      SVDimputation = round(impute.svd(dataMiss, k = 1)$x, 2)
      
      head(SVDimputation) 
            [,1]  [,2]  [,3]
      [1,]  0.96 -0.23  0.52
      [2,]  0.02 -0.23 -1.92
      [3,] -1.87 -0.23  0.52
      [4,] -0.92 -0.23  0.52
      [5,]  0.49 -0.46  0.52
      [6,] -1.87 -0.23  0.52
      

      【讨论】:

      • 谢谢,我已经尝试过这种方式,但是 K 是矩阵的压缩参数,所以我猜一小部分会加快计算 svd 的近似值插补的秩矩阵,但插补结果不佳
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-18
      • 2022-11-03
      • 1970-01-01
      • 2022-01-14
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多