2016-05-04 11 views
1

私はジュリアの機械学習アルゴリズムをマシン上の限られたスペアメモリで実行しています。とにかく、私はリポジトリから使用しているコードにかなり大きなボトルネックがあることに気付きました。配列を(ランダムに)分割することは、コードの非効率性を強調すると思われるディスクからファイルを読み込むよりも時間がかかります。前にも述べたように、この機能をスピードアップするためのあらゆるトリックが大いに評価されます。元の関数はhereです。短い機能なので、私も下に掲載します。Juliaでアレイをトレーニングとテストセットに分割する効率的な方法は何ですか?

# Split a list of ratings into a training and test set, with at most 
# target_percentage * length(ratings) in the test set. The property we want to 
# preserve is: any user in some rating in the original set of ratings is also 
# in the training set and any item in some rating in the original set of ratings 
# is also in the training set. We preserve this property by iterating through 
# the ratings in random order, only adding an item to the test set only if we 
# haven't already hit target_percentage and we've already seen both the user 
# and the item in some other ratings. 
function split_ratings(ratings::Array{Rating,1}, 
         target_percentage=0.10) 
    seen_users = Set() 
    seen_items = Set() 
    training_set = (Rating)[] 
    test_set = (Rating)[] 
    shuffled = shuffle(ratings) 
    for rating in shuffled 
     if in(rating.user, seen_users) && in(rating.item, seen_items) && length(test_set) < target_percentage * length(shuffled) 
      push!(test_set, rating) 
     else 
      push!(training_set, rating) 
     end 
     push!(seen_users, rating.user) 
     push!(seen_items, rating.item) 
    end 
    return training_set, test_set 
end 

前述のように、とにかく私はデータをプッシュすることができます非常に感謝します。私は重複を取り除く能力を本当に保持する必要はないことにも気付くだろうが、それは素晴らしい機能だろう。また、これがすでにJuliaライブラリに実装されている場合は、それについて知っていただければ幸いです。ジュリアの並列性を活用するあらゆるソリューションのボーナスポイント!

+2

チェックアウトhttps://github.com/JuliaML/MLDataUtils.jl –

+0

シングルトンレーティング(アイテムまたはユーザーに固有のもの)をトレーニングセットに自動的にルーティングすると、バイアスが生成されることはありません学習アルゴリズムのために? –

+0

私は元のアルゴリズムを実装していませんでしたが、とにかく私は使用し終わったコードでその部分を無視しました。 – Skylion

答えて

2

これはメモリの面で最も効率的なコードです。

function splitratings(ratings::Array{Rating,1}, target_percentage=0.10) 
    N = length(ratings) 
    splitindex = round(Integer, target_percentage * N) 
    shuffle!(ratings) #This shuffles in place which avoids the allocation of another array! 
    return sub(ratings, splitindex+1:N), sub(ratings, 1:splitindex) #This makes subarrays instead of copying the original array! 
end 

しかし、ジュリアのファイルIOは非常に遅いので、今やボトルネックになっています。このアルゴリズムは、1億7千万要素の配列を実行するのに約20秒かかるので、私はそれがむしろ実行可能であると言います。

+0

これは、テストセットとトレーニングセットの両方で要素を 'splitindex'に複製します。 'splitindex + 1:N'を使います。また、バージョン0.4では 'iround'は廃止予定です。 –

+0

ポインタありがとう!分割インデックスを複製することはひどい問題ではありませんが、私はそれを私のポストで本当に速く修正します。 – Skylion

関連する問題