if (!$("#InvCopyRadio").prop("checked") && $("#InvCopyRadio").prop("checked"))
// do something
Здесь я попытался с помощью этого подхода:
import numpy as np
#converting to one_hot
def one_hot_encoder(value, datal):
datal[value] = 1
return datal
def _one_hot_values(labels_data):
encoded = [0] * len(labels_data)
for j, i in enumerate(labels_data):
max_value = [0] * (np.max(labels_data) + 1)
encoded[j] = one_hot_encoder(i, max_value)
return np.array(encoded)
Во-первых, самый простой способ для одного горячего кодирования: использовать Sklearn.
http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html
Во-вторых, я не думаю, что использование pandas для одного горячего кодирования является простым (неподтвержденным, хотя)
Создание фиктивных переменных в 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
EDIT: сравнение будет более четким:
Однострунная кодировка: convert n уровни до n-1 столбцов.
Index Animal Index cat mouse
1 dog 1 0 0
2 cat --> 2 1 0
3 mouse 3 0 1
Вы можете увидеть, как это взорвёт вашу память, если у вас много разных типов (или уровней) в вашей категориальной функции. Имейте в виду, что это всего лишь один столбец.
Dummy Coding:
Index Animal Index Animal
1 dog 1 0
2 cat --> 2 1
3 mouse 3 2
Вместо этого преобразуйте в числовые представления. Значительно экономит пространство для объектов за счет некоторой точности.
mouse > cat > dog
, но это не так. get_dummies
является самым прямым способом передачи категориальных переменных в дружественные модели данные из моего опыта (хотя и очень ограниченного)
– Martin O Leary
16 January 2017 в 21:06
Вы можете использовать функцию 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()
Результат
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.]]
Чтобы добавить к другим вопросам, позвольте мне представить, как я это сделал с помощью функции Python 2.0 с помощью Numpy:
def one_hot(y_):
# Function to encode output labels from number indexes
# e.g.: [[5], [0], [3]] --> [[0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0]]
y_ = y_.reshape(len(y_))
n_values = np.max(y_) + 1
return np.eye(n_values)[np.array(y_, dtype=np.int32)] # Returns FLOATS
Строка n_values = np.max(y_) + 1
может быть жестко закодирована для вас, чтобы использовать хорошую количество нейронов, если вы используете мини-партии, например.
Демо-проект / учебник, в котором эта функция использовалась: https://github.com/guillaume-chevalier/LSTM-Human-Activity-Recognition
Вы можете сделать это с помощью 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]
Возвращаемое значение 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.]]])
.reshape(-1)
, чтобы убедиться, что у вас есть правильный формат ярлыков (у вас также может быть [[2], [3], [4], [0]]
).
Одно горячее кодирование с помощью 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
EDIT:
Другой способ one_hot использовать sklearn's 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)
Подход 1: вы можете использовать get_dummies в кадре данных pandas.
Пример 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
Пример 2:
Следующее преобразует заданный столбец в одну горячую. Использовать префикс, чтобы иметь несколько манекенов.
Подход 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.]])
Вот ссылка для этого примера: http: // scikit -learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html
drop_first=True
с get_dummies
устраняет необходимость отбрасывать исходный столбец отдельно
– Cameron Taylor
28 February 2018 в 16:14
Вот решение, использующее DictVectorizer
и метод Pandas DataFrame.to_dict('records')
.
>>> import pandas as pd
>>> X = pd.DataFrame({'income': [100000,110000,90000,30000,14000,50000],
'country':['US', 'CAN', 'US', 'CAN', 'MEX', 'US'],
'race':['White', 'Black', 'Latino', 'White', 'White', 'Black']
})
>>> from sklearn.feature_extraction import DictVectorizer
>>> v = DictVectorizer()
>>> qualitative_features = ['country','race']
>>> X_qual = v.fit_transform(X[qualitative_features].to_dict('records'))
>>> v.vocabulary_
{'country=CAN': 0,
'country=MEX': 1,
'country=US': 2,
'race=Black': 3,
'race=Latino': 4,
'race=White': 5}
>>> X_qual.toarray()
array([[ 0., 0., 1., 0., 0., 1.],
[ 1., 0., 0., 1., 0., 0.],
[ 0., 0., 1., 0., 1., 0.],
[ 1., 0., 0., 0., 0., 1.],
[ 0., 1., 0., 0., 0., 1.],
[ 0., 0., 1., 1., 0., 0.]])
Однострунная кодировка требует бит больше, чем преобразование значений в переменные индикатора. Обычно процесс ML требует, чтобы вы несколько раз применяли это кодирование для проверки или тестирования наборов данных и применяли модель, которую вы создаете, к наблюдаемым в режиме реального времени данным. Вы должны сохранить отображение (преобразование), которое использовалось для построения модели. Хорошее решение будет использовать DictVectorizer
или LabelEncoder
(за ним следует get_dummies
. Вот функция, которую вы можете использовать:
def oneHotEncode2(df, le_dict = {}):
if not le_dict:
columnsToEncode = list(df.select_dtypes(include=['category','object']))
train = True;
else:
columnsToEncode = le_dict.keys()
train = False;
for feature in columnsToEncode:
if train:
le_dict[feature] = LabelEncoder()
try:
if train:
df[feature] = le_dict[feature].fit_transform(df[feature])
else:
df[feature] = le_dict[feature].transform(df[feature])
df = pd.concat([df,
pd.get_dummies(df[feature]).rename(columns=lambda x: feature + '_' + str(x))], axis=1)
df = df.drop(feature, axis=1)
except:
print('Error encoding '+feature)
#df[feature] = df[feature].convert_objects(convert_numeric='force')
df[feature] = df[feature].apply(pd.to_numeric, errors='coerce')
return (df, le_dict)
Это работает в кадре данных pandas и для каждого столбца созданный ими, и возвращает обратное отображение. Таким образом, вы бы назвали это следующим образом:
train_data, le_dict = oneHotEncode2(train_data)
Затем в тестовых данных вызов выполняется путем передачи словаря, возвращенного из обучения:
test_data, _ = oneHotEncode2(test_data, le_dict)
Эквивалентный метод заключается в использовании DictVectorizer
. Связанная с ним публикация в том же разделе содержится в моем блоге. Я упоминаю ее здесь, поскольку она дает некоторые аргументы в пользу этого подхода, просто используя get_dummies post (раскрытие: это мой собственный блог).
Я использовал это в своей акустической модели: возможно, это помогает в модели ур.
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,))