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