Мы знакомы с несколькими типами расстояния в мире машинного обучения, включая манхэттенское расстояние, расстояние косинусного сходства и т. д. Но конкретное расстояние в сегодняшнем обсуждении — евклидово расстояние, и мы рассмотрим его особенность и посмотрим, как оно помогает в решение задачи кластеризации. Здесь мы не будем сосредотачиваться на сложных математических формулах, мы просто воспользуемся Python и Jupyter Notebook, чтобы узнать соответствующее расстояние с помощью самостоятельно созданного набора данных.

# Let's create a dataframe using pandas first for our calculation
import pandas as pd
df = pd.DataFrame(data=[[12,95],
                  [10,86],
                  [9,75],
                  [11,98],
                  [5,45],
                  [6,59],
                  [4,28]],columns=['Hours Studied','Marks Obtained'])
df.head()
Hours Studied Marks Obtained
0 12 95
1 10 86
2 9 75
3 11 98
4 5 45

Теперь, просто для нашего понимания, давайте возьмем индексы 0 и 1 как наши два кластера C1 и C2. Затем мы рассчитаем евклидовы расстояния всех других индексированных точек данных с этими кластерами. Под кластером мы просто подразумеваем две отдельные области, где большая часть данных разбросана. Давайте сначала визуализируем данные, чтобы понять концепцию кластера здесь.

from matplotlib import pyplot as plt
%matplotlib inline
#display the data
plt.scatter(df['Hours Studied'],df['Marks Obtained'])

Мы можем каким-то образом идентифицировать 2 кластера в данных. Назовем эти кластеры c1 и c2 и случайным образом выберем здесь 2 центроида, из которых мы узнаем евклидово расстояние других точек данных.

c1 = df.iloc[0]
c2 = df.iloc[1]

Теперь давайте продолжим и рассчитаем евклидово расстояние каждой точки данных с нашими кластерами. Здесь мы проверим как процедуру библиотеки numpy, так и метод библиотеки обучения sci-kit.

print(f"the c1 cluster data points are {c1} and it's data type is {type(c1)}")
print(f"the c2 cluster data points are {c2} and it's data type is {type(c2)}")
the c1 cluster data points are [[12 95]] and it's data type is <class 'numpy.ndarray'>
the c2 cluster data points are [[10 86]] and it's data type is <class 'numpy.ndarray'>

Теперь из нашего основного фрейма данных давайте возьмем второй индекс и преобразуем его в пустой массив. Затем мы проверим евклидово расстояние этой точки данных как с c1, так и с2.

d1 = np.array([df.iloc[2]])

Метод Numpy для проверки евклидова расстояния

# first let's find out the sum of squares
sum_sq_c1 = np.sum(np.square(d1-c1))
sum_sq_c2 = np.sum(np.square(d1-c2))
# Then let's square root the result and find out the euclidean distance
ed_c1d1 = np.sqrt(sum_sq_c1)
ed_c2d1 = np.sqrt(sum_sq_c2)
# Let's print our results
print(f"the euclidean distance between c1 cluster and d1 datapoint is {ed_c1d1}")
print(f"the euclidean distance between c2 cluster and d1 datapoint is {ed_c2d1}")
the euclidean distance between c1 cluster and d1 datapoint is 20.223748416156685
the euclidean distance between c2 cluster and d1 datapoint is 11.045361017187261

Из приведенного выше примера видно, что евклидово расстояние d1 меньше в кластере c2, поэтому можно с уверенностью сказать, что точка данных d1 будет принадлежать кластеру c2. И поскольку кластер c2 получает дополнительную точку данных, его центроид необходимо вычислить снова. Но сначала давайте также проверим евклидово расстояние с помощью библиотечного метода Sklearn.

Метод модуля Sklearn для нахождения евклидова расстояния

# importing the module
from sklearn.metrics.pairwise import euclidean_distances
ed_c1d1_sklearn = euclidean_distances(d1,c1)
ed_c2d1_sklearn = euclidean_distances(d1,c2)
#printing the result
print(f"the euclidean distance between c1 cluster and d1 datapoint with sklearn method is {ed_c1d1_sklearn}")
print(f"the euclidean distance between c2 cluster and d1 datapoint with sklearn method is {ed_c2d1_sklearn}")
the euclidean distance between c1 cluster and d1 datapoint with sklearn method is [[20.22374842]]
the euclidean distance between c2 cluster and d1 datapoint with sklearn method is [[11.04536102]]

Теперь, когда наша теория была доказана с помощью методов numpy и sklearn, мы можем с уверенностью сказать, что точка данных d1 принадлежит кластеру c2. Теперь давайте рассчитаем новый центроид для кластера c2. Это простое добавление новой добавленной стоимости к существующему центроидному значению и деление на 2, и теперь у нас есть 2 элемента в кластере. Во-первых, давайте возьмем вещи вручную, в массиве c2 у нас есть [10,86], а в массиве d1 у нас есть [9,75], поэтому в идеале наш новый центроид для c2 должен быть ([10+9]/2,[86+ 75]/2) или (9,5,80,5). Давай выясним ,

c2 = (c2+d1)/2
print(f"The new centroid values for c2 cluster is {c2}")
The new centroid values for c2 cluster is [[ 9.5 80.5]]

Теперь следующие расчеты будут производиться на основе нового центроида c2. Каждый раз, когда точка данных добавляется в кластер, значение центроида для этого кластера будет продолжать изменяться. Надеюсь, это даст вам хорошее представление о евклидовом расстоянии, и это обходной путь.

Чтобы узнать больше такого контента, пожалуйста, следуйте за моим профилем на Medium и странице LinkedIn — https://www.linkedin.com/in/chandan-sengupta/