18 KiB
Кластеризація методом K-Means
Тест перед лекцією
У цьому уроці ви навчитеся створювати кластери за допомогою Scikit-learn і набору даних про нігерійську музику, який ви імпортували раніше. Ми розглянемо основи методу K-Means для кластеризації. Пам’ятайте, що, як ви дізналися в попередньому уроці, існує багато способів роботи з кластерами, і метод, який ви використовуєте, залежить від ваших даних. Ми спробуємо K-Means, оскільки це найпоширеніша техніка кластеризації. Почнемо!
Терміни, які ви вивчите:
- Оцінка силуету
- Метод ліктя
- Інерція
- Дисперсія
Вступ
Кластеризація методом K-Means — це метод, що походить із галузі обробки сигналів. Він використовується для поділу та групування даних у 'k' кластерів за допомогою серії спостережень. Кожне спостереження працює над тим, щоб згрупувати дану точку даних найближче до її 'середнього', або центральної точки кластера.
Кластери можна візуалізувати як діаграми Вороного, які включають точку (або 'насіння') та її відповідну область.
Інфографіка від Jen Looper
Процес кластеризації методом K-Means виконується у три етапи:
- Алгоритм вибирає k-кількість центральних точок шляхом вибірки з набору даних. Після цього він повторює:
- Призначає кожну вибірку до найближчого центроїда.
- Створює нові центроїди, обчислюючи середнє значення всіх вибірок, призначених до попередніх центроїдів.
- Потім обчислює різницю між новими та старими центроїдами і повторює, поки центроїди не стабілізуються.
Одним із недоліків використання K-Means є те, що вам потрібно встановити 'k', тобто кількість центроїдів. На щастя, метод 'ліктя' допомагає оцінити гарне початкове значення для 'k'. Ви спробуєте це через хвилину.
Передумови
Ви працюватимете у файлі notebook.ipynb, який включає імпорт даних і попереднє очищення, яке ви виконали в попередньому уроці.
Вправа - підготовка
Почніть із повторного перегляду даних про пісні.
-
Створіть boxplot, викликавши
boxplot()
для кожного стовпця:plt.figure(figsize=(20,20), dpi=200) plt.subplot(4,3,1) sns.boxplot(x = 'popularity', data = df) plt.subplot(4,3,2) sns.boxplot(x = 'acousticness', data = df) plt.subplot(4,3,3) sns.boxplot(x = 'energy', data = df) plt.subplot(4,3,4) sns.boxplot(x = 'instrumentalness', data = df) plt.subplot(4,3,5) sns.boxplot(x = 'liveness', data = df) plt.subplot(4,3,6) sns.boxplot(x = 'loudness', data = df) plt.subplot(4,3,7) sns.boxplot(x = 'speechiness', data = df) plt.subplot(4,3,8) sns.boxplot(x = 'tempo', data = df) plt.subplot(4,3,9) sns.boxplot(x = 'time_signature', data = df) plt.subplot(4,3,10) sns.boxplot(x = 'danceability', data = df) plt.subplot(4,3,11) sns.boxplot(x = 'length', data = df) plt.subplot(4,3,12) sns.boxplot(x = 'release_date', data = df)
Ці дані трохи шумні: спостерігаючи кожен стовпець як boxplot, ви можете побачити аномалії.
Ви могли б пройтися по набору даних і видалити ці аномалії, але це зробило б дані досить мінімальними.
-
На даний момент виберіть, які стовпці ви будете використовувати для вправи кластеризації. Виберіть ті, що мають схожі діапазони, і закодуйте стовпець
artist_top_genre
як числові дані:from sklearn.preprocessing import LabelEncoder le = LabelEncoder() X = df.loc[:, ('artist_top_genre','popularity','danceability','acousticness','loudness','energy')] y = df['artist_top_genre'] X['artist_top_genre'] = le.fit_transform(X['artist_top_genre']) y = le.transform(y)
-
Тепер вам потрібно вибрати, скільки кластерів слід націлити. Ви знаєте, що є 3 жанри пісень, які ми виділили з набору даних, тому спробуємо 3:
from sklearn.cluster import KMeans nclusters = 3 seed = 0 km = KMeans(n_clusters=nclusters, random_state=seed) km.fit(X) # Predict the cluster for each data point y_cluster_kmeans = km.predict(X) y_cluster_kmeans
Ви бачите масив із передбаченими кластерами (0, 1 або 2) для кожного рядка фрейму даних.
-
Використовуйте цей масив для обчислення 'оцінки силуету':
from sklearn import metrics score = metrics.silhouette_score(X, y_cluster_kmeans) score
Оцінка силуету
Шукайте оцінку силуету ближче до 1. Ця оцінка варіюється від -1 до 1, і якщо оцінка дорівнює 1, кластер щільний і добре відокремлений від інших кластерів. Значення, близьке до 0, представляє кластер, що перекривається, із вибірками, дуже близькими до межі прийняття рішення сусідніх кластерів. (Джерело)
Наша оцінка становить 0.53, тобто посередині. Це свідчить про те, що наші дані не дуже добре підходять для цього типу кластеризації, але давайте продовжимо.
Вправа - створення моделі
-
Імпортуйте
KMeans
і почніть процес кластеризації.from sklearn.cluster import KMeans wcss = [] for i in range(1, 11): kmeans = KMeans(n_clusters = i, init = 'k-means++', random_state = 42) kmeans.fit(X) wcss.append(kmeans.inertia_)
Тут є кілька частин, які варто пояснити.
🎓 range: Це ітерації процесу кластеризації.
🎓 random_state: "Визначає генерацію випадкових чисел для ініціалізації центроїдів." Джерело
🎓 WCSS: "сума квадратів всередині кластерів" вимірює середню квадратну відстань усіх точок у кластері до центроїда кластера. Джерело.
🎓 Інерція: Алгоритми K-Means намагаються вибрати центроїди, щоб мінімізувати 'інерцію', "показник того, наскільки внутрішньо узгоджені кластери." Джерело. Значення додається до змінної wcss на кожній ітерації.
🎓 k-means++: У Scikit-learn ви можете використовувати оптимізацію 'k-means++', яка "ініціалізує центроїди так, щоб вони (зазвичай) були віддалені один від одного, що призводить до ймовірно кращих результатів, ніж випадкова ініціалізація."
Метод ліктя
Раніше ви припустили, що, оскільки ви націлилися на 3 жанри пісень, вам слід вибрати 3 кластери. Але чи так це?
-
Використовуйте метод 'ліктя', щоб переконатися.
plt.figure(figsize=(10,5)) sns.lineplot(x=range(1, 11), y=wcss, marker='o', color='red') plt.title('Elbow') plt.xlabel('Number of clusters') plt.ylabel('WCSS') plt.show()
Використовуйте змінну
wcss
, яку ви створили на попередньому кроці, щоб створити графік, що показує, де знаходиться 'згин' ліктя, який вказує на оптимальну кількість кластерів. Можливо, це дійсно 3!
Вправа - відображення кластерів
-
Спробуйте процес ще раз, цього разу встановивши три кластери, і відобразіть кластери як діаграму розсіювання:
from sklearn.cluster import KMeans kmeans = KMeans(n_clusters = 3) kmeans.fit(X) labels = kmeans.predict(X) plt.scatter(df['popularity'],df['danceability'],c = labels) plt.xlabel('popularity') plt.ylabel('danceability') plt.show()
-
Перевірте точність моделі:
labels = kmeans.labels_ correct_labels = sum(y == labels) print("Result: %d out of %d samples were correctly labeled." % (correct_labels, y.size)) print('Accuracy score: {0:0.2f}'. format(correct_labels/float(y.size)))
Точність цієї моделі не дуже висока, і форма кластерів дає вам підказку, чому.
Ці дані занадто незбалансовані, недостатньо корельовані, і між значеннями стовпців занадто велика дисперсія, щоб добре кластеризуватися. Насправді кластери, які формуються, ймовірно, сильно впливають або спотворюються трьома категоріями жанрів, які ми визначили вище. Це був процес навчання!
У документації Scikit-learn ви можете побачити, що модель, як ця, з кластерами, які не дуже добре розмежовані, має проблему 'дисперсії':
Інфографіка з Scikit-learn
Дисперсія
Дисперсія визначається як "середнє квадратів різниць від середнього" (Джерело). У контексті цієї проблеми кластеризації це стосується даних, де числа нашого набору даних мають тенденцію занадто сильно відхилятися від середнього.
✅ Це чудовий момент, щоб подумати про всі способи, якими ви могли б виправити цю проблему. Ще трохи налаштувати дані? Використовувати інші стовпці? Використовувати інший алгоритм? Підказка: Спробуйте масштабувати ваші дані, щоб нормалізувати їх і протестувати інші стовпці.
Спробуйте цей 'калькулятор дисперсії', щоб краще зрозуміти концепцію.
🚀Виклик
Проведіть деякий час із цим ноутбуком, налаштовуючи параметри. Чи можете ви покращити точність моделі, краще очистивши дані (наприклад, видаливши аномалії)? Ви можете використовувати ваги, щоб надати більшу вагу певним вибіркам даних. Що ще ви можете зробити, щоб створити кращі кластери?
Підказка: Спробуйте масштабувати ваші дані. У ноутбуці є закоментований код, який додає стандартне масштабування, щоб стовпці даних більше нагадували один одного за діапазоном. Ви побачите, що хоча оцінка силуету знижується, 'згин' на графіку ліктя стає більш плавним. Це тому, що залишення даних без масштабування дозволяє даним із меншою дисперсією мати більшу вагу. Прочитайте трохи більше про цю проблему тут.
Тест після лекції
Огляд і самостійне навчання
Ознайомтеся з симулятором K-Means наприклад, таким. Ви можете використовувати цей інструмент для візуалізації точок даних і визначення їх центроїдів. Ви можете редагувати випадковість даних, кількість кластерів і кількість центроїдів. Чи допомагає це вам зрозуміти, як дані можуть бути згруповані?
Також перегляньте цей матеріал про K-Means зі Стенфорда.
Завдання
Спробуйте різні методи кластеризації
Відмова від відповідальності:
Цей документ було перекладено за допомогою сервісу автоматичного перекладу Co-op Translator. Хоча ми прагнемо до точності, зверніть увагу, що автоматичні переклади можуть містити помилки або неточності. Оригінальний документ мовою оригіналу слід вважати авторитетним джерелом. Для критично важливої інформації рекомендується професійний людський переклад. Ми не несемо відповідальності за будь-які непорозуміння або неправильні тлумачення, що виникли внаслідок використання цього перекладу.