Spaces:
Sleeping
Sleeping
Commit
·
2c77aab
1
Parent(s):
564f2a9
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,7 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
import gradio as gr
|
|
|
|
| 2 |
|
| 3 |
-
|
| 4 |
-
|
|
|
|
|
|
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
+
import numpy as np
|
| 3 |
+
import matplotlib.pyplot as plt
|
| 4 |
+
from statsmodels.tsa.arima.model import ARIMA
|
| 5 |
+
from statsmodels.tsa.stattools import adfuller
|
| 6 |
import gradio as gr
|
| 7 |
+
import pickle
|
| 8 |
|
| 9 |
+
# Загрузка данных
|
| 10 |
+
data = pd.read_csv('сетик-3.csv')
|
| 11 |
+
data['date'] = pd.to_datetime(data['date'], format='%d/%m/%Y')
|
| 12 |
+
data.set_index('date', inplace=True)
|
| 13 |
|
| 14 |
+
|
| 15 |
+
# Проверка стационарности ряда с помощью теста Дики-Фуллера
|
| 16 |
+
def test_stationarity(timeseries):
|
| 17 |
+
result = adfuller(timeseries)
|
| 18 |
+
print('ADF статистика:', result[0])
|
| 19 |
+
print('p-зачение (простое значение):', result[1])
|
| 20 |
+
if result[1] <= 0.05:
|
| 21 |
+
print("Ряд стационарен")
|
| 22 |
+
else:
|
| 23 |
+
print("Ряд не стационарен")
|
| 24 |
+
|
| 25 |
+
# Функция для загрузки моделей из файлов
|
| 26 |
+
|
| 27 |
+
|
| 28 |
+
def load_models():
|
| 29 |
+
with open('model_sprice.pkl', 'rb') as f:
|
| 30 |
+
model_fit_sprice = pickle.load(f)
|
| 31 |
+
|
| 32 |
+
with open('model_mprice.pkl', 'rb') as f:
|
| 33 |
+
model_fit_mprice = pickle.load(f)
|
| 34 |
+
|
| 35 |
+
return model_fit_sprice, model_fit_mprice
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
# Прогнозирование
|
| 39 |
+
def forecast_prices(data):
|
| 40 |
+
# Загрузка обученных моделей
|
| 41 |
+
model_fit_sprice, model_fit_mprice = load_models()
|
| 42 |
+
|
| 43 |
+
# Прогнозирование на 365 дней вперед
|
| 44 |
+
forecast_sprice = model_fit_sprice.forecast(steps=365)
|
| 45 |
+
forecast_mprice = model_fit_mprice.forecast(steps=365)
|
| 46 |
+
|
| 47 |
+
# Создание датафрейма
|
| 48 |
+
forecast_dates = pd.date_range(start=data.index[-1] + pd.Timedelta(days=1), periods=365)
|
| 49 |
+
forecast_df = pd.DataFrame({
|
| 50 |
+
'date': forecast_dates,
|
| 51 |
+
'Sprice_forecast': forecast_sprice,
|
| 52 |
+
'Mprice_forecast': forecast_mprice
|
| 53 |
+
})
|
| 54 |
+
|
| 55 |
+
forecast_df.set_index('date', inplace=True)
|
| 56 |
+
|
| 57 |
+
return forecast_df
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
# Функция для создания графиков
|
| 61 |
+
def plot_forecasts(forecast_df):
|
| 62 |
+
plt.figure(figsize=(14, 6))
|
| 63 |
+
|
| 64 |
+
plt.subplot(1, 2, 1)
|
| 65 |
+
plt.plot(data['Sprice'], label='Известные данные')
|
| 66 |
+
plt.plot(forecast_df.index, forecast_df['Sprice_forecast'], label='Прогноз', color='r')
|
| 67 |
+
plt.title('Прогноз начальной стоимости поездки')
|
| 68 |
+
plt.xlabel('Дата/Год')
|
| 69 |
+
plt.ylabel('Цена/руб')
|
| 70 |
+
plt.legend()
|
| 71 |
+
|
| 72 |
+
plt.subplot(1, 2, 2)
|
| 73 |
+
plt.plot(data['Mprice'], label='Известные данные')
|
| 74 |
+
plt.plot(forecast_df.index, forecast_df['Mprice_forecast'], label='Прогноз', color='r')
|
| 75 |
+
plt.title('Прогноз поминутной стоимости поездки')
|
| 76 |
+
plt.xlabel('Дата/Год')
|
| 77 |
+
plt.ylabel('Цена/руб')
|
| 78 |
+
plt.legend()
|
| 79 |
+
|
| 80 |
+
plt.tight_layout()
|
| 81 |
+
|
| 82 |
+
plt.savefig('forecast_plot.png')
|
| 83 |
+
plt.close()
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
# Расчёт стоимости поездки
|
| 87 |
+
def cost(date_str, distance):
|
| 88 |
+
date = pd.to_datetime(date_str, format='%d/%m/%Y')
|
| 89 |
+
|
| 90 |
+
forecast_df = forecast_prices(data)
|
| 91 |
+
|
| 92 |
+
if date in forecast_df.index:
|
| 93 |
+
sprice = forecast_df.loc[date, 'Sprice_forecast']
|
| 94 |
+
mprice = forecast_df.loc[date, 'Mprice_forecast']
|
| 95 |
+
|
| 96 |
+
travel_time_seconds = distance / 3 # берём среднюю скорость поездки в 3 м/с
|
| 97 |
+
|
| 98 |
+
total_cost = sprice + (mprice * (travel_time_seconds / 60))
|
| 99 |
+
return f"Итоговая средняя для Ростовской области стоимость поездки: {total_cost:.2f} руб."
|
| 100 |
+
|
| 101 |
+
return "Дата не найдена в прогнозе. Максимальная дата прогноза на данный момент 01/07/2025, так же используйте формат 'День/Месяц/Год' "
|
| 102 |
+
|
| 103 |
+
#Gradio
|
| 104 |
+
def gradio_interface(date_str, distance):
|
| 105 |
+
forecast_df = forecast_prices(data)
|
| 106 |
+
|
| 107 |
+
plot_forecasts(forecast_df)
|
| 108 |
+
|
| 109 |
+
cost_message = cost(date_str, distance)
|
| 110 |
+
|
| 111 |
+
return 'forecast_plot.png', cost_message
|
| 112 |
+
|
| 113 |
+
txt = gr.Textbox(label="Введите дату (dd/mm/yyyy)")
|
| 114 |
+
num = gr.Number(label="Введите расстояние (в метрах)")
|
| 115 |
+
iface = gr.Interface(fn=gradio_interface,inputs=[txt,num],outputs=["image", "text"],title="Прогноз цен на прокат электросамокатов")
|
| 116 |
+
iface.launch()
|