Gradient boosting no aprendizado de máquina transdutivo e ativo

17 março 2021, 12:48
Maxim Dmitrievsky
0
188

Introdução

O aprendizado semi supervisionado ou transdutiva usa os dados não rotulados, permitindo que o modelo compreenda melhor a estrutura geral de dados. Isso é semelhante ao nosso pensamento. Ao lembrar apenas algumas imagens, o cérebro humano é capaz de extrapolar o conhecimento sobre essas imagens para novos objetos em termos gerais, sem se concentrar em detalhes insignificantes. Isso resulta num menor sobreajuste e numa melhor generalização. 

A transdução foi introduzida por Vladimir Vapnik, que é o coinventor da Support-Vector Machine (SVM). Ele acredita que a transdução é preferível à indução, uma vez que a indução requer a resolução de um problema mais geral (inferir uma função) antes de resolver um problema mais específico (computar as saídas para os novos casos). 

“Ao resolver um problema de interesse, não resolva um problema mais geral como uma etapa intermediária. Tente obter a resposta de que realmente precisa, mas não uma resposta mais geral."

A suposição de Vapnik é semelhante à observação feita anteriormente por Bertrand Russell:

"nós chegaremos à conclusão de que Sócrates é mortal com uma abordagem maior da certeza se tornarmos nosso argumento puramente indutivo do que se seguirmos o caminho de 'todos os homens são mortais' e então usarmos a dedução".

Espera-se que o aprendizado não supervisionado (com dados não rotulados) se torne muito mais importante no longo prazo. A aprendizagem não supervisionada geralmente é típica de pessoas e animais: eles descobrem a estrutura do mundo observando, não reconhecendo o nome de cada objeto. 

Assim, a aprendizagem semi supervisionada combina os dois processos: a aprendizagem supervisionada ocorre em uma pequena quantidade de dados rotulados, após o modelo extrapolar o seu conhecimento para uma grande área não rotulada. 

O uso de dados não rotulados implica em alguma conexão com a distribuição de dados subjacente. Pelo menos uma das seguintes premissas deve ser atendida:

  • Pressuposto de continuidade. Os pontos próximos um do outro têm maior probabilidade de compartilhar um rótulo. Isso também é assumido no aprendizado supervisionado e produz uma preferência por limites geometricamente simples que separam as classes. No caso de aprendizagem semi supervisionada, a suposição de suavidade adicionalmente produz uma preferência em regiões de baixa densidade, onde poucos pontos estão próximos uns dos outros, mas em classes diferentes.
  • Suposição de cluster. Os dados tendem a formar clusters discretos e os pontos no mesmo cluster têm mais probabilidade de compartilhar um rótulo (embora os dados que compartilham um rótulo possam se espalhar por vários clusters). Este é um caso especial da suposição de suavidade que leva ao aprendizado com algoritmos de agrupamento.
  • Pressuposto de geração de coleções. Os dados estão aproximadamente em uma coleção de dimensão muito menor do que o espaço de entrada. Nesse caso, o aprendizado da coleção usando os dados rotulados e não rotulados pode evitar a maldição da dimensionalidade. Então, o aprendizado pode continuar usando distâncias e densidades definidas na coleção.

Verifique o link para mais detalhes sobre o aprendizado semi supervisionado.

O método principal no aprendizado semi supervisionado é a pseudo-rotulagem que é implementada da seguinte forma:

  • Alguma medida de proximidade (por exemplo, distância euclidiana) é usada para rotular o restante dos dados com base na região dos dados rotulados (pseudo-rótulo).
  • Rótulos de treinamento são combinados com pseudo-rótulos e sinais.
  • O modelo é treinado em todo o conjunto de dados.

De acordo com os pesquisadores, o uso de dados rotulados em combinação com os dados não rotulados pode melhorar significativamente a precisão do modelo. Eu usei uma ideia semelhante no meu artigo anterior, em que eu usei a estimativa da densidade de probabilidade da distribuição dos dados rotulados e a amostragem dessa distribuição. Mas a distribuição de novos dados pode ser diferente, então o aprendizado semi supervisionado pode trazer alguns benefícios, como o experimento deste artigo mostrará.

O aprendizado ativo é uma certa continuação lógica do aprendizado semi supervisionado. Ele é um processo iterativo de rotular novos dados de forma que os limites que separam as classes sejam locais de otimalidade.

A hipótese principal do aprendizado ativo afirma que o algoritmo de aprendizagem pode escolher os dados com os quais se deseja aprender. Ele pode funcionar melhor do que os métodos tradicionais com uma quantidade significativamente menor de dados de treinamento. Aqui, os métodos tradicionais se referem ao aprendizado supervisionado convencional usando os dados rotulados. Esse treinamento pode ser chamado de passivo. O modelo é simplesmente treinado em dados rotulados. Quanto mais dados, melhor. Um dos problemas mais demorados na aprendizagem passiva é a coleta e rotulagem de dados. Em muitos casos, pode haver restrições associadas à coleta de dados adicionais ou à sua rotulagem adequada. 

O aprendizado ativo tem três cenários mais populares, nos quais o modelo de aprendizado solicitará novos rótulos de instância de classe da região não rotulada:

  • Solicitar um exemplo sintetizado artificialmente. Nesse caso, o modelo gera uma instância a partir de uma determinada distribuição que é comum a todos os exemplos. Pode ser uma instância de classe com ruído adicionado ou apenas um ponto plausível no espaço em questão. Este novo ponto é enviado ao especialista para treinamento. O especialista é o nome convencional para a função de avaliador que avalia o valor de uma determinada instância de recurso para o modelo.
  • Amostragem baseada em fluxo. De acordo com esse cenário, cada ponto de dados não rotulado é examinado um por vez, após o qual o especialista escolhe se deseja consultar um rótulo de classe para esse ponto ou rejeitá-lo com base em algum critério de informação. 
  • Amostragem baseada em pool. Nesse cenário, há um grande conjunto de exemplos não rotulados, como no caso anterior. As instâncias são selecionadas da pool com base na informatividade. As instâncias mais informativas são selecionadas da pool. Isto é o cenário mais popular entre os fãs do aprendizado ativo. Todas as instâncias não rotuladas serão classificadas e, em seguida, as instâncias mais informativas serão selecionadas.

Cada cenário pode ser baseado em uma estratégia de consulta específica. Conforme mencionado acima, a principal diferença entre o aprendizado ativo e passivo é a capacidade de consultar instâncias de uma região não rotulada com base em consultas anteriores e respostas de modelo. Portanto, todas as consultas requerem alguma medida de informatividade. 

As estratégias de consulta mais populares são as seguintes:

  • Amostragem de incerteza (menor confiança). De acordo com essa estratégia, nós selecionamos a instância na qual o modelo é mais incerto. Por exemplo, a probabilidade de atribuir um rótulo a uma determinada classe está abaixo de um certo limite.
  • Amostragem de margem. A desvantagem da primeira estratégia é que ela determina a probabilidade de pertencer a apenas um rótulo, ao mesmo tempo que desconsidera as probabilidades de pertencer a outros rótulos. A estratégia de amostragem de margem seleciona a menor diferença de probabilidade entre os dois rótulos mais prováveis.
  • Amostragem de entropia. A fórmula de entropia é aplicada a cada instância, e a instância com o valor mais alto é consultada.

Igual o aprendizado semi supervisionado, o processo de aprendizado ativo consiste em várias etapas:

  • O modelo é treinado em dados rotulados.
  • O mesmo modelo é usado para rotular dados não rotulados para prever probabilidades (pseudo-rótulos).
  • Uma nova estratégia de consulta de instância é selecionada.
  • N instâncias são selecionadas da pool de dados de acordo com a informatividade e são adicionadas à amostra de treinamento. 
  • Este ciclo é repetido até que algum critério de parada seja alcançado. Um critério de parada pode ser o número de iterações ou a estimativa do erro de aprendizagem, bem como outros critérios externos.

Aprendizado Ativo

Vamos direto ao aprendizado ativo e testar sua eficácia em nossos dados.

Existem várias bibliotecas para o aprendizado ativo na linguagem Python, sendo a mais popular delas:

  • modAL é um pacote bastante simples e fácil de aprender, que é uma espécie de invólucro para a famosa biblioteca de aprendizado de máquina scikit-learn (eles são totalmente compatíveis). O pacote fornece os métodos mais famosos de aprendizado ativo.
  • Libact usa a estratégia multi-armed bandit sobre as estratégias de consulta existentes para uma seleção dinâmica da melhor consulta. 
  • Alipy é uma espécie de laboratório de provedores de pacotes, que contém muitas estratégias de consulta.

Eu selecionei a biblioteca modAL por ser mais intuitiva e adequada para me familiarizar com a filosofia de aprendizado ativo. Ela oferece maior liberdade no desenho de modelos e na criação de seus próprios modelos usando blocos padrão ou criando os seus próprios blocos.

Vamos considerar o processo descrito acima usando o esquema abaixo, que não requer mais explicações:

Veja a documentação

O melhor da biblioteca é que você pode usar qualquer classificador scikit-learn. O exemplo a seguir demonstra o uso de uma floresta aleatória como modelo de aprendizagem:

from modAL.models import ActiveLearner
from modAL.uncertainty import entropy_sampling
from sklearn.ensemble import RandomForestClassifier

learner = ActiveLearner(
    estimator=RandomForestClassifier(),
    query_strategy=entropy_sampling,
    X_training=X_training, y_training=y_training
)

A floresta aleatória aqui atua como um modelo de aprendizado e como um avaliador permitindo a seleção de novas amostras de dados não rotulados dependendo da estratégia de consulta (por exemplo, com base na entropia, como neste exemplo). Em seguida, um conjunto de dados que consiste em uma pequena quantidade de dados rotulados é passado para o modelo. Isso é usado para o treinamento preliminar. 

A biblioteca modAL permite uma combinação fácil de estratégias de consulta e permite fazer estratégias ponderadas compostas a partir delas:

from modAL.utils.combination import make_linear_combination, make_product
from modAL.uncertainty import classifier_uncertainty, classifier_margin

# creating new utility measures by linear combination and product
# linear_combination will return 1.0*classifier_uncertainty + 1.0*classifier_margin
linear_combination = make_linear_combination(
    classifier_uncertainty, classifier_margin,
    weights=[1.0, 1.0]
)
# product will return (classifier_uncertainty**0.5)*(classifier_margin**0.1)
product = make_product(
    classifier_uncertainty, classifier_margin,
    exponents=[0.5, 0.1]
)

Depois que a consulta é gerada, as instâncias que atendem aos critérios da consulta são selecionadas da região de dados sem rótulo, usando os seletores multi_argmax ou weighted_randm:

from modAL.utils.selection import multi_argmax

# defining the custom query strategy, which uses the linear combination of
# classifier uncertainty and classifier margin
def custom_query_strategy(classifier, X, n_instances=1):
    utility = linear_combination(classifier, X)
    query_idx = multi_argmax(utility, n_instances=n_instances)
    return query_idx, X[query_idx]

custom_query_learner = ActiveLearner(
    estimator=GaussianProcessClassifier(1.0 * RBF(1.0)),
    query_strategy=custom_query_strategy,
    X_training=X_training, y_training=y_training
)

Estratégias de Consulta

Existem três estratégias de consulta principais. Todas as estratégias são baseadas na incerteza de classificação, por isso são chamadas de medidas de incerteza. Vamos ver como elas funcionam.

A incerteza de classificação, em um caso simples, é avaliada como U(x)=1−P(x^|x), onde x é o caso a ser previsto, enquanto x^ é a previsão mais provável. Por exemplo, se houver três classes e três itens de amostra, as incertezas correspondentes podem ser calculadas da seguinte forma:

[[0.1 , 0.85, 0.05],
 [0.6 , 0.3 , 0.1 ],
 [0.39, 0.61, 0.0 ]]

1 - proba.max(axis=1)

[0.15, 0.4 , 0.39]

Assim, o segundo exemplo será selecionado como o mais incerto.

A margem de classificação é a diferença nas probabilidades da primeira e da segunda consultas com maior probabilidade. A diferença é determinada de acordo com a seguinte fórmula: M(x)=P(x1^|x)−P(x2^|x), onde x1^ e x2^ são a primeira e a segunda classes com maior probabilidade.

Essa estratégia de consulta seleciona instâncias com a menor margem entre as probabilidades das duas classes mais prováveis, pois quanto menor a margem da solução, mais incerta ela é.

>>> import numpy as np
>>> proba = np.array([[0.1 , 0.85, 0.05],
...                   [0.6 , 0.3 , 0.1 ],
...                   [0.39, 0.61, 0.0 ]])
>>>
>>> proba
array([[0.1 , 0.85, 0.05],
       [0.6 , 0.3 , 0.1 ],
       [0.39, 0.61, 0.  ]])
>>> part = np.partition(-proba, 1, axis=1)
>>> part
array([[-0.85, -0.1 , -0.05],
       [-0.6 , -0.3 , -0.1 ],
       [-0.61, -0.39, -0.  ]])
>>> part[:, 0]
array([-0.85, -0.6 , -0.61])
>>> part[:, 1]
array([-0.1 , -0.3 , -0.39])
>>> margin = - part[:, 0] + part[:, 1]
>>> margin
array([0.75, 0.3 , 0.22])

Nesse caso, a terceira amostra (a terceira linha do array) será selecionada, pois a margem de probabilidade para esta instância é mínima.

A entropia de classificação é calculada usando a fórmula de entropia da informação: H(x)=−∑kpklog(pk), onde pk é a probabilidade de que a amostra pertença à k-ésima classe. Quanto mais próxima a distribuição estiver da uniformidade, maior será a entropia. Em nosso exemplo, a entropia máxima é obtida para o segundo exemplo.

[0.51818621, 0.89794572, 0.66874809]

Ela não parece ser muito difícil. Esta descrição parece ser suficiente para entender as três estratégias de consulta principais. Para mais detalhes, estude a documentação do pacote, porque eu forneço apenas os pontos básicos.

Estratégias de consulta em lote

Consultar um elemento por vez e retreinar o modelo nem sempre é eficiente. Uma solução mais eficiente é rotular e selecionar várias instâncias dos dados não rotulados de uma vez. Existem várias questões para isso. O mais popular deles é a Amostragem de Conjuntos Classificados com base em uma função de similaridade, como a similaridade de cossenos. Este método estima quão bem o espaço de características é explorado próximo à x (instância não rotulada). Após a avaliação, a instância com a classificação mais alta é adicionada ao conjunto de treinamento e removida do conjunto de dados não rotulados. Depois disso, a classificação é recalculada e a melhor instância é adicionada novamente até que o número de instâncias atinja o tamanho especificado (tamanho do lote). 

Consultas de densidade de informação

As estratégias de consulta simples descritas acima não avaliam a estrutura de dados. Isso pode levar a consultas abaixo da otimalidade. Para melhorar a amostragem, você pode usar as medidas da densidade de informação que ajudarão a selecionar corretamente os elementos dos dados não rotulados. Ele usa cosseno ou a distância euclidiana. Quanto maior a densidade da informação, maior será a semelhança desta instância selecionada com todas as outras. 

Consultas do comitê de classificação

Este tipo de consulta elimina algumas das desvantagens dos tipos de consulta simples. Por exemplo, a seleção de elementos tende a ser enviesada devido às características de um determinado classificador. Alguns elementos de amostragem importantes podem estar faltando. Este efeito é eliminado armazenando simultaneamente várias hipóteses e selecionando as consultas entre as quais existem divergências. Assim, o comitê de classificadores aprende cada um em sua própria cópia da amostra e, em seguida, os resultados são pesados. Outros tipos de aprendizado do comitê de classificação incluem bagging e bootstrapping.

Esta breve descrição cobre quase que completamente a funcionalidade da biblioteca. Você pode consultar a documentação para obter mais detalhes.

Aprendendo de forma ativa

Eu selecionei a estratégia de consulta em lote, bem como as consultas do comitê de classificação, e executei uma série de experimentos. A estratégia de consulta em lote não apresentou bom desempenho nos novos dados, no entanto, ao enviar o conjunto de dados gerado ao GMM, eu comecei a obter resultados interessantes. 

Considere um exemplo de implementação da função de aprendizado ativo em lote:

def active_learner(data, labeled_size, unlabeled_size, batch_size, max_depth):
    X_raw = data[data.columns[1:-1]].to_numpy()
    y_raw = data[data.columns[-1]].to_numpy()

    # Isolate our examples for our labeled dataset.
    training_indices = np.random.randint(low=0, high=X_raw.shape[0] + 1, size=labeled_size)

    X_train = X_raw[training_indices]
    y_train = y_raw[training_indices]

    # fit the model on all data
    cl = AdaBoostClassifier(DecisionTreeClassifier(max_depth=max_depth), n_estimators=50, learning_rate = 0.01)
    cl.fit(X_raw, y_raw)
    print('Score for the passive learning: ', cl.score(X_raw, y_raw), ' with train size: ', data.shape[0])

    # Isolate the non-training examples we'll be querying.
    X_pool = np.delete(X_raw, training_indices, axis=0)
    y_pool = np.delete(y_raw, training_indices, axis=0)

    # Pre-set our batch sampling to retrieve 3 samples at a time.
    preset_batch = partial(uncertainty_batch_sampling, n_instances=batch_size)

    # Specify our core estimator along with its active learning model.
    cl = AdaBoostClassifier(DecisionTreeClassifier(max_depth=3), n_estimators=50, learning_rate = 0.03)
    learner = ActiveLearner(estimator=cl, query_strategy=preset_batch, X_training=X_train, y_training=y_train)

A entrada da função passa um conjunto de dados rotulado, o número de instâncias rotuladas, o número de instâncias não rotuladas, o tamanho do lote para a consulta de rótulo do lote e a profundidade máxima da árvore.

Um número especificado de instâncias rotuladas é selecionado aleatoriamente do conjunto de dados rotulado para o pré-treinamento do modelo. O resto do conjunto de dados forma uma pool a partir do qual as instâncias serão consultadas. Eu usei o AdaBoost como um classificador básico, que é semelhante ao CatBoost. Depois disso, o modelo é treinado iterativamente:

    # Allow our model to query our unlabeled dataset for the most
    # informative points according to our query strategy (uncertainty sampling).
    N_QUERIES = unlabeled_size // batch_size

    for index in range(N_QUERIES):
        query_index, query_instance = learner.query(X_pool)

        # Teach our ActiveLearner model the record it has requested.
        X, y = X_pool[query_index], y_pool[query_index]
        learner.teach(X=X, y=y)

        # Remove the queried instance from the unlabeled pool.
        X_pool, y_pool = np.delete(
            X_pool, query_index, axis=0), np.delete(y_pool, query_index)

        # Calculate and report our model's accuracy.
        model_accuracy = learner.score(X_raw, y_raw)
        print('Accuracy after query {n}: {acc:0.4f}'.format(
            n=index + 1, acc=model_accuracy))

        # Save our model's performance for plotting.
        performance_history.append(model_accuracy)

    print('Score for the active learning with train size: ',
          learner.X_training.shape)     

Como tudo pode acontecer como resultado dessa aprendizagem semi supervisionada, o resultado pode ser qualquer um. No entanto, após algumas manipulações com as configurações do aprendiz, eu obtive resultados comparáveis aos do artigo anterior. 

Idealmente, a precisão da classificação de um aprendiz ativo em uma pequena quantidade de dados rotulados deve exceder a precisão de um classificador semelhante com todos os dados rotulados.

>>> learned = active_learner(pr, 1000, 1000, 50)
Score for the passive learning:  0.5991245668429692  with train size:  5483
Accuracy after query 1: 0.5710
Accuracy after query 2: 0.5836
Accuracy after query 3: 0.5749
Accuracy after query 4: 0.5847
Accuracy after query 5: 0.5829
Accuracy after query 6: 0.5823
Accuracy after query 7: 0.5650
Accuracy after query 8: 0.5667
Accuracy after query 9: 0.5854
Accuracy after query 10: 0.5836
Accuracy after query 11: 0.5807
Accuracy after query 12: 0.5907
Accuracy after query 13: 0.5944
Accuracy after query 14: 0.5865
Accuracy after query 15: 0.5949
Accuracy after query 16: 0.5873
Accuracy after query 17: 0.5833
Accuracy after query 18: 0.5862
Accuracy after query 19: 0.5902
Accuracy after query 20: 0.6002
Score for the active learning with train size:  (2000, 8)

De acordo com o relatório, o classificador que foi treinado em todos os dados rotulados têm uma precisão menor do que o aprendiz ativo que foi treinado por apenas 2.000 instâncias. Isso provavelmente é bom. 

Agora, essa amostra pode ser enviada para o modelo GMM, após o qual o classificador CatBoost pode ser treinado.

# prepare data for CatBoost
catboost_df = pd.DataFrame(learned.X_training)
catboost_df['labels'] = learned.y_training

# perform GMM clusterization over dataset
X = catboost_df.copy()
gmm = mixture.GaussianMixture(
    n_components=75, max_iter=500, covariance_type='full', n_init=1).fit(X)

# sample new dataset
generated = gmm.sample(10000)
# make labels
gen = pd.DataFrame(generated[0])
gen.rename(columns={gen.columns[-1]: "labels"}, inplace=True)
gen.loc[gen['labels'] >= 0.5, 'labels'] = 1
gen.loc[gen['labels'] < 0.5, 'labels'] = 0
X = gen[gen.columns[:-1]]
y = gen[gen.columns[-1]]
pr = pd.DataFrame(X)
pr['labels'] = y

# fit CatBoost model and test it
model = fit_model(pr)
test_model(model, TEST_START, END_DATE)

Este processo pode ser repetido várias vezes, pois em cada etapa do processamento dos dados existe um elemento de incerteza que não permite a construção de modelos inequívocos. Os seguintes gráficos foram obtidos no testador após todas as iterações (período de treinamento de 1 ano seguido por um período de teste de 5 anos):

Claro, esses resultados não são benchmark, e eles apenas demonstram que modelos lucrativos (em novos dados) podem ser obtidos. 

Vamos agora implementar a função de aprendizagem no comitê de classificação e ver o que acontece:

def active_learner_committee(data, learners_number, labeled_size, unlabeled_size, batch_size):
    X_pool = data[data.columns[1:-1]].to_numpy()
    y_pool = data[data.columns[-1]].to_numpy()

    cl = AdaBoostClassifier(DecisionTreeClassifier(max_depth=3), n_estimators=50, learning_rate = 0.05)
    cl.fit(X_pool, y_pool)
    print('Score for the passive learning: ', cl.score(
        X_pool, y_pool), ' with train size: ', data.shape[0])

    # initializing Committee members
    learner_list = list()

    # Pre-set our batch sampling to retrieve 3 samples at a time.
    preset_batch = partial(uncertainty_batch_sampling, n_instances=batch_size)
    
    for member_idx in range(learners_number):
        # initial training data
        train_idx = np.random.choice(range(X_pool.shape[0]), size=labeled_size, replace=False)
        X_train = X_pool[train_idx]
        y_train = y_pool[train_idx]

        # creating a reduced copy of the data with the known instances removed
        X_pool = np.delete(X_pool, train_idx, axis=0)
        y_pool = np.delete(y_pool, train_idx)

        # initializing learner
        learner = ActiveLearner(
            estimator=AdaBoostClassifier(DecisionTreeClassifier(max_depth=2), n_estimators=50, learning_rate = 0.05),
            query_strategy=preset_batch,
            X_training=X_train, y_training=y_train
        )
        learner_list.append(learner)

    # assembling the committee
    committee = Committee(learner_list=learner_list)

    unqueried_score = committee.score(X_pool, y_pool)
    performance_history = [unqueried_score]

    N_QUERIES = unlabeled_size // batch_size

    for idx in range(N_QUERIES):
        query_idx, query_instance = committee.query(X_pool)
        committee.teach(
            X=X_pool[query_idx].reshape(1, -1),
            y=y_pool[query_idx].reshape(1, )
        )
        model_accuracy = committee.score(X_pool, y_pool)
        performance_history.append(model_accuracy)
        print('Accuracy after query {n}: {acc:0.4f}'.format(
            n=idx + 1, acc=model_accuracy))

        # remove queried instance from pool
        X_pool = np.delete(X_pool, query_idx, axis=0)
        y_pool = np.delete(y_pool, query_idx)

    return committee

Novamente, eu selecionei a estratégia de consulta em lote para eliminar a necessidade de treinar novamente o modelo sempre que um elemento for adicionado. Quanto ao resto, eu criei um comitê de um número arbitrário de classificadores AdaBoost (acho que não faz sentido adicionar mais de cinco classificadores, mas você pode experimentar). 

Abaixo está uma pontuação de treinamento para um comitê de cinco modelos com as mesmas configurações que foram usadas para o método anterior:

>>> committee = active_learner_committee(pr, 5, 1000, 1000, 50)
Score for the passive learning:  0.6533842794759825  with train size:  5496
Accuracy after query 1: 0.5927
Accuracy after query 2: 0.5818
Accuracy after query 3: 0.5668
Accuracy after query 4: 0.5862
Accuracy after query 5: 0.5874
Accuracy after query 6: 0.5906
Accuracy after query 7: 0.5918
Accuracy after query 8: 0.5910
Accuracy after query 9: 0.5820
Accuracy after query 10: 0.5934
Accuracy after query 11: 0.5864
Accuracy after query 12: 0.5753
Accuracy after query 13: 0.5868
Accuracy after query 14: 0.5921
Accuracy after query 15: 0.5809
Accuracy after query 16: 0.5842
Accuracy after query 17: 0.5833
Accuracy after query 18: 0.5783
Accuracy after query 19: 0.5732
Accuracy after query 20: 0.5828

Os resultados do comitê de aprendiz ativos não são tão bons quanto os de um aprendiz passivo. É impossível adivinhar as razões. Talvez esta seja apenas um resultado aleatório. Em seguida, eu executei o conjunto de dados resultante várias vezes usando o mesmo princípio e obtive os seguintes resultados aleatórios:


Conclusões

Neste artigo, nós consideramos o aprendizado ativo. A impressão não é clara. Por um lado, é sempre tentador aprender com um pequeno número de instâncias, e esses modelos funcionam bem para alguns problemas de classificação. No entanto, isso ainda está longe de ser inteligência artificial. Esse modelo não pode encontrar padrões estáveis entre os dados de lixo e requer uma preparação mais completa de recursos e rótulos, incluindo a preparação dos dados com base em rótulos de especialistas. Eu não vi nenhum aumento significativo na qualidade dos modelos. Ao mesmo tempo, a intensidade de trabalho e o tempo necessário para treinar os modelos aumentaram, o que é um fator negativo. Eu gosto da filosofia do aprendizado ativo e da utilização das características do pensamento humano. O arquivo anexo fornece todas as funções discutidas. Você pode explorar ainda mais esses modelos e tentar aplicá-los de alguma outra forma original.

Traduzido do russo pela MetaQuotes Software Corp.
Artigo original: https://www.mql5.com/ru/articles/8743

Arquivos anexados |
Desenvolvendo um algoritmo auto-adaptável (Parte I): encontrando um padrão básico Desenvolvendo um algoritmo auto-adaptável (Parte I): encontrando um padrão básico
Numa série de artigos, mostrarei um exemplo de como desenvolver algoritmos auto-adaptativos que levam em consideração a maioria de fatores que surgem nos mercados, apresentarei como sistematizar essas situações, como descrevê-las de forma lógica e como considerá-las na hora de negociar. Vou começar com um algoritmo muito simples, que com o tempo irá ganhar teoria e evoluir para um projeto muito complexo.
Redes Neurais de Maneira Fácil (Parte 8): Mecanismos de Atenção Redes Neurais de Maneira Fácil (Parte 8): Mecanismos de Atenção
Nos artigos anteriores, nós já testamos várias opções para organizar as redes neurais. Nós também estudamos as redes convolucionais emprestadas dos algoritmos de processamento de imagem. Neste artigo, eu sugiro estudarmos os Mecanismos de Atenção, cujo surgimento deu impulso ao desenvolvimento dos modelos de linguagem.
Usando planilhas para construir estratégias de negociação Usando planilhas para construir estratégias de negociação
O artigo descreve os princípios básicos e abordagens que permitem analisar qualquer estratégia usando planilhas - Excel, Calc, Google. Os resultados também são comparados com os do testador do MetaTrader 5.
Trabalhando com séries temporais na biblioteca DoEasy (Parte 58): séries temporais de dados de buffers de indicadores Trabalhando com séries temporais na biblioteca DoEasy (Parte 58): séries temporais de dados de buffers de indicadores
No final do tópico sobre trabalho com séries temporais, realizaremos o armazenamento, a pesquisa e a classificação dos dados armazenados em buffers de indicadores, o que nos permitirá realizar análises posteriores com base nos valores dos indicadores criados assentes na biblioteca para nossos programas. O conceito geral por trás de todas as classes-coleções da biblioteca torna mais fácil encontrar os dados necessários na coleção correspondente, assim, o mesmo será possível na classe que será criada hoje.