Merge pull request 'zhukova_alina_lab_6 is ready' (#258) from zhukova_alina_lab_6 into main

Reviewed-on: http://student.git.athene.tech/Alexey/IIS_2023_1/pulls/258
This commit is contained in:
Alexey 2023-12-07 16:05:39 +04:00
commit 8444b11675
6 changed files with 20328 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,205 @@
import pandas
from flask import Flask, render_template
from matplotlib import pyplot as plt
from numpy import vectorize
from sklearn.metrics import mean_absolute_error, accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPRegressor
app = Flask(__name__)
@app.route("/")
def home():
return "<html>" \
"<h1>Жукова Алина ПИбд-41</h1>" \
"<h1>Лабораторная работа №6</h1>" \
"<table>" \
"<td>" \
"<form Action='http://127.0.0.1:5000/k4_1_task_6' Method=get>" \
"<input type=submit value='Нейронная сеть'>" \
"</form>" \
"</td>" \
"</table>" \
"</html>"
# Нейронная сеть
# 10 вариант - MLPRegressor
@app.route("/k4_1_task_6", methods=['GET'])
def k4_1_task_6():
data = pandas.read_csv('Data_chess_games.csv')
data = data.loc[data['created_at'] - data['last_move_at'] != 0]
data = data.drop_duplicates()
data = data.sample(n=18000, replace=True, random_state=1)
# отбор нужных столбцов
corr = data[['white_rating', 'black_rating', 'moves', 'opening_eco', 'opening_name', 'winner']]
def SplitPr(stroke):
return len(stroke.split(" "))
corr['len'] = corr['moves'].apply(SplitPr)
corr = corr.loc[corr['len'] >= 10]
number_element = 0
def SelectElemToStolb(elem):
return elem.split(" ")[number_element]
def ScoreXod(elem):
if(elem == "O-O" or elem == "O-O-O"):
return 50
if(elem.__contains__("x")):
return 20
if (elem.__contains__("+")):
return 50
return 10
def EcoToScore(elem):
score_eco = 0
if(str(elem).startswith("A")):
score_eco = 100
if (str(elem).startswith("B")):
score_eco = 200
if (str(elem).startswith("C")):
score_eco = 300
if (str(elem).startswith("D")):
score_eco = 400
if (str(elem).startswith("E")):
score_eco = 500
score_eco += int(str(elem)[1:])
return score_eco
# 0 - white || 1 - black
gamer_ind = 0
def ScoreAllXods(elem):
score = 0
xods = elem.split(" ")
ind_temp = 0
for xod in xods:
if(ind_temp % 2 == gamer_ind % 2):
score += ScoreXod(xod)
ind_temp += 1
return score
corr['score_eco'] = corr['opening_eco'].apply(EcoToScore)
corr['w_score_all'] = corr['moves'].apply(ScoreAllXods)
gamer_ind = 1
corr['b_score_all'] = corr['moves'].apply(ScoreAllXods)
def WinnerSelect(elem):
if(elem == "white"):
return 1
if(elem == "black"):
return -1
return 0
corr['winner'] = corr['winner'].apply(WinnerSelect)
y = corr[['winner']]
# Нормирование к 1
max_zn = corr['white_rating'].max()
min_zn = corr['white_rating'].min()
def normirovanie(elem):
return ((elem - min_zn) / (max_zn - min_zn))
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)
corr_st = corr
corr = corr[['white_rating', 'black_rating', 'b_score_all', 'w_score_all', 'score_eco']]
X_train, X_test, y_train, y_test = train_test_split(corr, y, test_size=.01, random_state=42)
iter_count = 200
mlpRegressor = MLPRegressor(
hidden_layer_sizes=(50, 50), # слои и нейроны
activation='relu', # функция активации
solver='adam',
alpha=0.0001, # регуляризация
max_iter=iter_count, # макс итераций
learning_rate='constant',
batch_size=32, # размер мини партии
early_stopping=True, # для предотвращения переобучения
validation_fraction=0.2 # 20% данных для проверки
)
mlpRegressor.fit(X_train, y_train)
prediction = mlpRegressor.predict(X_test)
accuracy = str(mlpRegressor.score(X_test, y_test))
def FunkPorog(elem):
if(elem >= 0.5):
return 1
if(elem > -0.5):
return 0
if(elem <= -0.5):
return -1
prediction = mlpRegressor.predict(X_test)
n_predict_vect = vectorize(FunkPorog)
# Средняя ошибка
accuracy_mean_abs_error = mean_absolute_error(prediction, y_test)
# Предсказание исхода партии, в целых числах
predict_acc_score = n_predict_vect(prediction)
accuracy_acc_score = accuracy_score(predict_acc_score, y_test)
white_win = corr_st.loc[corr_st['winner'] == 1]
white_score = (white_win['w_score_all'])
black_score = (white_win['b_score_all'])
white_win_x = white_score - black_score + white_win['score_eco']
white_win_y = white_win['winner'] + (white_win['black_rating'] - white_win['white_rating'])
black_win = corr_st.loc[corr_st['winner'] == -1]
white_score = (black_win['w_score_all'])
black_score = (black_win['b_score_all'])
black_win_x = white_score - black_score + black_win['score_eco']
black_win_y = black_win['winner'] + (black_win['black_rating'] - black_win['white_rating'])
no_win = corr_st.loc[corr_st['winner'] == 0]
white_score = (no_win['w_score_all'])
black_score = (no_win['b_score_all'])
no_win_x = white_score - black_score + no_win['score_eco']
no_win_y = no_win['winner'] + (no_win['black_rating'] - no_win['white_rating'])
white_win = white_win[['white_rating', 'black_rating', 'b_score_all', 'w_score_all', 'score_eco']]
black_win = black_win[['white_rating', 'black_rating', 'b_score_all', 'w_score_all', 'score_eco']]
no_win = no_win[['white_rating', 'black_rating', 'b_score_all', 'w_score_all', 'score_eco']]
plt.subplot(1, 2, 1)
plt.scatter(white_win_x, (corr_st.loc[corr_st['winner'] == 1])['winner'], alpha=0.6, s=25, c='red')
plt.scatter(black_win_x, (corr_st.loc[corr_st['winner'] == -1])['winner'], alpha=0.6, s=25, c='blue')
plt.scatter(no_win_x, (corr_st.loc[corr_st['winner'] == 0])['winner'], alpha=0.6, s=25, c='green')
plt.scatter(white_win_x, white_win_y, alpha=0.2, s=25, c='pink')
plt.scatter(black_win_x, black_win_y, alpha=0.2, s=25, c='cyan')
plt.scatter(no_win_x, no_win_y, alpha=0.2, s=25, c='yellow')
plt.savefig('static\k4_1_6_neiro_net.png')
# Данные для статистики (100, 200, 400, 600, 800, 1000 итераций)
# 50,50 нейронов в слоях
# Отклонение по абсолютной ошибке 0.776, 0.773, 0.822, 0.761, 0.750, 0.883
# Отклонение по исходу в целых числах 0.222, 0.320, 0.188, 0.314, 0.331, 0.188
# 50,50,50 нейронов в слоях
# Отклонение по абсолютной ошибке 0.759, 0.812, 0.766, 0.751, 0.757, 0.748
# Отклонение по исходу в целых числах 0.354, 0.280, 0.228, 0.331, 0.217, 0.331
return "<html>" \
"<h1>Нейронная сеть</h1>" \
"<h2>Вариант 10. Задание 6 - MLPRegressor</h2>" \
"<h2> Точность модели на " + str(iter_count) + " итераций:</h2>" \
"<h2> Отклонение по абсолютной ошибке: " + str(accuracy_mean_abs_error) + "</h2>" \
"<h2> Отклонение по исходу партии в целых числах: " + str(accuracy_acc_score) + "</h2>" \
"<div align='center'>" + render_template(
'4_1_l6_figure1.html') + "</div>" \
"</html>"
if __name__ == "__main__":
app.run(debug=True)

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -0,0 +1,54 @@
## Задание
Использовать нейронную сеть по варианту для выбранных данных,
самостоятельно сформулировав задачу.
Интерпретировать результаты и оценить, насколько хорошо она подходит для
решения сформулированной вами задачи
Вариант №10
## Используемые технологии
В лабораторной были использованы библиотеки:
+ pandas - позволяет работать с наборами данных
+ matplotlib - используется для создания графиков
+ sklearn - используется для работы с моделями и методами машинного обучения
+ numpy - позволяет работать с массивами и матрицами
+ Flask - предоставляет способ быстрого создания веб-страниц для визуализации работы приложения
## Используемые компоненты
+ MLPRegressor - многослойный перцептрон, который обучается с
использованием обратного распространения без функции активации в выходном слое
+ accuracy_score - метрика измерения точности для определения качества регресии
+ mean_absolute_error - метрика измерения точности регресии через среднюю абсолютную ошибку
## Как запустить
Запустить файл flask-server, который поднимет локальный сервер
и позволит обратиться к программе через браузер по ссылке [http://127.0.0.1:5000/](http://127.0.0.1:5000/)
## Что делает программа
Берет все записи из датасета (датасет Chess Game Dataset)
[https://www.kaggle.com/datasets/datasnaek/chess](https://www.kaggle.com/datasets/datasnaek/chess)),
Преобразует данные нечисловых столбцов в числовые значения, осуществляет нормализацию и взвешивание параметров.
Строит регрессионную зависимость используя нейронную сеть MLPRegressor,
Оценивает качество полученной модели с помощью метрик accuracy_score и mean_absolute_error
## Анализ и скриншоты работы программы
С помощью регрессии планировалось получить предсказание об исходе партий,
а именно вероятность победы того или иного игрока.
Предсказание строиться исходя из ходов в шахматной записи,
каждому из которого присваивается своя ценность, а также учитывается рейтинг игроков
и открывающая комбинация ходов.
![img.png](img_screen_1.png)
Судить о модели можно и по средней абсолютной ошибке, но намного проще воспринимать
ее по точности данных предсказаний. Отклонение по исходу партии представляет
точность модели как процент неверных ответов об исходе партии.
Так как регрессионная модель выдает результаты от -1 до +1, а нам нужно получить
исход игры, значения из регресии с помощью специальной фунции приводятся к одному
числу из -1, 0, +1, где 0 означает ничью, +1 победу игрока играющего белыми,
-1 победу игрока играющего черными.
При варьировании параметров структуры модели (50,50 нейронов и 50,50,50 нейронов),
и количества итераций (от 200 до 1000) была найдена наилучшая модель,
которая дает точность в 78%, и отклонение по абсолютной ошибке 0.81

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View 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_6_neiro_net.png')}}" align="middle"/>
</body>
</html>