Merge pull request 'istyukov_timofey_lab_5 is ready' (#293) from istyukov_timofey_lab_5 into main
Reviewed-on: http://student.git.athene.tech/Alexey/IIS_2023_1/pulls/293
This commit is contained in:
commit
81ec79f7fe
BIN
istyukov_timofey_lab_5/1_dataset.jpg
Normal file
BIN
istyukov_timofey_lab_5/1_dataset.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 55 KiB |
BIN
istyukov_timofey_lab_5/2_features.jpg
Normal file
BIN
istyukov_timofey_lab_5/2_features.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
BIN
istyukov_timofey_lab_5/3_confusion_matrix.jpg
Normal file
BIN
istyukov_timofey_lab_5/3_confusion_matrix.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
istyukov_timofey_lab_5/4_score.jpg
Normal file
BIN
istyukov_timofey_lab_5/4_score.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
BIN
istyukov_timofey_lab_5/5_report.jpg
Normal file
BIN
istyukov_timofey_lab_5/5_report.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
108
istyukov_timofey_lab_5/README.md
Normal file
108
istyukov_timofey_lab_5/README.md
Normal file
@ -0,0 +1,108 @@
|
||||
# Лабораторная работа №5. Регрессия
|
||||
## 12 вариант
|
||||
___
|
||||
|
||||
### Задание:
|
||||
Использовать регрессию по варианту для своих данных по варианту,
|
||||
самостоятельно сформулировав задачу. Оценить, насколько хорошо она
|
||||
подходит для решения сформулированной вами задачи.
|
||||
|
||||
### Вариант:
|
||||
- Тип регрессии: **Логистическая регрессия**
|
||||
|
||||
### Вариант набора данных по курсовой работе:
|
||||
- Прогнозирование музыкальных жанров ("Prediction of music genre")
|
||||
|
||||
___
|
||||
|
||||
### Запуск
|
||||
- Запустить файл lab5.py
|
||||
|
||||
### Используемые технологии
|
||||
- Язык программирования **Python**
|
||||
- Среда разработки **PyCharm**
|
||||
- Библиотеки:
|
||||
* pandas
|
||||
* sklearn
|
||||
* matplotlib
|
||||
* warnings
|
||||
|
||||
### Описание программы
|
||||
**Набор данных (Kaggle):** Полный список жанров, включенных в CSV:
|
||||
«Электронная музыка», «Аниме», «Джаз», «Альтернатива», «Кантри», «Рэп»,
|
||||
«Блюз», «Рок», «Классика», «Хип-хоп».
|
||||
|
||||
**Задача, решаемая регрессией:**
|
||||
Предсказание популярности нового музыкального трека на основе его
|
||||
определённых характеристик. Регрессионная модель может предсказывать
|
||||
числовую оценку популярности трека, что может быть полезно
|
||||
для музыкальных платформ по типу Spotify.
|
||||
|
||||
**Задача оценки:**
|
||||
|
||||
- Вычисление 5 важных признаков и удаление из классификации ненужных
|
||||
- Прогноз на тестовом на наборе и расчёт точности.
|
||||
- Формирование матрицы путаницы для большего понимания.
|
||||
- Формирование отчёта классификации
|
||||
|
||||
---
|
||||
### Пример работы
|
||||
|
||||
*Датасет, сформированный из случайных строк csv-файла.*
|
||||
|
||||
![Graphics](1_dataset.jpg)
|
||||
|
||||
---
|
||||
|
||||
*Вычисленные характеристики признаков. Меткой True и рангом №1
|
||||
указаны 5 важных для популярности музыкального трека признаков.*
|
||||
|
||||
*Например, danceability (танцевальность) трека оказалось важным признаком,
|
||||
а duration_ms (длительность в милисекундах) — самый незначительный признак.*
|
||||
|
||||
![Graphics](2_features.jpg)
|
||||
|
||||
---
|
||||
|
||||
*Матрица путаницы — это табличное представление прогнозов, сделанных моделью
|
||||
классификации, показывающее количество правильных и неправильных прогнозов
|
||||
для каждого класса. На пересечениях n-строки и n-столба показаны верные прогнозы
|
||||
признака с индексом i. На данной матрице видно, что на популярности уровня 0 и 3
|
||||
не было ни одного верного предсказания.*
|
||||
|
||||
![Graphics](3_confusion_matrix.jpg)
|
||||
|
||||
---
|
||||
|
||||
*Оценка точности модели. По матрице путаницы можно было заметить, что оценка
|
||||
по значению чуть больше 50%, так как количество верных и неверных прогнозов
|
||||
не сильно отличается.*
|
||||
|
||||
![Graphics](4_score.jpg)
|
||||
|
||||
---
|
||||
|
||||
*На отчёте также можно заметить по нулям у уровней популярности 0 и 3,
|
||||
что там ни одно значение не было верно предсказано.*
|
||||
|
||||
![Graphics](5_report.jpg)
|
||||
|
||||
|
||||
### Вывод
|
||||
Итак, можно сказать, что с поставленной задачей логистическая регрессия больше
|
||||
справилась, чем не справилась. Но в то же время популярность трека — неоднозначный
|
||||
признак. Нельзя по характеристикам музыкального трека точно сказать, насколько
|
||||
он взлетит в чартах. Считаю, что именно поэтому программа не смогла предсказать
|
||||
нулевую и высшую популярность, а назначила тестовой выборке лишь средние
|
||||
значения популярности.
|
||||
|
||||
Логистическая регрессия выполняется быстро и относительно несложно, в ней удобно
|
||||
интерпретировать результаты. Хотя по сути это метод бинарной классификации,
|
||||
его также можно применять к задачам мультиклассов, что я и сделал (было бы
|
||||
нелогично обозначать популярность лишь метками True и False, когда можно
|
||||
её разделить на уровни).
|
||||
|
||||
Также логистическая регрессия не готова обрабатывать избыточное количество
|
||||
категорических признаков. Она подвержена переподбору, что и было сделано в
|
||||
данной лабораторной работе. Логистическая регрессия не будет хорошо работать
|
||||
с независимыми признаки трека, которые не коррелируют с популярностью трека.
|
108
istyukov_timofey_lab_5/lab5.py
Normal file
108
istyukov_timofey_lab_5/lab5.py
Normal file
@ -0,0 +1,108 @@
|
||||
"""
|
||||
Использовать регрессию по варианту для своих данных по варианту, самостоятельно сформулировав задачу.
|
||||
Оценить, насколько хорошо она подходит для решения сформулированной вами задачи.
|
||||
|
||||
"""
|
||||
|
||||
"""
|
||||
Задача, решаемая регрессией:
|
||||
Предсказание популярности нового музыкального трека на основе его определённых характеристик.
|
||||
Регрессионная модель может предсказывать числовую оценку популярности трека,
|
||||
что может быть полезно для музыкальных платформ по типу 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()
|
50006
istyukov_timofey_lab_5/music_genre.csv
Normal file
50006
istyukov_timofey_lab_5/music_genre.csv
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user