Python:海量数据的one-hot编码
Python: One-hot encoding for huge data
我一直在尝试将 字符串标签 编码为单热编码时遇到内存问题。大约有 500 万行和大约 10000 个不同的标签。我尝试了以下但不断出现内存错误:
from sklearn import preprocessing
lb = preprocessing.LabelBinarizer()
label_fitter = lb.fit(y)
y = label_fitter.transform(y)
我也试过这样的方法:
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)
仍然出现内存错误。任何提示?有些人在这里问同样的问题,但没有答案似乎很有用。
您的主要问题似乎是二值化后的 y
不适合您的记忆。您可以使用稀疏数组来避免这种情况。
>>> import numpy as np
>>> from scipy.sparse import csc_matrix
>>> y = np.random.randint(0, 10000, size=5000000) # 5M random integers [0,10K)
您可以将这些标签 y
转换为 5M x 10K
稀疏矩阵,如下所示:
>>> 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'
这在提问时可能不可用,但 LabelBinarizer 需要一个 sparse_output
参数。
from sklearn.preprocessing import LabelBinarizer
lb = LabelBinarizer(sparse_output=True)
我一直在尝试将 字符串标签 编码为单热编码时遇到内存问题。大约有 500 万行和大约 10000 个不同的标签。我尝试了以下但不断出现内存错误:
from sklearn import preprocessing
lb = preprocessing.LabelBinarizer()
label_fitter = lb.fit(y)
y = label_fitter.transform(y)
我也试过这样的方法:
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)
仍然出现内存错误。任何提示?有些人在这里问同样的问题,但没有答案似乎很有用。
您的主要问题似乎是二值化后的 y
不适合您的记忆。您可以使用稀疏数组来避免这种情况。
>>> import numpy as np
>>> from scipy.sparse import csc_matrix
>>> y = np.random.randint(0, 10000, size=5000000) # 5M random integers [0,10K)
您可以将这些标签 y
转换为 5M x 10K
稀疏矩阵,如下所示:
>>> 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'
这在提问时可能不可用,但 LabelBinarizer 需要一个 sparse_output
参数。
from sklearn.preprocessing import LabelBinarizer
lb = LabelBinarizer(sparse_output=True)