Серия машинного обучения: (6) Кластеризация K-средних

машинное обучение

Отказ от ответственности: Все права защищены, пожалуйста, свяжитесь с автором для перепечатки и укажите источник http://blog.csdn.net/u013719780?viewmode=contents


Профиль блоггера: Фэн Сюэ Йе Гуй Цзы (английское имя: Аллен), осадный лев алгоритма машинного обучения, любит изучать черную технологию машинного обучения, проявляет интерес к глубокому обучению и искусственному интеллекту, часто обращает внимание на интеллектуальный анализ данных kaggle. платформу для соревнований и проявляет большой интерес к интеллектуальному анализу данных. Дети, заинтересованные в машинном обучении и искусственном интеллекте, могут обсудить их вместе, личный блог CSDN:blog.CSDN.net/U013719780?…



Кластеризация K-средних

В предыдущих главах мы представили контролируемое обучение, включая алгоритмы регрессии и классификации, которые обучаются на размеченных данных. В этой главе мы обсудим алгоритм обучения без учителя, кластеризацию. Кластеризация — это алгоритм поиска сходства в неразмеченных данных. Мы представим идею кластеризации K-Means, решим задачу сжатия изображения, а затем оценим эффект алгоритма. Наконец, мы объединяем алгоритмы кластеризации и классификации для решения задачи обучения с полуучителем.

В главе 1 «Основы машинного обучения» мы рассказали, что цель обучения без учителя состоит в том, чтобы извлечь неявные связи из немаркированных обучающих данных. Кластеризация, или кластерный анализ (кластерный анализ) — это метод группировки наблюдений, группирования более сходных выборок в группу, или класс (кластер), при этом выборки в одной группе более похожи, чем выборки в других группах. Как и в случае с контролируемыми методами обучения, мы представляем наблюдение в виде n-мерного вектора. Например, предположим, что ваши обучающие данные выглядят так:

cluster

Алгоритмы кластеризации можно разделить на две группы, представленные точками и квадратами, как показано на следующем рисунке:

twocluster

Его также можно разделить на четыре группы, как показано на следующем рисунке:

fourcluster

Кластеризация часто используется для изучения наборов данных. Социальные сети могут использовать алгоритмы кластеризации для идентификации сообществ, а затем давать рекомендации пользователям, которые не присоединились к сообществу. В биологии кластеризация используется для поиска геномов с похожими паттернами. Рекомендательные системы также иногда используют алгоритмы кластеризации, чтобы рекомендовать продукты и медиа-ресурсы пользователям. В маркетинговых исследованиях для группировки пользователей используются алгоритмы кластеризации. Затем мы используем алгоритм кластеризации K-средних для кластеризации набора данных.

Введение в алгоритм кластеризации K-средних

Благодаря отличной скорости и хорошей масштабируемости алгоритм кластеризации K-средних является самым известным методом кластеризации. Алгоритм K-Means представляет собой процесс многократного перемещения центральной точки класса, перемещения центральной точки класса, также называемой центром тяжести (центроидами), в среднее положение содержащихся в нем членов, а затем повторного деления его внутренних членов. K — гиперпараметр, вычисляемый алгоритмом и представляющий количество классов; K-Means может автоматически относить выборки к разным классам, но не может решать, сколько классов классифицировать. K должно быть положительным целым числом, меньшим, чем количество выборок обучающей выборки. Иногда количество классов определяется содержанием вопроса. Например, у обувной фабрики есть три новых стиля, и она хочет знать, кто является потенциальными клиентами для каждого нового стиля, поэтому она исследует клиентов и находит три категории из данных. Есть также некоторые задачи, в которых не указано количество кластеров, а оптимальное количество кластеров не определено. Позже мы представим эвристический метод оценки оптимального количества кластеров, называемый правилом локтя. метод).

Параметрами K-Means являются расположение центроида класса и расположение его внутренних наблюдений. Подобно обобщенным линейным моделям и деревьям решений, оптимальное решение параметров K-средних также направлено на минимизацию функции стоимости. Формула функции стоимости K-средних выглядит следующим образом:


μ k – это Положение центра тяжести k классов. Функция стоимости представляет собой сумму искажений каждого класса. Степень деформации каждого класса равна сумме квадратов расстояний между центром тяжести класса и положениями его внутренних элементов. Если члены внутри класса более компактны друг с другом, то степень искажения класса будет меньше, и наоборот, если члены внутри класса более разбросаны друг с другом, степень искажения класса будет меньше. больше. Решение параметров минимизации функции стоимости представляет собой процесс многократной настройки наблюдений, содержащихся в каждом классе, и постоянного смещения центра тяжести класса. Во-первых, центр тяжести класса определяется случайным образом. По сути, положение центра тяжести равно расположению случайно выбранных наблюдений. На каждой итерации K-Means присваивает наблюдениям ближайший к ним класс, а затем смещает центр тяжести на среднее значение позиций всех членов этого класса. Давайте поэкспериментируем с тренировочными данными, показанными в таблице ниже:

образец X0 X1
1 7 5
2 5 7
3 7 7
4 3 3
5 4 6
6 1 4
7 0 0
8 2 2
9 8 7
10 6 8
11 5 5
12 3 7

В приведенной выше таблице есть две объясняющие переменные, и каждый образец имеет две функции. Рисунок выглядит так:

%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\msyh.ttc", size=10)
import numpy as np
X0 = np.array([7, 5, 7, 3, 4, 1, 0, 2, 8, 6, 5, 3])
X1 = np.array([5, 7, 7, 3, 6, 4, 0, 2, 7, 8, 5, 7])
plt.figure()
plt.axis([-1, 9, -1, 9])
plt.grid(True)
plt.plot(X0, X1, 'k.');



Предполагая, что при инициализации K-Means центр тяжести первого класса устанавливается на 5-й образец, а центр тяжести второго класса устанавливается на 11-й образец, Тогда мы можем вычислить расстояние между каждым экземпляром и два центра тяжести, отнесите его к ближайшему классу. Результаты расчета представлены в следующей таблице:

образец X0 X1 Расстояние от С1 Расстояние от C2 Последний результат кластеризации Новый результат кластеризации менять ли
1 7 5 3.16 2.00 None C2 YES
2 5 7 1.41 2.00 None C1 YES
3 7 7 3.16 2.83 None C2 YES
4 3 3 3.16 2.83 None C2 YES
5 4 6 0.00 1.41 None C1 YES
6 1 4 3.61 4.12 None C1 YES
7 0 0 7.21 7.07 None C2 YES
8 2 2 4.47 4.24 None C2 YES
9 8 7 4.12 3.61 None C2 YES
10 6 8 2.83 3.16 None C1 YES
11 5 5 1.41 0.00 None C2 YES
12 3 7 1.41 2.83 None C1 YES
центр тяжести С1 4 6          
центр тяжести С2 5 5        

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

C1 = [1, 4, 5, 9, 11]
C2 = list(set(range(12)) - set(C1))
X0C1, X1C1 = X0[C1], X1[C1]
X0C2, X1C2 = X0[C2], X1[C2]
plt.figure()
plt.title('第一次迭代后聚类结果',fontproperties=font)
plt.axis([-1, 9, -1, 9])
plt.grid(True)
plt.plot(X0C1, X1C1, 'rx')
plt.plot(X0C2, X1C2, 'g.')
plt.plot(4,6,'rx',ms=12.0)
plt.plot(5,5,'g.',ms=12.0);


Теперь мы пересчитываем центр тяжести двух классов, перемещаем центр тяжести в новое положение и пересчитываем расстояние между каждым образцом и новым центром тяжести и переклассифицируем образцы в соответствии с расстоянием. Результаты представлены в следующей таблице:

образец X0 X1 Расстояние от С1 Расстояние от C2 Последний результат кластеризации Новый результат кластеризации менять ли
1 7 5 3.49 2.58 C2 C2 NO
2 5 7 1.34 2.89 C1 C1 NO
3 7 7 3.26 3.75 C2 C1 YES
4 3 3 3.49 1.94 C2 C2 NO
5 4 6 0.45 1.94 C1 C1 NO
6 1 4 3.69 3.57 C1 C2 YES
7 0 0 7.44 6.17 C2 C2 NO
8 2 2 4.75 3.35 C2 C2 NO
9 8 7 4.24 4.46 C2 C1 YES
10 6 8 2.72 4.11 C1 C1 NO
11 5 5 1.84 0.96 C2 C2 NO
12 3 7 1.00 3.26 C1 C1 NO
центр тяжести С1 3.80 6.40          
центр тяжести С2 4.57 4.14          

Результаты розыгрыша следующие:

C1 = [1, 2, 4, 8, 9, 11]
C2 = list(set(range(12)) - set(C1))
X0C1, X1C1 = X0[C1], X1[C1]
X0C2, X1C2 = X0[C2], X1[C2]
plt.figure()
plt.title('第二次迭代后聚类结果',fontproperties=font)
plt.axis([-1, 9, -1, 9])
plt.grid(True)
plt.plot(X0C1, X1C1, 'rx')
plt.plot(X0C2, X1C2, 'g.')
plt.plot(3.8,6.4,'rx',ms=12.0)
plt.plot(4.57,4.14,'g.',ms=12.0);


Мы снова повторяем описанный выше метод, перемещаем центр тяжести в новое положение, пересчитываем расстояние между каждым образцом и новым центром тяжести и переклассифицируем образцы в соответствии с расстоянием. Результаты представлены в следующей таблице:

образец X0 X1 Расстояние от С1 Расстояние от C2 Последний результат кластеризации Новый результат кластеризации менять ли
1 7 5 2.50 5.28 C1 C1 NO
2 5 7 0.50 5.05 C1 C1 NO
3 7 7 1.50 6.38 C1 C1 NO
4 3 3 4.72 0.82 C2 C2 NO
5 4 6 1.80 3.67 C1 C1 NO
6 1 4 5.41 1.70 C2 C2 NO
7 0 0 8.90 3.56 C2 C2 NO
8 2 2 6.10 0.82 C2 C2 NO
9 8 7 2.50 7.16 C1 C1 NO
10 6 8 1.12 6.44 C1 C1 NO
11 5 5 2.06 3.56 C2 C1 YES
12 3 7 2.50 4.28 C1 C1 NO
центр тяжести С1 5.50 7.00          
центр тяжести С2 2.20 2.80          

Результаты розыгрыша следующие:

C1 = [0, 1, 2, 4, 8, 9, 10, 11]
C2 = list(set(range(12)) - set(C1))
X0C1, X1C1 = X0[C1], X1[C1]
X0C2, X1C2 = X0[C2], X1[C2]
plt.figure()
plt.title('第三次迭代后聚类结果',fontproperties=font)
plt.axis([-1, 9, -1, 9])
plt.grid(True)
plt.plot(X0C1, X1C1, 'rx')
plt.plot(X0C2, X1C2, 'g.')
plt.plot(5.5,7.0,'rx',ms=12.0)
plt.plot(2.2,2.8,'g.',ms=12.0);


Повторение вышеописанного метода обнаружит, что центр тяжести класса остается неизменным, и K-Means перестанет повторять процесс кластеризации, когда будут выполнены условия. Обычно условие состоит в том, что разница между значениями функции стоимости двух итераций до и после достигает предельного значения, или изменение положения центра тяжести между двумя предыдущими итерациями достигает предельного значения. Если эти условия остановки достаточно малы, K-Means может найти оптимальное решение. Однако это оптимальное решение не обязательно является глобальным оптимальным решением.

локальный оптимум

Начальное положение центра тяжести K-Means выбирается случайным образом. Иногда, если не повезет, случайно выбранный центр тяжести может привести к тому, что K-средние застрянут в локальном оптимуме. Например, начальное положение центра тяжести K-Means показано на следующем рисунке:

clusterlocaloptima

K-Means в конечном итоге получит локальное оптимальное решение, как показано на рисунке ниже. Эти классы могут быть спорными, а верхняя и нижняя части наблюдений могут быть более разумными результатами кластеризации. Чтобы избежать локальных оптимальных решений, K-Means обычно сначала запускается десятки или даже сотни раз. Каждый раз, когда он повторяется, он случайным образом начинается с другой позиции. Наконец, положение центра тяжести, соответствующее функции минимальной стоимости, используется в качестве положения инициализации.

clusterlocaloptima2

Правило локтя

Если не указано в вопросе Значение K можно использовать для оценки количества кластеров с помощью правила локтя. Правило локтя изменит ситуацию Значение функции стоимости для значения K отображается на графике. вместе с По мере увеличения значения КК средняя степень искажения будет уменьшаться, количество отсчетов, содержащихся в каждом классе, будет уменьшаться, поэтому отсчеты будут ближе к своему центру тяжести. Однако с Значение KK продолжает увеличиваться, а эффект улучшения средней степени искажения будет продолжать уменьшаться. В процессе увеличения значения К эффект улучшения степени искажения соответствует положению, в котором производится наибольшее уменьшение. Значение K K – локоть. Давайте воспользуемся правилом локтя, чтобы определить оптимальную К К значение. Данные на рисунке ниже можно четко разделить на две категории:

import numpy as np
cluster1 = np.random.uniform(0.5, 1.5, (2, 10))
cluster2 = np.random.uniform(3.5, 4.5, (2, 10))
X = np.hstack((cluster1, cluster2)).T
plt.figure()
plt.axis([0, 5, 0, 5])
plt.grid(True)
plt.plot(X[:,0],X[:,1],'k.');


Рассчитаем среднюю степень искажения, соответствующую значениям K от 1 до 10:

from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist
K = range(1, 10)
meandistortions = []
for k in K:
    kmeans = KMeans(n_clusters=k)
    kmeans.fit(X)
    meandistortions.append(sum(np.min(cdist(X, kmeans.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0])
plt.plot(K, meandistortions, 'bx-')
plt.xlabel('k')
plt.ylabel('平均畸变程度',fontproperties=font)
plt.title('用肘部法则来确定最佳的K值',fontproperties=font);


Как видно из рисунка, при значении К от 1 до 2 больше всего изменяется средняя степень искажения. После более чем 2 среднее изменение степени искажения значительно снижается. Итак, локоть К=2. Затем мы используем правило локтя, чтобы определить оптимальное значение K для 3 классов:

import numpy as np
x1 = np.array([1, 2, 3, 1, 5, 6, 5, 5, 6, 7, 8, 9, 7, 9])
x2 = np.array([1, 3, 2, 2, 8, 6, 7, 6, 7, 1, 2, 1, 1, 3])
X = np.array(list(zip(x1, x2))).reshape(len(x1), 2)
plt.figure()
plt.axis([0, 10, 0, 10])
plt.grid(True)
plt.plot(X[:,0],X[:,1],'k.');


from sklearn.cluster import KMeans
from scipy.spatial.distance import cdist
K = range(1, 10)
meandistortions = []
for k in K:
    kmeans = KMeans(n_clusters=k)
    kmeans.fit(X)
    meandistortions.append(sum(np.min(cdist(X, kmeans.cluster_centers_, 'euclidean'), axis=1)) / X.shape[0])
plt.plot(K, meandistortions, 'bx-')
plt.xlabel('k')
plt.ylabel('平均畸变程度',fontproperties=font)
plt.title('用肘部法则来确定最佳的K值',fontproperties=font);


Как видно из рисунка, при значении К от 1 до 3 больше всего изменяется средняя степень искажения. После более чем 3 среднее изменение степени искажения значительно снижается. Итак, локоть K=3.

Оценка эффекта кластеризации

Мы определяем машинное обучение как проектирование и изучение систем путем изучения эмпирических данных, используя в качестве показателя постоянное улучшение выполнения задач. K-Means — это неконтролируемое обучение без меток и другой информации для сравнения результатов кластеризации. Однако у нас все еще есть некоторые метрики для оценки производительности алгоритма. Мы уже ввели меру искажения класса. В этом разделе будет представлен еще один метод оценки эффекта алгоритма кластеризации, называемый коэффициентом силуэта. Коэффициент силуэта является оценочным показателем степени плотности и рассеянности класса. Он будет расти по мере увеличения размера класса. Классы, находящиеся далеко друг от друга и сами по себе плотные, имеют большие коэффициенты силуэта, сосредоточены друг в друге и сами большие, а коэффициенты силуэта меньше. Коэффициент силуэта рассчитывается для всех выборок и рассчитывается среднее значение балла каждой выборки Формула расчета выглядит следующим образом:

s =b- a m ax(a ,b )

a — среднее расстояние выборок в каждом классе друг от друга, а b — среднее расстояние выборок в классе от всех выборок ближайшего класса. В приведенном ниже примере K-Means запускается четыре раза, чтобы создать 2, 3, 4 и 8 классов из набора данных, а затем отдельно вычислить их коэффициенты силуэта.

import numpy as np
from sklearn.cluster import KMeans
from sklearn import metrics

plt.figure(figsize=(8, 10)) 
plt.subplot(3, 2, 1)
x1 = np.array([1, 2, 3, 1, 5, 6, 5, 5, 6, 7, 8, 9, 7, 9])
x2 = np.array([1, 3, 2, 2, 8, 6, 7, 6, 7, 1, 2, 1, 1, 3])
X = np.array(list(zip(x1, x2))).reshape(len(x1), 2)
plt.xlim([0, 10])
plt.ylim([0, 10])
plt.title('样本',fontproperties=font)
plt.scatter(x1, x2)
colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'b']
markers = ['o', 's', 'D', 'v', '^', 'p', '*', '+']
tests = [2, 3, 4, 5, 8]
subplot_counter = 1
for t in tests:
    subplot_counter += 1
    plt.subplot(3, 2, subplot_counter)
    kmeans_model = KMeans(n_clusters=t).fit(X)
    for i, l in enumerate(kmeans_model.labels_):
        plt.plot(x1[i], x2[i], color=colors[l], marker=markers[l],ls='None')
        plt.xlim([0, 10])
        plt.ylim([0, 10])
        plt.title('K = %s, 轮廓系数 = %.03f' % (t, metrics.silhouette_score(X, kmeans_model.labels_,metric='euclidean')),fontproperties=font)
d:\programfiles\Miniconda3\lib\site-packages\numpy\core\_methods.py:59: RuntimeWarning: Mean of empty slice.
  warnings.warn("Mean of empty slice.", RuntimeWarning)


Очевидно, что этот набор данных включает в себя три класса. существует При K=3 K=3 коэффициент силуэта максимален. существует При K=8 K=8 выборки каждого класса не только очень близки друг к другу, но и очень близки к выборкам других классов, поэтому коэффициент силуэта в это время наименьший.

квантование изображения

Ранее мы исследовали структурированные наборы данных с помощью алгоритмов кластеризации. Теперь мы используем его для решения новой задачи. Квантование изображения — это метод сжатия с потерями, при котором схожие цвета в изображении заменяются тем же цветом. Квантование изображения уменьшает пространство для хранения изображения из-за меньшего количества байтов, представляющих разные цвета. В следующем примере мы будем использовать метод кластеризации, чтобы найти сжатую цветовую палитру (палитру), которая содержит большинство цветов изображения из изображения, а затем мы будем использовать эту сжатую цветовую палитру для регенерации изображения. Этот пример требуетmahotasБиблиотека обработки изображений, доступ к которой можно получить черезpip install mahotasУстановить:

import numpy as np
from sklearn.cluster import KMeans
from sklearn.utils import shuffle
import mahotas as mh

Сначала прочитайте изображение, затем разверните матрицу изображения в вектор-строку.

original_img = np.array(mh.imread('mlslpic\6.6 tree.png'), dtype=np.float64) / 255
original_dimensions = tuple(original_img.shape)
width, height, depth = tuple(original_img.shape)
image_flattened = np.reshape(original_img, (width * height, depth))

Затем мы используем алгоритм K-средних для построения 64 классов из 1000 случайно выбранных образцов цвета. Каждый класс может быть цветом из сжатой палитры.

image_array_sample = shuffle(image_flattened, random_state=0)[:1000]
estimator = KMeans(n_clusters=64, random_state=0)
estimator.fit(image_array_sample)
KMeans(copy_x=True, init='k-means++', max_iter=300, n_clusters=64, n_init=10,
    n_jobs=1, precompute_distances='auto', random_state=0, tol=0.0001,
    verbose=0)

После этого выполняем присвоение класса каждому пикселю исходного изображения.

cluster_assignments = estimator.predict(image_flattened)

Наконец, мы создаем сжатое изображение, сжимая результаты назначения палитры и класса:

compressed_palette = estimator.cluster_centers_
compressed_img = np.zeros((width, height, compressed_palette.shape[1]))
label_idx = 0
for i in range(width):
    for j in range(height):
        compressed_img[i][j] = compressed_palette[cluster_assignments[label_idx]]
        label_idx += 1
plt.subplot(122)
plt.title('Original Image')
plt.imshow(original_img)
plt.axis('off')
plt.subplot(121)
plt.title('Compressed Image')
plt.imshow(compressed_img)
plt.axis('off')
plt.show()


Особенности обучения с помощью кластеризации

В следующем примере мы объединяем кластеризацию и классификацию для изучения задачи обучения с полуучителем. Вы будете кластеризовать неразмеченные данные, получить некоторые функции и использовать эти функции для создания классификатора контролируемых методов.

Предположим, у вас есть кошка и собака. Предположим также, что вы купили смартфон, который якобы использовался для телефонных звонков, а на самом деле вы использовали его только для того, чтобы фотографировать кошек и собак. Ваши фотографии великолепны, поэтому вы думаете, что они понравятся вашим друзьям и коллегам. И вы знаете, что некоторые люди просто хотят видеть изображения кошек, а некоторые люди просто хотят видеть изображения собак, но разбирать эти изображения слишком обременительно. Далее мы создадим полууправляемую систему обучения, чтобы различать фотографии кошек и собак.

Напомним из главы 3, Извлечение и обработка признаков, что существует оригинальный подход к классификации изображений с использованием значений плотности пикселей или яркости изображения в качестве независимых переменных. В отличие от многомерных векторов, которые мы использовали для обработки текста ранее, векторы признаков изображений не являются разреженными. Кроме того, этот метод очень чувствителен к изменению яркости, размера и поворота изображения. В главе 3 «Извлечение и обработка признаков» мы также представили дескрипторы SIFT и SURF, которые используются для описания точек интереса на изображениях.Эти методы нечувствительны к изменениям яркости, размера и поворота изображения. В следующем примере мы обработаем эти дескрипторы с помощью алгоритма кластеризации, чтобы изучить особенности изображения. Каждый элемент будет закодирован как количество дескрипторов, извлеченных из изображения, которые относятся к одному и тому же классу. Этот подход также иногда называют представлением мешка признаков, поскольку этот набор классов похож на словарь в модели мешка слов. мы будем использоватьKaggle's Dogs vs. Cats competitionВнутри 1000 фотографий кошек и 1000 фотографий собак. Обратите внимание, что изображения бывают разных размеров; поскольку наши векторы признаков не представлены в пикселях, нам также не нужно масштабировать все изображения до одинакового размера. Мы будем тренироваться на 60 из этих изображений, а затем протестируем оставшиеся 40 изображений:

import numpy as np
import mahotas as mh
from mahotas.features import surf
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import *
from sklearn.cluster import MiniBatchKMeans
import glob

Сначала мы загружаем изображение, преобразуем его в оттенки серого и извлекаем дескриптор SURF. Дескриптор SURF можно извлечь быстрее, чем другие подобные функции, но извлечение дескриптора из 2000 изображений по-прежнему занимает много времени.

all_instance_filenames = []
all_instance_targets = []
for f in glob.glob('cats-and-dogs-img/*.jpg'):
    target = 1 if 'cat' in f else 0
    all_instance_filenames.append(f)
    all_instance_targets.append(target)
surf_features = []
counter = 0
for f in all_instance_filenames:
    print('Reading image:', f)
    image = mh.imread(f, as_grey=True)
    surf_features.append(surf.surf(image)[:, 5:])
    
train_len = int(len(all_instance_filenames) * .60)
X_train_surf_features = np.concatenate(surf_features[:train_len])
X_test_surf_feautres = np.concatenate(surf_features[train_len:])
y_train = all_instance_targets[:train_len]
y_test = all_instance_targets[train_len:]

Затем мы делим извлеченные дескрипторы на 300 классов. использоватьMiniBatchKMeansРеализация класса, представляющая собой вариант алгоритма K-средних, рисует случайные выборки на каждой итерации. Поскольку он вычисляет расстояние от центра тяжести только для небольшой части этих случайно выбранных выборок на каждой итерации, поэтомуMiniBatchKMeansКластеризация может быть быстрее, но она будет более искаженной. На самом деле результаты расчетов примерно одинаковы:

n_clusters = 300
print('Clustering', len(X_train_surf_features), 'features')
estimator = MiniBatchKMeans(n_clusters=n_clusters)
estimator.fit_transform(X_train_surf_features)

После этого мы строим векторы признаков для обучающих и тестовых наборов. Мы находим класс каждого дескриптора SURF, используя Numpy.binCount()считать. Следующий код генерирует 300-мерный вектор признаков для каждого образца:

X_train = []
for instance in surf_features[:train_len]:
    clusters = estimator.predict(instance)
    features = np.bincount(clusters)
    if len(features) < n_clusters:
    features = np.append(features, np.zeros((1, n_clusterslen(features))))
    X_train.append(features)
    
X_test = []
for instance in surf_features[train_len:]:
    clusters = estimator.predict(instance)
    features = np.bincount(clusters)
    if len(features) < n_clusters:
    features = np.append(features, np.zeros((1, n_clusterslen(features))))
    X_test.append(features)

Наконец, мы обучаем классификатор логистической регрессии вектору признаков и цели, а затем оцениваем его точность, полноту и точность:

clf = LogisticRegression(C=0.001, penalty='l2')
clf.fit_transform(X_train, y_train)
predictions = clf.predict(X_test)
print(classification_report(y_test, predictions))
print('Precision: ', precision_score(y_test, predictions))
print('Recall: ', recall_score(y_test, predictions))
print('Accuracy: ', accuracy_score(y_test, predictions))

Системы полууправляемого обучения достигают большей точности и отзыва, чем классификаторы логистической регрессии, использующие только плотность пикселей в качестве векторов признаков. Кроме того, наш вектор признаков имеет только 300 измерений, что намного меньше, чем 10000 измерений изображения размером 100x100 пикселей.

Суммировать

В этой главе мы представляем наш первый метод обучения без учителя: кластеризацию. Кластеризация используется для изучения структуры неразмеченных данных. Мы представили алгоритм кластеризации K-средних, который многократно назначает выборки классу и постоянно обновляет положение центра тяжести класса. Хотя K-Means является методом обучения без учителя, его эффект все же измерим; степень искажения и коэффициент силуэта можно использовать для оценки эффекта кластеризации. Мы исследовали две проблемы с K-средними. Первый вопрос касается квантования изображения, метода сжатия изображения, в котором используется один цвет для представления группы похожих цветов. Мы также изучаем характеристику задач полуконтролируемой классификации изображений с помощью K-средних.

В следующей главе мы представим еще одну задачу обучения без учителя — уменьшение размерности. Подобно проблеме полуконтролируемой классификации изображений кошек и собак, которую мы представили ранее, алгоритмы уменьшения размерности могут уменьшить размерность набора объясняющих переменных, максимально сохраняя целостность информации.