Spaces:
Running
Running
Upload 32 files
Browse files- .devcontainer/devcontainer.json +33 -0
- Home.py +71 -0
- image/Frame.png +0 -0
- models/booking_cancel_pred.pkl +3 -0
- models/car_cost_pred.pkl +3 -0
- models/clients_churn.pkl +3 -0
- models/ohe_booking_cancel_pred.pkl +3 -0
- models/ohe_car_cost_pred.pkl +3 -0
- models/ohe_clients_churn.pkl +3 -0
- models/ohe_star_temperature_pred.pkl +3 -0
- models/power_forecasting.pkl +3 -0
- models/scaler_booking_cancel_pred.pkl +3 -0
- models/scaler_car_cost_pred.pkl +3 -0
- models/scaler_clients_churn.pkl +3 -0
- models/scaler_power_forecasting.pkl +3 -0
- models/scaler_star_temperature_pred.pkl +3 -0
- models/star_temperature_pred.pkl +3 -0
- models/tariff_recommendation.pkl +3 -0
- models/taxi.csv +0 -0
- models/taxi_orders_prediction.pkl +3 -0
- models/toxic_comments_bert.pkl +3 -0
- pages/10_power_forecasting.py +137 -0
- pages/1_tariff_recommendation.py +72 -0
- pages/2_clients_churn.py +114 -0
- pages/3_booking_cancel_pred.py +202 -0
- pages/4_toxic_comments.py +106 -0
- pages/5_star_temperature.py +147 -0
- pages/6_sql_stackoverflow.py +191 -0
- pages/7_car_cost_pred.py +148 -0
- pages/8_accident_prediction.py +145 -0
- pages/9_taxi_orders_prediction.py +85 -0
- requirements.txt +12 -0
.devcontainer/devcontainer.json
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"name": "Python 3",
|
3 |
+
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
4 |
+
"image": "mcr.microsoft.com/devcontainers/python:1-3.11-bullseye",
|
5 |
+
"customizations": {
|
6 |
+
"codespaces": {
|
7 |
+
"openFiles": [
|
8 |
+
"README.md",
|
9 |
+
"project_1/Hello.py"
|
10 |
+
]
|
11 |
+
},
|
12 |
+
"vscode": {
|
13 |
+
"settings": {},
|
14 |
+
"extensions": [
|
15 |
+
"ms-python.python",
|
16 |
+
"ms-python.vscode-pylance"
|
17 |
+
]
|
18 |
+
}
|
19 |
+
},
|
20 |
+
"updateContentCommand": "[ -f packages.txt ] && sudo apt update && sudo apt upgrade -y && sudo xargs apt install -y <packages.txt; [ -f requirements.txt ] && pip3 install --user -r requirements.txt; pip3 install --user streamlit; echo '✅ Packages installed and Requirements met'",
|
21 |
+
"postAttachCommand": {
|
22 |
+
"server": "streamlit run project_1/Hello.py --server.enableCORS false --server.enableXsrfProtection false"
|
23 |
+
},
|
24 |
+
"portsAttributes": {
|
25 |
+
"8501": {
|
26 |
+
"label": "Application",
|
27 |
+
"onAutoForward": "openPreview"
|
28 |
+
}
|
29 |
+
},
|
30 |
+
"forwardPorts": [
|
31 |
+
8501
|
32 |
+
]
|
33 |
+
}
|
Home.py
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from pathlib import Path
|
3 |
+
st.set_page_config(page_title="Главная страница")
|
4 |
+
|
5 |
+
from st_pages import Page, show_pages
|
6 |
+
|
7 |
+
show_pages(
|
8 |
+
[
|
9 |
+
Page("Home.py", "Главная страница", "🏠"),
|
10 |
+
Page("pages/1_tariff_recommendation.py", "Рекомендация тарифа", ":receipt:"),
|
11 |
+
Page("pages/2_clients_churn.py", "Отток клиентов «Бета-Банка»", ":classical_building:"),
|
12 |
+
Page("pages/3_booking_cancel_pred.py", "Прогнозирование оттока клиентов в сети отелей «Как в гостях»", ":house_buildings:"),
|
13 |
+
Page("pages/4_toxic_comments.py", "Выявление негативных комментариев с BERT", ":female-student:"),
|
14 |
+
Page("pages/5_star_temperature.py", "Прогнозирование температуры звезды", ":star:"),
|
15 |
+
Page("pages/6_sql_stackoverflow.py", "Анализ данных StackOverflow", ":page_facing_up:"),
|
16 |
+
Page("pages/7_car_cost_pred.py", "Определение стоимости автомобилей", ":car:"),
|
17 |
+
Page("pages/8_accident_prediction.py", "Разработка модели для оценки ДТП", ":rotating_light:"),
|
18 |
+
Page("pages/9_taxi_orders_prediction.py", "Прогнозирование заказов такси", ":taxi:"),
|
19 |
+
Page("pages/10_power_forecasting.py", "Потребление электроэнергии производством", ":factory:")
|
20 |
+
]
|
21 |
+
)
|
22 |
+
st.write("## Демонстрационный проект на базе Streamlit 👋")
|
23 |
+
st.markdown(
|
24 |
+
"""
|
25 |
+
**О себе:** Меня зовут Махнев Андрей, и я являюсь начинающим специалистом в области Data Science. Начал свой путь с курсов, изучая основы языка Python:
|
26 |
+
- [Питонтьютор](https://pythontutor.ru/)
|
27 |
+
- ["Поколение Python": курс для начинающих](https://stepik.org/course/58852/promo)
|
28 |
+
- ["Поколение Python": курс для продвинутых](https://stepik.org/course/68343/promo)
|
29 |
+
- ["Поколение Python": курс для профессионалов](https://stepik.org/course/82541/promo)
|
30 |
+
- [SQL Academy](https://sql-academy.org/ru)
|
31 |
+
|
32 |
+
Спустя время определился с выбором направления и прошел курс:
|
33 |
+
- [Яндекс Практикум (2022) по направлению Data Science Plus](https://practicum.yandex.ru/data-scientist-plus/)
|
34 |
+
|
35 |
+
По прошествия обучения хочу продемонстрировать результаты в виде самостоятельного проекта на базе [Streamlit](https://streamlit.io/) для наглядной демонстрации работы моделей машинного обучения, которые созданы на основе учебных проектов в процессе
|
36 |
+
обучения на курсах Яндекс Практикум. [Ссылка мой на профиль с проектами на GitHub](https://github.com/Sazuppy/yandex_project)
|
37 |
+
"""
|
38 |
+
)
|
39 |
+
st.header("Технологии")
|
40 |
+
|
41 |
+
st.markdown(
|
42 |
+
"""
|
43 |
+
Технологии которые были мною изучены в процессе обучения и применены в данном проекте и проектах Яндекс Практикум:
|
44 |
+
|
45 |
+
- **Streamlit:** Создание визуальных интерфейсов для демонстрации результатов моих проектов.
|
46 |
+
- **Keras и TensorFlow:** Работа с нейронными сетями и глубоким обучением.
|
47 |
+
- **scikit-learn и PyTorch:** Применение различных алгоритмов машинного обучения и глубокого обучения.
|
48 |
+
- **torchvision:** Работа с изображениями и компьютерным зрением в экосистеме PyTorch.
|
49 |
+
- **Seaborn:** Визуализация данных с использованием стильных и информативных графиков.
|
50 |
+
- **scipy:** Использование для научных и технических вычислений.
|
51 |
+
- **PostgreSQL:** Работа с базами данных для хранения и обработки данных.
|
52 |
+
- **Pandas и Numpy:** Обработка и анализ данных.
|
53 |
+
- **Matplotlib:** Визуализация данных и результатов.
|
54 |
+
- **Transformers:** Применение в обработке естественного языка и обучении с использованием трансформерных моделей.
|
55 |
+
- **Apache Spark и Hadoop:** Обработка больших объемов данных и распределенные в��числения.
|
56 |
+
|
57 |
+
"""
|
58 |
+
)
|
59 |
+
|
60 |
+
st.header("Проект по компьютерному зрению")
|
61 |
+
|
62 |
+
st.markdown(
|
63 |
+
"""
|
64 |
+
Дополнительно, я представляю проект, посвященный компьютерному зрению, который был разработан на основе учебного проекта в рамках обучения на платформе Яндекс Практикум.
|
65 |
+
|
66 |
+
**Определение возраста человека по фотографии:**
|
67 |
+
|
68 |
+
Этот проект позволяет определить возраст человека по предоставленной фотографии. Интерактивный интерфейс проекта доступен по [ссылке](https://age-determination.streamlit.app/).
|
69 |
+
Здесь я применял навыки обработки изображений, использовал библиотеки Keras и TensorFlow для построения модели, способной анализировать и предсказывать возраст объекта на фотографии.
|
70 |
+
"""
|
71 |
+
)
|
image/Frame.png
ADDED
models/booking_cancel_pred.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:6d1a7574609b847aec6b1a347bee88402a798337f5829c234df4e9df16dffd41
|
3 |
+
size 68823
|
models/car_cost_pred.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:80be2229d21bcaf2da8592c92ab3570a96e247fea49997f8852af785b9a17885
|
3 |
+
size 8295711
|
models/clients_churn.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:f452d3ece8e1438a1a718657a0db14bcad468d59e923aec7b1a64c31633824db
|
3 |
+
size 5181683
|
models/ohe_booking_cancel_pred.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:124f0d95b09462eed177539952e34f55e30549360a9f12073bb932353e977103
|
3 |
+
size 984
|
models/ohe_car_cost_pred.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:61950fd47913fc9702dbfba13f2be48b0593c853870518a8c45ca0390279e016
|
3 |
+
size 3444
|
models/ohe_clients_churn.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:397342064e8cf7ce466870d6f17237620e3aadbeb4e6c7b9999706a9f705e95e
|
3 |
+
size 653
|
models/ohe_star_temperature_pred.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:ad47df9ea186609a43a3829e4bbf2d9d11264699e88e734c0b93198266022682
|
3 |
+
size 844
|
models/power_forecasting.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:703543a7a672a6ce96c16153bc40a25a0471acab5c7e993a2d445b3aaeb9b92a
|
3 |
+
size 5294943
|
models/scaler_booking_cancel_pred.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:2cebbc6f32acb1cf51a280cb88fafabbaf814f9a64ca536205fa3a276cf6ccaa
|
3 |
+
size 1372
|
models/scaler_car_cost_pred.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:2c8a3e358f1b674163101927104ffac360714045890b18fc0cd4cf56388047db
|
3 |
+
size 647
|
models/scaler_clients_churn.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:7f5441a5afc62fe300a9fe251bf38711f29d6e8576658a8095d8e4cff84b2895
|
3 |
+
size 757
|
models/scaler_power_forecasting.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:4e67b40558f05cd79d9333334a37dcb9fe8d65ae64c84ebc34fcc55515f78863
|
3 |
+
size 984
|
models/scaler_star_temperature_pred.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:b39f4edfa0d62aa7d066458831085e5e8566ef6a78f5a1d77c3f9b6870af5181
|
3 |
+
size 646
|
models/star_temperature_pred.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:4bb0d577d5b8db0cd277db496d4eaa3a3fd454e4d39665e39168afcb740c7197
|
3 |
+
size 2451028
|
models/tariff_recommendation.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:77d6bb70e01a95b663005f3c27e9b9fccf7e7b6e9c18f4edbf30c8df71b82ade
|
3 |
+
size 4260748
|
models/taxi.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
models/taxi_orders_prediction.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:9bb2fe04bf59dc58968d4dc35e03590a3d419c9a00e632e556dd0b49aa958100
|
3 |
+
size 1091095
|
models/toxic_comments_bert.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:eb212aafced3aff3a3333f67443225653c04774a02d3250955b7bc8bd59df3f6
|
3 |
+
size 370126
|
pages/10_power_forecasting.py
ADDED
@@ -0,0 +1,137 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
import pickle
|
5 |
+
from sklearn.ensemble import RandomForestClassifier
|
6 |
+
from sklearn.preprocessing import StandardScaler, OneHotEncoder
|
7 |
+
|
8 |
+
st.set_page_config(page_title="# Оптимизация производственных расходов металлургического комбината.")
|
9 |
+
|
10 |
+
st.markdown('# Оптимизация производственных расходов металлургического комбината.')
|
11 |
+
|
12 |
+
with st.expander("Описание проекта"):
|
13 |
+
st.write("""
|
14 |
+
Для оптимизации производственных расходов, металлургический комбинат решил уменьшить потребление электроэнергии на этапе обработки стали.
|
15 |
+
Для этого нужно контролировать температуру сплава.
|
16 |
+
Задача — построить модель, которая будет её предсказывать, заказчик хочет использовать разработанную модель для имитации технологического процесса.
|
17 |
+
""")
|
18 |
+
with st.expander("Описание процесса обработки"):
|
19 |
+
st.write("""
|
20 |
+
Сталь обрабатывают в металлическом ковше вместимостью около 100 тонн. Чтобы ковш выдерживал высокие температуры, изнутри его облицовывают огнеупорным кирпичом. Расплавленную сталь заливают в ковш и подогревают до нужной температуры графитовыми электродами. Они установлены на крышке ковша.
|
21 |
+
Сначала происходит десульфурация — из стали выводят серу и корректируют её химический состав добавлением примесей. Затем сталь легируют — добавляют в неё куски сплава из бункера для сыпучих материалов или порошковую проволоку через специальный трайб-аппарат.
|
22 |
+
Прежде чем в первый раз ввести легирующие добавки, специалисты производят химический анализ стали и измеряют её температуру. Потом температуру на несколько минут повышают, уже после этого добавляют легирующие материалы и продувают сталь инертным газом, чтобы перемешать, а затем снова проводят измерения. Такой цикл повторяется до тех пор, пока не будут достигнуты нужный химический состав стали и оптимальная температура плавки.
|
23 |
+
Дальше расплавленная сталь отправляется на доводку металла или поступает в машину непрерывной разливки. Оттуда готовый продукт выходит в виде заготовок-слябов (англ. slab, «плита»).
|
24 |
+
""")
|
25 |
+
|
26 |
+
with st.expander("Описание данных"):
|
27 |
+
st.write("""
|
28 |
+
Данные хранятся в базе данных PostgreSQL. Она состоит из нескольких таблиц:
|
29 |
+
- steel.data_arc — данные об электродах;
|
30 |
+
- steel.data_bulk — данные об объёме сыпучих материалов;
|
31 |
+
- steel.data_bulk_time — данные о времени подачи сыпучих материалов;
|
32 |
+
- steel.data_gas — данные о продувке сплава газом;
|
33 |
+
- steel.data_temp — данные об измерениях температуры;
|
34 |
+
- steel.data_wire — данные об объёме проволочных материалов;
|
35 |
+
- steel.data_wire_time — данные о времени подачи проволочных материалов.
|
36 |
+
|
37 |
+
Таблица steel.data_arc:
|
38 |
+
- key — номер партии;
|
39 |
+
- BeginHeat — время начала нагрева;
|
40 |
+
- EndHeat — время окончания нагрева;
|
41 |
+
- ActivePower — значение активной мощности;
|
42 |
+
- ReactivePower — значение реактивной мощности.
|
43 |
+
|
44 |
+
Таблица steel.data_bulk:
|
45 |
+
- key — номер партии;
|
46 |
+
- Bulk1 … Bulk15 — объём подаваемого материала.
|
47 |
+
|
48 |
+
Таблица steel.data_bulk_time:
|
49 |
+
- key — номер партии;
|
50 |
+
- Bulk1 … Bulk15 — время подачи материала.
|
51 |
+
|
52 |
+
Таблица steel.data_gas:
|
53 |
+
- key — номер партии;
|
54 |
+
- gas — объём подаваемого газа.
|
55 |
+
|
56 |
+
Таблица steel.data_temp:
|
57 |
+
- key — номер партии;
|
58 |
+
- MesaureTime — время замера;
|
59 |
+
- Temperature — значение температуры.
|
60 |
+
|
61 |
+
Таблица steel.data_wire:
|
62 |
+
- key — номер партии;
|
63 |
+
- Wire1 … Wire15 — объём подаваемых проволочных материалов.
|
64 |
+
|
65 |
+
Таблица steel.data_wire_time:
|
66 |
+
- key — номер партии;
|
67 |
+
- Wire1 … Wire15 — время подачи проволочных материалов.
|
68 |
+
|
69 |
+
Во всех файлах столбец key содержит номер партии. В таблицах может быть несколько строк с одинаковым значением key: они соответствуют разным итерациям обработки.
|
70 |
+
""")
|
71 |
+
|
72 |
+
st.sidebar.header("Признаки для модели машинного обучения")
|
73 |
+
|
74 |
+
def changes(df):
|
75 |
+
pass
|
76 |
+
|
77 |
+
def user_input_features():
|
78 |
+
gas = st.sidebar.slider('объём подаваемого газа на продувку, м3/ч', 0, 100, 10)
|
79 |
+
temp_first = st.sidebar.slider('значение температуры сплава первого замера, С', 1500, 1680, 1580)
|
80 |
+
count = st.sidebar.slider('количество замеров температуры', 1, 20, 3)
|
81 |
+
measure_time = st.sidebar.slider('длительность замера, с', 10, 2000, 80)
|
82 |
+
Bulk_3 = st.sidebar.slider('объём подаваемого материала', 0, 450, 100)
|
83 |
+
Bulk_4 = st.sidebar.slider('объём подаваемого материала', 0, 300, 100)
|
84 |
+
Bulk_12 = st.sidebar.slider('объём подаваемого материала', 0, 2000, 500)
|
85 |
+
Bulk_14 = st.sidebar.slider('объём подаваемого материала', 0, 650, 300)
|
86 |
+
Bulk_15 = st.sidebar.slider('объём подаваемого материала', 0, 350, 100)
|
87 |
+
Wire_1 = st.sidebar.slider('объём подаваемых проволочных материалов', 0.0, 22.0, 10.0)
|
88 |
+
Wire_2 = st.sidebar.slider('объём подаваемых проволочных материалов', 0, 350, 100)
|
89 |
+
full_power = st.sidebar.slider('полная мощность', 0.25, 21.5, 10.5)
|
90 |
+
power_coef = st.sidebar.slider('коэффициент мощности', 0.50, 0.90, 0.60)
|
91 |
+
|
92 |
+
|
93 |
+
|
94 |
+
data = {'gas': gas,
|
95 |
+
'temp_first': temp_first,
|
96 |
+
'count_x': count,
|
97 |
+
'measure_time': measure_time,
|
98 |
+
'Bulk 3': Bulk_3,
|
99 |
+
'Bulk 4': Bulk_4,
|
100 |
+
'Bulk 12': Bulk_12,
|
101 |
+
'Bulk 14': Bulk_14,
|
102 |
+
'Bulk 15': Bulk_15,
|
103 |
+
'Wire 1': Wire_1,
|
104 |
+
'Wire 2': Wire_2,
|
105 |
+
'full_power': full_power,
|
106 |
+
'power_coef': power_coef,
|
107 |
+
}
|
108 |
+
features = pd.DataFrame(data, index=[0])
|
109 |
+
return features
|
110 |
+
|
111 |
+
df = user_input_features()
|
112 |
+
df = df.sort_index(axis=1)
|
113 |
+
|
114 |
+
st.subheader('Таблица с введенными вами параметрами:')
|
115 |
+
st.write(df)
|
116 |
+
|
117 |
+
def preprocessing_data(df, scaler):
|
118 |
+
df = scaler.transform(df)
|
119 |
+
|
120 |
+
return pd.DataFrame(df, index=[0])
|
121 |
+
|
122 |
+
@st.cache_resource
|
123 |
+
def get_model():
|
124 |
+
load_model = pickle.load(open('models/power_forecasting.pkl', 'rb'))
|
125 |
+
scaler_model = pickle.load(open('models/scaler_power_forecasting.pkl', 'rb'))
|
126 |
+
return load_model, scaler_model
|
127 |
+
|
128 |
+
model, sc_model = get_model()
|
129 |
+
|
130 |
+
df_new = preprocessing_data(df, sc_model)
|
131 |
+
|
132 |
+
prediction = model.predict(df_new)
|
133 |
+
|
134 |
+
|
135 |
+
st.subheader('Температура сплава')
|
136 |
+
rounded_prediction = np.around(prediction)
|
137 |
+
st.write(str(rounded_prediction.item()))
|
pages/1_tariff_recommendation.py
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import time
|
3 |
+
import numpy as np
|
4 |
+
import pandas as pd
|
5 |
+
import pickle
|
6 |
+
from sklearn.ensemble import RandomForestClassifier
|
7 |
+
|
8 |
+
st.set_page_config(page_title="Рекомендация тарифов")
|
9 |
+
|
10 |
+
st.markdown('# Рекомендация тарифов')
|
11 |
+
|
12 |
+
with st.expander("Описание проекта:"):
|
13 |
+
st.write(
|
14 |
+
"""Оператор мобильной связи «Мегалайн» выяснил: многие клиенты пользуются архивными тарифами.
|
15 |
+
Задача состояла в построении системы, способной проанализировать поведение клиентов
|
16 |
+
- пользователей архивных тарифов и предложить пользователям новый тариф: «Смарт» или «Ультра».
|
17 |
+
Была построена модель (RandomForestClassifier) для задачи классификации, которая выберает подходящий
|
18 |
+
тариф с максимально большим значением accuracy (доля правильных ответов).
|
19 |
+
""")
|
20 |
+
|
21 |
+
with st.expander("Описание данных:"):
|
22 |
+
st.write("""
|
23 |
+
Описание данных на которых можель была обучена:
|
24 |
+
|
25 |
+
* сalls — количество звонков,
|
26 |
+
* minutes — суммарная длительность звонков в минутах,
|
27 |
+
* messages — количество sms-сообщений,
|
28 |
+
* mb_used — израсходованный интернет-трафик в Мб,
|
29 |
+
* is_ultra — каким тарифом пользовался в течение месяца («Ультра» — 1, «Смарт» — 0).
|
30 |
+
"""
|
31 |
+
)
|
32 |
+
|
33 |
+
st.sidebar.header("Признаки для модели машинного обучения")
|
34 |
+
|
35 |
+
def user_input_features():
|
36 |
+
calls = st.sidebar.slider('Количество звонков', 0, 500, 60)
|
37 |
+
minutes = st.sidebar.slider('Количество потраченных минут', 0, 3000, 400)
|
38 |
+
messages = st.sidebar.slider('Количество sms-сообщений', 0, 500, 30)
|
39 |
+
mb_used = st.sidebar.slider('Количество потраченного интернет-трафика, Мб', 0, 70000, 17000)
|
40 |
+
data = {'calls': calls,
|
41 |
+
'minutes': minutes,
|
42 |
+
'messages': messages,
|
43 |
+
'mb_used': mb_used}
|
44 |
+
features = pd.DataFrame(data, index=[0])
|
45 |
+
return features
|
46 |
+
|
47 |
+
df = user_input_features()
|
48 |
+
|
49 |
+
st.subheader('Таблица с введенными вами параметрами:')
|
50 |
+
st.write(df)
|
51 |
+
|
52 |
+
@st.cache_resource
|
53 |
+
def get_model():
|
54 |
+
load_model = pickle.load(open('models/tariff_recommendation.pkl', 'rb'))
|
55 |
+
return load_model
|
56 |
+
|
57 |
+
model = get_model()
|
58 |
+
|
59 |
+
prediction = model.predict(df)
|
60 |
+
prediction_proba = model.predict_proba(df)
|
61 |
+
|
62 |
+
st.subheader('Рекомендация')
|
63 |
+
tariff = np.array(['Smart','Ultra'])
|
64 |
+
st.write(tariff[prediction])
|
65 |
+
|
66 |
+
st.subheader('Вероятность рекомендации')
|
67 |
+
st.write(prediction_proba)
|
68 |
+
|
69 |
+
|
70 |
+
|
71 |
+
|
72 |
+
|
pages/2_clients_churn.py
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
import pickle
|
5 |
+
from sklearn.ensemble import RandomForestClassifier
|
6 |
+
from sklearn.preprocessing import StandardScaler, OneHotEncoder
|
7 |
+
|
8 |
+
st.set_page_config(page_title="# Отток клиентов «Бета-Банка»")
|
9 |
+
|
10 |
+
st.markdown('# Отток клиентов «Бета-Банка»')
|
11 |
+
|
12 |
+
with st.expander("Описание проекта:"):
|
13 |
+
st.write(
|
14 |
+
"""Из «Бета-Банка» стали уходить клиенты. Каждый месяц. Немного, но заметно. Банковские маркетологи посчитали: сохранять текущих клиентов дешевле, чем привлекать новых.
|
15 |
+
Нужно спрогнозировать, уйдёт клиент из банка в ближайшее время или нет. Вам предоставлены исторические данные о поведении клиентов и расторжении договоров с банком.
|
16 |
+
Постройте модель с предельно большим значением *F1*-меры. Чтобы сдать проект успешно, нужно довести метрику до 0.59. Проверьте *F1*-меру на тестовой выборке самостоятельно.
|
17 |
+
Дополнительно измеряйте *AUC-ROC*, сравнивайте её значение с *F1*-мерой.
|
18 |
+
Источник данных: [https://www.kaggle.com/barelydedicated/bank-customer-churn-modeling](https://www.kaggle.com/barelydedicated/bank-customer-churn-modeling)
|
19 |
+
""")
|
20 |
+
|
21 |
+
with st.expander("Описание данных:"):
|
22 |
+
st.write("""
|
23 |
+
Признаки:
|
24 |
+
- CreditScore — кредитный рейтинг
|
25 |
+
- Geography — страна проживания
|
26 |
+
- Gender — пол
|
27 |
+
- Age — возраст
|
28 |
+
- Tenure — сколько лет человек является клиентом банка
|
29 |
+
- Balance — баланс на счёте
|
30 |
+
- NumOfProducts — количество продуктов банка, используемых клиентом
|
31 |
+
- HasCrCard — наличие кредитной карты
|
32 |
+
- IsActiveMember — активность клиента
|
33 |
+
- EstimatedSalary — предполагаемая зарплата
|
34 |
+
|
35 |
+
Целевой признак:
|
36 |
+
- Exited — факт ухода клиента
|
37 |
+
"""
|
38 |
+
)
|
39 |
+
|
40 |
+
st.sidebar.header("Признаки для модели машинного обучения")
|
41 |
+
|
42 |
+
def user_input_features():
|
43 |
+
credit_score = st.sidebar.slider('Кредитный рейтинг', 350, 850, 500)
|
44 |
+
geography = st.sidebar.selectbox('Страна проживания', ('France', 'Spain', 'Germany'))
|
45 |
+
gender = st.sidebar.selectbox('Пол', ('Female', 'Male'))
|
46 |
+
age = st.sidebar.slider('Возраст', 18, 92, 25)
|
47 |
+
tenure = st.sidebar.slider('Сколько лет человек является клиентом банка', 0, 10, 7)
|
48 |
+
balance = st.sidebar.slider('Баланс на счёте', 0, 300000, 20000)
|
49 |
+
num_of_products = st.sidebar.slider('Количество продуктов банка, используемых клиентом', 1, 4, 1)
|
50 |
+
has_cr_card = st.sidebar.selectbox('Наличие кредитной карты', ('Yes', 'No'))
|
51 |
+
is_active_member = st.sidebar.selectbox('Активность клиента', ('Yes', 'No'))
|
52 |
+
estimated_salary = st.sidebar.slider('Предполагаемая зарплата', 0, 200000, 10000)
|
53 |
+
|
54 |
+
|
55 |
+
data = {'credit_score': credit_score,
|
56 |
+
'geography': geography,
|
57 |
+
'gender': gender,
|
58 |
+
'age': age,
|
59 |
+
'tenure': tenure,
|
60 |
+
'balance': balance,
|
61 |
+
'num_of_products': num_of_products,
|
62 |
+
'has_cr_card': has_cr_card,
|
63 |
+
'is_active_member': is_active_member,
|
64 |
+
'estimated_salary': estimated_salary}
|
65 |
+
features = pd.DataFrame(data, index=[0])
|
66 |
+
return features
|
67 |
+
|
68 |
+
df = user_input_features()
|
69 |
+
|
70 |
+
st.subheader('Таблица с введенными вами параметрами:')
|
71 |
+
st.write(df)
|
72 |
+
|
73 |
+
def pre_category(data):
|
74 |
+
if data == "Yes":
|
75 |
+
return 1
|
76 |
+
else:
|
77 |
+
return 0
|
78 |
+
|
79 |
+
def preprocessing_data(df, scaler, ohe):
|
80 |
+
df['has_cr_card'] = df['has_cr_card'].apply(pre_category)
|
81 |
+
df['is_active_member'] = df['is_active_member'].apply(pre_category)
|
82 |
+
numeric = ['credit_score', 'age', 'tenure', 'balance', 'num_of_products', 'estimated_salary']
|
83 |
+
categorical = ['geography', 'gender']
|
84 |
+
df[numeric] = scaler.transform(df[numeric])
|
85 |
+
tmp = pd.DataFrame(ohe.transform(df[categorical]).toarray(),
|
86 |
+
columns=ohe.get_feature_names_out(),
|
87 |
+
index=df.index)
|
88 |
+
df.drop(categorical, axis=1, inplace=True)
|
89 |
+
df = df.join(tmp)
|
90 |
+
|
91 |
+
|
92 |
+
return pd.DataFrame(df, index=[0])
|
93 |
+
|
94 |
+
@st.cache_resource
|
95 |
+
def get_model():
|
96 |
+
load_model = pickle.load(open('models/clients_churn.pkl', 'rb'))
|
97 |
+
ohe_model = pickle.load(open('models/ohe_clients_churn.pkl', 'rb'))
|
98 |
+
scaler_model = pickle.load(open('models/scaler_clients_churn.pkl', 'rb'))
|
99 |
+
return load_model, scaler_model, ohe_model
|
100 |
+
|
101 |
+
model, sc_model, ohe_model = get_model()
|
102 |
+
|
103 |
+
df_new = preprocessing_data(df, sc_model, ohe_model)
|
104 |
+
|
105 |
+
prediction = model.predict(df_new)
|
106 |
+
prediction_proba = model.predict_proba(df_new)
|
107 |
+
|
108 |
+
|
109 |
+
st.subheader('Рекомендация')
|
110 |
+
exited = np.array(['Клиент вероятно уйдет','Клиент вероятно останется'])
|
111 |
+
st.write(exited[prediction])
|
112 |
+
|
113 |
+
st.subheader('Вероятность рекомендации')
|
114 |
+
st.write(prediction_proba)
|
pages/3_booking_cancel_pred.py
ADDED
@@ -0,0 +1,202 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
import pickle
|
5 |
+
from sklearn.ensemble import RandomForestClassifier
|
6 |
+
from sklearn.preprocessing import StandardScaler, OneHotEncoder
|
7 |
+
import datetime
|
8 |
+
|
9 |
+
st.set_page_config(page_title="# Прогнозирование оттока клиентов в сети отелей «Как в гостях»")
|
10 |
+
|
11 |
+
st.markdown('# Прогнозирование оттока клиентов в сети отелей «Как в гостях»')
|
12 |
+
|
13 |
+
with st.expander("Описание проекта"):
|
14 |
+
st.write(
|
15 |
+
"""Заказчик этого исследования — сеть отелей «Как в гостях».
|
16 |
+
Чтобы привлечь клиентов, эта сеть отелей добавила на свой сайт возможность забронировать номер без предоплаты.
|
17 |
+
Однако если клиент отменял бронирование, то компания терпела убытки. Сотрудники отеля могли, например, закупить продукты к приезду гостя
|
18 |
+
или просто не успеть найти другого клиента.
|
19 |
+
Чтобы решить эту проблему, вам нужно разработать систему, которая предсказывает отказ от брони. Если модель покажет,
|
20 |
+
что бронь будет отменена, то клиенту предлагается внести депозит. Размер депозита — 80% от стоимости номера за одни сутки и затрат на разовую уборку.
|
21 |
+
Деньги будут списаны со счёта клиента, если он всё же отменит бронь.
|
22 |
+
Бизнес-метрика и другие данные:
|
23 |
+
- Основная бизнес-метрика для любой сети отелей — её прибыль.
|
24 |
+
|
25 |
+
Прибыль отеля — это разница между стоимостью номера за все ночи и затраты на обслуживание: как при подготовке номера, так и при проживании постояльца.
|
26 |
+
|
27 |
+
В отеле есть несколько типов номеров. В зависимости от типа номера назначается стоимость за одну ночь.
|
28 |
+
Есть также затраты на уборку. Если клиент снял номер надолго, то убираются каждые два дня.
|
29 |
+
Стоимость номеров отеля:
|
30 |
+
- категория A: за ночь — 1 000, разовое обслуживание — 400;
|
31 |
+
- категория B: за ночь — 800, разовое обслуживание — 350;
|
32 |
+
- категория C: за ночь — 600, разовое обслуживание — 350;
|
33 |
+
- категория D: за ночь — 550, разовое обслуживание — 150;
|
34 |
+
- категория E: за ночь — 500, разовое обслуживание — 150;
|
35 |
+
- категория F: за ночь — 450, разовое обслуживание — 150;
|
36 |
+
- категория G: за ночь — 350, разовое обслуживание — 150.""")
|
37 |
+
|
38 |
+
with st.expander("Описание данных:"):
|
39 |
+
st.write("""
|
40 |
+
- id — номер записи;
|
41 |
+
- adults — количество взрослых постояльцев;
|
42 |
+
- arrival_date_year — год заезда;
|
43 |
+
- arrival_date_month — месяц заезда;
|
44 |
+
- arrival_date_week_number — неделя заезда;
|
45 |
+
- arrival_date_day_of_month — день заезда;
|
46 |
+
- babies — количество младенцев;
|
47 |
+
- booking_changes — количество изменений параметров заказа;
|
48 |
+
- children — количество детей от 3 до 14 лет;
|
49 |
+
- country — гражданство постояльца;
|
50 |
+
- customer_type — тип заказчика:
|
51 |
+
- Contract — договор с юридическим лицом;
|
52 |
+
- Group — групповой заезд;
|
53 |
+
- Transient — не связано с договором или групповым заездом;
|
54 |
+
- Transient-party — не связано с договором или групповым заездом, но связано с бронированием типа Transient.
|
55 |
+
- days_in_waiting_list — сколько дней заказ ожидал подтверждения;
|
56 |
+
- distribution_channel — канал дистрибуции заказа:
|
57 |
+
- "Direct" (Прямой)
|
58 |
+
- "TA/TO" (Туристические агентства/Туроператоры)
|
59 |
+
- "Corporate" (Корпоративный)
|
60 |
+
- "GDS" (Глобальные системы бронирования)
|
61 |
+
- is_canceled — отмена заказа;
|
62 |
+
- is_repeated_guest — признак того, что гость бронирует номер второй раз;
|
63 |
+
- lead_time — количество дней между датой бронирования и датой прибытия;
|
64 |
+
- meal — опции заказа:
|
65 |
+
- SC — нет дополнительных опций;
|
66 |
+
- BB — включён завтрак;
|
67 |
+
- HB — включён завтрак и обед;
|
68 |
+
- FB — включён завтрак, обед и ужин.
|
69 |
+
- previous_bookings_not_canceled — количество подтверждённых заказов у клиента;
|
70 |
+
- previous_cancellations — количество отменённых заказов у клиента;
|
71 |
+
- required_car_parking_spaces — необходимость места для автомобиля;
|
72 |
+
- reserved_room_type — тип забронированной комнаты;
|
73 |
+
- stays_in_weekend_nights — количество ночей в выходные дни;
|
74 |
+
- stays_in_week_nights — количество ночей в будние дни;
|
75 |
+
- total_nights — общее количество ночей;
|
76 |
+
- total_of_special_requests — количество специальных отметок.
|
77 |
+
"""
|
78 |
+
)
|
79 |
+
|
80 |
+
st.sidebar.header("Признаки для модели машинного обучения")
|
81 |
+
|
82 |
+
def changes(df):
|
83 |
+
pass
|
84 |
+
|
85 |
+
def user_input_features():
|
86 |
+
meal = st.sidebar.selectbox('опции заказа', ('BB', 'FB', 'HB', 'SC'))
|
87 |
+
country = st.sidebar.selectbox('гражданство постояльца', ('GBR', 'PRT', 'ESP', 'IRL', 'FRA', 'Others', 'USA', 'DEU', 'BEL', 'CHE', 'NLD', 'ITA', 'BRA', 'AUT'))
|
88 |
+
distribution_channel = st.sidebar.selectbox('канал дистрибуции заказа', ('Direct', 'TA/TO', 'Corporate', 'GDS'))
|
89 |
+
reserved_room_type = st.sidebar.selectbox('тип забронированной комнаты', ('A', 'C', 'D', 'E', 'G', 'F', 'B'))
|
90 |
+
customer_type = st.sidebar.selectbox('тип заказчика', ('Transient', 'Contract', 'Transient-Party', 'Group'))
|
91 |
+
adults = st.sidebar.slider('количество взрослых постояльцев', 0, 6, 2)
|
92 |
+
children = st.sidebar.slider('количество детей от 3 до 14 лет', 0, 5, 2)
|
93 |
+
babies = st.sidebar.slider('количество младенцев', 0, 1, 5)
|
94 |
+
days_in_waiting_list = st.sidebar.slider('сколько дней заказ ожидал подтверждения', 0, 250, 0)
|
95 |
+
previous_cancellations = st.sidebar.slider('количество отменённых заказов у клиента', 0, 30, 0)
|
96 |
+
data_lead = st.sidebar.date_input("день бронирования", datetime.date(2019, 7, 6))
|
97 |
+
end_time = st.sidebar.date_input("день заезда", datetime.date(2019, 7, 20))
|
98 |
+
count_day = st.sidebar.slider('Количество дней проживания', 0, 31, 0)
|
99 |
+
data_back = end_time + datetime.timedelta(days=count_day)
|
100 |
+
lead_time = (end_time-data_lead).days
|
101 |
+
total_of_special_requests = st.sidebar.slider('количество специальных отметок', 0, 8, 0)
|
102 |
+
arrival_date_day_of_month = end_time.day
|
103 |
+
arrival_date_year = end_time.year
|
104 |
+
arrival_date_month = end_time.month
|
105 |
+
arrival_date_week_number = end_time.isocalendar()[1]
|
106 |
+
|
107 |
+
stays_in_weekend_nights = 0
|
108 |
+
stays_in_week_nights = 0
|
109 |
+
total_nights = stays_in_weekend_nights + stays_in_week_nights
|
110 |
+
current_date = end_time
|
111 |
+
while current_date < data_back:
|
112 |
+
if current_date.weekday() < 5: # Понедельник (0) - Пятница (4)
|
113 |
+
stays_in_week_nights += 1
|
114 |
+
else:
|
115 |
+
stays_in_weekend_nights += 1
|
116 |
+
current_date += datetime.timedelta(days=1)
|
117 |
+
|
118 |
+
is_repeated_guest = st.sidebar.selectbox('признак того, что гость бронирует номер второй раз', ('Yes', 'No'))
|
119 |
+
previous_bookings_not_canceled = st.sidebar.slider('количество подтверждённых заказов у клиента', 0, 60, 0)
|
120 |
+
required_car_parking_spaces = st.sidebar.selectbox('необходимость места для автомобиля', ('Yes', 'No'))
|
121 |
+
booking_changes = st.sidebar.slider('количество измененных вами параметров', 0, 10, 0)
|
122 |
+
|
123 |
+
|
124 |
+
|
125 |
+
data = {'meal': meal,
|
126 |
+
'country': country,
|
127 |
+
'distribution_channel': distribution_channel,
|
128 |
+
'reserved_room_type': reserved_room_type,
|
129 |
+
'customer_type': customer_type,
|
130 |
+
'lead_time': lead_time,
|
131 |
+
'adults': adults,
|
132 |
+
'children': children,
|
133 |
+
'booking_changes': booking_changes,
|
134 |
+
'babies': babies,
|
135 |
+
'days_in_waiting_list': days_in_waiting_list,
|
136 |
+
'previous_cancellations': previous_cancellations,
|
137 |
+
'total_nights': total_nights,
|
138 |
+
'total_of_special_requests': total_of_special_requests,
|
139 |
+
'arrival_date_day_of_month': arrival_date_day_of_month,
|
140 |
+
'arrival_date_year': arrival_date_year,
|
141 |
+
'arrival_date_month': arrival_date_month,
|
142 |
+
'arrival_date_week_number': arrival_date_week_number,
|
143 |
+
'stays_in_weekend_nights': stays_in_weekend_nights,
|
144 |
+
'stays_in_week_nights': stays_in_week_nights,
|
145 |
+
'is_repeated_guest': is_repeated_guest,
|
146 |
+
'previous_bookings_not_canceled': previous_bookings_not_canceled,
|
147 |
+
'required_car_parking_spaces': required_car_parking_spaces,
|
148 |
+
}
|
149 |
+
features = pd.DataFrame(data, index=[0])
|
150 |
+
return features
|
151 |
+
|
152 |
+
df = user_input_features()
|
153 |
+
df = df.sort_index(axis=1)
|
154 |
+
|
155 |
+
st.subheader('Таблица с введенными вами параметрами:')
|
156 |
+
# st.write(df)
|
157 |
+
|
158 |
+
def pre_category(data):
|
159 |
+
if data == "Yes":
|
160 |
+
return 1
|
161 |
+
else:
|
162 |
+
return 0
|
163 |
+
|
164 |
+
def preprocessing_data(df, scaler, ohe):
|
165 |
+
df['is_repeated_guest'] = df['is_repeated_guest'].apply(pre_category)
|
166 |
+
df['required_car_parking_spaces'] = df['required_car_parking_spaces'].apply(pre_category)
|
167 |
+
numeric = ['adults', 'children', 'booking_changes', 'babies', 'days_in_waiting_list', 'previous_cancellations', 'lead_time',
|
168 |
+
'total_nights', 'total_of_special_requests', 'arrival_date_day_of_month', 'arrival_date_year', 'arrival_date_month',
|
169 |
+
'arrival_date_week_number', 'stays_in_weekend_nights', 'stays_in_week_nights', 'is_repeated_guest', 'previous_bookings_not_canceled',
|
170 |
+
'required_car_parking_spaces', 'booking_changes']
|
171 |
+
categorical = ['meal', 'country', 'distribution_channel', 'reserved_room_type', 'customer_type']
|
172 |
+
df[numeric] = scaler.transform(df[numeric])
|
173 |
+
tmp = pd.DataFrame(ohe.transform(df[categorical]).toarray(),
|
174 |
+
columns=ohe.get_feature_names_out(),
|
175 |
+
index=df.index)
|
176 |
+
df.drop(categorical, axis=1, inplace=True)
|
177 |
+
df = df.join(tmp).sort_index(axis=1)
|
178 |
+
|
179 |
+
|
180 |
+
return pd.DataFrame(df, index=[0])
|
181 |
+
|
182 |
+
@st.cache_resource
|
183 |
+
def get_model():
|
184 |
+
load_model = pickle.load(open('models/booking_cancel_pred.pkl', 'rb'))
|
185 |
+
ohe_model = pickle.load(open('models/ohe_booking_cancel_pred.pkl', 'rb'))
|
186 |
+
scaler_model = pickle.load(open('models/scaler_booking_cancel_pred.pkl', 'rb'))
|
187 |
+
return load_model, scaler_model, ohe_model
|
188 |
+
|
189 |
+
model, sc_model, ohe_model = get_model()
|
190 |
+
|
191 |
+
df_new = preprocessing_data(df, sc_model, ohe_model)
|
192 |
+
# st.write(df_new)
|
193 |
+
prediction = model.predict(df_new)
|
194 |
+
prediction_proba = model.predict_proba(df_new)
|
195 |
+
|
196 |
+
|
197 |
+
st.subheader('Рекомендация')
|
198 |
+
exited = np.array(['Клиент вероятно оставит бронь','Клиент вероятно отменит бронь'])
|
199 |
+
st.write(exited[prediction])
|
200 |
+
|
201 |
+
st.subheader('Вероятность рекомендации')
|
202 |
+
st.write(prediction_proba)
|
pages/4_toxic_comments.py
ADDED
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import pickle
|
4 |
+
import transformers as tfs
|
5 |
+
from catboost import CatBoostClassifier
|
6 |
+
from sklearn.linear_model import LogisticRegression
|
7 |
+
import numpy as np
|
8 |
+
import torch as t
|
9 |
+
from transformers import AutoTokenizer, AutoModelForSequenceClassification
|
10 |
+
|
11 |
+
st.set_page_config(page_title="# Выявление негативных комментариев с BERT")
|
12 |
+
|
13 |
+
st.markdown('# Выявление негативных комментариев с BERT')
|
14 |
+
|
15 |
+
with st.expander("Описание проекта"):
|
16 |
+
st.write("""
|
17 |
+
Интернет-магазин «Викишоп» запускает новый сервис.
|
18 |
+
Теперь пользователи могут редактировать и дополнять описания товаров, как в вики-сообществах.
|
19 |
+
То есть клиенты предлагают свои правки и комментируют изменения других.
|
20 |
+
Магазину нужен инструмент, который будет искать токсичные комментарии и отправлять их на модерацию.
|
21 |
+
""")
|
22 |
+
|
23 |
+
|
24 |
+
def detect_language(text):
|
25 |
+
first_letter = text[0].lower()
|
26 |
+
if 'а' <= first_letter <= 'я':
|
27 |
+
return 'ru'
|
28 |
+
|
29 |
+
|
30 |
+
def ru_bert_comments(text):
|
31 |
+
|
32 |
+
model_checkpoint = 'cointegrated/rubert-tiny-toxicity'
|
33 |
+
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)
|
34 |
+
model = AutoModelForSequenceClassification.from_pretrained(model_checkpoint)
|
35 |
+
if t.cuda.is_available():
|
36 |
+
model.cuda()
|
37 |
+
|
38 |
+
def text2toxicity(text, aggregate=True):
|
39 |
+
""" Calculate toxicity of a text (if aggregate=True) or a vector of toxicity aspects (if aggregate=False)"""
|
40 |
+
with t.no_grad():
|
41 |
+
inputs = tokenizer(text, return_tensors='pt', truncation=True, padding=True).to(model.device)
|
42 |
+
proba = t.sigmoid(model(**inputs).logits).cpu().numpy()
|
43 |
+
if isinstance(text, str):
|
44 |
+
proba = proba[0]
|
45 |
+
if aggregate:
|
46 |
+
return 1 - proba.T[0] * (1 - proba.T[-1])
|
47 |
+
return proba
|
48 |
+
|
49 |
+
return round(text2toxicity(text, True))
|
50 |
+
|
51 |
+
def preprocessing(text):
|
52 |
+
lang = detect_language(text)
|
53 |
+
if lang == "ru":
|
54 |
+
return ru_bert_comments(str(text))
|
55 |
+
else:
|
56 |
+
tokenizer = tfs.AutoTokenizer.from_pretrained('unitary/toxic-bert')
|
57 |
+
model = tfs.AutoModel.from_pretrained('unitary/toxic-bert')
|
58 |
+
tokenized = tokenizer.encode(text, add_special_tokens=True)
|
59 |
+
|
60 |
+
if len(tokenized) > 512:
|
61 |
+
truncated_tokens = tokenized[:510]
|
62 |
+
truncated_tokens = [101] + truncated_tokens + [102]
|
63 |
+
tokenized = truncated_tokens
|
64 |
+
|
65 |
+
padded = np.array(tokenized + [0] * (512 - len(tokenized)))
|
66 |
+
attention_mask = np.where(padded != 0, 1, 0)
|
67 |
+
input_ids = t.tensor(padded)
|
68 |
+
attention_mask = t.tensor(attention_mask)
|
69 |
+
|
70 |
+
with t.no_grad():
|
71 |
+
embeddings = model(input_ids.unsqueeze(0), attention_mask=attention_mask.unsqueeze(0))[0][:, 0, :].cpu().numpy()
|
72 |
+
|
73 |
+
return embeddings
|
74 |
+
|
75 |
+
def query(features):
|
76 |
+
model = pickle.load(open('models/toxic_comments_bert.pkl', 'rb'))
|
77 |
+
predict = model.predict(features)
|
78 |
+
return predict
|
79 |
+
|
80 |
+
comment = st.text_area("Введите ваш комментарий, модель работает на английском и русском языках и нажмите Ctrl+Enter", "")
|
81 |
+
result = None
|
82 |
+
|
83 |
+
if comment:
|
84 |
+
st.markdown('## Результат:')
|
85 |
+
embeddings = preprocessing(comment)
|
86 |
+
if isinstance(embeddings, int):
|
87 |
+
if embeddings == 0:
|
88 |
+
result = 'Комментарий не токсичный'
|
89 |
+
else:
|
90 |
+
result = 'Комментарий является токсичным'
|
91 |
+
else:
|
92 |
+
if query(embeddings) == 0:
|
93 |
+
result = 'Комментарий не токсичный'
|
94 |
+
else:
|
95 |
+
result = 'Комментарий является токсичным'
|
96 |
+
|
97 |
+
if result is not None:
|
98 |
+
st.write(result)
|
99 |
+
|
100 |
+
|
101 |
+
|
102 |
+
|
103 |
+
|
104 |
+
|
105 |
+
|
106 |
+
|
pages/5_star_temperature.py
ADDED
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
import pickle
|
5 |
+
import torch
|
6 |
+
import torch.nn as nn
|
7 |
+
from torch.utils.data import Dataset, DataLoader
|
8 |
+
from math import ceil
|
9 |
+
from sklearn.metrics import mean_squared_error
|
10 |
+
from sklearn.model_selection import train_test_split
|
11 |
+
from sklearn.preprocessing import StandardScaler, OneHotEncoder
|
12 |
+
from sklearn.compose import ColumnTransformer
|
13 |
+
|
14 |
+
st.set_page_config(page_title="# Прогнозирование температуры звезды")
|
15 |
+
|
16 |
+
st.markdown('# Прогнозирование температуры звезды')
|
17 |
+
|
18 |
+
with st.expander("Описание проекта"):
|
19 |
+
st.write("""
|
20 |
+
Вам пришла задача от обсерватории «Небо на ладони»: придумать, как с помощью нейросети определять температуру на поверхности обнаруженных звёзд. Обычно для расчёта температуры учёные пользуются следующими методами:
|
21 |
+
- Закон смещения Вина.
|
22 |
+
- Закон Стефана-Больцмана.
|
23 |
+
- Спектральный анализ.
|
24 |
+
|
25 |
+
Каждый из них имеет плюсы и минусы. Обсерватория хочет внедрить технологии машинного обучения для предсказания температуры звёзд, надеясь, что этот метод будет наиболее точным и удобным.
|
26 |
+
В базе обсерватории есть характеристики уже изученных 240 звёзд.
|
27 |
+
**Характеристики**
|
28 |
+
- Относительная светимость L/Lo — светимость звезды относительно Солнца.
|
29 |
+
- Относительный радиус R/Ro — радиус звезды относительно радиуса Солнца.
|
30 |
+
- Абсолютная звёздная величина Mv — физическая величина, характеризующая блеск звезды.
|
31 |
+
- Звёздный цвет (white, red, blue, yellow, yellow-orange и др.) — цвет звезды, который определяют на основе спектрального анализа.
|
32 |
+
- Тип звезды.
|
33 |
+
- 0 - Коричневый карлик
|
34 |
+
- 1 - Красный карлик
|
35 |
+
- 2 - Белый карлик
|
36 |
+
- 3 - Звёзды главной последовательности
|
37 |
+
- 4 - Сверхгигант
|
38 |
+
- 5 - Гипергигант
|
39 |
+
|
40 |
+
- Абсолютная температура T(K) — температура на поверхности звезды в Кельвинах.
|
41 |
+
|
42 |
+
В этом самостоятельном проекте вам необходимо разработать нейронную сеть, которая поможет предсказывать абсолютную температуру на поверхности звезды.
|
43 |
+
Справочная информация:
|
44 |
+
Светимость Солнца (англ. Average Luminosity of Sun)
|
45 |
+
$L_0 = 3.828 \cdot 10^{26}\,Вт$
|
46 |
+
|
47 |
+
Радиус Солнца (англ. Average Radius of Sun)
|
48 |
+
$R_0 = 6.9551\cdot 10^8\,м$
|
49 |
+
""")
|
50 |
+
|
51 |
+
|
52 |
+
st.sidebar.header("Признаки для модели машинного обучения")
|
53 |
+
|
54 |
+
def star_type_cat(type_star):
|
55 |
+
type_dict = {'Коричневый карлик':0,
|
56 |
+
'Красный карлик':1,
|
57 |
+
'Белый карлик':2,
|
58 |
+
'Звёзды главной последовательности':3,
|
59 |
+
'Сверхгигант':4,
|
60 |
+
'Гипергигант':5
|
61 |
+
}
|
62 |
+
return type_dict[type_star]
|
63 |
+
|
64 |
+
def user_input_features():
|
65 |
+
star_color = st.sidebar.selectbox('цвет звезды, который определяют на основе спектрального анализа', ('red', 'blue', 'white', 'blue-white', 'orange', 'yellow-white', 'whitish'))
|
66 |
+
luminosity = st.sidebar.slider('светимость звезды относительно Солнца', 0.00008, 900000.0, 2000.0)
|
67 |
+
radius = st.sidebar.slider('радиус звезды относительно радиуса Солнца', 0.007, 2000.0, 200.0)
|
68 |
+
abs_magnitude = st.sidebar.slider('физическая величина, характеризующая блеск звезды', -12.0, 25.0, 10.0)
|
69 |
+
star_type = st.sidebar.selectbox('цвет звезды, который определяют на основе спектрального анализа', ('Коричневый карлик', 'Красный карлик', 'Белый карлик', 'Звёзды главной последовательности',
|
70 |
+
'Сверхгигант', 'Гипергигант'))
|
71 |
+
|
72 |
+
data = {'luminosity': luminosity,
|
73 |
+
'radius':radius,
|
74 |
+
'abs_magnitude':abs_magnitude,
|
75 |
+
'star_color':star_color,
|
76 |
+
'star_type':star_type
|
77 |
+
}
|
78 |
+
features = pd.DataFrame(data, index=[0])
|
79 |
+
return features
|
80 |
+
|
81 |
+
df = user_input_features()
|
82 |
+
df = df.sort_index(axis=1)
|
83 |
+
|
84 |
+
st.subheader('Таблица с введенными вами параметрами:')
|
85 |
+
st.write(df)
|
86 |
+
|
87 |
+
def preprocessing_data(df, scaler, ohe):
|
88 |
+
df['star_type']=df['star_type'].apply(star_type_cat)
|
89 |
+
numeric = ['luminosity', 'radius', 'abs_magnitude']
|
90 |
+
categorial = ['star_color', 'star_type']
|
91 |
+
df[numeric] = scaler.transform(df[numeric])
|
92 |
+
tmp = pd.DataFrame(ohe.transform(df[categorial]).toarray(),
|
93 |
+
columns=ohe.get_feature_names_out(),
|
94 |
+
index=df.index)
|
95 |
+
df.drop(categorial, axis=1, inplace=True)
|
96 |
+
df = df.join(tmp).sort_index(axis=1)
|
97 |
+
df = torch.FloatTensor(df.values)
|
98 |
+
return df
|
99 |
+
|
100 |
+
class Net(nn.Module):
|
101 |
+
def __init__(self, input_size, hidden_size1, hidden_size2, num_classes):
|
102 |
+
super(Net, self).__init__()
|
103 |
+
|
104 |
+
self.fc1 = nn.Linear(input_size, hidden_size1)
|
105 |
+
self.act1 = nn.Tanh()
|
106 |
+
|
107 |
+
self.fc2 = nn.Linear(hidden_size1, hidden_size2)
|
108 |
+
self.act2 = nn.ReLU()
|
109 |
+
|
110 |
+
self.fc3 = nn.Linear(hidden_size2, num_classes)
|
111 |
+
|
112 |
+
|
113 |
+
|
114 |
+
def forward(self, x):
|
115 |
+
out = self.fc1(x)
|
116 |
+
out = self.act1(out)
|
117 |
+
|
118 |
+
out = self.fc2(out)
|
119 |
+
out = self.act2(out)
|
120 |
+
|
121 |
+
out = self.fc3(out)
|
122 |
+
|
123 |
+
return out
|
124 |
+
|
125 |
+
|
126 |
+
def get_model_pre():
|
127 |
+
ohe_model = pickle.load(open('models/ohe_star_temperature_pred.pkl', 'rb'))
|
128 |
+
scaler_model = pickle.load(open('models/scaler_star_temperature_pred.pkl', 'rb'))
|
129 |
+
return scaler_model, ohe_model
|
130 |
+
|
131 |
+
def get_model():
|
132 |
+
net = Net(df_new.shape[1], 700, 850, 1)
|
133 |
+
net.load_state_dict(torch.load('models/star_temperature_pred.pkl'))
|
134 |
+
net.eval()
|
135 |
+
prediction = net.forward(df_new).detach().numpy()[0][0]
|
136 |
+
|
137 |
+
return prediction
|
138 |
+
|
139 |
+
sc_model, ohe_model = get_model_pre()
|
140 |
+
df_new = preprocessing_data(df, sc_model, ohe_model)
|
141 |
+
|
142 |
+
model_pred = get_model()
|
143 |
+
|
144 |
+
st.subheader('Температура звезды:')
|
145 |
+
st.write(str(model_pred) + ' K')
|
146 |
+
|
147 |
+
|
pages/6_sql_stackoverflow.py
ADDED
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
from sqlalchemy import create_engine
|
4 |
+
from PIL import Image
|
5 |
+
|
6 |
+
st.set_page_config(page_title="# Анализ данных StackOverflow")
|
7 |
+
|
8 |
+
st.markdown('# Анализ данных StackOverflow')
|
9 |
+
|
10 |
+
with st.expander("Описание проекта"):
|
11 |
+
st.write("""
|
12 |
+
Вы будете работать с базой данных StackOverflow — сервиса вопросов и ответов о программировании.
|
13 |
+
StackOverflow похож на социальную сеть — пользователи сервиса задают вопросы, отвечают на посты, оставляют комментарии и ставят оценки другим ответам.
|
14 |
+
Вы будете работать с версией базы, где хранятся данные о постах за 2008 год, но в таблицах вы найдёте информацию и о более поздних оценках, которые эти посты получили.
|
15 |
+
|
16 |
+
Описание данных:
|
17 |
+
|
18 |
+
- Таблица badges:
|
19 |
+
Хранит информацию о значках, которые присуждаются за разные достижения. Например, пользователь, правильно ответивший на большое количество вопросов про PostgreSQL, может получить значок postgresql.
|
20 |
+
- id Идентификатор значка, первичный ключ таблицы
|
21 |
+
- name Название значка
|
22 |
+
- user_id Идентификатор пользователя, которому присвоили значок, внешний ключ, отсылающий к таблице users
|
23 |
+
- creation_date Дата присвоения значка
|
24 |
+
|
25 |
+
- Таблица post_types:
|
26 |
+
Содержит информацию о типе постов. Их может быть два:
|
27 |
+
- Question — пост с вопросом;
|
28 |
+
- Answer — пост с ответом.
|
29 |
+
|
30 |
+
- id Идентификатор поста, первичный ключ таблицы
|
31 |
+
- type Тип поста
|
32 |
+
- Таблица posts:
|
33 |
+
Содержит информацию о постах.
|
34 |
+
|
35 |
+
- id Идентификатор поста, первичный ключ таблицы
|
36 |
+
- title Заголовок поста
|
37 |
+
- creation_date Дата создания поста
|
38 |
+
- favorites_count Число, которое показывает, сколько раз пост добавили в «Закладки»
|
39 |
+
- last_activity_date Дата последнего действия в посте, например комментария
|
40 |
+
- last_edit_date Дата последнего изменения поста
|
41 |
+
- user_id Идентификатор пользователя, который создал пост, внешний ключ к таблице users
|
42 |
+
- parent_id Если пост написали в ответ на другую публикацию, в это поле попадёт идентификатор поста с вопросом
|
43 |
+
- post_type_id Идентификатор типа поста, внешний ключ к таблице post_types
|
44 |
+
- score Количество очков, которое набрал пост
|
45 |
+
- views_count Количество просмотров
|
46 |
+
- Таблица users:
|
47 |
+
Содержит информацию о пользователях.
|
48 |
+
|
49 |
+
- id Идентификатор пользователя, первичный ключ таблицы
|
50 |
+
- creation_date Дата регистрации пользователя
|
51 |
+
- display_name Имя пользователя
|
52 |
+
- last_access_date Дата последнего входа
|
53 |
+
- location Местоположение
|
54 |
+
- reputation Очки репутации, которые получают за хорошие вопросы и полезные ответы
|
55 |
+
- views Число просмотров профиля пользователя
|
56 |
+
- Таблица vote_types:
|
57 |
+
Содержит информацию о типах голосов. Голос — это метка, которую пользователи ставят посту. Типов бывает несколько:
|
58 |
+
- UpMod — такую отметку получают посты с вопросами или ответами, которые пользователи посчитали уместными и полезными.
|
59 |
+
- DownMod — такую отметку получают посты, которые показались пользователям наименее полезными.
|
60 |
+
- Close — такую метку ставят опытные пользователи сервиса, если заданный вопрос нужно доработать или он вообще не подходит для платформы.
|
61 |
+
- Offensive — такую метку могут поставить, если пользователь ответил на вопрос в грубой и оскорбительной манере, например, указав на неопытность автора поста.
|
62 |
+
- Spam — такую метку ставят в случае, если пост пользователя выглядит откровенной рекламой.
|
63 |
+
|
64 |
+
- id Идентификатор типа голоса, первичный ключ
|
65 |
+
- name Название метки
|
66 |
+
- Таблица votes:
|
67 |
+
Содержит информацию о голосах за посты.
|
68 |
+
- id Идентификатор голоса, первичный ключ
|
69 |
+
- post_id Идентификатор поста, внешний ключ к таблице posts
|
70 |
+
- user_id Идентификатор пользователя, который поставил посту голос, внешний ключ к таблице users
|
71 |
+
- bounty_amount Сумма вознаграждения, которое назначают, чтобы привлечь внимание к посту
|
72 |
+
- vote_type_id Идентификатор типа голоса, внешний ключ к таблице vote_types
|
73 |
+
- creation_date Дата назначения голоса
|
74 |
+
""")
|
75 |
+
|
76 |
+
|
77 |
+
|
78 |
+
db_config = {
|
79 |
+
'user': 'praktikum_student', # имя пользователя
|
80 |
+
'pwd': 'Sdf4$2;d-d30pp', # пароль
|
81 |
+
'host': 'rc1b-wcoijxj3yxfsf3fs.mdb.yandexcloud.net',
|
82 |
+
'port': 6432, # порт подключения
|
83 |
+
'db': 'data-analyst-advanced-sql' # название базы данных
|
84 |
+
}
|
85 |
+
|
86 |
+
connection_string = 'postgresql://{}:{}@{}:{}/{}'.format(
|
87 |
+
db_config['user'],
|
88 |
+
db_config['pwd'],
|
89 |
+
db_config['host'],
|
90 |
+
db_config['port'],
|
91 |
+
db_config['db'],
|
92 |
+
)
|
93 |
+
engine = create_engine(connection_string)
|
94 |
+
|
95 |
+
def query_db(query):
|
96 |
+
return pd.read_sql_query(query, con=engine)
|
97 |
+
|
98 |
+
query_1 = '''SELECT date_trunc('month', creation_date) as month_date, sum(views_count) as total_views
|
99 |
+
FROM stackoverflow.posts
|
100 |
+
WHERE extract( YEAR from creation_date) = '2008'
|
101 |
+
GROUP BY month_date
|
102 |
+
ORDER BY total_views DESC
|
103 |
+
'''
|
104 |
+
query_2 = '''SELECT u.display_name, count(DISTINCT p.user_id)
|
105 |
+
FROM stackoverflow.users as u
|
106 |
+
JOIN stackoverflow.posts as p ON p.user_id = u.id
|
107 |
+
JOIN stackoverflow.post_types as pt ON pt.id = p.post_type_id
|
108 |
+
WHERE pt.type = 'Answer' AND
|
109 |
+
p.creation_date::date BETWEEN u.creation_date AND (u.creation_date::date + INTERVAL '1 month')
|
110 |
+
GROUP BY u.display_name
|
111 |
+
HAVING count(p.user_id)>100
|
112 |
+
ORDER BY u.display_name
|
113 |
+
'''
|
114 |
+
query_3 = '''WITH dt as (SELECT u.id
|
115 |
+
FROM stackoverflow.posts as p
|
116 |
+
JOIN stackoverflow.users as u ON p.user_id = u.id
|
117 |
+
WHERE DATE_TRUNC('month', u.creation_date) = '2008-09-01' AND
|
118 |
+
DATE_TRUNC('month', p.creation_date) = '2008-12-01')
|
119 |
+
SELECT date_trunc('month', p.creation_date)::date as month, count(p.id)
|
120 |
+
FROM stackoverflow.posts as p
|
121 |
+
WHERE p.user_id in (SELECT * FROM dt) AND
|
122 |
+
EXTRACT(YEAR FROM p.creation_date) = '2008'
|
123 |
+
GROUP BY month
|
124 |
+
ORDER BY month DESC
|
125 |
+
'''
|
126 |
+
query_4 = '''SELECT user_id, AVG(avg_daily)
|
127 |
+
FROM (SELECT DISTINCT user_id, date_trunc('day', creation_date)::date as t,
|
128 |
+
count(id) OVER (PARTITION BY user_id, date_trunc('day', creation_date)::date) as avg_daily,
|
129 |
+
count(id) OVER (PARTITION BY user_id, date_trunc('month', creation_date)::date) as cnt
|
130 |
+
FROM stackoverflow.posts
|
131 |
+
WHERE date_trunc('month', creation_date)::date = '2008-08-01') as dt
|
132 |
+
WHERE cnt>120
|
133 |
+
GROUP BY user_id
|
134 |
+
ORDER BY AVG(avg_daily)
|
135 |
+
'''
|
136 |
+
|
137 |
+
examples = {'Выводит общую сумму просмотров постов за каждый месяц 2008 года':query_1,
|
138 |
+
'Выводит имена самых активных пользователей, которые в первый месяц после регистрации (включая день регистрации) дали больше 100 ответов':query_2,
|
139 |
+
'Выводит количество постов за 2008 год по месяцам. Отбирает посты от пользователей, которые зарегистрировались в сентябре 2008 года и сделали хотя бы один пост в декабре того же года.':query_3,
|
140 |
+
'Найдет среднее количество постов пользователей в день за август 2008 года. Отберет данные о пользователях, которые опубликовали больше 120 постов за август. Дни без публикаций не учитывает.':query_4,
|
141 |
+
}
|
142 |
+
with st.expander("Схема быза данных"):
|
143 |
+
image = Image.open('image/Frame.png')
|
144 |
+
st.image(image)
|
145 |
+
|
146 |
+
with st.expander("Примеры SQL запросов"):
|
147 |
+
|
148 |
+
query = st.selectbox('Выберете один из запросов:', ('Выводит общую сумму просмотров постов за каждый месяц 2008 года',
|
149 |
+
'Выводит имена самых активных пользователей, которые в первый месяц после регистрации (включая день регистрации) дали больше 100 ответов',
|
150 |
+
'Выводит количество постов за 2008 год по месяцам. Отбирает посты от пользователей, которые зарегистрировались в сентябре 2008 года и сделали хотя бы один пост в декабре того же года.',
|
151 |
+
'Найдет среднее количество постов пользователей в день за август 2008 года. Отберет данные о пользователях, которые опубликовали больше 120 постов за август. Дни без публикаций не учитывает.',
|
152 |
+
))
|
153 |
+
|
154 |
+
st.code(examples[query], language="sql", line_numbers=False)
|
155 |
+
if st.button("Запуск запроса"):
|
156 |
+
st.markdown('## Результат запроса:')
|
157 |
+
st.write(query_db(examples[query]))
|
158 |
+
|
159 |
+
|
160 |
+
|
161 |
+
def submit():
|
162 |
+
st.session_state.title = st.session_state.widget
|
163 |
+
st.session_state.widget = ""
|
164 |
+
|
165 |
+
st.text_input("Введите ваш SQL запрос", key="widget", on_change=submit)
|
166 |
+
|
167 |
+
if 'title' not in st.session_state:
|
168 |
+
st.session_state.title = ""
|
169 |
+
|
170 |
+
title = st.session_state.title
|
171 |
+
|
172 |
+
|
173 |
+
|
174 |
+
# st.write(title)
|
175 |
+
# title = st.text_input('Введите ваш SQL запрос')
|
176 |
+
|
177 |
+
if title:
|
178 |
+
st.markdown('## Ваш запрос:')
|
179 |
+
st.code(title, language="sql", line_numbers=False)
|
180 |
+
st.markdown('## Результат запроса:')
|
181 |
+
try:
|
182 |
+
st.write(query_db(title))
|
183 |
+
except:
|
184 |
+
'Запрос неверен, убедитесь в правильности запроса'
|
185 |
+
|
186 |
+
|
187 |
+
|
188 |
+
|
189 |
+
|
190 |
+
|
191 |
+
|
pages/7_car_cost_pred.py
ADDED
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
import pickle
|
5 |
+
from catboost import CatBoostRegressor
|
6 |
+
from sklearn.preprocessing import StandardScaler, OneHotEncoder
|
7 |
+
import datetime
|
8 |
+
|
9 |
+
st.set_page_config(page_title="# Определение стоимости автомобилей")
|
10 |
+
|
11 |
+
st.markdown('# Определение стоимости автомобилей')
|
12 |
+
|
13 |
+
with st.expander("Описание проекта"):
|
14 |
+
st.write(
|
15 |
+
"""Сервис по продаже автомобилей с пробегом «Не бит, не крашен» разрабатывает приложение для привлечения новых клиентов. В нём можно быстро узнать рыночную стоимость своего автомобиля.
|
16 |
+
В вашем распоряжении исторические данные: технические характеристики, комплектации и цены автомобилей. Вам нужно построить модель для определения стоимости.
|
17 |
+
|
18 |
+
Описание данных:
|
19 |
+
|
20 |
+
- DateCrawled — дата скачивания анкеты из базы
|
21 |
+
- VehicleType — тип автомобильного кузова
|
22 |
+
- RegistrationYear — год регистрации автомобиля
|
23 |
+
- Gearbox — тип коробки передач
|
24 |
+
- Power — мощность (л. с.)
|
25 |
+
- Model — модель автомобиля
|
26 |
+
- Kilometer — пробег (км)
|
27 |
+
- RegistrationMonth — месяц регистрации автомобиля
|
28 |
+
- FuelType — тип топлива
|
29 |
+
- Brand — марка автомобиля
|
30 |
+
- Repaired — была машина в ремонте или нет
|
31 |
+
- DateCreated — дата создания анкеты
|
32 |
+
- NumberOfPictures — количество фотографий автомобиля
|
33 |
+
- PostalCode — почтовый индекс владельца анкеты (пользователя)
|
34 |
+
- LastSeen — дата последней активности пользователя
|
35 |
+
Целевой признак:
|
36 |
+
- Price — цена (евро)
|
37 |
+
"""
|
38 |
+
)
|
39 |
+
|
40 |
+
st.sidebar.header("Признаки для модели машинного обучения")
|
41 |
+
|
42 |
+
def changes(df):
|
43 |
+
pass
|
44 |
+
|
45 |
+
def user_input_features():
|
46 |
+
VehicleType = st.sidebar.selectbox('тип автомобильного кузова', ('suv', 'convertible', 'sedan', 'wagon', 'small', 'bus', 'coupe',
|
47 |
+
'unknown', 'other'))
|
48 |
+
RegistrationYear = st.sidebar.slider('год регистрации автомобиля', 1900, 2018, 2000)
|
49 |
+
Gearbox = st.sidebar.selectbox('тип коробки передач', ('manual', 'auto', 'unknown'))
|
50 |
+
Power = st.sidebar.slider('мощность (л. с.)', 1, 1000, 300)
|
51 |
+
Model = st.sidebar.selectbox('модель автомобиля', ('tiguan', 'fortwo', '3er', 'unknown', 'logan', 'mondeo', 'golf',
|
52 |
+
'astra', 'polo', 'omega', 'zafira', 'touran', 'other', 'c_klasse',
|
53 |
+
'cooper', '2_reihe', 'rav', 'clio', '601', '500', 'laguna', 'a4',
|
54 |
+
'civic', 'picanto', 'combo', 'boxster', 'stilo', 'ka', 'a3', 'eos',
|
55 |
+
'7er', 'passat', 'tt', 'focus', 'fiesta', 'twingo', 'panda',
|
56 |
+
'e_klasse', 'xc_reihe', 'carnival', 'kuga', 'a6', 'a_klasse',
|
57 |
+
'5er', 'caddy', '6_reihe', 'cc', 'm_klasse', 'vectra', 'mx_reihe',
|
58 |
+
'transit', 'insignia', 'corsa', 'discovery', 'bora', 'transporter',
|
59 |
+
'touareg', 'lupo', 'leon', 'galant', 'v50', 'vito', '1_reihe',
|
60 |
+
'colt', 'c5', 'cl', 'c4', 'v40', '3_reihe', 'sharan', 'slk',
|
61 |
+
'galaxy', 'z_reihe', 'kangoo', 'c_max', 'clk', 'escort',
|
62 |
+
'scirocco', 'avensis', 'ibiza', 'alhambra', 'octavia', 'megane',
|
63 |
+
'pajero', '1er', 'auris', 'arosa', 'roadster', 'jimny', 's_klasse',
|
64 |
+
'punto', 'ducato', 'agila', 'a1', 'x_reihe', 'meriva', 'i_reihe',
|
65 |
+
'seicento', 'berlingo', 'captiva', 'ceed', 'q5', '156', 'beetle',
|
66 |
+
'fabia', '147', 'citigo', '80', '900', 'phaeton', 'sandero',
|
67 |
+
'kalos', 'roomster', 'rx_reihe', '5_reihe', 'cordoba', 'forfour',
|
68 |
+
'qashqai', 'a8', 's_type', 'c3', 'micra', 'matiz', 'scenic',
|
69 |
+
'clubman', 'antara', '4_reihe', 'superb', 'santa', 'primera',
|
70 |
+
'b_klasse', 'tigra', 'yaris', 'modus', '159', 'carisma', 'cayenne',
|
71 |
+
'cuore', 'viano', 'x_trail', 'espace', 'exeo', 'yeti', 'fox',
|
72 |
+
'duster', 'spider', 'grand', 'mustang', 'c2', '100', 'vivaro',
|
73 |
+
'niva', 'corolla', 'r19', 'sorento', 'terios', 'swift', 'fusion',
|
74 |
+
'a5', 'x_type', 'cherokee', 'one', 'verso', 'rio', 'm_reihe',
|
75 |
+
'cr_reihe', 'altea', 'juke', 'v_klasse', 'toledo', 'jazz', 'v70',
|
76 |
+
'delta', 'outlander', 'signum', 'jetta', 'calibra', 's60', 'doblo',
|
77 |
+
'impreza', 'forester', '911', 'sportage', 'lybra', '850',
|
78 |
+
'sprinter', 'sl', 'c1', 'voyager', 'kadett', 'aveo', 'bravo',
|
79 |
+
'justy', 'almera', 'freelander', 'ptcruiser', 'tucson', 'aygo',
|
80 |
+
'kaefer', 'up', 's_max', 'getz', 'a2', 'cx_reihe', 'elefantino',
|
81 |
+
'90', 'lancer', 'q7', 'defender', 'ypsilon', 'c_reihe', 'accord',
|
82 |
+
'mii', 'nubira', 'glk', 'sirion', 'lanos', 'navara', '6er',
|
83 |
+
'croma', '300c', 'range_rover', 'g_klasse', 'range_rover_sport',
|
84 |
+
'note', 'spark', 'b_max', 'crossfire', 'move', 'kappa', '145',
|
85 |
+
'legacy', 'charade', 'musa', 'kalina', 'lodgy', 'serie_2', 'q3',
|
86 |
+
'samara', 'wrangler', 'materia', 'amarok', '9000', '200', 'i3',
|
87 |
+
'v60', 'gl', 'rangerover'))
|
88 |
+
Kilometer = st.sidebar.slider('пробег (км)', 1000, 150000, 30000)
|
89 |
+
FuelType = st.sidebar.selectbox('тип топлива', ('gasoline', 'petrol', 'unknown', 'electric', 'lpg', 'other', 'cng',
|
90 |
+
'hybrid'))
|
91 |
+
Brand = st.sidebar.selectbox('марка автомобиля', ('volkswagen', 'smart', 'bmw', 'dacia', 'ford', 'opel',
|
92 |
+
'mitsubishi', 'mercedes_benz', 'renault', 'mini', 'peugeot',
|
93 |
+
'toyota', 'citroen', 'trabant', 'fiat', 'audi', 'porsche', 'honda',
|
94 |
+
'kia', 'mazda', 'volvo', 'suzuki', 'land_rover', 'seat', 'hyundai',
|
95 |
+
'skoda', 'chevrolet', 'nissan', 'sonstige_autos', 'alfa_romeo',
|
96 |
+
'saab', 'rover', 'daewoo', 'chrysler', 'jaguar', 'daihatsu',
|
97 |
+
'lancia', 'jeep', 'lada', 'subaru'))
|
98 |
+
Repaired = st.sidebar.selectbox('была машина в ремонте или нет', ('no', 'unknown', 'yes'))
|
99 |
+
|
100 |
+
data = {'VehicleType': VehicleType,
|
101 |
+
'RegistrationYear': RegistrationYear,
|
102 |
+
'Gearbox': Gearbox,
|
103 |
+
'Power': Power,
|
104 |
+
'Model': Model,
|
105 |
+
'Kilometer': Kilometer,
|
106 |
+
'FuelType': FuelType,
|
107 |
+
'Brand': Brand,
|
108 |
+
'Repaired': Repaired
|
109 |
+
}
|
110 |
+
features = pd.DataFrame(data, index=[0])
|
111 |
+
return features
|
112 |
+
|
113 |
+
df = user_input_features()
|
114 |
+
df = df.sort_index(axis=1)
|
115 |
+
|
116 |
+
st.subheader('Таблица с введенными вами параметрами:')
|
117 |
+
st.write(df)
|
118 |
+
|
119 |
+
def preprocessing_data(df, scaler, ohe):
|
120 |
+
numeric = ['Power', 'Kilometer', 'RegistrationYear']
|
121 |
+
categorial = ['FuelType', 'Repaired', 'Gearbox', 'VehicleType', 'Brand', 'Model']
|
122 |
+
df[numeric] = scaler.transform(df[numeric])
|
123 |
+
tmp = pd.DataFrame(ohe.transform(df[categorial]).toarray(),
|
124 |
+
columns=ohe.get_feature_names_out(),
|
125 |
+
index=df.index)
|
126 |
+
df.drop(categorial, axis=1, inplace=True)
|
127 |
+
df = df.join(tmp).sort_index(axis=1)
|
128 |
+
|
129 |
+
|
130 |
+
return pd.DataFrame(df, index=[0])
|
131 |
+
|
132 |
+
@st.cache_resource
|
133 |
+
def get_model():
|
134 |
+
load_model = pickle.load(open('models/car_cost_pred.pkl', 'rb'))
|
135 |
+
ohe_model = pickle.load(open('models/ohe_car_cost_pred.pkl', 'rb'))
|
136 |
+
scaler_model = pickle.load(open('models/scaler_car_cost_pred.pkl', 'rb'))
|
137 |
+
return load_model, scaler_model, ohe_model
|
138 |
+
|
139 |
+
model, sc_model, ohe_model = get_model()
|
140 |
+
|
141 |
+
df_new = preprocessing_data(df, sc_model, ohe_model)
|
142 |
+
# st.write(df_new)
|
143 |
+
prediction = model.predict(df_new)
|
144 |
+
|
145 |
+
|
146 |
+
st.subheader('Рекомендованная стоимость')
|
147 |
+
rounded_prediction = np.around(prediction)
|
148 |
+
st.write(str(abs(rounded_prediction.item())) + ' евро')
|
pages/8_accident_prediction.py
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
import pickle
|
5 |
+
from sklearn.ensemble import RandomForestClassifier
|
6 |
+
from sklearn.preprocessing import StandardScaler, OneHotEncoder
|
7 |
+
import datetime
|
8 |
+
|
9 |
+
st.set_page_config(page_title="# Разработка модели для оценки ДТП по выбранному маршруту движения.")
|
10 |
+
|
11 |
+
st.markdown('# Разработка модели для оценки ДТП по выбранному маршруту движения.')
|
12 |
+
|
13 |
+
st.write(
|
14 |
+
"""Цель:
|
15 |
+
Нужно создать систему, которая могла бы оценить риск ДТП по выбранному маршруту движения.
|
16 |
+
Под риском понимается вероятность ДТП с любым повреждением транспортного средства.
|
17 |
+
Как только водитель забронировал автомобиль, сел за руль и выбрал маршрут, система должна оценить уровень риска.
|
18 |
+
Если уровень риска высок, водитель увидит предупреждение и рекомендации по маршруту.
|
19 |
+
|
20 |
+
"""
|
21 |
+
)
|
22 |
+
|
23 |
+
st.sidebar.header("Признаки для модели машинного обучения")
|
24 |
+
|
25 |
+
def changes(df):
|
26 |
+
pass
|
27 |
+
|
28 |
+
def user_input_features():
|
29 |
+
meal = st.sidebar.selectbox('опции заказа', ('BB', 'FB', 'HB', 'SC'))
|
30 |
+
country = st.sidebar.selectbox('гражданство постояльца', ('GBR', 'PRT', 'ESP', 'IRL', 'FRA', 'Others', 'USA', 'DEU', 'BEL', 'CHE', 'NLD', 'ITA', 'BRA', 'AUT'))
|
31 |
+
distribution_channel = st.sidebar.selectbox('канал дистрибуции заказа', ('Direct', 'TA/TO', 'Corporate', 'GDS'))
|
32 |
+
reserved_room_type = st.sidebar.selectbox('тип забронированной комнаты', ('A', 'C', 'D', 'E', 'G', 'F', 'B'))
|
33 |
+
customer_type = st.sidebar.selectbox('тип заказчика', ('Transient', 'Contract', 'Transient-Party', 'Group'))
|
34 |
+
adults = st.sidebar.slider('количество взрослых постояльцев', 0, 6, 2)
|
35 |
+
children = st.sidebar.slider('количество детей от 3 до 14 лет', 0, 5, 2)
|
36 |
+
babies = st.sidebar.slider('количество младенцев', 0, 1, 5)
|
37 |
+
days_in_waiting_list = st.sidebar.slider('сколько дней заказ ожидал подтверждения', 0, 250, 0)
|
38 |
+
previous_cancellations = st.sidebar.slider('количество отменённых заказов у клиента', 0, 30, 0)
|
39 |
+
data_lead = st.sidebar.date_input("день бронирования", datetime.date(2019, 7, 6))
|
40 |
+
end_time = st.sidebar.date_input("день заезда", datetime.date(2019, 7, 20))
|
41 |
+
count_day = st.sidebar.slider('Количество дней проживания', 0, 31, 0)
|
42 |
+
data_back = end_time + datetime.timedelta(days=count_day)
|
43 |
+
lead_time = (end_time-data_lead).days
|
44 |
+
total_of_special_requests = st.sidebar.slider('количество специальных отметок', 0, 8, 0)
|
45 |
+
arrival_date_day_of_month = end_time.day
|
46 |
+
arrival_date_year = end_time.year
|
47 |
+
arrival_date_month = end_time.month
|
48 |
+
arrival_date_week_number = end_time.isocalendar()[1]
|
49 |
+
|
50 |
+
stays_in_weekend_nights = 0
|
51 |
+
stays_in_week_nights = 0
|
52 |
+
total_nights = stays_in_weekend_nights + stays_in_week_nights
|
53 |
+
current_date = end_time
|
54 |
+
while current_date < data_back:
|
55 |
+
if current_date.weekday() < 5: # Понедельник (0) - Пятница (4)
|
56 |
+
stays_in_week_nights += 1
|
57 |
+
else:
|
58 |
+
stays_in_weekend_nights += 1
|
59 |
+
current_date += datetime.timedelta(days=1)
|
60 |
+
|
61 |
+
is_repeated_guest = st.sidebar.selectbox('признак того, что гость бронирует номер второй раз', ('Yes', 'No'))
|
62 |
+
previous_bookings_not_canceled = st.sidebar.slider('количество подтверждённых заказов у клиента', 0, 60, 0)
|
63 |
+
required_car_parking_spaces = st.sidebar.selectbox('необходимость места для автомобиля', ('Yes', 'No'))
|
64 |
+
booking_changes = st.sidebar.slider('количество измененных вами параметров', 0, 10, 0)
|
65 |
+
|
66 |
+
|
67 |
+
|
68 |
+
data = {'meal': meal,
|
69 |
+
'country': country,
|
70 |
+
'distribution_channel': distribution_channel,
|
71 |
+
'reserved_room_type': reserved_room_type,
|
72 |
+
'customer_type': customer_type,
|
73 |
+
'lead_time': lead_time,
|
74 |
+
'adults': adults,
|
75 |
+
'children': children,
|
76 |
+
'booking_changes': booking_changes,
|
77 |
+
'babies': babies,
|
78 |
+
'days_in_waiting_list': days_in_waiting_list,
|
79 |
+
'previous_cancellations': previous_cancellations,
|
80 |
+
'total_nights': total_nights,
|
81 |
+
'total_of_special_requests': total_of_special_requests,
|
82 |
+
'arrival_date_day_of_month': arrival_date_day_of_month,
|
83 |
+
'arrival_date_year': arrival_date_year,
|
84 |
+
'arrival_date_month': arrival_date_month,
|
85 |
+
'arrival_date_week_number': arrival_date_week_number,
|
86 |
+
'stays_in_weekend_nights': stays_in_weekend_nights,
|
87 |
+
'stays_in_week_nights': stays_in_week_nights,
|
88 |
+
'is_repeated_guest': is_repeated_guest,
|
89 |
+
'previous_bookings_not_canceled': previous_bookings_not_canceled,
|
90 |
+
'required_car_parking_spaces': required_car_parking_spaces,
|
91 |
+
}
|
92 |
+
features = pd.DataFrame(data, index=[0])
|
93 |
+
return features
|
94 |
+
|
95 |
+
df = user_input_features()
|
96 |
+
df = df.sort_index(axis=1)
|
97 |
+
|
98 |
+
st.subheader('Таблица с введенными вами параметрами:')
|
99 |
+
# st.write(df)
|
100 |
+
|
101 |
+
def pre_category(data):
|
102 |
+
if data == "Yes":
|
103 |
+
return 1
|
104 |
+
else:
|
105 |
+
return 0
|
106 |
+
|
107 |
+
def preprocessing_data(df, scaler, ohe):
|
108 |
+
df['is_repeated_guest'] = df['is_repeated_guest'].apply(pre_category)
|
109 |
+
df['required_car_parking_spaces'] = df['required_car_parking_spaces'].apply(pre_category)
|
110 |
+
numeric = ['adults', 'children', 'booking_changes', 'babies', 'days_in_waiting_list', 'previous_cancellations', 'lead_time',
|
111 |
+
'total_nights', 'total_of_special_requests', 'arrival_date_day_of_month', 'arrival_date_year', 'arrival_date_month',
|
112 |
+
'arrival_date_week_number', 'stays_in_weekend_nights', 'stays_in_week_nights', 'is_repeated_guest', 'previous_bookings_not_canceled',
|
113 |
+
'required_car_parking_spaces', 'booking_changes']
|
114 |
+
categorical = ['meal', 'country', 'distribution_channel', 'reserved_room_type', 'customer_type']
|
115 |
+
df[numeric] = scaler.transform(df[numeric])
|
116 |
+
tmp = pd.DataFrame(ohe.transform(df[categorical]).toarray(),
|
117 |
+
columns=ohe.get_feature_names_out(),
|
118 |
+
index=df.index)
|
119 |
+
df.drop(categorical, axis=1, inplace=True)
|
120 |
+
df = df.join(tmp).sort_index(axis=1)
|
121 |
+
|
122 |
+
|
123 |
+
return pd.DataFrame(df, index=[0])
|
124 |
+
|
125 |
+
@st.cache_resource
|
126 |
+
def get_model():
|
127 |
+
load_model = pickle.load(open('models/booking_cancel_pred.pkl', 'rb'))
|
128 |
+
ohe_model = pickle.load(open('models/ohe_booking_cancel_pred.pkl', 'rb'))
|
129 |
+
scaler_model = pickle.load(open('models/scaler_booking_cancel_pred.pkl', 'rb'))
|
130 |
+
return load_model, scaler_model, ohe_model
|
131 |
+
|
132 |
+
model, sc_model, ohe_model = get_model()
|
133 |
+
|
134 |
+
df_new = preprocessing_data(df, sc_model, ohe_model)
|
135 |
+
# st.write(df_new)
|
136 |
+
prediction = model.predict(df_new)
|
137 |
+
prediction_proba = model.predict_proba(df_new)
|
138 |
+
|
139 |
+
|
140 |
+
st.subheader('Рекомендация')
|
141 |
+
exited = np.array(['Клиент вероятно оставит бронь','Клиент вероятно отменит бронь'])
|
142 |
+
st.write(exited[prediction])
|
143 |
+
|
144 |
+
st.subheader('Вероятность рекомендации')
|
145 |
+
st.write(prediction_proba)
|
pages/9_taxi_orders_prediction.py
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import numpy as np
|
3 |
+
import pandas as pd
|
4 |
+
import pickle
|
5 |
+
from catboost import CatBoostRegressor
|
6 |
+
import datetime
|
7 |
+
|
8 |
+
|
9 |
+
st.set_page_config(page_title="# Прогнозирование заказов такси")
|
10 |
+
|
11 |
+
st.markdown('# Прогнозирование заказов такси')
|
12 |
+
|
13 |
+
with st.expander("Описание проекта"):
|
14 |
+
st.write("""
|
15 |
+
Компания «Чётенькое такси» собрала исторические данные о заказах такси в аэропортах.
|
16 |
+
Чтобы привлекать больше водителей в период пиковой нагрузки, нужно спрогнозировать количество заказов такси на следующий час.
|
17 |
+
|
18 |
+
Описание данных:
|
19 |
+
- datetime - время заказа
|
20 |
+
- num_orders - число заказов
|
21 |
+
""")
|
22 |
+
|
23 |
+
df_old = pd.read_csv('models/taxi.csv', index_col=[0], parse_dates=[0]).sort_index().resample('1H').sum()
|
24 |
+
|
25 |
+
|
26 |
+
def user_input_features():
|
27 |
+
date = st.date_input("дата заказа такси", datetime.date(2018, 9, 6))
|
28 |
+
time = st.time_input('время заказа такси', datetime.time(8, 45))
|
29 |
+
target_datetime = datetime.datetime.combine(date, time)
|
30 |
+
data = {'datetime': target_datetime }
|
31 |
+
features = pd.DataFrame(data, index=[0])
|
32 |
+
return features
|
33 |
+
|
34 |
+
df = user_input_features()
|
35 |
+
df = df.sort_index(axis=1)
|
36 |
+
|
37 |
+
|
38 |
+
|
39 |
+
def preprocessing_data(data, max_lag, rolling_mean_size, target_datetime):
|
40 |
+
df_new = data.copy()
|
41 |
+
df_new['month'] = df_new.index.month
|
42 |
+
df_new['day'] = df_new.index.day
|
43 |
+
df_new['dayofweek'] = df_new.index.dayofweek
|
44 |
+
df_new['hour'] = df_new.index.hour
|
45 |
+
# Создаем признаки - значения за предыдущие периоды
|
46 |
+
for lag in range(1, max_lag + 1):
|
47 |
+
df_new[f'lag_{lag}'] = df_new['num_orders'].shift(lag)
|
48 |
+
# Создаем признак "скользящее среднее"
|
49 |
+
df_new['rolling_mean'] = df_new['num_orders'].shift().rolling(rolling_mean_size).mean()
|
50 |
+
# Удаляем пропуски
|
51 |
+
df_new = df_new.dropna(axis=0)
|
52 |
+
|
53 |
+
# Создаем DataFrame для target_datetime
|
54 |
+
target_df = target_datetime.copy()
|
55 |
+
target_df['month'] = target_df['datetime'].dt.month
|
56 |
+
target_df['day'] = target_df['datetime'].dt.day
|
57 |
+
target_df['dayofweek'] = target_df['datetime'].dt.dayofweek
|
58 |
+
target_df['hour'] = target_df['datetime'].dt.hour
|
59 |
+
target_df = target_df.set_index('datetime')
|
60 |
+
|
61 |
+
# Создаем признаки - значения за предыдущие периоды для target_datetime
|
62 |
+
for lag in range(1, max_lag + 1):
|
63 |
+
target_df[f'lag_{lag}'] = df_new['num_orders'].shift(lag).iloc[-1]
|
64 |
+
|
65 |
+
# Создаем признак "скользящее среднее" для target_datetime
|
66 |
+
target_df['rolling_mean'] = df_new['num_orders'].shift().rolling(rolling_mean_size).mean().iloc[-1]
|
67 |
+
|
68 |
+
return target_df
|
69 |
+
|
70 |
+
|
71 |
+
|
72 |
+
|
73 |
+
@st.cache_resource
|
74 |
+
def get_model():
|
75 |
+
load_model = pickle.load(open('models/taxi_orders_prediction.pkl', 'rb'))
|
76 |
+
|
77 |
+
return load_model
|
78 |
+
|
79 |
+
model = get_model()
|
80 |
+
target_datetime = pd.to_datetime(df['datetime'].iloc[0])
|
81 |
+
features_for_prediction = preprocessing_data(df_old, 10, 10, df)
|
82 |
+
|
83 |
+
prediction = model.predict(features_for_prediction)
|
84 |
+
st.subheader('Прогназируемое количество заказов:')
|
85 |
+
st.write(str(round(prediction[0])))
|
requirements.txt
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
scikit-learn==1.2.2
|
2 |
+
streamlit==1.28.0
|
3 |
+
numpy
|
4 |
+
pandas
|
5 |
+
sqlalchemy==2.0.20
|
6 |
+
psycopg2-binary
|
7 |
+
torch
|
8 |
+
catboost
|
9 |
+
transformers
|
10 |
+
langid
|
11 |
+
tensorflow==2.15.0
|
12 |
+
st_pages==0.4.5
|