IIS_2023_1/istyukov_timofey_lab_4/lab4.py
2024-01-07 04:56:43 +04:00

85 lines
4.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Использовать для своих данных метод кластеризации по варианту, самостоятельно сформулировав задачу.
Интерпретировать результаты и оценить, насколько хорошо он подходит для решения сформулированной вами задачи.
"""
"""
Задача, решаемая алгоритмом кластеризации:
Группировка музыкальных треков на основе их характеристик с целью создания кластеров треков
с схожими характеристиками. Алгоритм кластеризации может помочь в создании плейлистов и рекомендаций,
основанных на схожести музыкальных треков по некоторым характеристикам.
"""
# 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()