Um classificador é um modelo computacional capaz de predizer classes para determinado conjunto de informações, a partir de um conhecimento prévio de o que caracteriza cada classe. Por exemplo, se você possui diversas categorias de projetos de leis (educacional, saúde, segurança, etc...), é possível criar um classificador que, a partir do texto de um projeto, consegue identificar a categoria a que ele pertence.
Para ser capaz de fazer uma classificação bem sucedida, o classificador precisa antes passar por um processo de aprendizado (ou treinamento). Esse processo consiste em apresentar ao modelo computacional exemplos de dados dos quais já se sabe a classe, de forma que o classificador consiga identificar em suas características (ou atributos) os critérios que definem cada classe.
Assim como para a clusterização, existem disversas técnicas disponíveis para essa tarefa. Para este exercício, usaremos o SVM (Support Vector Machine) como classificador - você pode ler mais a respeito em [0]. Outros modelos, como as Redes Neurais Artificiais também estão disponíveis através da biblioteca scikit-learn. Encorajamos o estudo destes outros modelos, mas prezando a simplicidade não os incluiremos neste tutorial.
Neste exemplo, aprenderemos a utilizar um classificador para encontrar a classe correta de uma flor.
Para isso, escolhemos o banco de dados Iris [1], que contem informações sobre 3 subespécies diferentes da flor Iris.
Este banco tem 150 exemplos, 50 de cada classe:
Cada exemplo possui 4 atributos numéricos:
Nossa tarefa é: Dada a descrição de uma flor (os 4 números), descobrir qual é sua subespécie. Usaremos o algoritmo SVM - Support Vector Machine da biblioteca scikit-learn para essa tarefa.
In [ ]:
import numpy as np
import pylab as pl
from sklearn import datasets, svm
A primeira coisa que devemos fazer é carregar as informações sobre as flores. Armazenaremos elas em duas variáveis: X e Y.
A variável X é uma matriz, em cada linha temos uma flor diferente (total = 150 linhas) e em cada coluna uma característica daquela flor (total = 4 colunas).
Enquanto isso, guardaremos na variável y a classe correta daquela flor para utilizarmos durante o treinamento e, depois, medirmos a acurácia da nossa classificação (total = 150 linhas).
In [ ]:
iris = datasets.load_iris() #carrega a base iris
X = iris.data
y = iris.target #guarda o "gabarito", com informações das classes
print 'Linhas de X: ' + str(len(X)) + ', Colunas de X: ' + str(len(X[0]))
print 'Linhas de Y: ' + str(len(y))
Agora que temos todas as flores, suas descrições e classificação correta, queremos separá-las em dois conjuntos distintos:
O conjunto de treinamento serve para treinar o nosso classificador. Entregaremos para o SVM as flores do conjunto de treinamento, com sua descrição (4 números) e sua classe (1 das 3 classes possíveis - número de 0 a 2). A partir daí, o SVM tentará aprender como identificar cada espécie de flor com base na sua descrição.
Definimos que 50% das flores serão usadas no conjunto de treinamento, e as 50% restantes no conjunto de testes.
O conjunto de testes não é usado durante o treinamento.
Assim, garantimos que o classificador nunca os viu antes, e teremos uma medição confiável de quão bom ele é - já que estamos classificando flores "desconhecidas" até o momento.
In [ ]:
n_flores = len(X)
porcentagem_treino = 0.5 # No intervalo 0..1; 0.8 = 80%
np.random.seed(0)
ordem = np.random.permutation(n_flores)
X = X[ordem]
y = y[ordem].astype(np.float)
X_treino = X[:int(porcentagem_treino * n_flores)]
y_treino = y[:int(porcentagem_treino * n_flores)]
X_teste = X[int(porcentagem_treino * n_flores):]
y_teste = y[int(porcentagem_treino * n_flores):]
print 'Tamanho do conjunto de treinamento: ' + str(len(y_treino))
print 'Tamanho do conjunto de testes: ' + str(len(y_teste))
Com os conjuntos de treino e testes separados, podemos treinar o nosso classificador (SVM).
Inicialmente, definimos quais parâmetros vamos usar.
O SVM tem vários tipos de kernel (funções usadas no momento de definir um hiperplano para classificação), como RBF, Linear, Polinomial etc. Para este exemplo, usaremos o kernel linear - que é o mais simples e rápido. Para mais informações sobre kernels e parâmetros, visite [2].
O comando fit, então, realiza o treinamento.
In [ ]:
classificador = svm.SVC(kernel='linear')
classificador.fit(X_treino, y_treino);
Com o classificador treinado, podemos tentar predizer as classes de flor para o nosso conjunto de testes, sem olhar a variável y_teste, que contém as classes verdadeiras.
In [ ]:
y_classificado = classificador.predict(X_teste)
print y_classificado
Agora que temos os valores que nosso classificador atribuiu para cada flor, podemos conferir na variável y_teste, que armazena os valores corretos, qual foi a acurácia de nosso classificador.
In [ ]:
print y_classificado
print y_teste
acertos = sum(y_teste == y_classificado)
print str(acertos) + ' acertos de ' + str(len(y_teste)) + ' testes. Acurácia = %.2f%%' % (acertos / float(len(y_teste)) * 100)
Usando 50% das nossas flores no treinamento, conseguimos acurácia de 98.67% no conjunto de teste - 1 erro em 75.
Essa é uma taxa alta, que pode ser melhorada. Quanto mais exemplos forem usados no conjunto de treino, melhor o modelo poderá ficar;
em contrapartida, quanto maior o conjunto de treino, menor o conjunto de teste - e menos confiança temos no resultado.
Então, precisamos encontrar um ponto em que aceitamos os resultados obtidos como confiáveis, e não existe regra para isso.
Em bancos maiores e mais complexos, é comum usar mais dados para o conjunto de treino (80%, por exemplo).
In [ ]:
# seu código aqui!
In [ ]:
In [ ]: