""" Использовать для своих данных метод кластеризации по варианту, самостоятельно сформулировав задачу. Интерпретировать результаты и оценить, насколько хорошо он подходит для решения сформулированной вами задачи. """ """ Задача, решаемая алгоритмом кластеризации: Группировка музыкальных треков на основе их характеристик с целью создания кластеров треков с схожими характеристиками. Алгоритм кластеризации может помочь в создании плейлистов и рекомендаций, основанных на схожести музыкальных треков по некоторым характеристикам. """ # 12 вариант # Набор данных по курсовой: "Prediction of music genre" # Алгоритм кластеризации: linkage import pandas as pd from scipy.cluster.hierarchy import linkage, dendrogram, fcluster import matplotlib.pyplot as plt DATASET_FILE = 'music_genre.csv' def main(): df = open_dataset(DATASET_FILE) df = df.sample(frac=.5) # отбираем 50% рандомных строк с набора данных, т.к. он большой print("\033[92m[-----> Набор данных <-----]\033[00m") print(df) # Перевод жанров и ладов (минор/мажор) в числовые признаки df_genres = pd.get_dummies(df['music_genre']) df_modes = pd.get_dummies(df['mode']) # Объединение основной таблицы с числовыми признаками df_music = pd.concat([df, df_genres, df_modes], axis=1).reindex(df.index) # Удаление строковых стоблцов, которые заменили на числовые признаки df_music = df_music.drop(columns=['music_genre', 'mode']) # Датасет для работы с кластеризацией (без исполнителя и названия трека) X = df_music.drop(columns=['artist_name', 'track_name']) # Иерархическая кластеризация с связью ward # (минимизация суммы квадратов разностей во всех кластерах) linkage_matrix = linkage(X, method='ward', metric='euclidean') # Формирование кластеров из матрицы связей cluster_label = fcluster(Z=linkage_matrix, t=300, criterion='distance') # Присвоение кластера треку df['cluster'] = cluster_label # Установка опции показа 3 столбцов при выводе pd.set_option('display.max_columns', 3) # Вывод результата кластеризации print("\033[92m\nЫ[-----> Результат иерархической кластеризации <-----]\033[00m") print(df[['artist_name', 'track_name', 'cluster']].head(10)) print("\033[92mКоличество кластеров: {}\033[00m" .format(cluster_label.max())) # Дендрограмма plt.figure(figsize=(12, 6)) dendrogram(linkage_matrix, truncate_mode='lastp', p=20, leaf_rotation=90., leaf_font_size=8., show_contracted=True) plt.title('Дендрограмма иерархической кластеризации музыкальных треков') plt.xlabel('Количество треков в узле') plt.ylabel('Евклидово расстояние между треками') plt.savefig('1_dendrogram') plt.show() # Функция считывания и очищения csv-файла def open_dataset(csv_file): # открываем файл с указанием знака-отделителя df = pd.read_csv(csv_file, delimiter=',') # выбираем необходимые признаки df = df[['artist_name', 'track_name', 'mode', 'tempo', 'instrumentalness', 'acousticness', 'speechiness', 'danceability', 'energy', 'liveness', 'valence', 'music_genre']] # очищаем набор данных от пустых и неподходящих значений df = df[df['tempo'] != '?'] df = df.dropna() return df if __name__ == "__main__": main()