3

任意の割合で分割したいコレクションがあります。私が解決しようとしている実際の問題は、データセットをトレーニングと相互検証のセットに分割することです。

各要素の宛先はランダムに選択する必要がありますが、各ソース要素は結果に1回だけ表示され、パーティションのサイズは固定されています。ソースコレクションに重複がある場合、重複は異なる出力パーティションまたは同じものに表示される可能性があります。

私はこの実装を持っています:

(defn split-shuffled
  "Returns a 2 element vector partitioned by the percentage 
   specified by p. Elements are selected at random. Each 
   element of the source collection will appear only once in 
   the result."
  [c p]
  (let [m (count c)
        idxs (into #{} (take (* m p) (shuffle (range m))))
        afn (fn [i x] (if (idxs i) x))
        bfn (fn [i x] (if-not (idxs i) x))]
    [(keep-indexed afn c) (keep-indexed bfn c)]))

repl> (split-shuffled (range 10) 0.2)
[(4 6) (0 1 2 3 5 7 8 9)]

repl> (split-shuffled (range 10) 0.4)
[(1 4 6 7) [0 2 3 5 8 9)] 

しかし、それkeep-indexedが二度呼ばれるのは不幸です。

これをどのように改善できますか?

編集:私はもともとパーティションの順序を維持したかったのですが、再考せずにその要件を削除したので、@ mikeraのソリューションは正しいです!

4

1 に答える 1

5

なぜインデックスが必要なのですか?

コレクションを直接シャッフルするだけです。

(defn split-shuffled
     [c p]
     (let [c (shuffle c)
           m (count c)
           t (* m p)]
       [(take t c) (drop t c)]))
于 2012-07-21T16:52:18.917 に答える