Ads Top

[Machine Learning] - Trabalhando com dados reais: criando um set de testes

Pode parecer estranho anular voluntariamente parte dos dados nesta fase. Afinal, você apenas deu uma olhada rápida nos dados e certamente deveria aprender muito mais sobre eles antes de decidir quais algoritmos usar, certo? 


Isso é verdade, mas seu cérebro é um sistema de detecção de padrões incrível, o que significa que é altamente propenso a sobreajuste: se você olhar para o conjunto de teste, poderá tropeçar em algum padrão aparentemente interessante nos dados de teste que o leva a selecionar um tipo particular de modelo de aprendizado de máquina. 


Ao estimar o erro de generalização usando o conjunto de testes, sua estimativa será muito otimista e você iniciará um sistema que não terá o desempenho esperado. Isso é chamado de viés de espionagem de dados. 


Criar um conjunto de testes é teoricamente simples: escolha algumas instâncias aleatoriamente, normalmente 20% do conjunto de dados (ou menos, se seu conjunto de dados for muito grande) e reserve:





Funciona, mas não é perfeito: se você executar o programa novamente, ele irá gerar um conjunto de teste diferente! Com o tempo, você (ou seus algoritmos de aprendizado de máquina) verá todo o conjunto de dados, que é o que você deseja evitar. 


Uma solução é salvar o conjunto de testes na primeira execução e carregá-lo nas execuções subsequentes. Outra opção é definir a semente do gerador de número aleatório (por exemplo, com np.random.seed (42)) 14 antes de chamar np.random.permutation () para que sempre gere os mesmos índices embaralhados. 


Mas ambas as soluções irão quebrar o na próxima vez que você buscar um conjunto de dados atualizado. Para ter uma divisão de treinamento / teste estável, mesmo depois de atualizar o conjunto de dados, uma solução comum é usar o identificador de cada instância para decidir se deve ou não entrar no conjunto de teste (assumindo que as instâncias têm um identificador único e imutável). 


Por exemplo, você pode calcular um hash do identificador de cada instância e colocar essa instância no conjunto de teste se o hash for menor ou igual a 20% do valor máximo de hash. Isso garante que o conjunto de testes permanecerá consistente em várias execuções, mesmo se você atualizar o conjunto de dados. O novo conjunto de teste conterá 20% das novas instâncias, mas não conterá nenhuma instância que estava anteriormente no conjunto de treinamento. 


Aqui está uma possível solução:




Infelizmente, o conjunto de dados de habitação não tem uma coluna de identificador. A solução mais simples é usar o índice de linha como o ID:




Se você usar o índice de linha como um identificador exclusivo, precisará garantir que os novos dados sejam anexados ao final do conjunto de dados e que nenhuma linha seja excluída. Se isso não for possível, você pode tentar usar os recursos mais estáveis para construir um identificador exclusivo. Por exemplo, a latitude e a longitude de um distrito têm garantia de estabilidade por alguns milhões de anos, então você pode combiná-las em um ID como:




O Scikit-Learn fornece algumas funções para dividir conjuntos de dados em vários subconjuntos de várias maneiras. A função mais simples é train_test_split (), que faz praticamente a mesma coisa que a função split_train_test (), com alguns recursos adicionais. Primeiro, há um parâmetro random_state que permite definir a semente do gerador aleatório. Em segundo lugar, você pode passar vários conjuntos de dados com um número idêntico de linhas e ele os dividirá nos mesmos índices (isso é muito útil, por exemplo, se você tiver um DataFrame separado para rótulos):




Até agora, consideramos métodos de amostragem puramente aleatórios. Em geral, isso é bom se seu conjunto de dados for grande o suficiente (especialmente em relação ao número de atributos), mas se não for, você corre o risco de introduzir um viés de amostragem significativo. 


Quando uma empresa de pesquisa decide ligar para 1.000 pessoas para fazer algumas perguntas, ela não escolhe apenas 1.000 pessoas aleatoriamente em uma lista telefônica. Eles tentam garantir que essas 1.000 pessoas sejam representativas de toda a população. 


Por exemplo, a população dos EUA é de 51,3% mulheres e 48,7% homens, portanto, uma pesquisa bem conduzida nos EUA tentaria manter essa proporção na amostra: 513 mulheres e 487 homens. Isso é chamado de amostragem estratificada: a população é dividida em subgrupos homogêneos chamados estratos, e o número certo de instâncias são amostradas de cada estrato para garantir que o conjunto de teste seja representativo da população geral. 


Se as pessoas que realizam a pesquisa usassem amostragem puramente aleatória, haveria cerca de 12% de chance de amostrar um conjunto de teste distorcido que fosse menos de 49% feminino ou mais de 54% feminino. 


De qualquer forma, os resultados da pesquisa seriam significativamente tendenciosos. Suponha que você conversou com especialistas que lhe disseram que a renda média é um atributo muito importante para prever os preços médios de habitação. 


Você pode querer garantir que o conjunto de teste seja representativo das várias categorias de receitas em todo o conjunto de dados. Como a renda mediana é um atributo numérico contínuo, primeiro você precisa criar um atributo de categoria de renda. 


Vamos examinar o histograma da renda mediana mais de perto: a maioria dos valores da renda mediana estão agrupados em torno de 1,5 a 6 (ou seja, $ 15.000– $ 60.000), mas algumas rendas medianas vão muito além de 6. É importante ter um número suficiente de instâncias em seu conjunto de dados para cada estrato, ou então a estimativa da importância de um estrato pode ser tendenciosa. 


Isso significa que você não deve ter muitos estratos e cada estrato deve ser grande o suficiente. O código a seguir usa a função pd.cut () para criar um atributo de categoria de renda com cinco categorias (rotuladas de 1 a 5): categoria 1 varia de 0 a 1,5 (ou seja, menos de $ 15.000), categoria 2 de 1,5 a 3, e assim por diante:




Agora você está pronto para fazer uma amostragem estratificada com base na categoria de renda. Para isso, você pode usar a classe StratifiedShuffleSplit do Scikit-Learn:




Vamos ver se funcionou conforme o esperado. Você pode começar observando as proporções da categoria de renda no conjunto de teste:




Com código semelhante, você pode medir as proporções da categoria de renda no conjunto de dados completo. O print abaixo compara as proporções da categoria de renda no conjunto de dados geral, no conjunto de teste gerado com amostragem estratificada e em um conjunto de teste gerado usando amostragem puramente aleatória. 


Como você pode ver, o conjunto de teste gerado usando amostragem estratificada tem proporções de categoria de renda quase idênticas àquelas do conjunto de dados completo, enquanto o conjunto de teste gerado usando amostragem puramente aleatória é distorcido.




Agora você deve remover o atributo income_cat para que os dados voltem ao estado original:




Gastamos um bom tempo na geração de conjuntos de teste por um bom motivo: esta é uma parte frequentemente negligenciada, mas crítica de um projeto de aprendizado de máquina. 

Além disso, muitas dessas ideias serão úteis posteriormente, quando discutirmos a validação cruzada. 

Agora é hora de passar para a próxima etapa: explorar os dados.


Nenhum comentário:

Tecnologia do Blogger.