Я использую функцию sklearn и агломеративной кластеризации. У меня смешанные данные, которые включают как числовые, так и номинальные столбцы данных. В моих номинальных столбцах есть такие значения, как «Утро», «После полудня», «Вечер», «Ночь». Если я конвертирую свои номинальные данные в числовые, присваивая целочисленные значения, например 0,1,2,3; евклидово расстояние будет вычисляться как 3 между «Ночью» и «Утром», но 1 должно быть возвращаемым значением как расстояние.
X = pd.read_csv("mydata.csv", sep = ",", header=0, encoding = "utf-8")
X = StandardScaler().fit_transform(X)
print("n_samples: %d, n_features: %d" % X.shape)
km = AgglomerativeClustering(n_clusters=5, affinity='euclidean', linkage='average')
km.fit(X)
print("k = %d, Silhouette Coefficient: %0.3f" % (x,
metrics.silhouette_score(X, km.labels_, sample_size=None)))
Вот мой код.
Как я могу настроить функцию расстояния в sklearn или преобразовать мои номинальные данные в числовые?
Вы действительно хотите использовать OneHotEncoder.






Эта проблема характерна для приложений машинного обучения. Вам необходимо определить одну категорию в качестве базовой (неважно какую), а затем определить индикаторные переменные (0 или 1) для каждой из других категорий. Другими словами, создайте 3 новые переменные с названиями «Утро», «После полудня» и «Вечер» и присвойте по одной той категории, которая есть у каждого наблюдения. Если это ночное наблюдение, оставьте для каждой из этих новых переменных значение 0.
Я думаю, у вас есть 3 варианта, как преобразовать категориальные характеристики в числовые:
Код:
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. ]])
Хотя в хронологическом порядке утро должно быть ближе к полудню, чем, например, к вечеру, качественно в данных может не быть оснований предполагать, что это так. Одно горячее кодирование позволяет машине вычислить, какие категории наиболее похожи. Мне нравится идея, лежащая в основе ваших двух методов горячего кодирования, но она может навязывать данные вашим собственным предположениям.
Вы правы, это зависит от задачи. Для некоторых задач может быть лучше рассматривать каждый день по-разному. Но утверждение: «Одно горячее кодирование позволяет машине вычислять, какие категории наиболее похожи» неверно для кластеризации. Кластеризация вычисляет кластеры на основе расстояний примеров, которые основаны на функциях. Таким образом, мы должны проектировать функции таким образом, чтобы аналогичные примеры имели векторы функций с коротким расстоянием.
Можно ли использовать встроенный склеарн Лабеленкодер?