我有一个80%类别变量的机器学习分类问题。如果我想使用一些分类器进行分类,我必须使用一个热编码吗?我可以将数据传递给分类器而不进行编码吗?

我试图做以下的特征选择:

I read the train file: num_rows_to_read = 10000 train_small = pd.read_csv("../../dataset/train.csv", nrows=num_rows_to_read) I change the type of the categorical features to 'category': 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') I use one hot encoding: train_small_with_dummies = pd.get_dummies(train_small, sparse=True)

问题是,第三部分经常卡住,尽管我使用的是一个强大的机器。

因此,如果没有一个热编码,我就无法进行任何特征选择,以确定特征的重要性。

你有什么建议吗?


当前回答

我在我的声学模型中使用了这个: 也许这对你的模型有帮助。

def one_hot_encoding(x, n_out):
    x = x.astype(int)  
    shape = x.shape
    x = x.flatten()
    N = len(x)
    x_categ = np.zeros((N,n_out))
    x_categ[np.arange(N), x] = 1
    return x_categ.reshape((shape)+(n_out,))

其他回答

首先,最简单的热编码方法:使用Sklearn。

http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html

其次,我不认为使用熊猫进行一个热编码是那么简单(虽然未经证实)

在pandas中为python创建虚拟变量

最后,你需要一个热编码吗?一个热编码以指数方式增加了特征的数量,大大增加了任何分类器或任何你要运行的东西的运行时间。特别是当每个分类特征都有很多层次时。相反,你可以进行虚拟编码。

使用虚拟编码通常工作得很好,运行时间和复杂性要少得多。一位睿智的教授曾经告诉我,“少即是多”。

如果你愿意,这是我的自定义编码函数的代码。

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

编辑:比较更清楚:

一热编码:将n层转换为n-1列。

Index  Animal         Index  cat  mouse
  1     dog             1     0     0
  2     cat       -->   2     1     0
  3    mouse            3     0     1

你可以看到,如果你的分类特征中有许多不同类型(或级别),这会使你的记忆爆发式增长。记住,这只是一列。

伪代码:

Index  Animal         Index  Animal
  1     dog             1      0   
  2     cat       -->   2      1 
  3    mouse            3      2

转换为数字表示。极大地节省了特征空间,代价是准确性。

试试这个:

!pip install category_encoders
import category_encoders as ce

categorical_columns = [...the list of names of the columns you want to one-hot-encode ...]
encoder = ce.OneHotEncoder(cols=categorical_columns, use_cat_names=True)
df_train_encoded = encoder.fit_transform(df_train_small)

df_encoded.head ()

生成的数据框架df_train_encoded与原始数据框架相同,但是分类特征现在被它们的单热编码版本所取代。

更多关于category_encoders的信息请点击这里。

我在我的声学模型中使用了这个: 也许这对你的模型有帮助。

def one_hot_encoding(x, n_out):
    x = x.astype(int)  
    shape = x.shape
    x = x.flatten()
    N = len(x)
    x_categ = np.zeros((N,n_out))
    x_categ[np.arange(N), x] = 1
    return x_categ.reshape((shape)+(n_out,))

简短的回答

这里有一个函数,可以在不使用numpy、pandas或其他包的情况下进行一次性编码。它接受一个整数、布尔值或字符串(也可能是其他类型)的列表。

import typing


def one_hot_encode(items: list) -> typing.List[list]:
    results = []
    # find the unique items (we want to unique items b/c duplicate items will have the same encoding)
    unique_items = list(set(items))
    # sort the unique items
    sorted_items = sorted(unique_items)
    # find how long the list of each item should be
    max_index = len(unique_items)

    for item in items:
        # create a list of zeros the appropriate length
        one_hot_encoded_result = [0 for i in range(0, max_index)]
        # find the index of the item
        one_hot_index = sorted_items.index(item)
        # change the zero at the index from the previous line to a one
        one_hot_encoded_result[one_hot_index] = 1
        # add the result
        results.append(one_hot_encoded_result)

    return results

例子:

one_hot_encode([2, 1, 1, 2, 5, 3])

# [[0, 1, 0, 0],
#  [1, 0, 0, 0],
#  [1, 0, 0, 0],
#  [0, 1, 0, 0],
#  [0, 0, 0, 1],
#  [0, 0, 1, 0]]
one_hot_encode([True, False, True])

# [[0, 1], [1, 0], [0, 1]]
one_hot_encode(['a', 'b', 'c', 'a', 'e'])

# [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0], [0, 0, 0, 1]]

长(er)回答

I know there are already a lot of answers to this question, but I noticed two things. First, most of the answers use packages like numpy and/or pandas. And this is a good thing. If you are writing production code, you should probably be using robust, fast algorithms like those provided in the numpy/pandas packages. But, for the sake of education, I think someone should provide an answer which has a transparent algorithm and not just an implementation of someone else's algorithm. Second, I noticed that many of the answers do not provide a robust implementation of one-hot encoding because they do not meet one of the requirements below. Below are some of the requirements (as I see them) for a useful, accurate, and robust one-hot encoding function:

单热编码函数必须:

处理各种类型的列表(例如,整数,字符串,浮点数等)作为输入 处理带有重复项的输入列表 返回与输入相对应(与输入顺序相同)的列表的列表 返回一个列表的列表,其中每个列表都尽可能短

我测试了这个问题的许多答案,其中大多数都未能满足上述要求之一。

你可以用numpy来做。眼和一个使用数组元素的选择机制:

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]

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

. remodeling(-1)的作用是确保标签格式正确(也可能有[[2],[3],[4],[0]])。