Executar testes A/B com duas versões de um modelo

Depois de treinar um novo modelo personalizado ou o modelo do AutoML Vision Edge, é possível usar o Teste A/B para comparar o desempenho do novo modelo em condições reais com o do modelo que você já usa. Depois de confirmar que seu novo modelo é uma melhoria, ele poderá ser implantado facilmente para todos os usuários, sem a necessidade de uma atualização do app.

Veja nesta página como realizar um teste A/B para avaliar duas versões de um modelo que potencializa um recurso hipotético de pesquisa visual de plantas. Nele, um modelo de rotulagem de imagens personalizado permite que os usuários usem imagens para identificar espécies de plantas.

Suponha que você acabou de publicar um novo modelo de rotulagem de plantas, plant_labeler_v2, e quer executar um experimento que o compare com seu modelo atual, chamado plant_labeler_v1. Veja nas etapas abaixo como configurar e executar o experimento e tomar medidas em relação aos resultados.

1. Possibilitar a configuração remota do seu modelo

Ao fazer um teste A/B nos seus modelos, a primeira etapa é alterar o app para que use um parâmetro da Configuração remota a fim de determinar qual modelo vai ser usado. Primeiro, defina o valor padrão desse parâmetro como o modelo que o app já usa. Como o nome do modelo é controlado por um parâmetro de configuração remota, é possível alterar e fazer experimentos com vários modelos sem a necessidade de enviar atualizações do app para os usuários.

Dessa forma, ao publicar seu modelo atual com o nome plant_labeler_v1, você define, no código de inicialização do seu aplicativo, plant_labeler_v1 como valor padrão do parâmetro plant_labeler_model, conforme o exemplo a seguir:

Swift

let remoteConfig = RemoteConfig.remoteConfig()
let defaults = [
    "plant_labeler_model": "plant_labeler_v1" as NSObject,
    // ...
]
remoteConfig.setDefaults(defaults)
remoteConfig.fetchAndActivate()

Objective-C

FIRRemoteConfig *remoteConfig = [FIRRemoteConfig remoteConfig];
NSDictionary<NSString *, NSObject *> *defaults = @{
  @"plant_labeler_model" : (NSObject *)@"plant_labeler_v1",
  // ...
};
[remoteConfig setDefaults:defaults];
[remoteConfig fetchAndActivateWithCompletionHandler:nil];

Em seguida, altere o código de configuração do modelo para carregar o modelo especificado pelo parâmetro plant_labeler_model:

Swift

let rcValue = remoteConfig.configValue(forKey: "plant_labeler_model")
guard let remoteModelName = rcValue.stringValue else { return }

// ...

let remoteModel = RemoteModel(
    name: remoteModelName,
    allowsModelUpdates: true,
    initialConditions: initialConditions,
    updateConditions: updateConditions
)
ModelManager.modelManager().register(remoteModel)

// Optionally configure a local model:
// https://firebase.google.com/docs/ml/ios/label-images-with-automl#configure-a-local-model-source
// https://firebase.google.com/docs/ml/ios/use-custom-models#configure_a_local_model

Objective-C

FIRRemoteConfigValue *rcValue = [remoteConfig configValueForKey:@"plant_labeler_model"];
NSString *remoteModelName = [rcValue stringValue];

// ...

FIRRemoteModel *remoteModel = [[FIRRemoteModel alloc] initWithName:remoteModelName
                                                allowsModelUpdates:YES
                                                 initialConditions:initialConditions
                                                  updateConditions:updateConditions];
[[FIRModelManager modelManager] registerRemoteModel:remoteModel];

// Optionally configure a local model:
// https://firebase.google.com/docs/ml/android/label-images-with-automl#configure-a-local-model-source
// https://firebase.google.com/docs/ml/android/use-custom-models#configure_a_local_model

Agora que o app usa um parâmetro da Configuração remota para determinar qual modelo carregar, é possível alterar o modelo. Basta publicar um novo modelo e atribuir o nome dele ao parâmetro. Com esse recurso, o Teste A/B atribui modelos diferentes a usuários diferentes com o objetivo de compará-los.

Antes de continuar, faça também a seguinte adição ao download do código do modelo:

Swift

NotificationCenter.default.addObserver(
    forName: .firebaseMLModelDownloadDidSucceed,
    object: nil,
    queue: nil
) { [weak self] notification in
    guard let _ = self,
        let userInfo = notification.userInfo,
        let model = userInfo[ModelDownloadUserInfoKey.remoteModel.rawValue]
            as? RemoteModel,
        model.name == remoteModelName
        else { return }
    // If the model downloaded was specified by a remote parameter, log an
    // event, which will be our experiment's activation event.
    if rcValue.source == .remote {
        Analytics.logEvent("nondefault_model_downloaded", parameters: nil)
    }
}

Objective-C

__weak typeof(self) weakSelf = self;

[NSNotificationCenter.defaultCenter
    addObserverForName:FIRModelDownloadDidSucceedNotification
                object:nil
                 queue:nil
            usingBlock:^(NSNotification *_Nonnull note) {
              if (weakSelf == nil | note.userInfo == nil) {
                return;
              }

              FIRRemoteModel *model = note.userInfo[FIRModelDownloadUserInfoKeyRemoteModel];
              if ([model.name isEqualToString:remoteModelName] &&
                  rcValue.source == FIRRemoteConfigSourceRemote) {
                // If the model downloaded was specified by a remote parameter, log an
                // event, which will be our experiment's activation event.
                [FIRAnalytics logEventWithName:@"nondefault_model_downloaded" parameters:nil];
              }
            }];

O código acima registra um evento personalizado no Analytics que você vai usar adiante como o evento de ativação do experimento. O usuário precisa acionar o evento de ativação antes de ser considerado para fazer parte do experimento. Isso garante que os usuários não sejam registrados no Teste A/B até que o dispositivo conclua o download do seu modelo de ML personalizado.

2. Determinar uma métrica de meta

A próxima etapa é decidir como mensurar o sucesso do seu modelo e verificar se o aplicativo está coletando os dados necessários para testar o desempenho de diferentes versões do modelo de acordo com essa métrica.

O Teste A/B tem várias métricas internas, como "Receita", "Engajamento diário" e "Retenção de usuários". Essas métricas costumam ser úteis para testar diferentes fluxos de UX ou ajustar parâmetros, mas podem não ser adequadas para avaliar seu modelo e caso de uso. Nesses casos, otimize um evento personalizado no Analytics em vez de usar métricas.

Por exemplo, no recurso hipotético de pesquisa visual de plantas, suponha que você apresentou os resultados da pesquisa ao usuário na ordem de confiança do modelo em cada resultado. Observe a frequência com que os usuários abriram o primeiro resultado da pesquisa para verificar a precisão do seu modelo.

Para testar qual modelo melhor cumpriu o objetivo de maximizar cliques nos resultados principais, registre um evento personalizado sempre que um usuário tocar no primeiro item da lista.

Swift

Analytics.logEvent("first_result_opened", parameters: nil)

Objective-C

[FIRAnalytics logEventWithName:@"first_result_opened" parameters:nil];

A métrica a ser testada depende, basicamente, da maneira que o aplicativo usa seu modelo.

Agora é possível implantar o aplicativo na App Store. O app vai continuar usando seu modelo original, mas o código da Configuração remota e do Analytics que você adicionou vai possibilitar a realização de experimentos com modelos diferentes usando apenas o Console do Firebase.

3. Executar um experimento do Teste A/B

Agora que seu aplicativo está nas mãos dos usuários e coletando dados de análise, crie um experimento do Teste A/B para avaliar o efeito do novo modelo no lugar do modelo atual.

Siga as etapas a seguir para criar o experimento:

  1. Na página Eventos do Console do Firebase, verifique se você registrou os eventos relevantes do Analytics: o evento de ativação e a métrica de meta.

    É preciso que seu aplicativo registre cada evento pelo menos uma vez para que ele apareça no Console do Firebase.

  2. No Console do Firebase, abra a seção Teste A/B.

  3. Crie um novo experimento:

    1. Clique em Criar experimento > Configuração remota.

    2. Na seção Segmentação, siga as etapas a seguir:

      • Escolha seu aplicativo na lista.
      • Especifique quantos usuários você quer incluir no experimento.
      • Selecione o evento de ativação que você começou a registrar (neste exemplo, nondefault_model_downloaded)
    3. Na seção Metas, escolha a métrica determinada na seção anterior (neste exemplo, first_result_opened) na lista de métricas de meta e selecione as outras que você quer rastrear, como "Receita de compra" ou "Usuários sem falhas".

    4. Na seção Variantes, defina as duas a seguir:

      • Grupo de controle (criado automaticamente)
      • Rotulador de plantas experimental

      Para o grupo de controle, crie um parâmetro plant_labeler_model e defina-o como plant_labeler_v1. Os usuários atribuídos a esse grupo utilizarão o modelo antigo. Não defina o parâmetro como (no change) porque, no seu aplicativo, você está testando se está usando um valor remoto.

      Para a variante Rotulador de plantas experimental, defina o parâmetro plant_labeler_model como plant_labeler_v2 (supondo que você tenha publicado seu novo modelo com esse nome). Os usuários atribuídos a essa variante usarão o novo modelo.

    Tela de configuração do teste A/B

Inicie e execute o experimento por vários dias ou mais, até que o Teste A/B selecione a variante vencedora. Poderá ser necessário expandir a experiência para mais usuários se o experimento não determinar um líder.

4. Distribuir a variante vencedora para todos os usuários

Card de resultados do teste A/B

Depois que o Teste A/B coletar informações suficientes para apresentar um líder (neste caso, a variante que maximizou os cliques nos principais resultados da pesquisa), você decidirá se quer distribuir a variante vencedora, ou qualquer outra, para todos os usuários.

Na seção Teste A/B do Console do Firebase, abra a visualização de detalhes do experimento concluído. Nela, você verá o desempenho de cada variante de acordo com a métrica da meta e outras métricas secundárias selecionadas. Com essas informações, você pode optar pela distribuição da variante líder ou de outra variante.

Para lançar uma variante para todos os usuários, clique em > Lançar variante na página de detalhes do experimento. Depois de fazer isso, o valor do parâmetro plant_labeler_model será plant_labeler_v2 para todos os usuários.

Em uma futura atualização do app, altere o valor padrão do parâmetro plant_labeler_model para plant_labeler_v2 e atualize o modelo agrupado, caso você use um. No entanto, seus usuários já usarão o modelo mais recente. Assim, você vai poder enviar a atualização como parte do app publicado sempre que for conveniente, como quando você fizer uma atualização de recursos.