Merge pull request 'zhukova_alina_lab_4 is ready' (#159) from zhukova_alina_lab_4 into main
Reviewed-on: http://student.git.athene.tech/Alexey/IIS_2023_1/pulls/159
This commit is contained in:
commit
2d1a2a6fb4
20059
zhukova_alina_lab_4/Data_chess_games.csv
Normal file
20059
zhukova_alina_lab_4/Data_chess_games.csv
Normal file
File diff suppressed because it is too large
Load Diff
130
zhukova_alina_lab_4/flask-server.py
Normal file
130
zhukova_alina_lab_4/flask-server.py
Normal file
@ -0,0 +1,130 @@
|
||||
import pandas
|
||||
from flask import Flask, render_template
|
||||
from matplotlib import pyplot as plt
|
||||
from sklearn.cluster import KMeans
|
||||
from sklearn.metrics import silhouette_score
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route("/")
|
||||
def home():
|
||||
return "<html>" \
|
||||
"<h1>Жукова Алина ПИбд-41</h1>" \
|
||||
"<h1>Лабораторная работа №4</h1>" \
|
||||
"<table>" \
|
||||
"<td>" \
|
||||
"<form Action='http://127.0.0.1:5000/k4_1_task_4' Method=get>" \
|
||||
"<input type=submit value='Кластеризация'>" \
|
||||
"</form>" \
|
||||
"</td>" \
|
||||
"</table>" \
|
||||
"</html>"
|
||||
|
||||
# Кластеризация
|
||||
# 4 Решите задачу кластеризации методом k-means
|
||||
@app.route("/k4_1_task_4", methods=['GET'])
|
||||
def k4_1_task_4():
|
||||
data = pandas.read_csv('Data_chess_games.csv')
|
||||
data = data.loc[data['created_at'] - data['last_move_at'] != 0]
|
||||
data = data.drop_duplicates()
|
||||
i = len(data)
|
||||
data = data.sample(n=5000, replace=True, random_state=1)
|
||||
|
||||
count_klasters = 3
|
||||
labels_clasters = ["Очень напряженная", "Напряженная", "Спокойная"]
|
||||
|
||||
# отбор нужных столбцов
|
||||
corr = data[['rated', 'turns', 'white_rating', 'black_rating', 'created_at', 'last_move_at', 'increment_code']]
|
||||
# Добавление времени игры
|
||||
corr['time_game'] = corr['last_move_at'] - corr['created_at']
|
||||
corr['middle_time_turn'] = corr['time_game'] / corr['turns']
|
||||
def formatted_float(ch):
|
||||
return float('{:.2f}'.format(ch))
|
||||
|
||||
corr['middle_time_turn'] = corr['middle_time_turn'].apply(formatted_float)
|
||||
|
||||
def true_false_changer(str_true_false):
|
||||
if (str_true_false == True):
|
||||
return 1
|
||||
else:
|
||||
if (str_true_false == False):
|
||||
return 0
|
||||
return 2
|
||||
|
||||
corr['new_rated'] = corr['rated'].apply(true_false_changer)
|
||||
corr = corr[['new_rated', 'middle_time_turn', 'white_rating', 'black_rating', 'increment_code']]
|
||||
corr = corr.loc[corr['middle_time_turn'] < 10000000]
|
||||
# Преобразование системы учета времени к численным значениям
|
||||
def new_code(code):
|
||||
return (int(code.split("+")[1]) * 100) + int(code.split("+")[0])
|
||||
corr['n_increment_code'] = corr['increment_code'].apply(new_code)
|
||||
# Нормирование к 1
|
||||
max_zn = corr['middle_time_turn'].max()
|
||||
min_zn = corr['middle_time_turn'].min()
|
||||
def normirovanie(elem):
|
||||
return ((elem - min_zn) / (max_zn - min_zn))
|
||||
weight = 1
|
||||
def WeightAdd(elem):
|
||||
return elem * weight
|
||||
weight = 1
|
||||
corr['new_rated'] = corr['new_rated'].apply(WeightAdd)
|
||||
|
||||
weight = 1
|
||||
corr['middle_time_turn'] = corr['middle_time_turn'].apply(normirovanie).apply(WeightAdd)
|
||||
|
||||
max_zn = corr['white_rating'].max()
|
||||
min_zn = corr['white_rating'].min()
|
||||
corr['white_rating'] = corr['white_rating'].apply(normirovanie)
|
||||
|
||||
max_zn = corr['black_rating'].max()
|
||||
min_zn = corr['black_rating'].min()
|
||||
corr['black_rating'] = corr['black_rating'].apply(normirovanie)
|
||||
|
||||
max_zn = corr['n_increment_code'].max()
|
||||
min_zn = corr['n_increment_code'].min()
|
||||
weight = 1
|
||||
corr['n_increment_code'] = corr['n_increment_code'].apply(normirovanie).apply(WeightAdd)
|
||||
def ObratnoeNormirovanie(elem):
|
||||
return 1 - elem
|
||||
corr['n_increment_code'] = corr['n_increment_code'].apply(ObratnoeNormirovanie)
|
||||
|
||||
# Исключение из модели рейтинговой игры
|
||||
corr = corr[['new_rated', 'middle_time_turn', 'white_rating', 'black_rating', 'n_increment_code']]
|
||||
# создание и обучение алгоритма
|
||||
kmeans = KMeans(n_clusters=count_klasters)
|
||||
kmeans.fit(corr)
|
||||
|
||||
accuracy = silhouette_score(corr, kmeans.labels_, metric='euclidean')
|
||||
|
||||
colors_mass = ['blue', 'red', 'orange', 'green', 'black', 'gold', 'purple', 'pink', 'olive', 'gray',
|
||||
'cyan', 'crimson', 'royalblue', 'greenyellow', 'maroon']
|
||||
|
||||
for klaster in range(count_klasters):
|
||||
ind = 0
|
||||
matr_x = []
|
||||
matr_y = []
|
||||
for label in kmeans.labels_:
|
||||
if(label == klaster):
|
||||
elem = corr.iloc[ind]
|
||||
X = elem['white_rating']
|
||||
Y = elem['new_rated'] + elem['middle_time_turn'] + elem['n_increment_code'] + elem['black_rating']
|
||||
matr_x.append(X)
|
||||
matr_y.append(Y)
|
||||
ind += 1
|
||||
plt.scatter(matr_x, matr_y, alpha=0.6, s=25, c=colors_mass[klaster])
|
||||
|
||||
plt.savefig('static/k4_1_4_klaster.png')
|
||||
|
||||
|
||||
return "<html>" \
|
||||
"<h1>Кластеризация</h1>" \
|
||||
"<h2>Вариант 10. Задание 4 - метод Kmeans</h2>" \
|
||||
"<h2> Точность модели по метрике Силуэт: " + str(accuracy) + "</h2>" \
|
||||
"<div align='center'>" + render_template('4_1_l4_figure1.html') + "</div>" \
|
||||
"</html>"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(debug=True)
|
BIN
zhukova_alina_lab_4/img_screen_1.png
Normal file
BIN
zhukova_alina_lab_4/img_screen_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 62 KiB |
BIN
zhukova_alina_lab_4/img_screen_2.png
Normal file
BIN
zhukova_alina_lab_4/img_screen_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
49
zhukova_alina_lab_4/readme.md
Normal file
49
zhukova_alina_lab_4/readme.md
Normal file
@ -0,0 +1,49 @@
|
||||
## Задание
|
||||
Использовать метод кластеризации по варианту для выбранных данных,
|
||||
самостоятельно сформулировав задачу.
|
||||
Интерпретировать результаты и оценить, насколько хорошо он подходит для
|
||||
решения сформулированной вами задачи
|
||||
|
||||
Вариант №10
|
||||
|
||||
## Используемые технологии
|
||||
В лабораторной были использованы библиотеки:
|
||||
+ pandas - позволяет работать с наборами данных
|
||||
+ matplotlib - используется для создания графиков
|
||||
+ sklearn - используется для работы с моделями и методами машинного обучения
|
||||
+ Flask - предоставляет способ быстрого создания веб-страниц для визуализации работы приложения
|
||||
|
||||
## Используемые компоненты
|
||||
+ KMeans - библиотечная реализация метода k-средних, алгоритм
|
||||
стремится минимизировать суммарное квадратичное отклонение точек кластеров от центров этих кластеров
|
||||
+ silhouette_score - метрика "Силуэт" для определения качества кластеризации.
|
||||
Вычисляется с помощью среднего внутрикластерного расстояния и среднего расстояния до ближайшего кластера по каждому образцу
|
||||
|
||||
## Как запустить
|
||||
Запустить файл flask-server, который поднимет локальный сервер
|
||||
и позволит обратиться к программе через браузер по ссылке [http://127.0.0.1:5000/](http://127.0.0.1:5000/)
|
||||
|
||||
## Что делает программа
|
||||
Берет 5000 записей из датасета (датасет Chess Game Dataset
|
||||
[https://www.kaggle.com/datasets/datasnaek/chess](https://www.kaggle.com/datasets/datasnaek/chess)),
|
||||
Преобразует данные нечисловых столбцов в числовые значения, осуществляет нормализацию и взвешивание параметров.
|
||||
Проводит кластеризацию с помощью метода KMeans на данных, количество кластеров выбрано вручную.
|
||||
Оценивает качество кластеризации с помощью метрики "Силуэт"
|
||||
|
||||
## Анализ и скриншоты работы программы
|
||||
|
||||
С помощью кластеризации планировалось разбить все шахматные партии на группы
|
||||
с учетом напряженности игры. Так, рейтинговые игры, с меньшими временными затратами
|
||||
на ход и более высокими рейтингами игроков считаются более напряженными.
|
||||
|
||||
Наилучшие результаты по метрике "Силуэт" получаются, если задать количество кластеров,
|
||||
равное двум. Но при этом всего лишь происходит разделение игр на рейтинговые и
|
||||
не рейтинговые. Изменение веса этого параметра также не дает существенных результатов
|
||||
![img.png](img_screen_2.png)
|
||||
|
||||
С другой стороны, разделение данных на 3 кластера визуально совпадает с ожидаемым
|
||||
разделнием. Так, самые напряженные игры войдут в синий кластер, менее напряженные - в желтый.
|
||||
Красный кластер соберет все наимее напряженные игры, так как они проходят вне рейтинга.
|
||||
Однако оценка по метрике "Силуэт" будет существенно хуже.
|
||||
![img.png](img_screen_1.png)
|
||||
|
BIN
zhukova_alina_lab_4/static/k4_1_4_klaster.png
Normal file
BIN
zhukova_alina_lab_4/static/k4_1_4_klaster.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
10
zhukova_alina_lab_4/templates/4_1_l4_figure1.html
Normal file
10
zhukova_alina_lab_4/templates/4_1_l4_figure1.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
</head>
|
||||
<body>
|
||||
<img src="{{url_for('static', filename='k4_1_4_klaster.png')}}" align="middle"/>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user