ETL (Extract, Transform, Load) — это процесс извлечения, преобразования и загрузки данных, который часто используется при обработке и подготовке данных для анализа, включая задачи A/B тестирования. В контексте A/B тестов на Python, ETL позволяет собрать данные из различных источников (например, систем аналитики, баз данных или CSV-файлов), привести их в удобный для анализа формат и затем загрузить в хранилище для последующего изучения.
Основные этапы ETL для A/B тестирования на Python:
- Извлечение (Extract): На этом этапе данные загружаются из источников. В A/B тестировании это могут быть данные о взаимодействии пользователей (например, клики, покупки) из систем аналитики или баз данных. В Python популярными библиотеками для этого этапа являются pandas (для чтения файлов CSV или Excel), SQLAlchemy (для взаимодействия с SQL базами данных), а также requests и BeautifulSoup (для загрузки данных из API или веб-страниц).
- Преобразование (Transform): Здесь данные очищаются и подготавливаются к анализу. Например, можно преобразовать временные метки, заполнить пропущенные значения, создать новые признаки (например, вычислить разницу конверсий между версиями), а также удалить дублирующиеся или нерелевантные строки. Для обработки данных на этом этапе широко используется библиотека pandas, которая поддерживает фильтрацию, агрегацию, изменение типов данных и другие трансформации.
- Загрузка (Load): На финальном этапе данные загружаются в хранилище, откуда они будут использованы для анализа. Это может быть база данных, облачное хранилище, либо локальный CSV-файл. Например, данные могут быть записаны в SQL базу данных для дальнейшей обработки или анализа с помощью инструментов BI.
ETL на Python помогает подготовить данные для дальнейшего анализа эффективности разных версий в A/B тестировании, что позволяет маркетологам и аналитикам принимать обоснованные решения.
Пример ETL процесса на Python для A/B теста:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | import pandas as pdfrom sqlalchemy import create_engine# Извлечение данных из CSVdata_a = pd.read_csv('version_a.csv')data_b = pd.read_csv('version_b.csv')# Преобразование данныхdata_a['converted'] = data_a['actions'] > 0 # Пример создания бинарного признакаdata_b['converted'] = data_b['actions'] > 0data_a.dropna(inplace=True) # Удаление пропусковdata_b.dropna(inplace=True)# Объединение данных для последующего анализаdata = pd.concat([data_a, data_b])# Загрузка в SQL базу данныхengine = create_engine('sqlite:///ab_test_data.db')data.to_sql('ab_test_results', con=engine, if_exists='replace') |
Пример 2
Давайте реализуем A/B-тестирование на Python на примере набора данных. Этот набор данных можно скачать здесь.
1 2 3 4 5 6 7 8 9 10 | import numpy as npimport pandas as pdimport scipy.stats as statsimport statsmodels.stats.api as smsimport seaborn as snsfrom math import ceil# Load datasetdf = pd.read_csv('ab_data.csv')df.head() |
Output:
1 2 3 4 5 6 7 | | index | user_id | timestamp | group | landing_page | converted ||:-----:|:--------:|:---------------------------:|:---------:|:-------------:|:---------:|| 0 | 851104 | 2017-01-21 22:11:48.556739 | control | old_page | 0.0 || 1 | 804228 | 2017-01-12 08:01:45.159739 | control | old_page | 0.0 || 2 | 661590 | 2017-01-11 16:55:06.154213 | treatment | new_page | 0.0 || 3 | 853541 | 2017-01-08 18:28:03.143765 | treatment | new_page | 0.0 || 4 | 864975 | 2017-01-21 01:52:26.210827 | control | old_page | 1.0 | |
Этот набор данных содержит идентификаторы пользователей, метку времени сеанса доступа к целевой странице и информацию о том, принадлежит ли пользователь к контрольной или преобразуемой группе. Этот набор данных содержит данные нескольких сеансов для некоторых пользователей. Мы удалим пользователей с несколькими сеансами из нашего тестирования.
1 2 3 4 5 6 7 8 | # Users with multiple session countssession_counts = df['user_id'].value_counts(ascending = False)multi_users = session_counts[session_counts > 1].count()# dropping with multiple session countsusers_to_drop = session_counts[session_counts > 1].indexdf = df[~ df['user_id'].isin(users_to_drop)] |
Затем мы случайным образом выберем данные 5000 пользователей из каждой группы и проведем тест статистической значимости.
1 2 3 4 5 6 7 8 9 10 11 | # Sample control and treatment groupcontrol_sample = df[df['group'] == 'control'].sample(n = 5000, random_state = 12)treatment_sample = df[df['group'] == 'treatment'].sample(n = 5000, random_state = 12)ab_test = pd.concat([control_sample, treatment_sample], axis=0)ab_test.reset_index(drop=True, inplace=True)# Define functions for standard deviation and standard errorstd_dev = lambda x : np.std(x, ddof = 0) std_error = lambda x : stats.sem(x, ddof = 0)conversion_rate = ab_test.groupby('group')['converted'].agg([np.mean, std_dev, std_error])conversion_rate.columns = ['conversion_rate', 'std_deviation', 'std_error']conversion_rate |
Output
1 2 3 4 | | group | conversion_rate | std_deviation | std_error ||:---------:|:----------------:|:--------------:|:----------:|| control | 0.1114 | 0.318296 | 0.004501 || treatment | 0.1218 | 0.327055 | 0.004625 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | from statsmodels.stats.proportion import proportions_ztest, proportion_confintcontrol_results = ab_test[ab_test['group'] == 'control']['converted']treatment_results = ab_test[ab_test['group'] == 'treatment']['converted']num_control = control_results.count()num_treatment = treatment_results.count()successes = [control_results.sum(), treatment_results.sum()]nobs = [num_control, num_treatment]z_stat, pval = proportions_ztest(successes, nobs = nobs)(lower_con, lower_treat), (upper_con, upper_treat) = proportion_confint(successes, nobs=nobs, alpha=0.05)print(f'Z Statistic - {z_stat:.2f}')print(f'P-Value - {pval:.3f}')print(f'CI 95% for control group - [{lower_con:.3f}, {upper_con:.3f}]')print(f'CI 95% for treatment group - [{lower_treat:.3f}, {upper_treat:.3f}]') |
Output
1 2 3 4 | Z Statistic - -1.15P-Value - 0.252CI 95% for control group - [0.106, 0.123]CI 95% for treatment group - [0.113, 0.131] |
Как видите, значение p для результатов A/B-тестирования составляет 0,252. Если мы установим уровень значимости 0,05, то мы не сможем отвергнуть НУЛЕВУЮ гипотезу при этом значении p. Это означает, что наблюдаемые результаты произошли случайно и не являются статистически значимыми, чтобы сказать, что целевая страница экспериментальной группы работает лучше.
Итак,
- A/B-тестирование сравнивает две версии продукта, веб-сайта, приложения или маркетинговой кампании, чтобы определить, какая из них работает лучше. Это полезно в ситуации, когда вы хотите проверить эффективность дополнительных изменений в продукте, веб-сайте или приложении.
- После проведения A/B-тестирования нам необходимо доказать, что результаты статистически значимы. Это означает, что наблюдаемые результаты не являются случайными

Comments
Post a Comment