【问题标题】:Can I use a numpy array to generate folds for cross validation?我可以使用 numpy 数组生成折叠以进行交叉验证吗?
【发布时间】:2017-03-04 05:42:00
【问题描述】:

我想使用一个 numpy 数组来为 k 折叠交叉验证任务构建折叠。取出测试片很容易,但我不知道如何返回数组的其余部分,省略了测试片。有没有有效的方法来做到这一点?

examples = range(50)
classes = range(50)
data = np.array(zip(classes,examples))
test_slice = data[5:10]
train_on_remainder = ??

【问题讨论】:

  • 连接两边的切片;结果将是一个副本。

标签: python numpy slice


【解决方案1】:

你可以这样设置:

test_slice, remainder = np.split(data.copy(), [test_size], axis=0)
# run test
remainder[:test_size], test_slice = test_slice, remainder[:test_size].copy()
# run test
remainder[test_size:2*test_size], test_slice = test_slice, remainder[test_size:2*test_size].copy()

# etc.

我不认为你可以用更少的复制来拥有它。

它是如何工作的:

.      full set:            | 0 | 1 | 2 | 3 | 4 | 5 |
       split (full copy)       / \
       tst / rem         | 0 |     | 1 | 2 | 3 | 4 | 5 |
         run trial
                             | 1 | 2 | 3 | 4 | 5 |
       swap tst and           ^ |
       first segment:         | v
       (partial copy)        | 0 |

       tst / rem         | 1 |     | 0 | 2 | 3 | 4 | 5 |
         run trial
                             | 0 | 2 | 3 | 4 | 5 |
       swap tst and               ^ |
       second segment:            | v
       (partial copy)            | 1 |

       tst / rem         | 2 |     | 0 | 1 | 3 | 4 | 5 |
         run trial
                             | 0 | 1 | 3 | 4 | 5 |
       swap tst and                   ^ |
       third segment:                 | v
       (partial copy)                | 2 |

等等。正如你所看到的,它几乎实际上是在改变折叠。保存许多完整的副本。

【讨论】:

    【解决方案2】:

    这是一个奇怪的问题,因为如果它可用,通常会使用 sklearn 的 train_test_split()

    编辑:另一种方法可能是

    r = np.arange(len(data))
    trainX = data[r < 5 | r > 10]
    

    一个有效的解决方案我不确定,但试试这个 使用列表推导构建索引器。

    def indx(n, test_slice):
        return [x for x in range(n) if, x not in test_slice]
    
    test_slice = set(range(5, 10))
    trainX = data[indx(len(data), test_slice))]
    

    当然,如果有 sklearn 的 train_test_split(),您应该使用类似的东西。

    【讨论】:

      【解决方案3】:

      如果您必须为任意数量的拆分手动实现 k 折方法:我使用了以下解决方案(为交叉验证制作训练和验证集):

      #Generate indices on the row-wise length of the whole 
      #array
      
      fold_indices = np.arange(x.shape[0])
      
      #Shuffle the indices -- if you want, but not 
      #neccessary
      np.random.shuffle(fold_indices)
      
      #Split the indices into k-parts (returns a list of 
      #numpy arrays)
      eval_indices = np.array_split(fold_indices, k)
      for e in eval_indices:
        #Define the evaluation set for the current fold
        eval_set_x = x[e]
      
        #exclude the upon parts indices from the 
        #whole array (similarly on the upon answers)
        
        mask_eval = np.ones(x.shape[0], bool)
        
        #Set indices of the eval set to false
        mask_eval[e] = False
      
        #Subset by the bool array:
        train_set_x = x[mask_eval]
          
      

      【讨论】:

        【解决方案4】:
        split = np.vsplit(data, np.array([5,10]))
        
        '''This will give you a list with 3 elements'''
        
        test_slice = split[1]
        train_slice = np.vstack((split[0],split[2]))
        

        [[5 5] [6 6] [7 7] [8 8] [9 9]]

        [[ 0 0] [ 1 1] [ 2 2] [ 3 3] [ 4 4] [10 10] [11 11] [12 12] [13 13] [14 14] [15 15] [16 16] [17 17] [18 18] … [47 47] [48 48] [49 49]]

        【讨论】:

          【解决方案5】:

          两种方法,在一维数组上演示:

          In [64]: data = np.arange(20)
          In [65]: test = data[5:10]
          In [66]: rest = np.concatenate((data[:5],data[10:]),axis=0)
          In [67]: rest
          Out[67]: array([ 0,  1,  2,  3,  4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
          In [68]: 
          In [68]: mask = np.zeros(data.shape[0], dtype=bool)
          In [69]: mask[5:10] = True
          In [70]: test = data[mask]
          In [71]: rest = data[~mask]
          In [72]: rest
          Out[72]: array([ 0,  1,  2,  3,  4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
          

          有一个np.delete函数

          In [75]: np.delete(data, np.arange(5,10))
          Out[75]: array([ 0,  1,  2,  3,  4, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
          

          它在内部使用我演示的两种方法之一。

          【讨论】:

            猜你喜欢
            • 2023-02-24
            • 2014-05-12
            • 2020-02-06
            • 2017-05-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-03-19
            • 2016-12-25
            相关资源
            最近更新 更多