2016-12-09 8 views
3

文字列ラベルをワンホットエンコードにエンコードしようとすると、メモリの問題が引き続き発生します。約500万行と約10000種類のラベルがあります。私は以下のが、キープ取得メモリエラーを試してみました:巨大なデータのためのPython:ワンホットエンコード

import numpy as np 

def one_hot_encoding(y): 
    unique_values = set(y) 
    label_length = len(unique_values) 
    enu_uniq = zip(unique_values , range(len(unique_values))) 
    dict1 = dict(enu_uniq) 
    values = [] 
    for i in y: 
     temp = np.zeros((label_length,), dtype="float32") 
     if i in dict1: 
      temp[dict1[i]] = 1.0 
     values.append(temp) 
    return np.array(values) 

それでもなっメモリerros:

from sklearn import preprocessing 
lb = preprocessing.LabelBinarizer() 
label_fitter = lb.fit(y) 
y = label_fitter.transform(y) 

は、私もこのような何かを試してみました。すべてのヒント?いくつかの人がスタックで同じことを尋ねていますが、答えはちょっと役に立たないようです。

答えて

3

あなたの主な問題は、2進化されたyがあなたのメモリに収まらないということです。これを避けるために、疎配列で作業することができます。

>>> import numpy as np 
>>> from scipy.sparse import csc_matrix 
>>> y = np.random.randint(0, 10000, size=5000000) # 5M random integers [0,10K) 

次のように、5M x 10Kスパース行列にこれらのラベルyを変換することができ:

>>> dtype = np.uint8 # change to np.bool if you want boolean or other data type 
>>> rows = np.arange(y.size) # each of the elements of `y` is a row itself 
>>> cols = y # `y` indicates the column that is going to be flagged 
>>> data = np.ones(y.size, dtype=dtype) # Set to `1` each (row,column) pair 
>>> ynew = csc_matrix((data, (rows, cols)), shape=(y.size, y.max()+1), dtype=dtype) 

ynew次に、各行が一つのエントリを除いてゼロに満ちている疎行列である:

>>> ynew 
<5000000x10000 sparse matrix of type '<type 'numpy.uint8'>' 
    with 5000000 stored elements in Compressed Sparse Column format> 

スパース行列を扱う方法を学習するためにコードを修正する必要がありますが、おそらく最良の選択です。

任意のデータ型の列ラベルまたはラベルの
>>> row0 = ynew[0].toarray() # row0 is a standard numpy array 

:また、あなたはとして疎行列からフル行または列を回復することができ

>>> y = ['aaa' + str(i) for i in np.random.randint(0, 10000, size=5000000)] # e.g. 'aaa9937' 

まずラベルから整数へのマッピングを抽出します:

>>> labels = np.unique(y) # List of unique labels 
>>> mapping = {u:i for i,u in enumerate(labels)} 
>>> inv_mapping = {i:u for i,u in enumerate(labels)} # Only needed if you want to recover original labels at some point 

上記mapping整数にラベルのそれぞれをマッピング(に基づきますユニークなセットlabelsに格納されている順序)。再びスパース行列を作成し、その後

そして:

>>> N, M = len(y), labels.size 
>>> dtype = np.uint8 # change np.bool if you want boolean 
>>> rows = np.arange(N) 
>>> cols = [mapping[i] for i in y] 
>>> data = np.ones(N, dtype=dtype) 
>>> ynew = csc_matrix((data, (rows, cols)), shape=(N, M), dtype=dtype) 

あなたはlabel Xオリジナルラベルのマップ先のを知りたい、将来的にあれば(必要ありませんが)逆マッピングを作成することができます。

>>> inv_mapping = {i:u for i,u in enumerate(labels)} 
>>> inv_mapping[10] # ---> something like 'aaaXXX' 
+0

私は本当に問題をどのように扱ったのが好きです。残念ながら、それは文字列ラベルを意味しません。 –

+0

@MpizosDimitris編集を参照してください。 2番目のバージョンは、マッピング(および逆マッピング*)によって、ラベル用のあらゆる種類のデータ型で動作するようになりました。 –

関連する問題