Experimentation isn't just a cornerstone for innovation and sound decision-making; it's often referred to as the gold standard for problem-solving, thanks in part to its roots in the scientific method. The term itself conjures a sense of rigor, validity, and trust. Yet as powerful as experimentation is, its integrity can be compromised by overlooked details and unforeseen challenges. One of these challenges is sample ratio mismatch, or SRM.
O SRM representa um dos problemas de qualidade de dados mais flagrantes nos testes A/B porque compromete fundamentalmente o pressuposto básico da atribuição aleatória. Por exemplo, se se espera que dois grupos de tamanho razoável sejam divididos em 50/50, mas em vez disso mostram uma divisão 55/45, o processo de atribuição provavelmente está comprometido. Isto significa que existe uma forte possibilidade de que quaisquer resultados experimentais e decisões neles baseadas não sejam válidos.
Na DoorDash, estamos constantemente a inovar e a experimentar. Para o fazer de forma eficaz, tivemos de encontrar formas de reduzir a nossa taxa de SRM. Neste post, exploramos alguns dos exemplos comuns de falhas de SRM que experimentamos, as soluções que implementamos para resolver esses problemas e como aumentamos a conscientização sobre essas soluções internamente para reduzir drasticamente nossa taxa de SRM.
Figura 1: Se tivermos dois grupos que se espera que tenham uma distribuição de 50/50, esperamos que a verificação das MRE passe se essa divisão de 50/50 for efetivamente observada. No entanto, devemos preocupar-nos se, em vez disso, houver uma divisão de 55/45.
Histórias cautelosas de ganhos falsos e perdas reais
Exemplo 1: A miragem de 10 milhões de dólares
Imagine that your target is to improve weekly revenue per user. After setting up the experiment with a 50/50 split between control and treatment groups, you run the experiment for a week and see that revenue has improved 2% - a $200,000 weekly incremental revenue impact. Annualized, this results in more than $10 million per year. High-fives are exchanged and your team is already setting its sights on the next big project.
Fortunately, a more observant experimenter has noticed that the SRM check failed. Instead of a 50/50 split between treatment and control, there actually was a 49.5/50.5 split - more than enough to trigger an SRM failure. Careful examination shows that the root cause for the failure is that all employees were exposed to the treatment. Almost every customer-focused company has an internal practice of dogfooding in which internal employees get the latest features by default. Because employees engage with the product much more frequently than outside users, the ~1% contribution to the total sample was enough to skew the metrics. The team's jubilation over a $10 million win was tragically premature.
Segmento | Grupo experimental | Número de amostras | Valor da receita/utilizador em 7 dias | Impacto incremental comunicado |
Todos os utilizadores | Controlo | 500,000 | $10 | $0 |
Todos os utilizadores | Tratamento | 500,000 | $10 | |
Empregados | Tratamento | 10000 | $30 | $200,000 |
Quadro 1: Nesta experiência, existe um desequilíbrio de 49,95/50,05 entre os grupos de controlo e de tratamento. O desequilíbrio é acidental, devido exclusivamente à inclusão dos empregados no grupo de tratamento. Uma vez que os funcionários se envolvem mais com o produto, distorcem o impacto nas receitas em 2%, o que leva ao impacto semanal de 200 000 dólares. Quando o segmento dos funcionários é excluído, o impacto incremental real é de $0.
Note that a small change in the absolute size of the groups (1%) can introduce a very large change in the experiment metric (2%), which means that the size of the SRM doesn't set a ceiling on its impact on the metric readout. Although the example above is fictitious, we have observed that on our platform experiments that have SRM have twice as many statistically significant metrics. Simply put, by turning a blind eye to imbalance, teams could erroneously double their rate of "statistically significant" findings, leading to potentially faulty conclusions.
Exemplo 2: O viés da correção de erros
Bug fix handling is another area in which users can inadvertently introduce SRM. Imagine, for example, that there's a bug in the implementation of a recently introduced new treatment. An engineer detects that bug and fixes it mid-experiment. They subsequently adjust the experiment's start date so that it does not include metric data collected prior to the bug fix.
Figura 2: Desequilíbrio das MRE introduzido após correção de erros a meio da experiência
Figure 2 shows the time lapse of exposure allocation change. Because users don't forget history, the introduced bug leads to an uneven distribution that deviates from the expected sample ratio; low-intent users likely have left the platform while remaining treatment users have decided to stay. This imbalance leads both to SRM and pre-experimental bias in how results from this experiment can be interpreted.
A solução para este problema é baralhar novamente a exposição para o controlo e para o tratamento depois de o erro ser corrigido. Reiniciar a experiência através da reordenação resolve o desequilíbrio e faz com que os grupos de controlo e de tratamento voltem ao mesmo ponto de partida.
Figura 3: Experiência de reordenamento após correção de erros resolve a SRM
Estes são apenas dois exemplos de como as MRE podem entrar na experimentação. Infelizmente, existe um consenso geral na indústria de que as MRE são fáceis de detetar, mas são extremamente difíceis de diagnosticar e corrigir, mesmo para experimentadores experientes. As SRM podem ser causadas por problemas de qualidade dos dados, problemas de configuração da experiência, filtragem incorrecta ao juntar dados, procedimentos inadequados de rollouts/rollback, interação entre experiências, definições inconsistentes para ConsumerIds (UUID vs. ids incrementais) e qualquer número de outras questões. O nosso desafio tem sido criar soluções para ajudar os nossos experimentadores a evitar, identificar e corrigir as SRM.
Soluções a partir das trincheiras
At DoorDash, we have pursued several approaches to reduce the platform's rate of SRM, including innovating on methodology for how we diagnose SRM, improving our real-time observability and alerting, and focusing on education and awareness.
Abordagens estatísticas para identificar desequilíbrios
The most common approach for identifying SRM is to use a chi-square test that can quickly detect when something is wrong. These tests, however, can't help identify why an imbalance has happened. So, as a follow up, some platforms allow experimenters to perform "eyeball statistics." This allows segmenting data to understand which attribute might be driving the imbalance. For example, information collected and randomized upon platform usage could be segmented into Android and iOS to allow a visual check for irregularities.
Uma melhoria desta segmentação ad-hoc seria executar um teste de qui-quadrado repetidamente em subpopulações de segmentos ou executar testes de permutação em tabelas de contingência. A última abordagem é melhor que um teste de qui-quadrado porque pode assinalar quais os segmentos de utilizadores que estão a provocar o desequilíbrio e fornece estatísticas inferenciais para utilização na tomada de decisões. Dito isto, existem três problemas com a execução de testes de permutação ou testes ad hoc do qui-quadrado:
- They don't generate orthogonal effects. Figure 3 below shows an example in which country and platform segments are analyzed separately, leading to imbalances in both. For example, the imbalance might be caused by Android exposures, yet because the U.S. has more Android users than other parts of the world, the country attribute will also be flagged as an imbalance. Lack of orthogonal effects is the biggest disadvantage of current methods.
- They don't provide a good tradeoff between false positives and the power to detect SRM. Running permutation tests and chi-square tests against dozens of segments requires aggressive p-value corrections, thus reducing the sensitivity of the SRM check.
- São computacionalmente ineficientes. A execução de testes de permutação em escala com dezenas de milhares de verificações diárias pode gerar rapidamente uma pegada de infraestrutura muito ineficiente.
Instead, we wanted an approach that allows us to generate orthogonal effects, scales well, and doesn't sacrifice power.
Figura 4: Para demonstrar porque é que os efeitos ortogonais são importantes, note-se que o Android é a raiz do problema que leva ao desequilíbrio. Mas como os EUA têm mais utilizadores de Android do que outros países, um experimentador pode assumir erradamente que o problema pode ser atribuído ao país do utilizador.
A nossa abordagem: A regressão é tudo o que precisamos
Quando atribuímos aleatoriamente os utilizadores aos grupos de tratamento e de controlo, assumimos que não existe nada no mundo para além da aleatoriedade que determina essas atribuições. Como ilustrado na Figura 5 abaixo, se atribuíssemos um estimador para verificar quaisquer relações entre os atributos dos utilizadores antes da aleatorização e da atribuição, deveria haver zero coeficientes de correlação ou de regressão.
Figura 5: Os atributos recolhidos antes da aleatorização não devem ter qualquer impacto na atribuição do tratamento.
Um estimador que nos fornece propriedades de ortogonalização e gera estatísticas simples de interpretar que nos permitem verificar se algo está relacionado com a atribuição de tratamento é a regressão linear.
We will use two dimensions to more clearly explain how to use linear regression to identify imbalance. Let's assume that we have two attributes we collect at the time of randomization:
- País: EUA, Canadá, Austrália
- Plataforma: Web, iOS, Android
Testaremos a nossa abordagem com três cenários:
- Sem desequilíbrio
- Desequilíbrio devido ao país=Austrália
- Desequilíbrio devido a país=Austrália OU plataforma=Web
Figura 6: No cenário 1, não se regista qualquer desequilíbrio. No cenário 2, existe um desequilíbrio devido ao facto de haver uma divisão de 80/20 em vez de 50/50 na Austrália. No cenário 3, há um desequilíbrio devido ao segmento Austrália e ao segmento Android, que também tem uma divisão 80/20.
import pandas as pd
import numpy as np
import statsmodels.formula.api as smf
def generate_data(n,
platforms=["iOS", "Android", "Web"],
countries=["USA", "AUS", "CAN"]):
np.random.seed(42)
expected_distribution = [0.5, 0.5]
experiment_groups = [1, 0]
df = pd.DataFrame(
{
"user_id": range(1, n + 1),
"platform": np.random.choice(platforms, size=n),
"country": np.random.choice(countries, size=n),
}
)
# Scenario 1: No imbalance
df["scenario_1"] = np.random.choice(experiment_groups, size=n, p=expected_distribution)
# Scenario 2: Australia 80/20 imbalance
df["scenario_2"] = df["scenario_1"]
mask_2 = df["country"] == "AUS"
df.loc[mask_2, "scenario_2"] = np.random.choice(experiment_groups, size=sum(mask_2), p=[0.8, 0.2])
# Scenario 3: Australia or Android 80/20 imbalance
df["scenario_3"] = df["scenario_1"]
mask_3 = (df["country"] == "AUS") | (df["platform"] == "Android")
df.loc[mask_3, "scenario_3"] = np.random.choice(experiment_groups, size=sum(mask_3), p=[0.8, 0.2])
return df
Neste trecho de código, geramos dados com três opções de aleatorização: uma com atribuição completamente aleatória, uma em que a distorção da distribuição é orientada pela plataforma e uma em que a distorção da distribuição é orientada pelo país ou pela plataforma.
Fundamentalmente, se quisermos compreender que atributos estão relacionados com a atribuição do tratamento, basta ajustar uma regressão com a seguinte forma:
is_treatment ~ país + plataforma
O código abaixo permite-nos executar esta regressão.
def run_model(df, scenario_name):
# center the outcome variable around expected ratio
df['is_treatment'] = df[scenario_name] - 0.5
formula = "is_treatment ~ 1 + platform + country"
# fit the regression
m = smf.glm(formula, data=df).fit(cov_type="HC1")
# get the p-values for the main effect using a Wald test
wald_p_values = m.wald_test_terms(scalar=True).table
return wald_p_values
Here we run a regression to explain if treatment assignment is a function of platform and country variables. Given that we're interested only in the main effects of those variables, we follow it up with a Wald test that asks: Is the main effect of a particular predictor related to treatment assignment?
Note that when we run the regression, we are interested in main effects (e.g., "Is there a main effect of the platform on treatment assignment?"), so we use a Wald test to get the p-values for the main effect. Figure 7 shows the Wald test output for each of the three scenarios. We can immediately draw these conclusions:
- No Cenário 1, nenhum dos atributos está relacionado com a atribuição do tratamento.
- In Scenario 2, we can see that country has a very low p-value. There is a main effect from country, but we don't know yet which specific country segment is responsible for the imbalance.
- No Cenário 3, podemos ver que tanto a plataforma como o país são factores de desequilíbrio.
Figure 7: The Wald test results show: In scenario 1, none of the attributes are related to treatment assignment. In scenario 2, only country is related to treatment assignment (p<0.0001) and in scenario 3 both platform and country are predictive of treatment assignment (p<0.0001).
Note-se que a nossa implementação interna é mais complexa. O processo de exemplo descrito até agora só nos permite encontrar os efeitos principais. Internamente, aplicamos um algoritmo recursivo para eliminar subconjuntos dos dados que mais contribuem para o desequilíbrio, à semelhança do que um experimentador faria no processo de recuperação de dados de SRM. Além disso, aplicamos uma correção aos valores de p quando efectuamos verificações múltiplas e tratamos uma variedade de casos extremos, como quando um segmento tem variância zero ou a regressão não é invertível devido a uma multicolinearidade perfeita.
Optimizações
As shown in the code snippet below, an important optimization we can do relies on weighted regression when performing the computation. Using weights in regression allows efficient scaling of the algorithm, even when interacting with large datasets. With this approach, we don't just perform the regression computation more efficiently, we also minimize any network transfer costs and latencies and can perform much of the aggregation to get the inputs on the data warehouse.
df_aggregated = df.groupby(['country', 'platform', 'scenario_1'], as_index=False).size()
model1 = smf.glm(formula, data=df, freq_weights=df.size.df_aggregated).fit(cov_type="HC1")
Neste exemplo, agregamos os dados ao nível da plataforma, do país e do grupo de experiências. Esta agregação permite-nos reduzir o tamanho dos dados de milhões para centenas de linhas, tornando o cálculo do SRM muitas ordens de grandeza mais eficiente. Esta agregação é efectuada no lado do armazém de dados.
Extensões
Depois de excluir todas as causas de desequilíbrio, uma extensão desta metodologia consistiria em utilizar a abordagem de regressão para corrigir as MRE, recuperando assim os dados recolhidos. Isto só deve ser feito depois de terem sido identificadas causas claras de desequilíbrio. Para aplicar a correção, basta ajustar uma regressão com esta forma:
metric_outcome ~ is_treatment + country + platform
A adição das duas variáveis regressoras não só corrige os resultados para a SRM, como também pode contribuir para a redução da variância, uma vez que as covariáveis adicionais podem explicar alguma da variância no resultado métrico.
Observabilidade
A DoorDash também explorou formas de proporcionar aos utilizadores uma melhor observabilidade das exposições a experiências, para além dos métodos estatísticos mencionados anteriormente. As exposições de experiências são um dos nossos eventos de maior volume. Num dia normal, a nossa plataforma produz entre 80 mil milhões e 110 mil milhões de eventos de exposição. Transmitimos esses eventos para o Kafka e depois armazenamo-los no Snowflake. Os utilizadores podem consultar estes dados para resolver problemas das suas experiências. No entanto, existem alguns problemas com as ferramentas actuais:
- Existe um desfasamento da ordem das dezenas de minutos entre o momento em que as exposições são criadas e o momento em que estão disponíveis para consulta no Snowflake.
- As consultas demoram muito tempo a ser executadas no Snowflake, mesmo depois de aplicarmos o particionamento. A execução de consultas complexas demora ainda mais tempo.
Queremos oferecer aos utilizadores um painel de controlo fácil de consumir que lhes permita monitorizar e observar as exposições das experiências em tempo real. Isto permite aos utilizadores obter informações imediatas sobre o desempenho e a saúde das suas experiências em curso. Como benefício adicional, o painel de controlo reduz a nossa dependência do Snowflake para solucionar problemas de experiências, reduzindo assim os custos operacionais gerais.
We needed to do two things to create the dashboards. First, we had to aggregate the exposure stream across different dimensions. We included dimensions like experiment name, experiment version, variant, and segment, which represents the population group for the sample as defined when setting up the experiment. For this task, we used Apache Flink, which supports stream processing and provides event-time processing semantics. Supported internally at DoorDash, Flink is used by many teams to run their processing jobs on streaming data. We use Flink's built-in time-window-based aggregation functions on exposure time. We then send this aggregated data to another Kafka topic.
Next, we had to save the data that is aggregated by the time-window into a datastore. We wanted an analytics OLAP datastore with low latency. For this we used Apache Pinot. Pinot is a real-time distributed OLAP datastore which can ingest data from streaming sources like Kafka, scale horizontally, and provide real-time analytics with low latency. We rely on Pinot's built-in aggregation functions to produce the final results, which are fed into the user dashboards to provide various visualizations. Figure 8 below shows the high-level overview of our solution:
Figura 8: Aqui resumimos o nosso processamento de fluxos em tempo real.
Adicionámos outra camada de transparência ao incorporar estes painéis na nossa plataforma de configuração de experiências. Com esta ferramenta, os utilizadores podem resolver rapidamente uma série de problemas associados ao SRM, incluindo:
- Lancei uma variante de tratamento mais cedo do que outra?
- Há mais exposições num grupo do que noutro?
- Existem anomalias nas séries cronológicas dos registos de exposição?
Abaixo encontram-se exemplos de gráficos dos nossos painéis de controlo.
Figura 9: Mostra a linha de tempo da contagem de exposições por variante. Um utilizador pode aceder a estes dados poucos minutos após o lançamento de uma experiência.
Figura 10: As visualizações da distribuição das exposições por cada variante permitem ao utilizador verificar se existem irregularidades importantes.
As informações em tempo real não só ajudam a diagnosticar problemas com as experiências, como também geram uma maior confiança de que uma implementação está a decorrer como esperado.
Alerta
To further minimize the rate of SRM occurrences, users can subscribe to an experiment health check alert system that notifies them quickly - often within 24 hours - if an imbalance is detected within their experiment. This allows for timely, proactive adjustments that can virtually eliminate the need to discard otherwise valuable data down the line due to invalidated results.
Figura 11: Ao criar uma experiência, os utilizadores podem subscrever o nosso sistema de alertas.
A educação é fundamental: O papel da sensibilização na redução das MRE
In our quest to reduce the incidence of SRM on the platform, we've explored and implemented a variety of technical solutions - from real-time monitoring systems to new algorithms that identify imbalance sources. While these advancements have been crucial in minimizing SRM, we found that human intervention through awareness and education remains indispensable and moves the needle most. Recognizing this gap, we initiated a multi-pronged educational approach, including:
- Sessões de formação: Organizámos um bootcamp interno centrado nas melhores práticas para a configuração de experiências, destacando a forma de evitar desequilíbrios devido a problemas simples de configuração.
- Documentation: We provided comprehensive guides with case studies that a non-technical person can understand. We even renamed the terminology internally from "Sample Ratio Mismatch," which is a technical mouthful, to "Imbalance Check."
- Stronger language: We changed documentation language and how we communicate SRM failures to be more in line with the size of impact that it has on decision making. Although there are rare cases in which SRM failures can be overlooked, the revised language emphasizes that imbalanced experiment results can't be trusted.
- Envolvimento proactivo do utilizador: A natureza reactiva da resolução de problemas constitui um desafio para minimizar as MRE. Os utilizadores só se apercebem das SRM depois de se depararem com o problema, o que muitas vezes leva a acções atrasadas. Em vez de esperar que os utilizadores participem na nossa sessão de formação ou abram a documentação e as ferramentas de diagnóstico, envolvemo-los desde o início através de sessões de partilha de conhecimentos específicos da equipa.
Por vezes, as melhores soluções não consistem apenas em construir uma ratoeira melhor, mas sim em garantir que toda a gente sabe como utilizar as novas ferramentas de forma eficaz. Para nós, a educação e a sensibilização fizeram toda a diferença. Escrever este blogue é, por si só, uma tentativa de promover uma maior sensibilização e educação.
Resultados
Nos seis meses seguintes ao início do nosso trabalho, registámos uma queda de 70% nos incidentes de SRM na plataforma. Isto significa que centenas de experiências que poderiam ter sido afectadas por conclusões incorrectas conduziram, em vez disso, a resultados legítimos. Para além dos números, houve uma mudança palpável na dinâmica da equipa. Com uma maior consciencialização, os testes A/B são definidos e revistos com mais cuidado e executados com mais sucesso. As equipas já não têm de gastar recursos valiosos e capacidade experimental para reiniciar testes ou reconciliar resultados inesperados causados por falhas de desequilíbrio.
Trabalho futuro
Embora tenhamos feito grandes progressos no sentido de reduzir a incidência de SRM na DoorDash, acreditamos que podem ser feitas ainda mais melhorias através da observabilidade em tempo real, da correção automática e da normalização.
- A observabilidade em tempo real pode ser melhorada através de uma integração mais estreita com os algoritmos utilizados na verificação de diagnóstico. É computacionalmente pouco dispendioso executar testes Wald e regressão ponderada em dados de contagem, pelo que gostaríamos de os executar nas saídas de consulta de Pinot sempre que um utilizador examina exposições em tempo real.
- A correção automática permite-nos corrigir problemas comuns das MRE e ajustar os resultados das experiências sem obrigar o utilizador a tomar qualquer medida adicional. Como demonstrado anteriormente, se conseguirmos identificar a origem do desequilíbrio, podemos muitas vezes salvar o resultado da análise adicionando covariáveis adicionais ao nosso estimador.
- A normalização oferece uma salvaguarda contra armadilhas comuns, reduzindo assim a probabilidade de erros do utilizador. Por exemplo, se um utilizador corrigir um erro e relançar uma experiência, o nosso sistema pode identificar proactivamente as potenciais repercussões das alterações e ajustar a intensidade dos avisos ou orientações em conformidade.
Através destas medidas, podemos aumentar ainda mais a robustez e a credibilidade dos resultados experimentais.
Agradecimentos
Os meus agradecimentos a Drew Trager, Sharon Weng, Hassan Djirdeh, Yixin Tang, Dave Press, Bhawana Goel, Caixia Huang, Kevin Tang e Qiyun Pan, que foram fundamentais no seu feedback, execução e colaboração em muitas das iniciativas acima descritas. Por último, os nossos agradecimentos à equipa de capacitação de engenheiros: Janet Rae-Dupree, Robby Kalland e Marisa Kwan pelo seu apoio contínuo na revisão e edição deste artigo.
If you're passionate about building innovative products that make positive impacts in the lives of millions of merchants, Dashers, and customers, consider joining our team.
Mantenha-se informado com as actualizações semanais
Subscreva o nosso blogue de Engenharia para receber actualizações regulares sobre todos os projectos mais interessantes em que a nossa equipa está a trabalhar