SeedFinder
- 편향을 최소화하기 위해 "SeedFinder" 방식에서 가장 적은 편향을 가진 SaltKey를 찾는 프로세스
- 기본적인 아이디어는 여러 SaltKey를 사용해 무작위화된 그룹을 생성하고, A/A 테스트에서 이 그룹들의 성과 지표(예: 전환율 등)가 균등한지 평가하여 편향이 적은 SaltKey를 선택하는 것입니다.
전체 프로세스
- 여러 SaltKey를 생성
- 각 SaltKey에 대해 고객 ID와 결합하여 무작위화된 Identifier 생성
- 각 SaltKey에 대해 A/A 테스트를 수행하고 그룹 간 차이를 비교
- 가장 적은 편향을 가진 SaltKey를 선택
코드
import hashlib
import pandas as pd
import numpy as np
from scipy import stats
import seaborn as sns
import matplotlib.pyplot as plt
# 예시 데이터: 최근 1-2주 동안의 고객 데이터 (Customer ID 및 성과 지표)
data = pd.DataFrame({
'customer_id': np.random.randint(1, 10000, 1000),
'metric': np.random.rand(1000) # 예: 구매 전환율
})
# Inf 값을 NaN으로 처리 (이 옵션을 직접 설정하는 방식 대신 수동으로 처리)
data.replace([np.inf, -np.inf], np.nan, inplace=True)
# SaltKey를 활용한 해시 기반 그룹 무작위화 함수
def create_randomized_identifier(customer_id, salt_key):
hash_input = f"{customer_id}{salt_key}".encode('utf-8')
hashed_value = hashlib.sha256(hash_input).hexdigest()
# 해시 값을 바탕으로 그룹을 결정 (2개의 그룹으로 나누기 위해 mod 연산)
return int(hashed_value, 16) % 2 # 0 또는 1로 그룹화
# 여러 SaltKey 시도 (예: 100개의 서로 다른 SaltKey 생성)
salt_keys = [f'salt_{i}' for i in range(100)]
# 결과를 저장할 리스트 초기화
bias_results = []
# 각 SaltKey에 대해 A/A 테스트 수행
for salt_key in salt_keys:
data['group'] = data['customer_id'].apply(lambda x: create_randomized_identifier(x, salt_key))
# 그룹별 성과 지표의 평균을 계산
group_means = data.groupby('group')['metric'].mean()
# 그룹 간 차이를 t-test로 평가 (A/A 테스트의 경우 p-value가 0.05 이상이 기대됨)
group_0 = data[data['group'] == 0]['metric']
group_1 = data[data['group'] == 1]['metric']
t_stat, p_value = stats.ttest_ind(group_0, group_1)
# p-value를 기준으로 편향이 적은 SaltKey 평가
bias_results.append({'salt_key': salt_key, 'p_value': p_value})
# bias_results 리스트를 DataFrame으로 변환
bias_results_df = pd.DataFrame(bias_results)
# NaN 값을 제거하고, p_value 컬럼을 float 타입으로 변환
bias_results_df = bias_results_df.dropna(subset=['p_value']) # NaN 값 제거
bias_results_df['p_value'] = bias_results_df['p_value'].astype(float) # 숫자형으로 변환
# 가장 Bias가 적은 SaltKey는 p-value가 가장 높은 값 (그룹 차이가 가장 적은 경우)
best_salt_key = bias_results_df.sort_values(by='p_value', ascending=False).iloc[0]
print(f"가장 적은 편향을 가진 SaltKey: {best_salt_key['salt_key']} (p-value: {best_salt_key['p_value']})")
# Seaborn을 사용한 p-value 분포 시각화
plt.figure(figsize=(10, 6))
sns.histplot(bias_results_df['p_value'], bins=30, kde=True)
plt.title('Distribution of p-values for Different SaltKeys')
plt.xlabel('p-value')
plt.ylabel('Frequency')
plt.axvline(x=0.05, color='red', linestyle='--', label='p=0.05')
plt.legend()
plt.show()