2016-12-09 2 views
3

문자열 레이블을 원 핫 인코딩으로 인코딩하려고하면 메모리 문제가 계속 발생합니다. 약 5 백만 행과 약 10000 개의 다른 레이블이 있습니다. 나는 다음과 같은 있지만 계속 점점 메모리 오류를 시도 :대용량 데이터를위한 파이썬 : one-hot 인코딩

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) 

여전히 점점 기억하는 오류 :

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

내가이 뭔가를 시도했다. 어떤 팁? 어떤 사람들은 스택에 같은 것을 묻는 사람들이 있지만 아무런 대답도 도움이되지 않습니다.

답변

3

주요 문제는 이진화 된 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' 

먼저 정수로 라벨 대응 관계를 추출 또한, 당신은 스파 스 매트릭스에서 전체 행 또는 열을 복구 할 수 있습니다 : mapping

>>> 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 

(가) 정수로 라벨의 각 매핑 (기반 고유 집합 labels에 저장된 순서).

그리고 다시 희소 행렬 생성 : (필요하지 않지만) 미래에 당신이 label X에있는 원래의 라벨지도 알고 싶다면 역 매핑을

>>> 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) 

당신은 만들 수 있습니다 :

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

나는 정말로 어떻게 문제를 해결했는지 좋아했다. 불행히도 문자열 레이블을 의미하지는 않습니다. –

+0

@MpizosDimitris 편집을 참조하십시오. 두 번째 버전은 이제 매핑 (및 역 매핑 *)을 통해 레이블에 대한 모든 종류의 데이터 유형과 함께 작동합니다. –