Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -21,64 +21,79 @@ st.write('Калькулятор для Дениса')
|
|
21 |
st.sidebar.title('Выбор параметров для расчета влияния фичи')
|
22 |
|
23 |
with st.sidebar:
|
24 |
-
count_view = st.number_input(
|
25 |
-
"Введите охват аудитории - сколько пользователей увидят Вашу фичу/виджет/баннер",
|
26 |
-
min_value=0, # Минимальное значение
|
27 |
-
step=1, # Шаг единицы
|
28 |
-
format='%d', # Формат для целых чисел
|
29 |
-
# max_value=(df1['ЗП в вакансии'].max() - 50000)
|
30 |
-
# ("IT", "Продажи"),
|
31 |
-
value = 1
|
32 |
-
)
|
33 |
|
34 |
-
|
35 |
-
"
|
36 |
-
|
37 |
-
)
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
|
44 |
-
money = st.selectbox(
|
45 |
-
"Хотите ли Вы указать значение среднего чека или при расчете брать прогнозируемое значений", options=["Выставлю сам", "Использовать прогноз"], key=f"1",
|
46 |
-
index=None,
|
47 |
-
)
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
)
|
|
|
54 |
|
55 |
-
|
56 |
-
"Введите количество месяцев, на протяжении которых желаете оценивать влияние фичи",
|
57 |
-
options=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24], key=f"2")
|
58 |
-
|
59 |
-
count_month = st.number_input(
|
60 |
-
"Введите количество месяцев прогноза",
|
61 |
-
min_value=0, # Минимальное значение
|
62 |
-
step=1, # Шаг единицы
|
63 |
-
format='%d', # Формат для целых чисел
|
64 |
-
# max_value=(df1['ЗП в вакансии'].max() - 50000)
|
65 |
-
# ("IT", "Продажи")
|
66 |
-
value=12
|
67 |
-
# key=f"3"
|
68 |
-
)
|
69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
|
72 |
# min_value=0, # Минимальное значение
|
73 |
# step=1, # Шаг единицы
|
74 |
# format='%d', # Формат для целых чисел
|
75 |
# # max_value=(df1['ЗП в вакансии'].max() - 50000)
|
76 |
# # ("IT", "Продажи")
|
77 |
-
# )
|
78 |
|
79 |
-
date_start = st.date_input("Выберите дату старта акции:", datetime.date(2024, 10, 1))
|
80 |
-
st.write("Вы выбрали дату:", date_start)
|
81 |
|
|
|
|
|
|
|
|
|
82 |
|
83 |
# Заголовок приложения
|
84 |
st.title("Расчет прогнозных значений моделью SARIMA, с добавлением параментов фичи")
|
@@ -87,7 +102,15 @@ st.write("Если Вы не подгружаете свои данные - ра
|
|
87 |
# Используем file_uploader для загрузки файла
|
88 |
uploaded_file = st.file_uploader("Выберите файл Excel", type=["xlsx"])
|
89 |
|
90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
# Проверяем, был ли загружен файл
|
92 |
if uploaded_file is not None:
|
93 |
# Читаем файл Excel в DataFrame
|
@@ -104,7 +127,7 @@ def load_file(path):
|
|
104 |
return data
|
105 |
|
106 |
@st.cache_data
|
107 |
-
def fit_model(data_list):
|
108 |
seasonal_order = (1, 1, 1, 12) # Настройте параметры сезонности (P, D, Q, s)
|
109 |
model = SARIMAX(data_list.dropna(), seasonal_order=seasonal_order)
|
110 |
model_fit = model.fit()
|
@@ -124,7 +147,7 @@ data = data.rename(columns={'Оборот по всем копилкам за м
|
|
124 |
# model_fit = model.fit()
|
125 |
# forecast_new = model_fit.forecast(steps=count_month)
|
126 |
|
127 |
-
forecast_new = fit_model(data['Оборот'])
|
128 |
|
129 |
fig, ax = plt.subplots(figsize=(10, 5))
|
130 |
# plt.figure(figsize=(10, 5))
|
@@ -145,7 +168,7 @@ st.pyplot(fig)
|
|
145 |
# # Прогнозируем
|
146 |
# forecast_chek = model_fit.forecast(steps=count_month)
|
147 |
|
148 |
-
forecast_chek = fit_model(data['Средний чек'])
|
149 |
|
150 |
# Визуализируем результаты
|
151 |
fig, ax = plt.subplots(figsize=(10, 5))
|
@@ -170,25 +193,53 @@ st.subheader('Визуализация влияния фичи')
|
|
170 |
|
171 |
month_start = date_start
|
172 |
|
173 |
-
summ_from_feature = 0
|
174 |
-
|
|
|
|
|
175 |
|
176 |
if money == 'Выставлю сам':
|
177 |
forecast_chek = [money_self for i in range(len(forecast_new))]
|
178 |
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
192 |
|
193 |
|
194 |
# Визуализируем результаты
|
@@ -196,7 +247,8 @@ fig, ax = plt.subplots(figsize=(10, 5))
|
|
196 |
# plt.plot(train['Оборот по всем копилкам за месяц'], label='Train')
|
197 |
ax.plot(data['Оборот'], label='Исторические данные', color='orange')
|
198 |
ax.plot(forecast_new.index, forecast_new, label='Прогноз', color='green', linestyle='--')
|
199 |
-
|
|
|
200 |
|
201 |
ax.set_title('Прогнозирование с помощью SARIMA')
|
202 |
ax.legend()
|
@@ -204,5 +256,21 @@ ax.grid()
|
|
204 |
st.pyplot(fig)
|
205 |
|
206 |
st.subheader('Данные с учетом влияния фичи')
|
207 |
-
df_no_feature['Прогноз с учетом фичи'] = list(new_summ_with_features)
|
208 |
-
st.dataframe(df_no_feature)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
st.sidebar.title('Выбор параметров для расчета влияния фичи')
|
22 |
|
23 |
with st.sidebar:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
+
count_features = st.selectbox(
|
26 |
+
"Введите количество фичей, влияние которых желаете оценить",
|
27 |
+
options=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], key=f"4")
|
28 |
+
list_with_data_by_features = [None for i in range(count_features)]
|
29 |
+
|
30 |
+
for i in range(count_features):
|
31 |
+
list_obout_features = [None for i in range(7)]
|
32 |
+
st.subheader(f'Введите данные по фиче #{i+1}')
|
33 |
+
|
34 |
+
count_view = st.number_input(
|
35 |
+
"Введите охват аудитории - сколько пользователей увидят Вашу фичу/виджет/баннер",
|
36 |
+
min_value=0, # Минимальное значение
|
37 |
+
step=1, # Шаг единицы
|
38 |
+
format='%d', # Формат для целых чисел
|
39 |
+
# max_value=(df1['ЗП в вакансии'].max() - 50000)
|
40 |
+
# ("IT", "Продажи"),
|
41 |
+
value = 1,
|
42 |
+
key = f"2{i}"
|
43 |
+
)
|
44 |
+
# if count_view:
|
45 |
+
list_obout_features[0] = count_view
|
46 |
|
|
|
|
|
|
|
|
|
47 |
|
48 |
+
ctr = st.number_input(
|
49 |
+
"Конверсия в клик",
|
50 |
+
value = 0.03,
|
51 |
+
key = f"22{i}"
|
52 |
)
|
53 |
+
list_obout_features[1] = ctr
|
54 |
|
55 |
+
# dict_with_data[f"i"]['ctr'] = ctr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
|
57 |
+
ctr_connect = st.number_input(
|
58 |
+
"Конверсия в подключение услуги",
|
59 |
+
value = 0.05,
|
60 |
+
|
61 |
+
key = f"26{i}"
|
62 |
+
)
|
63 |
+
list_obout_features[2] = ctr_connect
|
64 |
|
65 |
+
money = st.selectbox(
|
66 |
+
"Хотите ли Вы указать значение среднего чека или при расчете брать прогнозируемое значений", options=["Выставлю сам", "Использовать прогноз"], key = f"266{i}",
|
67 |
+
index=None,
|
68 |
+
)
|
69 |
+
# dict_with_data[f"i"]['money'] = None
|
70 |
+
|
71 |
+
if money == 'Выставлю сам':
|
72 |
+
money_self = st.number_input(
|
73 |
+
"Введите значение среднего чека",
|
74 |
+
value = 1, key = f"267{i}"
|
75 |
+
)
|
76 |
+
# dict_with_data[f"i"]['money'] = money_self
|
77 |
+
list_obout_features[3] = money_self
|
78 |
+
|
79 |
+
list_obout_features[6] = money
|
80 |
+
duration = st.selectbox(
|
81 |
+
"Введите количество месяцев, на протяжении которых желаете оценивать влияние фичи",
|
82 |
+
options=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24], key = f"2677{i}")
|
83 |
+
# dict_with_data[f"i"]['duration'] = duration
|
84 |
+
list_obout_features[4] = duration
|
85 |
|
86 |
# min_value=0, # Минимальное значение
|
87 |
# step=1, # Шаг единицы
|
88 |
# format='%d', # Формат для целых чисел
|
89 |
# # max_value=(df1['ЗП в вакансии'].max() - 50000)
|
90 |
# # ("IT", "Продажи")
|
|
|
91 |
|
|
|
|
|
92 |
|
93 |
+
date_start = st.date_input("Выберите дату старта акции:", datetime.date(2024, 10, 1), key = f"26i7{i}")
|
94 |
+
list_obout_features[5] = date_start
|
95 |
+
st.write("Вы выбрали дату:", date_start)
|
96 |
+
list_with_data_by_features[i] = list_obout_features
|
97 |
|
98 |
# Заголовок приложения
|
99 |
st.title("Расчет прогнозных значений моделью SARIMA, с добавлением параментов фичи")
|
|
|
102 |
# Используем file_uploader для загрузки файла
|
103 |
uploaded_file = st.file_uploader("Выберите файл Excel", type=["xlsx"])
|
104 |
|
105 |
+
count_month = st.number_input(
|
106 |
+
"Введите количество месяцев прогноза",
|
107 |
+
min_value=0, # Минимальное значение
|
108 |
+
step=1, # Шаг единицы
|
109 |
+
format='%d', # Формат для целых чисел
|
110 |
+
# max_value=(df1['ЗП в вакансии'].max() - 50000)
|
111 |
+
# ("IT", "Продажи")
|
112 |
+
value=12
|
113 |
+
)
|
114 |
# Проверяем, был ли загружен файл
|
115 |
if uploaded_file is not None:
|
116 |
# Читаем файл Excel в DataFrame
|
|
|
127 |
return data
|
128 |
|
129 |
@st.cache_data
|
130 |
+
def fit_model(data_list, count_month):
|
131 |
seasonal_order = (1, 1, 1, 12) # Настройте параметры сезонности (P, D, Q, s)
|
132 |
model = SARIMAX(data_list.dropna(), seasonal_order=seasonal_order)
|
133 |
model_fit = model.fit()
|
|
|
147 |
# model_fit = model.fit()
|
148 |
# forecast_new = model_fit.forecast(steps=count_month)
|
149 |
|
150 |
+
forecast_new = fit_model(data['Оборот'], count_month)
|
151 |
|
152 |
fig, ax = plt.subplots(figsize=(10, 5))
|
153 |
# plt.figure(figsize=(10, 5))
|
|
|
168 |
# # Прогнозируем
|
169 |
# forecast_chek = model_fit.forecast(steps=count_month)
|
170 |
|
171 |
+
forecast_chek = fit_model(data['Средний чек'], count_month)
|
172 |
|
173 |
# Визуализируем результаты
|
174 |
fig, ax = plt.subplots(figsize=(10, 5))
|
|
|
193 |
|
194 |
month_start = date_start
|
195 |
|
196 |
+
# summ_from_feature = 0
|
197 |
+
|
198 |
+
# random_colors = ['red', 'blue', 'lightgreen', 'gold', 'slategreay', 'indigo', 'coral', 'plum', 'blue', 'tomato']
|
199 |
+
new_summ_with_features = ['red']
|
200 |
|
201 |
if money == 'Выставлю сам':
|
202 |
forecast_chek = [money_self for i in range(len(forecast_new))]
|
203 |
|
204 |
+
# for i in range(count_features):
|
205 |
+
# структура list_with_data_by_features: count_view, ctr, ctr_connect, money_self, duration, date_start, sum
|
206 |
+
|
207 |
+
list_with_colour = ['red', 'blue', 'lightgreen', 'gold', 'plum', 'indigo', 'coral', 'plum', 'blue', 'tomato']
|
208 |
+
r = 1
|
209 |
+
oborot = df_no_feature['Оборот']
|
210 |
+
|
211 |
+
for j in list_with_data_by_features:
|
212 |
+
# st.write(j)
|
213 |
+
if j[6] == 'Выставлю сам':
|
214 |
+
forecast_chek = [j[3] for l in range(len(forecast_new))]
|
215 |
+
new_summ_with_features = []
|
216 |
+
list_retention = list_retention[:duration+1] + [0 for g in range(25)]
|
217 |
+
for i in range(len(forecast_new)):
|
218 |
+
# st.write(i)
|
219 |
+
summ_from_feature = 0
|
220 |
+
|
221 |
+
# print(f"Сумма прогноза без добавления фичи в период {forecast_new.index[i].date()} -", forecast_new[i])
|
222 |
+
if (forecast_new.index[i].date() >= j[5]) & (
|
223 |
+
forecast_new.index[i].date() <= j[5] + timedelta(days=j[4]*30)):
|
224 |
+
# st.write((forecast_new.index[i].date() >= j[5]) & (
|
225 |
+
# forecast_new.index[i].date() <= j[5] + timedelta(days=180)))
|
226 |
+
# oborot = df_no_feature['Оборот']
|
227 |
+
summ_from_feature += j[0] * j[1] * j[2] * forecast_chek[i] * list_retention[i]
|
228 |
+
# print("Доп сумма от фичи:", summ_from_feature)
|
229 |
+
# st.write(summ_from_feature)
|
230 |
+
|
231 |
+
new_summ_with_features.append(summ_from_feature + oborot[i])
|
232 |
+
# st.write(new_summ_with_features)
|
233 |
+
# i += 1
|
234 |
+
else:
|
235 |
+
new_summ_with_features.append(oborot[i])
|
236 |
+
# st.write('new_summ_with_features', type(new_summ_with_features))
|
237 |
+
# st.write('new_summ_with_features', type(new_summ_with_features))
|
238 |
+
# st.write(forecast_new)
|
239 |
+
# forecast_new
|
240 |
+
df_no_feature[f'Прогноз с учетом фичи # {r}'] = list(new_summ_with_features)
|
241 |
+
r+=1
|
242 |
+
oborot = new_summ_with_features
|
243 |
|
244 |
|
245 |
# Визуализируем результаты
|
|
|
247 |
# plt.plot(train['Оборот по всем копилкам за месяц'], label='Train')
|
248 |
ax.plot(data['Оборот'], label='Исторические данные', color='orange')
|
249 |
ax.plot(forecast_new.index, forecast_new, label='Прогноз', color='green', linestyle='--')
|
250 |
+
for k in range(len(list_with_data_by_features)):
|
251 |
+
ax.plot(forecast_new.index, df_no_feature[f'Прогноз с учетом фичи # {k+1}'], label=f'Прогноз с добавлением фичи # {k+1}', color=list_with_colour[k], linestyle='--')
|
252 |
|
253 |
ax.set_title('Прогнозирование с помощью SARIMA')
|
254 |
ax.legend()
|
|
|
256 |
st.pyplot(fig)
|
257 |
|
258 |
st.subheader('Данные с учетом влияния фичи')
|
259 |
+
# df_no_feature['Прогноз с учетом фичи'] = list(new_summ_with_features)
|
260 |
+
st.dataframe(df_no_feature)
|
261 |
+
|
262 |
+
st.subheader('Среднемесячные показатели за 2025 год')
|
263 |
+
mask = df_no_feature['Дата'].dt.year == 2025
|
264 |
+
df_no_feature_2 = df_no_feature[mask]
|
265 |
+
df_no_feature_2.drop(columns={'Дата'}, inplace=True)
|
266 |
+
averages = df_no_feature_2.mean()
|
267 |
+
# averages.columns = ['Средние показатели']
|
268 |
+
|
269 |
+
# Вывод результата в одной строке
|
270 |
+
|
271 |
+
st.dataframe(averages)
|
272 |
+
|
273 |
+
|
274 |
+
|
275 |
+
st.write("Блок тестирования")
|
276 |
+
st.write(list_with_data_by_features)
|