5  👥 Analisando diversos perfis

ou diversas campanhas em um resumo.

Agora que você chegou até aqui, acho que posso te dar uma boa notícia! Os indicadores analiticos campanha, público, quantidade de teste e controle e as quantidades de conversão, costumam vir calculados, pois é um processo que pode ser automatizado via banco de dados.

Com isso, cada linha da sua tabela pode representar uma campanha diferente, ou uma segmentação de público diferente dentro da mesma!

Nesse exemplo aplicado, irei seguir com quebras de público, onde quero testar diferenças entre conversões de taxas de emprestimos diferentes. Um teste A/B raiz, afinal, todos foram abordados, mas receberam ofertas diferentes, se aplicamos em marketing, seriam ofertas e/ou banners diferentes para cada público

5.1 ➕Um pouco mais de contexto

*dados ficticios

Esses resultados foram simulados a partir de uma atividade de princing, onde foram usados dois modelos para caracterizar os grupos de maneiras comparáveis.

  • MODELO 1: Risco de realizar essa operação

  • MODELO 2: Probabilidade do cliente aceitar a oferta

5.1.1 📥Import das bibliotecas

import pandas as pd
from statsmodels.stats.proportion import proportions_ztest
from scipy.stats import ttest_ind_from_stats
import numpy as np
import warnings

# Suprimir apenas RuntimeWarnings
warnings.filterwarnings("ignore", category=RuntimeWarning)
# Carregar a planilha com colunas a serem completadas
df = pd.read_excel("./diversos_grupos_calculo.xlsx")
df.head()
MODELO 1 MODELO2 Taxa Teste Taxa Controle Qtde Teste Qtde Controle Qtde Conversao Teste Qtde Conversao Controle Faturamento Teste Faturamento Controle
0 BAIXO BAIXO 0.0299 0.0399 21996 197964 1979 15837 8232897.27 3.895902e+06
1 BAIXO ALTO 0.0399 0.0499 31259 281331 1562 22506 1098086.00 9.585305e+07
2 MÉDIO BAIXO 0.0499 0.0599 36027 324243 1801 19454 6933850.00 7.322486e+07
3 MÉDIO ALTO 0.0599 0.0699 81498 733482 814 66013 4004066.00 3.671643e+07
4 ALTO BAIXO 0.0699 0.0799 57985 521865 4058 52186 7925274.00 2.569811e+08

5.1.2 🧠 Pró-Memória

Agora vamos passar por todos os cálculos feitos no capítulo anterior:

  • Conversão e Taxas

  • Gasto Médio

  • Incrementos

  • Testes de hipoteses para avaliar a significancia dos resultados

  • Avaliação Final

# Função para enriquecer o dataframe
def enrich_with_proportions(row):
    # Conversões e taxas
    conv_teste = row['Qtde Conversao Teste'] / row['Qtde Teste'] if row['Qtde Teste'] > 0 else 0
    conv_controle = row['Qtde Conversao Controle'] / row['Qtde Controle'] if row['Qtde Controle'] > 0 else 0
    delta_conv = conv_teste - conv_controle
    lift_conversao = (conv_teste - conv_controle) / conv_controle if conv_controle > 0 else np.nan
    lift_conversao_percentual = lift_conversao * 100

    # Gasto médio como proporção = Faturamento / Qtde Conversões
    faturamento_teste = row['Faturamento Teste']
    faturamento_controle = row['Faturamento Controle']
    
    gasto_medio_teste = faturamento_teste / row['Qtde Conversao Teste'] if row['Qtde Conversao Teste'] > 0 else 0
    gasto_medio_controle = faturamento_controle / row['Qtde Conversao Controle'] if row['Qtde Conversao Controle'] > 0 else 0
    delta_gasto = gasto_medio_teste - gasto_medio_controle

    # Incrementos
    incremento_contas = delta_conv * row['Qtde Teste']
    incremento_gasto = delta_gasto * row['Qtde Conversao Teste']
    incremento_faturamento = incremento_contas * gasto_medio_controle + incremento_gasto

    # Teste de hipótese para conversão (proporções)
    if row['Qtde Teste'] > 0 and row['Qtde Controle'] > 0:
        count_conv = [row['Qtde Conversao Controle'], row['Qtde Conversao Teste']]
        nobs_conv = [row['Qtde Controle'], row['Qtde Teste']]
        _, p_conv = proportions_ztest(count_conv, nobs_conv)
    else:
        p_conv = np.nan

    resultado_conv = "Rejeita H₀" if p_conv < 0.05 and delta_conv > 0 else "Aceita H₀"

    # Teste de hipótese para gasto (proporções também, pois gasto médio é faturamento/conversão)
    if row['Qtde Conversao Controle'] > 0 and row['Qtde Conversao Teste'] > 0:
        count_gasto = [faturamento_controle, faturamento_teste]
        nobs_gasto = [row['Qtde Conversao Controle'], row['Qtde Conversao Teste']]
        _, p_gasto = proportions_ztest(count_gasto, nobs_gasto)
    else:
        p_gasto = np.nan

    resultado_gasto = "Rejeita H₀" if p_gasto < 0.05 and delta_gasto > 0 else "Aceita H₀"

    # Avaliação final (tabela de decisão)
    amostra_suficiente = row['Qtde Teste'] >= 30 and row['Qtde Controle'] >= 30
    conv_significativa = p_conv < 0.05 if not np.isnan(p_conv) else False
    gasto_significativo = p_gasto < 0.05 if not np.isnan(p_gasto) else False

    if amostra_suficiente:
        if conv_significativa and gasto_significativo:
            interpretacao = "✅ Resultados estatisticamente confiáveis. Pode fazer rollout com segurança."
        elif conv_significativa and not gasto_significativo:
            interpretacao = "⚠️ Conversão positiva e confiável, mas impacto financeiro incerto. Teste complementar recomendado."
        elif not conv_significativa and gasto_significativo:
            interpretacao = "⚠️ Conversão estável, mas há aumento de gasto. Reavaliar se isso é desejável."
        else:
            interpretacao = "❌ Sem evidências de ganho. Não prosseguir com rollout."
    else:
        if conv_significativa and gasto_significativo:
            interpretacao = "⚠️ Indicadores promissores, mas resultados frágeis estatisticamente. Aumentar amostra."
        elif conv_significativa:
            interpretacao = "⚠️ Conversão aparente, mas não confiável. Repetir experimento com mais dados."
        elif gasto_significativo:
            interpretacao = "⚠️ Gasto parece maior, mas não confiável. Não tomar decisão ainda."
        else:
            interpretacao = "❌ Nada é significativo e a amostra é fraca. Não prosseguir."

    return pd.Series([
        conv_teste, conv_controle, delta_conv, lift_conversao_percentual,
        gasto_medio_teste, gasto_medio_controle, delta_gasto,
        incremento_contas, incremento_gasto, incremento_faturamento,
        resultado_conv, resultado_gasto, interpretacao
    ], index=[
        'Conversão Teste', 'Conversão Controle', 'Delta Conversão', 'Lift Conversão (%)',
        'Gasto Médio Teste', 'Gasto Médio Controle', 'Delta Gasto Médio',
        'Incremento Contas', 'Incremento Gasto', 'Incremento Faturamento',
        'Resultado Conversão', 'Resultado Gasto', 'Interpretação Final'
    ])

# Aplicar a função
df_enriched = df.join(df.apply(enrich_with_proportions, axis=1))
df_enriched
MODELO 1 MODELO2 Taxa Teste Taxa Controle Qtde Teste Qtde Controle Qtde Conversao Teste Qtde Conversao Controle Faturamento Teste Faturamento Controle ... Lift Conversão (%) Gasto Médio Teste Gasto Médio Controle Delta Gasto Médio Incremento Contas Incremento Gasto Incremento Faturamento Resultado Conversão Resultado Gasto Interpretação Final
0 BAIXO BAIXO 0.0299 0.0399 21996 197964 1979 15837 8232897.27 3.895902e+06 ... 12.464482 4160.13 246.00 3914.13 219.333333 7746063.27 7.800019e+06 Rejeita H₀ Aceita H₀ ⚠️ Conversão positiva e confiável, mas impacto...
1 BAIXO ALTO 0.0399 0.0499 31259 281331 1562 22506 1098086.00 9.585305e+07 ... -37.536657 703.00 4259.00 -3556.00 -938.666667 -5554472.00 -9.552253e+06 Aceita H₀ Aceita H₀ ⚠️ Conversão positiva e confiável, mas impacto...
2 MÉDIO BAIXO 0.0499 0.0599 36027 324243 1801 19454 6933850.00 7.322486e+07 ... -16.680374 3850.00 3764.00 86.00 -360.555556 154886.00 -1.202245e+06 Aceita H₀ Aceita H₀ ⚠️ Conversão positiva e confiável, mas impacto...
3 MÉDIO ALTO 0.0599 0.0699 81498 733482 814 66013 4004066.00 3.671643e+07 ... -88.902186 4919.00 556.20 4362.80 -6520.777778 3551319.20 -7.553740e+04 Aceita H₀ Aceita H₀ ⚠️ Conversão positiva e confiável, mas impacto...
4 ALTO BAIXO 0.0699 0.0799 57985 521865 4058 52186 7925274.00 2.569811e+08 ... -30.015713 1953.00 4924.33 -2971.33 -1740.444444 -12057657.14 -2.062818e+07 Aceita H₀ Aceita H₀ ⚠️ Conversão positiva e confiável, mas impacto...
5 ALTO ALTO 0.0799 0.0899 68921 620289 6892 31014 26058652.00 1.059748e+08 ... 100.000000 3781.00 3417.00 364.00 3446.000000 2508688.00 1.428367e+07 Rejeita H₀ Aceita H₀ ⚠️ Conversão positiva e confiável, mas impacto...
6 ALTISSIMO BAIXO 0.0899 0.0999 85970 773730 3438 30949 4201236.00 7.471089e+07 ... -0.022618 1222.00 2414.00 -1192.00 -0.777778 -4098096.00 -4.099974e+06 Aceita H₀ Aceita H₀ ❌ Sem evidências de ganho. Não prosseguir com ...
7 ALTISSIMO ALTO 0.0999 0.1099 98759 888831 6913 71106 31571671.00 2.320189e+08 ... -12.501055 4567.00 3263.00 1304.00 -987.666667 9014552.00 5.791796e+06 Aceita H₀ Aceita H₀ ⚠️ Conversão positiva e confiável, mas impacto...

8 rows × 23 columns

Agora que você possui o impacto de cada taxa é só tomar a decisão se fará um roll-out ou não.

#Exporta o resultado para o excel
df_enriched.to_excel("TesteABDiversosGrupos.xlsx", index=False)