KNN #3 — Codando nosso classificador de câncer de mama

Show me the code!

Italo José
aibrasil
5 min readJul 1, 2018

--

Para começarmos a brincadeira nós precisamos de dados, vamos então baixar o dataset Breast Cancer Wisconsin que vimos no artigo passado.

Você pode ver como baixar o arquivo com os dados seguindo o artigo anterior

Algumas observações antes de começarmos, após eu ter feito o dowlaond desse dataset, fiz algumas modificações bem simples nele que foram:

  • Remoção da coluna do ID que não servira como dado de tributo nesse nosso exemplo
  • Mudança da coluna de saída(classificação) para a última coluna

Após feito o dowload você tem duas opções:

1 — Baixar um dataset modificado por mim para facilitar o desenvolvimento do algoritmo KNN através desse link;

2 — Seguir o passo a passo e ir adaptando o código ao dataset;

Bem vamos começar! Antes de qualquer coisa, o código completo desse tutorial encontra-se nesse link.

Depois de ter seu dataset criado vamos criar dentro da pasta do nosso projeto criar uma pasta chamada “datas” e colocar todos os nossos datsets lá.

E fora dessa pasta “datas” vamos criar o nosso arquivo chamado main.go

Estou usando o editor VS Code para o desenvolvimento desse algoritmo, porém você pode usar qualquer um outro que não terá impacto nenhum para seguir o conteúdo da serie.

Vamos então definir o nome do pacote e criar a função main que será por onde nosso código irá começar

Obs: os comentários estarão em inglês pois vou fazer uma versão em inglês desse artigo também rs

Para começar a brincadeira nós vamos precisar trazer nosso dataset para a memória, então vamos criar um método que leia csv e traga isso em formato de matriz para dentro do código.

Agora toda o nosso dataset está dentro da variável “recodords”

Se imprimirmos o valor dessa variavel no terminal, teremos o seguinte valor

fmt.Println(records)…[7.76 24.54 47.92 181 0.05263 0.04362 0 0 0.1587 0.05884 0.3857 1.428 2.548 19.15 0.007189 0.00466 0 0 0.02676 0.002783 9.456 30.37 59.16 268.6 0.08996 0.06444 0 0 0.2871 B]]

Temos então nosso dataset ao qual nós vamos fazer varias iterações sobre ele e aplicar toda aquela teoria que vimos no artigo #1.

O próximo passo depois de obter o dataset, será dividi-lo em 2 partes, uma de treino e outra de teste.

Dados de treino: será os dados já classificados ao qual usaremos para treinar o nosso algoritmo;

Dados de teste: será os dados já classificados ao qual usaremos para validar a acurácia do nosso algoritmo;

Vamos dividir nosso dateset da seguinte forma, 70% dos dados de cada classe para teste e o restante(30%) de cada classe para teste.

Pra começar vamos extrair as classes do nosso dataset de forma unica, para isso vamos usar a seguinte lógica;

-> Extrair do nosso dataset(records) a coluna onde há os valores das classes;

-> Dar um distinct para limpar os valores repetidos e assim obter as nossas classes únicas;

[getCollum(…)]

No motodo getCollum nós recebemos uma matriz no parâmetro elements, vamos no índice de uma determinada coluna com o parâmetro columIndex e para cada linha dentro dessa coluna, nós adicionamos a um array novo que vamos retornar para o solicitante.

[distinct(…)]

Com o retorno do método getcolum nós vamos passar esse valor para o método distict que recebe um array e pra cada elemento desse array, ele:

-> Verifica-se se esse mesmo elemento encontra-se no map(dicionario) “encontred”

-> Caso não exista, ele irá adicionar o elemento ao map “encontred”

-> Caso exista, não adicione nada ao map “encontred”

No final vamos retornar nosso map encontred onde não terá classes repetidas.

Obs: optei por fazer tudo na mão para evitar o mal entendimento de quem não está acostumado com os pacotes do go.

Ao imprimir o valor de “classes” fmt.Println(classes) teremos um array com dois valores [M B]

Vamos então iterar sobre essas classes para obter os 70% de dados de cada classe para treino e 30% dos dados para teste.

Vamos criar nossas matrizes train e test antes das nossas iterações, pois nelas vamos atribuir os valores dos 70% e 30% dos dados.

No nosso método getValuesByClass() vamos receber uma matriz e uma classe, nela vamos filtrar nossa matriz para trabalharmos com dados apenas de uma classe em especifico.

Nossa variável “values” na primeira iteração, terá a matriz com valores correspondente a uma unica classe, exemplo: M.

Na segunda iteração sobre as nossas classes, a variável “values” terá então, dados correspondente a classe: B.

Depois de termos filtrado apenas os dados correspondente a uma determinada classe, precisamos dividir esses dados entre treino e teste, faremos isso da seguinte maneira:

Depois de termos obtido nossos dados de teste e de treino dentro do escopo da nossa iteração, vamos então alimentar a nossa matriz que está fora do escopo desse loop.

Eu sei, usar um loop para concatenar um array/slice não é a melhor forma, mas lembre-se que estou codificando da maneira mais didática que consegui, então por favor, sinta-se a vontade para melhorar o código.

Depois de separar os dados, vamos fazer as classificações e os testes!

Vamos classificar cada linha do nosso dataset de teste e vamos contabilizar quantos nós acertamos e quantos nós erramos.

Por fim podemos imprimir algumas coisinhas:

 fmt.Println(“Total de dados: “, len(records))
fmt.Println(“Total de treinamento: “, len(train))
fmt.Println(“Total de testes: “, len(test))
fmt.Println(“Total de acertos: “, hits)
fmt.Println(“Porcentagem de acertos: “, (100 * hits / len(test)), “%”)

No final, ao rodar “go run main.go” no terminal, teremos este resultado:

Total de dados: 569
Total de treinamento: 513
Total de testes: 513
Total de acertos: 484
Porcentagem de acertos: 94 %

E caso você queira ver quais foram os acertos e os erros, nós podemos imprimir a classificação que foi feita para o dado de teste descomentando a linha 22 do gist acima:


//fmt.Println(“tumor: “, test[i][columnIndex], “ classificado como:

E teremos a seguinte saída:

tumor: M classificado como: B
tumor: M classificado como: M
tumor: M classificado como: M
tumor: M classificado como: M
tumor: M classificado como: M
tumor: M classificado como: M
tumor: B classificado como: B
tumor: B classificado como: B
tumor: B classificado como: B
tumor: B classificado como: B
tumor: B classificado como: B
tumor: B classificado como: B
tumor: B classificado como: B
tumor: B classificado como: B
Total de dados: 569
Total de treinamento: 513
Total de testes: 513
Total de acertos: 479
Porcentagem de acertos: 93 %

Obrigado por ter lido todo o conteúdo, espero que lhe seja muito útil.

[Momento jabá]

Não deixe de se tornar membro da nossa comunidade (AI BRASIL) que está ganhando o brasil, já estamos em São Paulo em no Rio de Janeiro (por enquanto!), fazemos meetups todos os meses, e em todos os meetups temos hands-ons, falando de assuntos como o desse artigo, só que de uma forma mais aprofundada e com “tira duvidas” !

Link: https://meetup.com/pt-BR/ai-brasil/

--

--