import streamlit as st from scipy.stats import ttest_ind, norm import pandas as pd import numpy as np from sklearn.model_selection import train_test_split # Загрузка и предварительная обработка данных df = pd.read_csv("task_data.csv", encoding='ISO-8859-1') base_date = pd.Timestamp('2022-01-01') df['Date'] = base_date + pd.to_timedelta(df['Date'] - 44562, unit='D') # Отбор данных за март df_march = df[df['Date'].dt.month == 3] # Расчет медианных продаж для каждого магазина в марте march_sales_median = df_march.groupby('STORE')['Qty'].median().reset_index(name='Median Sales March') # Определение общей медианы продаж в марте overall_median_sales_march = march_sales_median['Median Sales March'].median() # Выборка магазинов с продажами вокруг общей медианы (10% от медианы) close_to_median_stores = march_sales_median[ abs(march_sales_median['Median Sales March'] - overall_median_sales_march) <= overall_median_sales_march * 0.1 ]['STORE'] # Разделение выбранных магазинов на контрольную и тестовую группы test_stores, control_stores = train_test_split(close_to_median_stores, test_size=0.5, random_state=42) test_stores_codes = test_stores.tolist() control_stores_codes = control_stores.tolist() # Подготовка данных о количестве продаж для новых контрольной и тестовой групп control_sales = df[df['STORE'].isin(control_stores_codes)]['Qty'] test_sales = df[df['STORE'].isin(test_stores_codes)]['Qty'] # Проведение t-теста t_test_result = ttest_ind(control_sales, test_sales) # Подготовка данных о качестве представленности для контрольной и тестовой групп за март control_quality_march = df_march[df_march['STORE'].isin(control_stores_codes)]['Quality of presence'] test_quality_march = df_march[df_march['STORE'].isin(test_stores_codes)]['Quality of presence'] # Проведение t-теста для качества представленности за март t_test_quality_result_march = ttest_ind(control_quality_march, test_quality_march) control_sales_march = df_march[df_march['STORE'].isin(control_stores_codes)]['Qty'] test_sales_march = df_march[df_march['STORE'].isin(test_stores_codes)]['Qty'] # Расчет стандартных отклонений и размеров выборок std_dev_control = control_sales_march.std(ddof=1) std_dev_test = test_sales_march.std(ddof=1) n_control = len(control_sales_march) n_test = len(test_sales_march) # Объединенное стандартное отклонение std_dev_pooled = np.sqrt((std_dev_control**2 + std_dev_test**2) / 2) # Уровень значимости и мощность alpha = 0.05 power = 0.8 z_alpha = norm.ppf(1 - alpha / 2) z_beta = norm.ppf(power) # Расчет MDE mde = (z_alpha + z_beta) * std_dev_pooled * np.sqrt(1/n_control + 1/n_test) mde_percent = (mde / df_march['Qty'].mean()) * 100 # Процент от среднего количества продаж median_quality = df_march['Quality of presence'].median() # Разделение магазинов на группы с хорошей и плохой представленностью good_quality_stores = df_march[df_march['Quality of presence'] > median_quality] poor_quality_stores = df_march[df_march['Quality of presence'] <= median_quality] # Расчет средней представленности для каждой группы average_good_quality = good_quality_stores['Quality of presence'].mean() average_poor_quality = poor_quality_stores['Quality of presence'].mean() st.markdown(f""" ### Гипотезы для А/Б-теста Так как магазины с высоким качеством представленности и магазины с низким качеством представленности имеют статистически значимое различие в средних количествах проданных батончиков, можно предположить, что увеличив среднюю представленность в магазинах с плохой представленностью, можно статистически значимо увеличить объем продаж в этих магазинах. Гипотеза здесь заключается в том, что магазины с плохой представленностью демонстируют плохие продажи именно из-за качества представленности, а не из-за социально-демографических особенностей аудитории покупателей или территориальных особенностей расположения магазина. Возможна и обратная ситуация: возможно, плохие продажи вызваны не плохой представленностью, а плохая представленность вызвана плохими продажами. Н0 — если в магазинах с плохой представленностью увеличить среднюю представленность до среднего уровня магазинов с хорошей представленностью, то количество проданных баточников не изменится. Н1 — если в магазинах с плохой представленностью увеличить среднюю представленность до среднего уровня магазинов с хорошей представленностью (средний уровень представленности в магазинах с хорошей представленностью: {average_good_quality:.2f}), то количество проданных баточников станет больше. #### Расчеты Так как на данный момент идёт февраль, я буду рассчитывать тест на март, с предположением, что данные показывают похожую сезонность в течение последних нескольких лет, и март 2024 года можно предсказывать, ориентируясь на март 2022 года. На основе средней представленности батончиков в магазинах за март, магазины были разделены на группы с хорошей и плохой представленностью. Магазины с хорошей представленностью — те, в которых средний уровень представленности в марте выше медианного. Cредний уровень прдставленности в магазинах с хорошей представленностью в марте: {average_good_quality:.2f}. Магазины с плохой представленностью — те, в которых средний уровень представленности в марте ниже медианного. Cредний уровень прдставленности в магазинах с плохой представленностью в марте: {average_poor_quality:.2f}. Для отбора магазинов для контрольной и тестовой группы, были отобраны магазины с продажами вокруг общей медианы (в пределах 10% от медианы). Таким образом, в тестовой и контрольной группе получилось по 46 и 47 магазинов соответственно. Тестовая группа: {test_stores_codes} Контрольная группа: {control_stores_codes} Результаты t-теста по объему продаж: - t-test: {t_test_result.statistic:.3f} - P-value: {t_test_result.pvalue:.3f} Результаты t-теста по качеству представленности: - t-test: {t_test_quality_result_march.statistic:.3f} - P-value: {t_test_quality_result_march.pvalue:.3f} Результаты говорят о том, что магазины разделены на группы хорошо, и между двумя группами нет статистически значимых различий ни в уровне продаж, ни в уровне средней представленности в магазинах. Я предлагаю проводить А/Б тест в течение марта, при такой продолжительности теста минимальным детектируемым эффектом от проведения теста будет {mde_percent:.3f}%. Это означает, что для того, чтобы обнаружить статистически значимые изменения в продажах между контрольной и тестовой группами с уровнем значимости 0.05 и мощностью теста 0.8, изменение в количестве проданных батончиков должно быть не менее {mde_percent:.3f}% от среднего уровня продаж. При этом продажи по результатам года в группе с низкой представленностью были более чем в 2 раза ниже, чем в группе с хорошей представленностью, что позволяет предполагать, что эффект от изменений, при условии того, что верна гипотеза Н1, будет значительно превышать минимальный детектируемый эффект. """)