svd 插补 R

Soj*_*ers 4 r svd imputation

我正在尝试使用 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
Run Code Online (Sandbox Code Playgroud)

我哪里错了?

Pat*_*rry 5

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

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

  2. 计算k对插补矩阵的秩近似。

  3. k步骤 2 中计算的秩近似中的相应值替换插补位置中的值。

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

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

如果您想执行除用列均值估算缺失值之外的其他操作,则需要为 使用较小的值k。以下代码使用您的示例数据演示了这一点:

> library("bcv")
> dataMiss = read.csv('dataMiss.csv')
Run Code Online (Sandbox Code Playgroud)

k=3

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

-0.01  0.01 
531  1062 
Run Code Online (Sandbox Code Playgroud)

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 
Run Code Online (Sandbox Code Playgroud)

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