Я думаю, у вас есть 3 варианта преобразования категориальных функций в числовые:
- Использовать OneHotEncoder . Вы преобразуете категориальную особенность в четыре новых столбца, где будет только один 1 и другой 0. Проблема здесь в том, что разница между «утром» и «днем» такая же, как «утро» и «вечер».
- Использовать OrdinalEncoder . Вы преобразуете категориальную особенность только в один столбец. «утро» до 1, «день» до 2 и т. д. Разница между «утром» и «днем» будет меньше, чем «утро» и «вечер», что хорошо, но разница между «утром» и «ночью» будет быть лучшим, что может быть не тем, что вы хотите.
- Используйте преобразование, которое я называю two_hot_encoder. Это похоже на OneHotEncoder, там только два 1 в строке. Разница между «утром» и «днем» будет такой же, как разница между «утром» и «ночью», и будет меньше, чем разница между «утром» и «вечером». Я думаю, что это лучшее решение. Проверьте код.
Код:
def two_hot(x):
return np.concatenate([
(x == "morning") | (x == "afternoon"),
(x == "afternoon") | (x == "evening"),
(x == "evening") | (x == "night"),
(x == "night") | (x == "morning"),
], axis=1).astype(int)
x = np.array([["morning", "afternoon", "evening", "night"]]).T
print(x)
x = two_hot(x)
print(x)
Выход:
[['morning']
['afternoon']
['evening']
['night']]
[[1 0 0 1]
[1 1 0 0]
[0 1 1 0]
[0 0 1 1]]
Тогда мы можем измерить расстояния:
from sklearn.metrics.pairwise import euclidean_distances
euclidean_distances(x)
Выход:
array([[0. , 1.41421356, 2. , 1.41421356],
[1.41421356, 0. , 1.41421356, 2. ],
[2. , 1.41421356, 0. , 1.41421356],
[1.41421356, 2. , 1.41421356, 0. ]])