O Tensor Flow é uma estrutura para criar e trabalhar com redes neurais do Google. Permite que você abstraia dos detalhes internos do aprendizado de máquina e se concentre diretamente na solução do seu problema. Uma coisa muito poderosa, permite criar, treinar e usar redes neurais de qualquer tipo conhecido. Não encontrei um único texto sensível sobre Habré sobre esse assunto, por isso escrevo o meu. A seguir, descreveremos a implementação da solução para o problema de cogumelos usando a biblioteca Tensor Flow. A propósito, o algoritmo descrito abaixo é adequado para previsões em quase todos os campos. Por exemplo, a probabilidade de câncer em uma pessoa no futuro ou de cartas em um oponente no pôquer.
Desafio
A essência do problema: com base nos parâmetros de entrada do fungo para determinar sua comestibilidade. A especificidade é que esses parâmetros são categóricos, não numéricos. Por exemplo, o parâmetro "formato do chapéu" pode ser definido como "plano" ou "convexo" ou "em forma de cone". Conjunto de dados de cogumelo para aprendizado de rede retirado do
repositório de aprendizado de máquina . Assim, a solução do problema pode ser chamada de um tipo de Olá Mundo no campo de aprendizado de máquina, juntamente com o
problema das íris , onde os parâmetros das flores são expressos em valores digitais.
Código fonte
Você pode baixar todas as fontes do meu repositório no Github:
link . Faça isso para ver o código em ação. Use apenas códigos-fonte, porque todos os recuos e codificações necessários são observados lá. Abaixo, todo o processo será discutido em detalhes.
Preparação
Supõe-se que você tenha uma instalação pré-instalada do Tensor Flow. Caso contrário, você pode instalar o
link .
Código fonte
from __future__ import absolute_import from __future__ import division from __future__ import print_function import tensorflow as tf import numpy as np import pandas as pd from sklearn.model_selection import train_test_split import os
Faça o download e prepare dados do repositório
Baixaremos os dados para treinamento e teste da rede neural do
repositório de aprendizado de máquina criado especialmente para isso. Todos os dados são apresentados em dois arquivos: agaricus-lepiota.data e agaricus-lepiota.names. As primeiras 8124 linhas e 22 colunas. Uma linha fornece um cogumelo, cada coluna é um dos 22 parâmetros do cogumelo na forma de um caractere de redução de toda a palavra de parâmetro. A legenda de todos os caracteres está no arquivo agarius-lepiota.names.
Os dados do repositório precisam ser processados para trazê-los para um formato aceitável para o Tensor Flow. Primeiro, importamos algumas bibliotecas para o trabalho
from __future__ import absolute_import from __future__ import division from __future__ import print_function import tensorflow as tf import numpy as np import pandas as pd from sklearn.model_selection import train_test_split import os
Em seguida, formaremos um cabeçalho a partir dos parâmetros do cogumelo para o Tensor Flow, para que a biblioteca saiba qual coluna no arquivo de dados corresponde a qual parâmetro. O chapéu é colado ao arquivo de dados. Formamos na forma de uma matriz, cujos elementos são retirados do arquivo agaricus-lepiota.names.
header = ['class', 'cap_shape', 'cap_surface', 'cap_color', 'bruises', 'odor', 'gill_attachment', 'gill_spacing', 'gill_size', 'gill_color', 'stalk_shape', 'stalk_root', 'stalk_surface_above_ring', 'stalk_surface_below_ring', 'stalk_color_above_ring', 'stalk_color_below_ring', 'veil_type', 'veil_color', 'ring_number', 'ring_type', 'spore_print_color', 'population', 'habitat'] df = pd.read_csv(data_file_name, sep=',', names=header)
Agora você precisa lidar com os dados ausentes. Nesse caso, o símbolo "?" É definido no arquivo agaricus-lepiota.data em vez do parâmetro. Existem muitos métodos para lidar com esses casos, mas simplesmente excluiremos a linha inteira com pelo menos um parâmetro ausente.
df.replace('?', np.nan, inplace=True) df.dropna(inplace=True)
Em seguida, você deve substituir manualmente o parâmetro de comestibilidade simbólica por um digital. Ou seja, substitua "p" e "e" por 0 e 1.
df['class'].replace('p', 0, inplace=True) df['class'].replace('e', 1, inplace=True)
E depois disso, você pode converter o restante dos dados em um dígito. É isso que a função get_dummies da biblioteca do pandas faz.
cols_to_transform = header[1:] df = pd.get_dummies(df, columns=cols_to_transform)
Qualquer rede neural precisa ser treinada. Além disso, ele também precisa ser calibrado para aumentar a precisão do trabalho em condições reais. Para fazer isso, dividiremos nosso conjunto de dados em dois - treinamento e calibração. O primeiro será maior que o segundo, como deveria ser.
df_train, df_test = train_test_split(df, test_size=0.1)
E o último. O fluxo tensor requer que o número de linhas e colunas do arquivo seja indicado no início dos arquivos de dados. Extrairemos essas informações manualmente de nossos conjuntos de dados de treinamento e calibração e, em seguida, gravaremos nos arquivos CSV resultantes.
No final, você deve obter esses arquivos:
treinamento e
calibração .
Jogue os dados gerados no fluxo tensor
Agora que baixamos do repositório e processamos os arquivos CSV com dados em forma de cogumelo, você pode enviá-los ao Tensor Flow para treinamento. Isso é feito usando a função load_csv_with_header () fornecida pela própria estrutura:
training_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename='mushroom_train.csv', target_dtype=np.int, features_dtype=np.int, target_column=0) test_set = tf.contrib.learn.datasets.base.load_csv_with_header( filename='mushroom_test.csv', target_dtype=np.int, features_dtype=np.int, target_column=0)
A função load_csv_with_header () está envolvida na formação de um conjunto de dados de treinamento a partir dos arquivos que coletamos acima. Além do arquivo de dados, a função aceita target_dtype como argumento, que é um tipo de dado previsto no final. No nosso caso, é necessário ensinar a rede neural a prever a comestibilidade ou toxicidade do fungo, que pode ser expressa com os valores 1 ou 0. Portanto, no nosso caso, target_dtype é um valor inteiro. features_dtype - parâmetro em que o tipo de parâmetros aceitos para treinamento está definido. No nosso caso, também é um número inteiro (inicialmente eles eram string, mas, como você se lembra, nós os ultrapassamos em um número). No final, o parâmetro target_column é definido, que é o índice da coluna com o parâmetro que a rede neural deve prever. Ou seja, com o parâmetro edibility.
Criar um objeto classificador de fluxo tensor
Ou seja, um objeto de uma classe diretamente envolvida na previsão do resultado. Em outras palavras, a classe da própria rede neural.
feature_columns = [tf.contrib.layers.real_valued_column("", dimension=98)] classifier = tf.contrib.learn.DNNClassifier( feature_columns=feature_columns, hidden_units=[10, 20, 10], n_classes=2, model_dir="/tmp/mushroom_model")
O primeiro parâmetro é feature_columns. Estes são os parâmetros dos cogumelos. Observe que o valor do parâmetro é criado ali mesmo, um pouco mais alto. Lá, na entrada, o valor do parâmetro de dimensão 98 é obtido, o que significa 98 parâmetros diferentes do cogumelo, com exceção da comestibilidade.
hidden_units - o número de neurônios em cada camada da rede neural. A seleção correta do número de camadas e neurônios nelas é algo no nível da arte no campo do aprendizado de máquina. É possível determinar corretamente esses valores somente após a experiência. Pegamos esses números apenas porque estão listados em um dos tutoriais do Tensor Flow. E eles trabalham.
n_classes - o número de classes a prever. Temos dois deles - comestíveis e não.
model_dir - o caminho onde o modelo treinado da rede neural será salvo. E no futuro será usado para prever resultados, para não treinar a rede todas as vezes.
Treinamento
Para facilitar o trabalho no futuro, criaremos duas funções:
def get_test_inputs(): x = tf.constant(test_set.data) y = tf.constant(test_set.target) return x, y def get_train_inputs(): x = tf.constant(training_set.data) y = tf.constant(training_set.target) return x, y
Cada função fornece seu próprio conjunto de dados de entrada - para treinamento e calibração. x e y são as constantes do Fluxo Tensor que a estrutura precisa para funcionar. Não entre em detalhes, apenas aceite que essas funções devem ser um intermediário entre dados e uma rede neural.
Nós treinamos uma rede:
classifier.fit(input_fn=get_train_inputs, steps=2000)
O primeiro parâmetro pega os dados de entrada formados logo acima, o segundo - o número de etapas do treinamento. Novamente, o número foi usado em um dos manuais do Tensor Flow, e o entendimento dessa configuração chegará até você com experiência.
Em seguida, calibre a rede treinada. Isso é feito usando o conjunto de dados de calibração gerado acima. O resultado do trabalho será a precisão das previsões futuras da rede (precision_score).
accuracy_score = classifier.evaluate(input_fn=get_test_inputs, steps=1)["accuracy"] print("\n : {0:f}\n".format(accuracy_score))
Vamos testar em
Agora a rede neural está pronta e você pode tentar prever com a ajuda da comestibilidade do fungo.
def new_samples(): return np.array([[0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]], dtype=np.int)
A função acima fornece os dados de dois cogumelos completamente novos que não estavam presentes no treinamento ou nos conjuntos de calibração (na verdade, eles simplesmente foram retirados deste último). Imagine, por exemplo, que você os comprou no mercado e esteja tentando entender se eles podem ser comidos. O código abaixo irá definir isso:
predictions = list(classifier.predict(input_fn=new_samples)) print(" : {}\n" .format(predictions))
O resultado do trabalho deve ser o seguinte:
: [0, 1]
E isso significa que o primeiro cogumelo é venenoso, o segundo é completamente comestível. Assim, você pode fazer previsões com base em quaisquer dados, sejam cogumelos, pessoas, animais ou qualquer coisa. É o suficiente para formar corretamente os dados de entrada. E prever, por exemplo, a probabilidade de arritmia do paciente no futuro ou o movimento do preço das ações na bolsa de valores.