""" Использовать регрессию по варианту для своих данных по варианту, самостоятельно сформулировав задачу. Оценить, насколько хорошо она подходит для решения сформулированной вами задачи. """ """ Задача, решаемая регрессией: Предсказание популярности нового музыкального трека на основе его определённых характеристик. Регрессионная модель может предсказывать числовую оценку популярности трека, что может быть полезно для музыкальных платформ по типу Spotify. """ # 12 вариант # Набор данных по курсовой: "Prediction of music genre" # Тип регрессии: Логистическая регрессия import pandas as pd import warnings import sklearn.exceptions from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report, confusion_matrix, f1_score from sklearn.feature_selection import RFE 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_music = df.copy() df_music['mode'] = df_music['mode'].apply(lambda x: 1 if x == 'Major' else 0) # разделим проценты популярности на 4 уровня (от 0 до 3) df_music['popularity'] = df_music['popularity'].apply(lambda x: int(x // 25)) X = df_music.drop(columns=['popularity']) # характеристики музыкального трека y = df_music['popularity'] # уровень популярности # Разделение датасета на тренировочные (95%) и тестовые данные (5%) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.05) # Создание и обучение модели логистической регрессии model = LogisticRegression(solver='lbfgs', max_iter=2000) model.fit(X_train.values, y_train) # Поиск 5 важных признаков rfe = RFE(estimator=model, n_features_to_select=5) rfe = rfe.fit(X_train.values, y_train) features_ranks = pd.DataFrame({'Признак': X.columns.values, 'Выбор': rfe.support_, 'Ранг': rfe.ranking_}) print("\033[92m\n[----------> Оценка признаков, влияющих на популярность трека <----------]\033[00m") print(features_ranks.sort_values(by=['Ранг'])) # Убираем незначительные признаки из датасета del_features = features_ranks['Признак'][features_ranks['Ранг'] == True] X_train = X_train[del_features] X_test = X_test[del_features] # Переобучаем на них модель model.fit(X_train.values, y_train) # Предсказание на тестовых данных уровня популярности трека y_pred = model.predict(X_test.values) # Формирование матрицы путаницы cm = confusion_matrix(y_test, y_pred) print("\033[92m\n[----------> Матрица путаницы <----------]\033[00m") print(cm) pred_true = sum(cm[i][i] for i in range(len(cm))) # верные прогнозы pred_false = cm.sum() - pred_true # неверные прогнозы print("\033[94mКол-во правильных предсказаний (главная диагональ) = {}\033[00m" .format(pred_true)) print("\033[91mКол-во неправильных предсказаний (остальное) = {}\033[00m".format(pred_false)) print("\033[92m\n[----------> Оценка модели <----------]\033[00m") print('Точность модели на тестовых данных: {:.2f}'.format(model.score(X_test.values, y_test))) print("\033[92m\n[----------> Отчёт о классификации по уровням <----------]\033[00m") # игнор ошибки отсутствия некоторых классах при прогнозе (в данном случае 0 и 3) warnings.filterwarnings("ignore", category=sklearn.exceptions.UndefinedMetricWarning) print(classification_report(y_test, y_pred)) print("\033[95mМаксимально предсказанный уровень: {}\033[00m".format(y_pred.max())) # Функция считывания и очищения csv-файла def open_dataset(csv_file): # открываем файл с указанием знака-отделителя df = pd.read_csv(csv_file, delimiter=',') # выбираем необходимые признаки df = df[['duration_ms', 'mode', 'tempo', 'instrumentalness', 'acousticness', 'speechiness', 'danceability', 'energy', 'liveness', 'valence', 'loudness', 'popularity']] # очищаем набор данных от пустых и неподходящих значений df = df[df['tempo'] != '?'] df = df.dropna() return df if __name__ == "__main__": main()