avi*_*hen 101 python machine-learning pandas anaconda one-hot-encoding
我有80%分类变量的机器学习分类问题.如果我想使用某种分类器进行分类,我必须使用一个热编码吗?我可以在没有编码的情况下将数据传递给分类器吗?
我正在尝试执行以下功能选择:
我读了火车文件:
num_rows_to_read = 10000
train_small = pd.read_csv("../../dataset/train.csv", nrows=num_rows_to_read)
Run Code Online (Sandbox Code Playgroud)我将分类要素的类型更改为"类别":
non_categorial_features = ['orig_destination_distance',
'srch_adults_cnt',
'srch_children_cnt',
'srch_rm_cnt',
'cnt']
for categorical_feature in list(train_small.columns):
if categorical_feature not in non_categorial_features:
train_small[categorical_feature] = train_small[categorical_feature].astype('category')
Run Code Online (Sandbox Code Playgroud)我使用一个热编码:
train_small_with_dummies = pd.get_dummies(train_small, sparse=True)
Run Code Online (Sandbox Code Playgroud)问题是第3部分经常卡住,虽然我使用的是强机.
因此,在没有热编码的情况下,我无法进行任何特征选择,以确定特征的重要性.
您有什么推荐的吗?
Say*_*ane 134
方法1:您可以在pandas数据帧上使用get_dummies.
例1:
import pandas as pd
s = pd.Series(list('abca'))
pd.get_dummies(s)
Out[]:
a b c
0 1.0 0.0 0.0
1 0.0 1.0 0.0
2 0.0 0.0 1.0
3 1.0 0.0 0.0
Run Code Online (Sandbox Code Playgroud)
例2:
以下内容将给定列转换为一个热点.使用前缀有多个假人.
import pandas as pd
df = pd.DataFrame({
'A':['a','b','a'],
'B':['b','a','c']
})
df
Out[]:
A B
0 a b
1 b a
2 a c
# Get one hot encoding of columns B
one_hot = pd.get_dummies(df['B'])
# Drop column B as it is now encoded
df = df.drop('B',axis = 1)
# Join the encoded df
df = df.join(one_hot)
df
Out[]:
A a b c
0 a 0 1 0
1 b 1 0 0
2 a 0 0 1
Run Code Online (Sandbox Code Playgroud)
方法2:使用Scikit-learn
给定具有三个特征和四个样本的数据集,我们让编码器找到每个特征的最大值并将数据转换为二进制单热编码.
>>> from sklearn.preprocessing import OneHotEncoder
>>> enc = OneHotEncoder()
>>> enc.fit([[0, 0, 3], [1, 1, 0], [0, 2, 1], [1, 0, 2]])
OneHotEncoder(categorical_features='all', dtype=<class 'numpy.float64'>,
handle_unknown='error', n_values='auto', sparse=True)
>>> enc.n_values_
array([2, 3, 4])
>>> enc.feature_indices_
array([0, 2, 5, 9], dtype=int32)
>>> enc.transform([[0, 1, 1]]).toarray()
array([[ 1., 0., 0., 1., 0., 0., 1., 0., 0.]])
Run Code Online (Sandbox Code Playgroud)
以下是此示例的链接:http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html
Mar*_*oma 25
您可以使用numpy.eye
和使用数组元素选择机制:
import numpy as np
nb_classes = 6
data = [[2, 3, 4, 0]]
def indices_to_one_hot(data, nb_classes):
"""Convert an iterable of indices to one-hot encoded labels."""
targets = np.array(data).reshape(-1)
return np.eye(nb_classes)[targets]
Run Code Online (Sandbox Code Playgroud)
现在的返回值indices_to_one_hot(nb_classes, data)
是
array([[[ 0., 0., 1., 0., 0., 0.],
[ 0., 0., 0., 1., 0., 0.],
[ 0., 0., 0., 0., 1., 0.],
[ 1., 0., 0., 0., 0., 0.]]])
Run Code Online (Sandbox Code Playgroud)
这.reshape(-1)
是为了确保您拥有正确的标签格式(您可能也有[[2], [3], [4], [0]]
).
Wbo*_*boy 20
首先,一个热门编码的最简单方法:使用Sklearn.
http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html
其次,我不认为将pandas用于一个热门编码就是那么简单(虽然未经证实)
最后,您需要一个热门编码吗?一个热编码会以指数方式增加功能的数量,从而大大增加任何分类器或您将要运行的任何其他内容的运行时间.特别是当每个分类特征具有多个级别时.相反,你可以做虚拟编码.
使用虚拟编码通常效果很好,运行时间和复杂性要低得多.一位聪明的教授曾告诉我,"少即是多".
如果需要,这是我自定义编码功能的代码.
from sklearn.preprocessing import LabelEncoder
#Auto encodes any dataframe column of type category or object.
def dummyEncode(df):
columnsToEncode = list(df.select_dtypes(include=['category','object']))
le = LabelEncoder()
for feature in columnsToEncode:
try:
df[feature] = le.fit_transform(df[feature])
except:
print('Error encoding '+feature)
return df
Run Code Online (Sandbox Code Playgroud)
编辑:比较更清晰:
单热编码:将n级转换为n-1列.
Index Animal Index cat mouse
1 dog 1 0 0
2 cat --> 2 1 0
3 mouse 3 0 1
Run Code Online (Sandbox Code Playgroud)
如果您的分类功能中有许多不同类型(或级别),您可以看到这将如何破坏您的记忆.请记住,这只是一列.
虚拟编码:
Index Animal Index Animal
1 dog 1 0
2 cat --> 2 1
3 mouse 3 2
Run Code Online (Sandbox Code Playgroud)
转而使用数字表示法.以极高的精度为代价,大大节省了功能空间.
Cyb*_*tic 20
更容易使用Pandas进行基本的单热编码.如果您正在寻找更多选项,可以使用scikit-learn.
对于使用Pandas的基本单热编码,您只需将数据帧传递给get_dummies函数即可.
例如,如果我有一个名为imdb_movies的数据框:
...我希望对"额定"列进行单热编码,我只需这样做:
pd.get_dummies(imdb_movies.Rated)
Run Code Online (Sandbox Code Playgroud)
这将返回一个新的数据框,其中包含存在的每个" 级别 "的列,以及指定给定观察的该评级的存在的1或0.
通常,我们希望这是原始数据帧的一部分.在这种情况下,我们只需使用" 列绑定 "将新的虚拟编码帧附加到原始帧上.
我们可以使用Pandas concat函数进行列绑定:
rated_dummies = pd.get_dummies(imdb_movies.Rated)
pd.concat([imdb_movies, rated_dummies], axis=1)
Run Code Online (Sandbox Code Playgroud)
我们现在可以对我们的完整数据框进行分析.
简单的实用功能
我建议你自己做一个实用功能来快速做到这一点:
def encode_and_bind(original_dataframe, feature_to_encode):
dummies = pd.get_dummies(original_dataframe[[feature_to_encode]])
res = pd.concat([original_dataframe, dummies], axis=1)
return(res)
Run Code Online (Sandbox Code Playgroud)
用法:
encode_and_bind(imdb_movies, 'Rated')
Run Code Online (Sandbox Code Playgroud)
结果:
另外,根据@pmalbu注释,如果您希望该函数删除原始feature_to_encode,请使用此版本:
def encode_and_bind(original_dataframe, feature_to_encode):
dummies = pd.get_dummies(original_dataframe[[feature_to_encode]])
res = pd.concat([original_dataframe, dummies], axis=1)
res = res.drop([feature_to_encode], axis=1)
return(res)
Run Code Online (Sandbox Code Playgroud)
Qy *_*Zuo 16
使用pandas进行一次热门编码非常简单:
def one_hot(df, cols):
"""
@param df pandas DataFrame
@param cols a list of columns to encode
@return a DataFrame with one-hot encoding
"""
for each in cols:
dummies = pd.get_dummies(df[each], prefix=each, drop_first=False)
df = pd.concat([df, dummies], axis=1)
return df
Run Code Online (Sandbox Code Playgroud)
编辑:
使用sklearn的one_hot的另一种方法LabelBinarizer
:
from sklearn.preprocessing import LabelBinarizer
label_binarizer = LabelBinarizer()
label_binarizer.fit(all_your_labels_list) # need to be global or remembered to use it later
def one_hot_encode(x):
"""
One hot encode a list of sample labels. Return a one-hot encoded vector for each label.
: x: List of sample Labels
: return: Numpy array of one-hot encoded labels
"""
return label_binarizer.transform(x)
Run Code Online (Sandbox Code Playgroud)
Die*_*ter 13
你可以使用numpy.eye函数.
import numpy as np
def one_hot_encode(x, n_classes):
"""
One hot encode a list of sample labels. Return a one-hot encoded vector for each label.
: x: List of sample Labels
: return: Numpy array of one-hot encoded labels
"""
return np.eye(n_classes)[x]
def main():
list = [0,1,2,3,4,3,2,1,0]
n_classes = 5
one_hot_list = one_hot_encode(list, n_classes)
print(one_hot_list)
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
结果
D:\Desktop>python test.py
[[ 1. 0. 0. 0. 0.]
[ 0. 1. 0. 0. 0.]
[ 0. 0. 1. 0. 0.]
[ 0. 0. 0. 1. 0.]
[ 0. 0. 0. 0. 1.]
[ 0. 0. 0. 1. 0.]
[ 0. 0. 1. 0. 0.]
[ 0. 1. 0. 0. 0.]
[ 1. 0. 0. 0. 0.]]
Run Code Online (Sandbox Code Playgroud)
pandas 具有内置函数“get_dummies”,以获得该特定列的一种热编码。
one-hot-encoding的一行代码:
df=pd.concat([df,pd.get_dummies(df['column name'],prefix='column name')],axis=1).drop(['column name'],axis=1)
Run Code Online (Sandbox Code Playgroud)