HyperOpt Desmistificado

Como automatizar o ajuste de modelo com HyperOpt

Você adora afinar modelos? Se sua resposta for “sim”, este post é não para você.

Modelo de ajuste de hiperparâmetros de hiperparâmetros ajuste de modelo de aprendizado de máquina ciência de dados modelo sklearn mllib spark hyperopt tree parzen estimador tpe tree based parzen esimtator mlflow databricks
Um desenho animado do meu avô - site do Network Development Group.

Neste blog, abordaremos o algoritmo de ajuste automatizado de hiperparâmetros extremamente popular chamado Estimadores Parzen baseados em árvores (TPE). O TPE é suportado pelo pacote de código aberto HyperOpt. Ao aproveitar o HyperOpt e o TPE, os engenheiros de aprendizado de máquina podem desenvolver rapidamente modelos altamente otimizados sem qualquer ajuste manual.

Sem mais delongas, vamos mergulhar!

HyperOpt é um pacote python de código aberto que usa um algoritmo chamado Parzen Esimtors baseado em árvore (TPE) para selecionar hiperparâmetros de modelo que otimizam uma função objetivo definida pelo usuário. Ao simplesmente definir a forma funcional e os limites de cada hiperparâmetro, o TPE pesquisa de forma completa, mas eficiente, através do hiperespaço complexo para alcançar os ótimos.

TPE é um algoritmo sequencial que aproveita a atualização bayesiana e segue a sequência abaixo.

  1. Treine um modelo com vários conjuntos de hiperparâmetros selecionados aleatoriamente, retornando valores de função objetivo.
  2. Divida nossos valores de função objetivo observados em grupos “bons” e “ruins”, de acordo com algum limite gama (γ).
  3. Calcule a pontuação de “promessa”, que é apenas P(x|bom) / P(x|ruim).
  4. Determine os hiperparâmetros que maximizam a promessa por meio de modelos de mistura.
  5. Ajuste nosso modelo usando os hiperparâmetros da etapa 4.
  6. Repita as etapas 2–5 até um critério de parada.

Aqui está um exemplo de código rápido.

Ok, foram muitas palavras complicadas. Vamos desacelerar e realmente entender o que está acontecendo.

1.1 — Nosso Objetivo

Os cientistas de dados estão ocupados. Queremos produzir modelos realmente bons, mas fazê-lo de maneira eficiente e, idealmente, sem intervenção.

No entanto, certas etapas do ciclo de vida da modelagem de ML são muito difíceis de automatizar. A análise exploratória de dados (EDA) e a engenharia de recursos, por exemplo, geralmente são específicas de um assunto e requerem intuição humana. O ajuste de modelo, por outro lado, é um processo iterativo onde os computadores podem se destacar.

Nosso objetivo ao longo desta postagem é entender como aproveitar algoritmos para automatizar o processo de ajuste de modelo.

Para nos ajudar a pensar nesse objetivo, vamos usar uma analogia: somos piratas em busca de um tesouro enterrado. Também é importante notar que somos piratas muito eficientes que procuram minimizar o nosso tempo na busca pelo tesouro enterrado. Então, como devemos minimizar o tempo gasto na pesquisa? A resposta é use um mapa!

Modelo de ajuste de hiperparâmetros de hiperparâmetros ajuste de modelo de aprendizado de máquina ciência de dados modelo sklearn mllib spark hyperopt tree parzen estimador tpe tree based parzen esimtator mlflow databricks
Figura 1: exemplo de espaço de pesquisa de hiperparâmetro 3D. A localização do baú do tesouro é um ótimo global. Imagem do autor.

Na figura 1 temos um mapa fictício que mostra onde está localizado o nosso tesouro. Depois de muita escalada e escavação, não seria muito difícil chegar a esse tesouro porque sabemos exatamente onde ele está localizado.

Mas o que acontece quando não temos um mapa?

Quando temos a tarefa de ajustar um modelo, infelizmente não recebemos um mapa. Nosso terreno, que corresponde ao espaço de busca do hiperparâmetro, é desconhecido. Além disso, a localização do nosso tesouro, que corresponde ao conjunto ideal de hiperparâmetros, também é desconhecida.

Com essa configuração, vamos falar sobre algumas maneiras possíveis de explorar esse espaço com eficiência e encontrar algum tesouro!

1.2 — Soluções Potenciais

O método original para ajuste do modelo é “manual” – o engenheiro testará manualmente muitas configurações diferentes e verá qual combinação de hiperparâmetros produz o melhor modelo. Embora informativo, esse processo é ineficiente. Deve haver uma maneira melhor…

1.2.1 — Pesquisa em grade (pior)

Nosso primeiro algoritmo de otimização é a pesquisa em grade. A pesquisa em grade testa iterativamente todas as combinações possíveis de hiperparâmetros dentro de uma grade especificada pelo usuário.

Modelo de ajuste de hiperparâmetros de hiperparâmetros ajuste de modelo de aprendizado de máquina ciência de dados modelo sklearn mllib spark hyperopt tree parzen estimador tpe tree based parzen esimtator mlflow databricks
Figura 2: exemplo de layout de pesquisa em grade. Imagem do autor

Por exemplo, na figura 2, onde quer que você veja um ponto vermelho é onde iremos treinar novamente e avaliar nosso modelo. Este quadro é ineficiente porque reutiliza hiperparâmetros ruins. Por exemplo, se o hiperparâmetro 2 tiver pouco impacto em nossa função objetivo, ainda testaremos todas as combinações de seus valores, aumentando assim o número necessário de iterações em 10x (neste exemplo).

Mas antes de prosseguir, é importante observar que a pesquisa em grade ainda é bastante popular porque é garantido encontrar um ótimo, dada uma grade especificada corretamente. Se você decidir usar o método, certifique-se de transformar sua grade para refletir a forma funcional de seus hiperparâmetros. Por exemplo, max_profundidade para um classificador de floresta aleatório é um número inteiro - não deixe que pesquise em um espaço contínuo. Também é improvável que tenha uma distribuição uniforme — se você conhece a forma funcional do seu hiperparâmetro, transforme a grade para refleti-la.

Em suma, a pesquisa em grade está sujeita à maldição da dimensionalidade e recalcula informações entre avaliações, mas ainda é amplamente utilizada.

1.2.2 — Pesquisa Aleatória (boa)

Nosso segundo algoritmo é a pesquisa aleatória. A pesquisa aleatória tenta valores aleatórios dentro de uma grade especificada pelo usuário. Ao contrário da pesquisa em grade, não estamos relegados a testar todas as combinações possíveis de hiperparâmetros, o que aumenta a eficiência.

Modelo de ajuste de hiperparâmetros de hiperparâmetros ajuste de modelo de aprendizado de máquina ciência de dados modelo sklearn mllib spark hyperopt tree parzen estimador tpe tree based parzen esimtator mlflow databricks
Figura 3: exemplo de busca aleatória. Imagem do autor.

Aqui está um fato interessante: a pesquisa aleatória encontrará (em média) uma configuração de hiperparâmetro de 5% superior dentro 60 iterações. Dito isto, assim como acontece com a pesquisa em grade, você deve transformar seu espaço de pesquisa para refletir a forma funcional de cada hiperparâmetro.

A pesquisa aleatória é uma boa base para otimização de hiperparâmetros.

1.2.3 — Otimização Bayesiana (melhor)

Nosso terceiro candidato é nosso primeiro algoritmo de otimização baseada em modelo sequencial (SMBO). A principal diferença conceitual das técnicas anteriores é que use iterativamente execuções anteriores para determinar pontos futuros de exploração.

Modelo de ajuste de hiperparâmetros de hiperparâmetros ajuste de modelo de aprendizado de máquina ciência de dados modelo sklearn mllib spark hyperopt tree parzen estimador tpe tree based parzen esimtator mlflow databricks
Figura 4: exemplo de otimização bayesiana — src. Imagem do autor.

A otimização bayesiana de hiperparâmetros busca desenvolver uma distribuição probabilística de nosso espaço de busca de hiperparâmetros. A partir daí, utiliza uma função de aquisição, como a melhoria esperada, para transformar o nosso hiperespaço para ser mais “pesquisável”. Finalmente, ele usa um algoritmo de otimização, como gradiente descendente estocástico, para encontrar os hiperparâmetros que maximizam nossa função de aquisição. Esses hiperparâmetros são usados ​​para ajustar nosso modelo e o processo é repetido até a convergência.

A otimização bayesiana normalmente supera a pesquisa aleatória, no entanto, tem algumas limitações básicas, como a necessidade de hiperparâmetros numéricos.

1.2.4 — Estimadores Parzen baseados em árvores (melhores)

Por fim, vamos falar sobre a estrela do show: Tree-Based Parzen Estimators (TPE). TPE é outro algoritmo SMBO que normalmente supera a otimização bayesiana básica, mas o principal ponto de venda é que ele lida com relacionamentos complexos de hiperparâmetros por meio de uma estrutura em árvore.

Modelo de ajuste de hiperparâmetros de hiperparâmetros ajuste de modelo de aprendizado de máquina ciência de dados modelo sklearn mllib spark hyperopt tree parzen estimador tpe tree based parzen esimtator mlflow databricks
Figura 5: exemplo de estrutura hierárquica para TPE — src. Imagem do autor.

Vamos usar a figura 5 para entender isso estrutura de árvore. Aqui estamos treinando um classificador Support Vector Machine (SVM). Testaremos dois kernels: linear e RBF. UMA linear o kernel não aceita um parâmetro de largura, mas RBF faz, então, usando um dicionário aninhado, podemos codificar essa estrutura e, assim, limitar o espaço de pesquisa.

O TPE também suporta variáveis ​​categóricas que a otimização Bayesiana tradicional não suporta.

Isenção de responsabilidade rápida antes de prosseguir, existem muitos outros pacotes de ajuste de hiperparâmetros. Cada um suporta uma variedade de algoritmos, alguns dos quais incluem floresta aleatória, processos gaussianos e algoritmos genéticos. TPE é um algoritmo muito popular e de uso geral, mas não é necessariamente o melhor.

Em geral, o TPE é uma solução de otimização de hiperparâmetros realmente robusta e eficiente.

Agora que temos uma compreensão geral de alguns algoritmos populares de otimização de hiperparâmetros, vamos nos aprofundar em como o TPE funciona.

Voltando à nossa analogia, somos piratas em busca de um tesouro enterrado mas não tenho um mapa. Nosso capitão precisa do tesouro o mais rápido possível, então precisamos cavar em locais estratégicos que tenham alta probabilidade de ter tesouros, usando escavações anteriores para determinar a localização de escavações futuras.

2.1 — Inicialização

Para começar, nós definir as restrições em nosso espaço. Conforme observado acima, nossos hiperparâmetros geralmente têm uma forma funcional, valores máximos/mínimos e relação hierárquica com outros hiperparâmetros. Usando nosso conhecimento sobre nossos algoritmos de ML e nossos dados, podemos definir nosso espaço de busca.

Em seguida, devemos definir nossa função objetivo, que é usado para avaliar quão “boa” é nossa combinação de hiperparâmetros. Alguns exemplos incluem funções clássicas de perda de ML, como RMSE ou AUC.

Ótimo! Agora que temos um espaço de pesquisa limitado e uma forma de medir o sucesso, estamos prontos para começar a pesquisar…

2.2 — Otimização Bayesiana Iterativa

A otimização bayesiana é um algoritmo sequencial que encontra pontos no hiperespaço com alta probabilidade de serem “bem-sucedidos” de acordo com uma função objetivo. O TPE aproveita a otimização bayesiana, mas usa alguns truques inteligentes para melhorar o desempenho e lidar com a complexidade do espaço de pesquisa…

2.2.0 — A configuração conceitual

O primeiro truque é modelar P(x|y) em vez de P(y|x)…

Modelo de ajuste de hiperparâmetros de hiperparâmetros ajuste de modelo de aprendizado de máquina ciência de dados modelo sklearn mllib spark hyperopt tree parzen estimador tpe tree based parzen esimtator mlflow databricks
Figura 6: probabilidade condicional que o TPE procura resolver. Imagem do autor.

A otimização bayesiana normalmente procura modelar P(y|x), que é a probabilidade de um valor de função objetivo (y), dados hiperparâmetros (x). O TPE faz o oposto – parece modelar P(x|y), que é a probabilidade dos hiperparâmetros (x), dado o valor da função objetivo (y).

Resumindo, o TPE tenta encontrar os melhores valores da função objetivo e, em seguida, determinar os hiperparâmetros associados.

Com essa configuração muito importante, vamos entrar no algoritmo real.

2.2.1 — Dividir nossos dados em grupos “bons” e “ruins”

Lembre-se, nosso objetivo é encontrar os melhores valores de hiperparâmetros de acordo com alguma função objetivo. Então, como podemos aproveitar P(x|y) fazer isso?

Primeiro, o TPE divide nossos pontos de dados observados em dois grupos: Bom estado, com sinais de uso, denotado g (x), e ruim, denotado eu(x). O ponto de corte entre bom e ruim é determinado por um parâmetro gama (γ) definido pelo usuário, que corresponde ao percentil da função objetivo que divide nossas observações (y*).

Portanto, com γ = 0.5, o valor da nossa função objetivo que divide nossas observações (y*) será a mediana dos nossos pontos observados.

Modelo de ajuste de hiperparâmetros de hiperparâmetros ajuste de modelo de aprendizado de máquina ciência de dados modelo sklearn mllib spark hyperopt tree parzen estimador tpe tree based parzen esimtator mlflow databricks
Figura 7: divisão de p(x|y) em dois conjuntos. Imagem do autor.

Conforme mostrado na figura 7, podemos formalizar p(x|y) usando a estrutura acima. E, para continuar com a analogia do pirata…

Perspectiva Pirata: olhando para os lugares que já exploramos, l(x) lista lugares com muito pouco tesouro e g(x) lista lugares com muito tesouro.

2.2.32— Calcule a pontuação de “promessa”

Em segundo lugar, o TPE define como devemos avaliar uma combinação de hiperparâmetros não observada através do pontuação “promissora”.

Modelo de ajuste de hiperparâmetros de hiperparâmetros ajuste de modelo de aprendizado de máquina ciência de dados modelo sklearn mllib spark hyperopt tree parzen estimador tpe tree based parzen esimtator mlflow databricks
Figura 8: definição do escore de promissibilidade. Imagem do autor.

A Figura 8 define nossa pontuação de promessa (P), que é apenas uma proporção com os seguintes componentes…

  • Numerador: a probabilidade de observar um conjunto de hiperparâmetros (x), dado que o valor da função objetivo correspondente é “Bom estado, com sinais de uso. "
  • Denominador: a probabilidade de observar um conjunto de hiperparâmetros (x), dado que o valor da função objetivo correspondente é “ruim. "

Quanto maior o valor “promissor”, maior a probabilidade de nossos hiperparâmetros x produzirá uma função objetivo “boa”.

Perspectiva Pirata: a promessa mostra a probabilidade de um determinado local em nosso terreno ter muitos tesouros.

Deixando de lado antes de prosseguir, se você estiver familiarizado com a otimização bayesiana, esta equação atua como uma função de aquisição e é proporcional ao Melhoria Esperada (EI).

2.2.3— Criar estimativas de densidade de probabilidade

Terceiro, o TPE procura avaliar a pontuação de “promisso” por meio de modelos de mistura. A ideia dos modelos de mistura é pegar múltiplas distribuições de probabilidade e juntá-las usando uma combinação linear – src. Essas distribuições de probabilidade combinadas são então usadas para desenvolver estimativas de densidade de probabilidade.

Geralmente, o processo de modelagem de mistura é…

  1. Defina o tipo de distribuição dos nossos pontos. No nosso caso, se a nossa variável for categórica, usamos uma distribuição categórica reponderada e se for numérica, usamos uma distribuição gaussiana (ou seja, normal) ou uniforme.
  2. Itere sobre cada ponto e insira uma distribuição nesse ponto.
  3. Some a massa de todas as distribuições para obter uma estimativa da densidade de probabilidade.

Observe que este processo é executado individualmente para ambos os conjuntos eu(x) e g(x).

Vamos examinar um exemplo na figura 9…

Modelo de ajuste de hiperparâmetros de hiperparâmetros ajuste de modelo de aprendizado de máquina ciência de dados modelo sklearn mllib spark hyperopt tree parzen estimador tpe tree based parzen esimtator mlflow databricks
Figura 9: exemplo de distribuições gaussianas truncadas ajustadas a 3 observações de hiperparâmetros. Imagem do autor.

Para cada observação (pontos azuis no eixo x), criamos uma distribuição normal ~N(μ, σ), onde…

  • μ (mu) é a média da nossa distribuição normal. Seu valor é a localização do nosso ponto ao longo do eixo x.
  • σ (sigma) é o desvio padrão da nossa distribuição normal. Seu valor é a distância até o ponto vizinho mais próximo.

Se os pontos estiverem próximos, o desvio padrão será pequeno e, portanto, a distribuição será muito alta e, inversamente, se os pontos estiverem separados, a distribuição será plana (figura 10)…

Modelo de ajuste de hiperparâmetros de hiperparâmetros ajuste de modelo de aprendizado de máquina ciência de dados modelo sklearn mllib spark hyperopt tree parzen estimador tpe tree based parzen esimtator mlflow databricks
Figura 10: exemplo do impacto do desvio padrão na forma de uma distribuição normal. Imagem do autor.

Perspectiva Pirata: NA – piratas não são bons com modelos de mistura.

Outro aparte rápido antes de prosseguir: se você estiver lendo a literatura, notará que o TPE usa gaussianas “truncadas”, o que significa simplesmente que as gaussianas são limitadas pelo intervalo que especificamos em nossa configuração de hiperparâmetros, em vez de se estenderem até +/- infinito .

2.2.4 — Determinando o próximo ponto a explorar!

Vamos juntar essas peças. Até agora, 1) adquirimos observações da função objetivo, 2) definimos nossa fórmula de “promessa” e 3) criamos uma estimativa de densidade de probabilidade por meio de modelos de mistura baseados em valores anteriores. Temos todas as peças para avaliar um determinado ponto!

Nosso primeiro passo é criar uma função de densidade de probabilidade média (PDF) para ambos g(x) e eu(x).

Modelo de ajuste de hiperparâmetros de hiperparâmetros ajuste de modelo de aprendizado de máquina ciência de dados modelo sklearn mllib spark hyperopt tree parzen estimador tpe tree based parzen esimtator mlflow databricks
Figura 11: sobreposição da densidade média de probabilidade dados 3 pontos observados. Imagem do autor.

Um exemplo de processo é mostrado na figura 11 — a linha vermelha é nosso PDF médio e é simplesmente a soma de todos os PDFs dividida pelo número de PDFs.

Usando o PDF médio, podemos obter a probabilidade de qualquer valor de hiperparâmetro (x) estar em g(x) or eu(x).

Por exemplo, digamos que os valores observados na figura 11 pertencem ao conjunto “bom”, g(x). Com base em nosso PDF médio, é improvável que um valor de hiperparâmetro de 3.9 ou 0.05 pertença ao conjunto “bom”. Por outro lado, um valor de hiperparâmetro de ~1.2 parece muito provavelmente pertencer ao conjunto “bom”.

Agora, esta é apenas metade da imagem. Aplicamos a mesma metodologia para o conjunto “ruim”, eu(x). Como estamos procurando maximizar g(x) / eu(x), pontos promissores devem estar localizados onde g(x) é alto e eu(x) é baixo.

Muito legal, certo?

Com essas distribuições de probabilidade, podemos extrair amostras de nossos hiperparâmetros estruturados em árvore e encontrar o conjunto de hiperparâmetros que maximizam a “promissividade” e, portanto, valem a pena explorar.

Perspectiva Pirata: o próximo local que escavamos é aquele que maximiza a (probabilidade de ter muito tesouro) / (probabilidade de ter pouco tesouro).

Agora que você sabe como funciona, aqui estão algumas dicas práticas para implementar o TPE por meio do pacote de código aberto HyperOpt.

3.1 — Estrutura de um aplicativo HyperOpt

Geralmente, existem três etapas principais ao aproveitar o HyperOpt…

  1. Defina o espaço de pesquisa, que são apenas os intervalos e formas funcionais dos hiperparâmetros que você deseja otimizar.
  2. Defina a função de ajuste, que chama o seu model.fit() função em uma determinada divisão de trem/teste.
  3. Defina a função objetivo, que é qualquer uma das métricas clássicas de precisão, como RMSE ou AUC.

Infelizmente, esses métodos de ajuste automatizado ainda exigem informações de design do cientista de dados – não é um almoço totalmente grátis. No entanto, anedoticamente, o TPE é bastante robusto à especificação incorreta de hiperparâmetros (dentro do razoável).

3.2— Dicas e Truques

  • HyperOpt é paralelizável através de ambos Apache Spark e MongoDB. Se você estiver trabalhando com vários núcleos, seja na nuvem ou em sua máquina local, isso poderá reduzir drasticamente o tempo de execução.
  • Se você estiver paralelizando o processo de ajuste via Apache Spark, use um SparkTrialsobjeto para modelos de ML de nó único (sklearn) e um Trails objeto para modelos de ML paralelizados (MLlib). O código está abaixo.
  • Fluxo de ML é um método de código aberto para rastrear a execução do seu modelo. Integra-se facilmente com HyperOpt.
  • Não restrinja o espaço de pesquisa muito cedo. Algumas combinações de hiperparâmetros podem ser surpreendentemente eficazes.
  • Definir o espaço de busca pode ser complicado, especialmente se você não conhece o forma funcional dos seus hiperparâmetros. No entanto, por experiência pessoal, o TPE é bastante robusto à especificação incorreta dessas formas funcionais.
  • Escolher uma boa função objetivo é um grande passo. Na maioria dos casos, o erro não é criado da mesma forma. Se um determinado tipo de erro for mais problemático, certifique-se de incorporar essa lógica à sua função.

3.3— Um exemplo de código

Aqui está um código para executar o HyperOpt de maneira distribuída. Foi adaptado do código do livro, Engenharia de aprendizado de máquina em ação - Aqui está o repositório git.

Alguns recursos interessantes deste trecho incluem paralelização via Apache Spark e registro de modelo via Fluxo de ML. Observe também que este trecho otimiza um RandomForestRegressor sklearn - você terá que alterar o modelo e a função de ajuste para atender às suas necessidades.

E aí está - HyperOpt em toda a sua glória!

Para esclarecer os pontos-chave, vamos recapitular rapidamente.

O ajuste de hiperparâmetros é uma parte necessária do ciclo de vida do modelo de ML, mas consome muito tempo. Os algoritmos de otimização baseada em modelo sequencial (SMBO) são excelentes na busca de ótimos em hiperespaços complexos e podem ser aplicados ao ajuste de hiperparâmetros. Estimadores Parzen baseados em árvore (TPE) são um SMBO muito eficiente e superam a otimização bayesiana e a pesquisa aleatória.

O TPE repete as etapas abaixo até um critério de parada:

  1. Divida os pontos observados em conjuntos “bons” e “ruins”, de acordo com algum hiperparâmetro, gama.
  2. Ajuste um modelo de mistura ao conjunto “bom” e “ruim” para desenvolver uma estimativa de densidade de probabilidade média.
  3. Selecione o ponto que otimiza a pontuação “promissora”, que aproveita a etapa 2 para estimar a probabilidade de estar nos conjuntos “bom” e “ruim”.

Finalmente, temos um trecho de código muito legal que mostra como paralelizar o HyperOpt via SparkTrials. Ele também registra todas as nossas iterações no MLflow.

HyperOpt desmistificado republicado da fonte https://towardsdatascience.com/hyperopt-demystified-3e14006eb6fa?source=rss—-7f60cf5620c9—4 via https://towardsdatascience.com/feed

<!–

->

Carimbo de hora:

Mais de Consultores Blockchain