62 lines
3.2 KiB
Python
62 lines
3.2 KiB
Python
|
import pandas as pd
|
|||
|
import numpy as np
|
|||
|
import matplotlib.pyplot as plt
|
|||
|
from sklearn.cluster import DBSCAN
|
|||
|
from sklearn.metrics import silhouette_score
|
|||
|
|
|||
|
# Загрузить данные
|
|||
|
data = pd.read_csv("spotify.csv")
|
|||
|
# Удалить все строки с пропусками
|
|||
|
data = data.dropna()
|
|||
|
data.drop('artist(s)_name', axis=1, inplace=True)
|
|||
|
# Список столбцов для нормализации
|
|||
|
columns_to_normalize = ['danceability_%', 'valence_%', 'energy_%', 'acousticness_%', 'instrumentalness_%', 'liveness_%', 'speechiness_%']
|
|||
|
# Проход по каждому столбцу и выполнение нормализации
|
|||
|
for column in columns_to_normalize:
|
|||
|
min_value = data[column].min()
|
|||
|
max_value = data[column].max()
|
|||
|
data[column] = (data[column] - min_value) / (max_value - min_value)
|
|||
|
# Удалить запятые из значений в столбце
|
|||
|
data['in_deezer_playlists'] = data['in_deezer_playlists'].str.replace(',', '')
|
|||
|
# Привести столбец к числовому типу данных
|
|||
|
data['in_deezer_playlists'] = data['in_deezer_playlists'].astype(np.int64)
|
|||
|
# Удалить запятые из значений в столбце
|
|||
|
data['in_shazam_charts'] = data['in_shazam_charts'].str.replace(',', '')
|
|||
|
# Привести столбец к числовому типу данных
|
|||
|
data['in_shazam_charts'] = data['in_shazam_charts'].astype(np.int64)
|
|||
|
# Создаем словарь соответствия числовых значений и названий трека
|
|||
|
track_name_dict = {name: index for index, name in enumerate(data['track_name'].unique())}
|
|||
|
# Заменяем значения в столбце на числовые
|
|||
|
data['track_name'] = data['track_name'].map(track_name_dict)
|
|||
|
# Создаем словарь соответствия числовых значений и названий тональности
|
|||
|
key_dict = {'C': 0, 'C#': 1, 'D': 2, 'D#': 3, 'E': 4, 'F': 5, 'F#': 6,
|
|||
|
'G': 7, 'G#': 8, 'A': 9, 'A#': 10, 'B': 11}
|
|||
|
# Заменяем значения в столбце на числовые
|
|||
|
data['key'] = data['key'].map(key_dict)
|
|||
|
# Создаем словарь соответствия числовых значений и режимов песни
|
|||
|
mode_dict = {'Major': 0, 'Minor': 1}
|
|||
|
# Заменяем значения в столбце на числовые
|
|||
|
data['mode'] = data['mode'].map(mode_dict)
|
|||
|
|
|||
|
eps = 45 # радиус окрестности
|
|||
|
min_samples = 1 # минимальное количество точек в окрестности
|
|||
|
|
|||
|
dbscan = DBSCAN(eps=eps, min_samples=min_samples)
|
|||
|
dbscan.fit(data)
|
|||
|
|
|||
|
# Добавляем метки кластеров в исходный датасет
|
|||
|
data['cluster_label'] = dbscan.labels_
|
|||
|
|
|||
|
# Создаем график рассеяния
|
|||
|
plt.scatter(data['bpm'], data['danceability_%'], c=data['cluster_label'])
|
|||
|
plt.xlabel('BPM')
|
|||
|
plt.ylabel('Danceability %')
|
|||
|
plt.title('Диаграмма рассеивания DBSCAN')
|
|||
|
|
|||
|
# Добавляем легенду
|
|||
|
plt.colorbar(label='Cluster Label')
|
|||
|
|
|||
|
# Показываем график
|
|||
|
plt.show()
|
|||
|
silhouette_avg = silhouette_score(data, dbscan.labels_)
|
|||
|
print("Значение индекса силуэта модели DBSCAN:", silhouette_avg)
|