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) за всеки ред от dataframe.
-
Използвайте този масив, за да изчислите 'оценка на силуета':
from sklearn import metrics score = metrics.silhouette_score(X, y_cluster_kmeans) score
Оценка на силуета
Търсете оценка на силуета, близка до 1. Тази оценка варира от -1 до 1, и ако оценката е 1, клъстерът е плътен и добре отделен от другите клъстери. Стойност близка до 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: "суми на квадратите в рамките на клъстера" измерва средното квадратно разстояние на всички точки в рамките на клъстера до центроида на клъстера. Източник.
🎓 Inertia: Алгоритмите на 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
Вариация
Вариацията се определя като "средната стойност на квадратните разлики от средната стойност" (Източник). В контекста на този проблем с клъстерирането, тя се отнася до данни, при които числата в нашия набор от данни са склонни да се отклоняват твърде много от средната стойност.
✅ Това е чудесен момент да помислите за всички начини, по които можете да коригирате този проблем. Да промените данните малко повече? Да използвате различни колони? Да използвате различен алгоритъм? Подсказка: Опитайте мащабиране на данните, за да ги нормализирате и да тествате други колони.
Опитайте този 'калкулатор за вариация', за да разберете концепцията малко повече.
🚀Предизвикателство
Прекарайте известно време с този notebook, настройвайки параметрите. Можете ли да подобрите точността на модела, като почистите данните повече (например премахване на отклонения)? Можете да използвате тегла, за да дадете повече тежест на определени извадки от данни. Какво друго можете да направите, за да създадете по-добри клъстери?
Подсказка: Опитайте да мащабирате данните си. В notebook има коментиран код, който добавя стандартно мащабиране, за да направи колоните с данни да си приличат повече по отношение на диапазон. Ще откриете, че докато оценката на силуета намалява, 'огъването' в графиката на лакътя се изглажда. Това е така, защото оставянето на данните немащабирани позволява данни с по-малка вариация да имат по-голяма тежест. Прочетете малко повече за този проблем тук.
Тест след лекцията
Преглед и самостоятелно обучение
Разгледайте симулатор за K-Means като този. Можете да използвате този инструмент, за да визуализирате примерни точки от данни и да определите техните центроиди. Можете да редактирате случайността на данните, броя на клъстерите и броя на центроидите. Помага ли това да получите представа как данните могат да бъдат групирани?
Също така разгледайте този материал за K-Means от Станфорд.
Задача
Опитайте различни методи за клъстериране
Отказ от отговорност:
Този документ е преведен с помощта на AI услуга за превод Co-op Translator. Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи може да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за недоразумения или погрешни интерпретации, произтичащи от използването на този превод.