numpy 机器学习的一种热编码

ruyhziif  于 2023-03-23  发布在  其他
关注(0)|答案(3)|浏览(171)

我有一个存储在(10000, 15) numpy数组中的数据集。列[1, 5, 6, 7, 8, 9, 13, 14]都是分类数据,而其余的都是数值数据。我需要将分类数据更改为数值数据,以便能够在模型中使用它(使用sklearn)。
我尝试使用sklearn.preprocessing库中的OneHotEncoder,

# train = subset of data used for training, shape (7000, 15)
cat_columns = [1, 5, 6, 7, 8, 9, 13, 14]
ohe = OneHotEncoder(sparse_output=False)
train_encoded = ohe.fit_transform(train[:, cat_columns)
train[:, cat_columns] = train_encoded

不幸的是,这不起作用,因为数据在编码后会改变形状。我将感谢任何关于如何将此分类数据转换为数值的建议。
下面是前3行数据的示例,最后一个特征是稍后将被分割和预测的内容。

[['39' 'State-gov' '77516' 'Bachelors' '13' 'Never-married'
  'Adm-clerical' 'Not-in-family' 'White' 'Male' '2174' '0' '40'
  'United-States' '<=50K']
 ['50' 'Self-emp-not-inc' '83311' 'Bachelors' '13' 'Married-civ-spouse'
  'Exec-managerial' 'Husband' 'White' 'Male' '0' '0' '13' 'United-States'
  '<=50K']
 ['38' 'Private' '215646' 'HS-grad' '9' 'Divorced' 'Handlers-cleaners'
  'Not-in-family' 'White' 'Male' '0' '0' '40' 'United-States' '<=50K']
]
wmomyfyw

wmomyfyw1#

我认为你对OneHotEncoder的理解不正确。这将比我更好地回答你的问题。
OneHotEncoder将分类值转换为字节。字节可以是yes/no、true/false、1/0等;但总是只有两种可能
如果你的分类值是男性/女性--〉好的,你可以把它转换成1和0,如果你的分类值是蓝色/红色/绿色--〉该死,1/0的表示是不够的。
这就是为什么OneHotEncoder将每个值都转换为数组的原因!如果您将red/blue/绿色拟合到OneHotEncoder,然后转换值“blue”,则其表示将是[0,1,0],代表0 no red,1 yes blue,0 no green。
我想你要找的是OrdinalEncoder。那个不应该改变形状,因为它只是用一个数字而不是字节数组替换你的“蓝色”。
无论如何,你会发现OrdinalEncoder也在我链接你的源代码。它应该给予更多的见解比我的演讲。希望它有帮助

from sklearn.preprocessing import OrdinalEncoder

data = [['39', 'State-gov', '77516', 'Bachelors', '13', 'Never-married',
  'Adm-clerical', 'Not-in-family', 'White', 'Male', '2174', '0', '40',
  'United-States', '<=50K'],
 ['50', 'Self-emp-not-inc', '83311', 'Bachelors', '13', 'Married-civ-spouse',
  'Exec-managerial', 'Husband' ,'White', 'Male' ,'0', '0', '13' ,'United-States',
  '<=50K'],
 ['38' ,'Private', '215646' ,'HS-grad' ,'9', 'Divorced' ,'Handlers-cleaners',
  'Not-in-family' ,'White' ,'Male', '0', '0', '40', 'United-States' ,'<=50K']
]
df = pd.DataFrame(data)
print(df[cat_columns].shape)  # (3,8)

cat_columns = [1, 5, 6, 7, 8, 9, 13, 14]
ohe = OrdinalEncoder(sparse_output=False)
train_encoded = ohe.fit_transform(df[cat_columns])
print(train_encoded.shape)  # (3,8)
df[cat_columns] = train_encoded
5w9g7ksd

5w9g7ksd2#

我建议使用category_encoders包中的TargetEncoder

from category_encoders import TargetEncoder

cat_columns = [1, 5, 6, 7, 8, 9, 13, 14]
enc = TargetEncoder(cols=cat_columns).fit(X, y)
# Where X is your exogenous variables pandas dataframe or array and y is your endogenous variable pandas series or array.

numeric_train = enc.transform(X)

这种解决方案不会改变原始数据的形状,并且它是一种更好的解决方案,因为它考虑了分类外生变量和内生变量之间的关系,而不是仅仅使用序数编码方法(用0,1,2......替换变量,根本没有标准)。在链接页面中有更详细的解释。
希望这有帮助!

ltskdhd1

ltskdhd13#

我知道您想使用OneHotEncoder,但只在数组的一部分上使用,而不是在所有列上使用。
您可以使用np.c_train_encoded添加到非编码列:

# train = subset of data used for training, shape (7000, 15)
cat_columns = [1, 5, 6, 7, 8, 9, 13, 14]
ohe = OneHotEncoder(sparse_output=False)

# Encoded columns
train_encoded = ohe.fit_transform(train[:, cat_columns])

# Non encoded columns
train_not_encoded = np.delete(train, cat_columns, 1)

# Merging the two
train_2 = np.c_[train_not_encoded , train_encoded]

更简单的是使用pd.get_dummies,它允许您指定要编码的列:

import pandas as pd
df = pd.DataFrame(train)
train_2  = pd.get_dummies(df, columns=cat_columns)

相关问题