• Nenhum resultado encontrado

Arvores de Decis˜ ´ ao

No documento Faculdade de Economia (páginas 35-41)

2.2 Elaborar modelos a partir de dados

2.2.1 Arvores de Decis˜ ´ ao

O R possu´ı uma gama bastante variada de m´etodos que podem ser usados para obter modelos para problemas de classifica¸c˜ao como por exemplo o da concess˜ao de cr´edito que temos vindo a usar. Um desses m´etodos ´e normalmente conhecido como ´arvores de decis˜ao. Antes de vermos como obter uma ´arvore de decis˜ao em R, vejamos em que consistem esses modelos e como podem ser usados para tomar decis˜oes. A Figura 3

mostra um exemplo de uma ´arvore de decis˜ao para o problema da concess˜ao de cr´edito.

Uma ´arvore de decis˜ao consiste numa hierarquia de testes a algumas das vari´aveis O que ´e uma ´arvore de decis˜ao

envolvidas no problema de decis˜ao, que no nosso exemplo s˜ao as vari´aveis montante, idade, sal´ario e conta. A ´arvore pode ser “lida” a partir do teste encontrado na

parte superior da mesma, normalmente chamado o n´o raiz da ´arvore. Em concreto, N´o raiz

se pretendˆessemos usar a ´arvore da Figura 3 para tomar uma decis˜ao para um novo cliente do banco, a primeira coisa para que dever´ıamos olhar, de acordo com esta ´arvore de decis˜ao, seria para o seu sal´ario. Se este fosse baixo, ent˜ao de acordo com a ´arvore dever´ıamos verificar qual o montante pedido. Se for um montante alto ou m´edio ent˜ao a decis˜ao aconselhada pela ´arvore ´e n˜ao conceder cr´edito. Se por outro lado o montante fosse baixo ent˜ao j´a dever´ıamos conceder cr´edito ao cliente. Ou seja, para usar uma ´arvore deste tipo para tomar decis˜oes, come¸camos por fazer o teste do n´o raiz. Se for verdadeiro

Figura 3: Um exemplo de uma ´arvore de decis˜ao.

seguimos para o ramo esquerdo da ´arvore e fazemos o teste que a´ı se encontra, se for falso seguimos o ramo direito, e assim sucessivamente at´e chegarmos a um n´o terminal

Folhas das ´arvores

(normalmente conhecidos por folhas da ´arvore), onde temos a decis˜ao do modelo para o caso em an´alise.

As ´arvores de decis˜ao como a da Figura 3 podem ser “lidas” como um conjunto de regras de decis˜ao. Por exemplo o caminho desde o n´o raiz, seguindo sempre o ramo esquerdo at´e encontrar uma folha, corresponde `a regra,

se sal´ario baixo e montante alto ou m´edio ent˜ao n˜ao conceder cr´edito

Isto quer dizer que seria poss´ıvel traduzir uma ´arvore de decis˜ao para um conjunto de regras de decis˜ao, e assim usar um procedimento semelhante ao seguido na Sec¸c˜ao2.1.1

para as implementar como uma fun¸c˜ao que toma decis˜oes para novos casos.

Vejamos agora como construir uma ´arvore de decis˜ao no R. Conforme j´a mencionamos anteriormente, a significˆancia da amostra usada para obter o modelo ´e essencial para termos um m´ınimo de garantias da representatividade do modelo constru´ıdo. Assim, n˜ao faz grande sentido obter uma ´arvore de decis˜ao usando meia d´uzia de exemplos de decis˜oes. De facto, quanto maior a amostra usada melhor. Apesar destas considera¸c˜oes, para o efeito de mostrar como se obt´em uma ´arvore em R, ´e indiferente o tamanho da amostra usada. Assim, vamos criar um pequeno data frame com exemplos de decis˜oes (por exemplo semelhantes `as apresentadas na Tabela 1da p´agina35). Podemos usar o editor de data frames do R para criar um data frame com os exemplos, ou em alternativa podemos usar a possibilidade que o R nos d´a de ir buscar informa¸c˜ao `a Internet, desde

Ir buscar dados `a

Internet que obviamente o computador em causa esteja ligado a esta rede. Vejamos como proceder

neste segundo caso,

> download.file(’http://www.liacc.up.pt/~ltorgo/Ensino/FEP/AnaliseDados/credito.Rdata’,’exp.data’) trying URL ‘http://www.liacc.up.pt/~ltorgo/Ensino/FEP/AnaliseDados/credito.Rdata’

Content type ‘text/plain’ length 2661 bytes opened URL

downloaded 2661 bytes

> dados <- read.csv(’exp.data’) > dados

montante idade salario conta emprestimo 1 medio junior baixo sim nao 2 medio junior baixo nao nao 3 baixo junior baixo sim sim 4 alto media baixo sim sim

2.2 Elaborar modelos a partir de dados 37

5 alto senior alto sim sim ...

...

A primeira instru¸c˜ao apresentada acima ´e uma chamada `a fun¸c˜ao download.file do R que pode ser usada para fazer o download de um ficheiro da Internet a partir do seu endere¸co (URL), colocando o resultado num ficheiro local ao computador onde se est´a a executar o R. Neste caso indicamos um URL que foi criado para este efeito, e que ´e suposto conter um ficheiro de texto com uma s´erie de exemplos de decis˜oes. O resultado do download ´e colocado num ficheiro que resolvemos chamar “exp.data”.

A segunda instru¸c˜ao usa a fun¸c˜ao read.csv para ler o conte´udo do ficheiro “exp.data” Ler dados de ficheiros de texto

para um data frame. Esta fun¸c˜ao pode ser usada para ler o conte´udo de ficheiros de

texto do tipo CSV. Este tipo de ficheiros cont´em informa¸c˜ao tabular com a informa¸c˜ao Ficheiros CSV

distribu´ıda por linhas, e com os valores em cada linha separados por v´ırgulas. Este tipo de ficheiros pode ser gerado pela maioria dos programas como por exemplo o Access, o Excel, etc. Para termos uma melhor ideia do seu conte´udo, apresentam-se em seguida as primeiras linhas do ficheiro “exp.data”,

montante,idade,salario,conta,emprestimo medio,junior,baixo,sim,nao medio,junior,baixo,nao,nao baixo,junior,baixo,sim,sim alto,media,baixo,sim,sim ...

Com a instru¸c˜ao read.csv() usada da forma apresentada acima, a primeira linha deste ficheiro ´e interpretada como os nomes a dar `as colunas do data frame que ser´a criado, e as linhas sucessivas como o conte´udo desse data frame. Isso mesmo pode ser confirmado pedindo ao R para mostrar o conte´udo do objecto dados.

Ap´os termos um conjunto de exemplos de cr´edito num data frame, estamos em

condi¸c˜oes de obter uma ´arvore de decis˜ao. As seguintes instru¸c˜oes fazem isso mesmo, Obter uma ´arvore em R

> library(rpart)

> ´arvore <- rpart(emprestimo ~ ., dados) > ´arvore

n= 99

node), split, n, loss, yval, (yprob) * denotes terminal node

1) root 99 29 sim (0.29292929 0.70707071) 2) salario=baixo 31 11 nao (0.64516129 0.35483871) 4) montante=alto,medio 21 1 nao (0.95238095 0.04761905) * 5) montante=baixo 10 0 sim (0.00000000 1.00000000) * 3) salario=alto 68 9 sim (0.13235294 0.86764706) 6) conta=nao 27 9 sim (0.33333333 0.66666667) 12) montante=alto 9 0 nao (1.00000000 0.00000000) * 13) montante=baixo,medio 18 0 sim (0.00000000 1.00000000) * 7) conta=sim 41 0 sim (0.00000000 1.00000000) *

A primeira destas instru¸c˜oes carrega o package “rpart” que cont´em as fun¸c˜oes necess´arias Carregar packages

para a obten¸c˜ao de ´arvores de decis˜ao no R. A segunda instru¸c˜ao obt´em um destes mod- elos usando a fun¸c˜ao rpart colocando o resultado no objecto ´arvore. A fun¸c˜ao rpart tem dois argumentos principais. Um indica a forma do modelo a obter, e o outro os dados a usar para o obter. A forma do modelo a obter ´e fornecida `a fun¸c˜ao usando uma

sintaxe gen´erica de descri¸c˜ao de modelos que consiste, sucintamente, em indicar o nome Formas dos modelos

da vari´avel de decis˜ao seguida do s´ımbolo “∼” e uma lista das vari´aveis que podem ser usadas no modelo para obter a decis˜ao. Esta lista pode ser substitu´ıda pelo s´ımbolo “.” (como no exemplo acima), querendo significar que se podem usar todas as outras vari´aveis existentes nos dados fornecidos `a fun¸c˜ao. Os dados a usar na obten¸c˜ao do mod- elo s˜ao fornecidos no segundo argumento da fun¸c˜ao e devem ser um data frame com as

colunas com nomes que estejam de acordo com os nomes de vari´aveis referidos na forma do modelo.

A seguir a obter a ´arvore podemos pedir ao R para mostrar o conte´udo do objecto a

Mostrar uma ´arvore

que atribu´ımos o resultado. O R apresenta a ´arvore de decis˜ao em forma de texto. Como veremos mais `a frente vai ser tamb´em poss´ıvel obter uma representa¸c˜ao gr´afica como a da Figura3. Analisemos para j´a a informa¸c˜ao dada pelo R sobre o objecto ´arvore. Em primeiro lugar o R indica-nos o n´umero de casos usados para obter o modelo. Em seguida, s˜ao apresentadas uma s´erie de linhas que representam os diferentes testes e n´os da ´arvore. Estes s˜ao apresentados seguindo uma certa indenta¸c˜ao e com um n´umero associado, com o objectivo de melhor percebermos a hierarquia dos testes. Maior indenta¸c˜ao significa que o teste / n´o se situa num n´ıvel mais abaixo na ´arvore (ajuda a compreender a informa¸c˜ao olhar para a Figura 3 em paralelo, que ´e uma representa¸c˜ao gr´afica da mesma ´arvore). Assim, neste exemplo concreto a primeira linha identificada com o n´umero 1 d´a-nos a informa¸c˜ao respeitante ao n´o raiz da ´arvore, antes de efectuar qualquer teste a uma vari´avel. De acordo com essa informa¸c˜ao no n´o raiz, antes de sabermos / testarmos o valor de qualquer vari´avel, a melhor decis˜ao seria “sim” (i.e. conceder cr´edito). Esta decis˜ao ´e sustentada pelo facto de dos 99 exemplos dados ao R s´o 29 serem da “classe” n˜ao, o que leva a uma probabilidade de 29.9% de qualquer cliente ser um caso de “n˜ao conceder” cr´edito, e uma probabilidade de 70.7% de ser uma caso de “sim, conceder” cr´edito. Estas probabilidades s˜ao os n´umeros apresentados entre parˆenteses. Deste n´o ra´ız temos duas deriva¸c˜oes consoante o valor da vari´avel sal´ario. Estas deriva¸c˜oes est˜ao identificadas pelos n´umeros 2 e 3, e correspondem ao n´ıvel seguinte de identa¸c˜ao. Dos 99 casos fornecidos ao R, 31 tˆem a propriedade “sal´ario = baixo” e nestes a classe maiorit´aria ´

e “n˜ao” conceder cr´edito, sendo que s´o 11 dos 31 correspodem a situa¸c˜oes onde os peritos decidiram dar cr´edito. Para estes 31 casos o teste seguinte ´e o valor do montante pedido. Se este for alto ou m´edio, ent˜ao atinge-se uma decis˜ao (o R assinala isso colocando um “*” na respectiva linha), que neste caso ´e n˜ao conceder cr´edito. Esta decis˜ao ´e suportada pelo facto de dos 21 casos com montante alto ou m´edio s´o 1 ter recebido uma decis˜ao de conceder cr´edito pelos peritos humanos. Em resumo, usando os n´umeros e a identa¸c˜ao ´e poss´ıvel ficar com uma ideia da forma do modelo de decis˜ao obtido com a fun¸c˜ao rpart. A cria¸c˜ao de uma representa¸c˜ao gr´afica de uma ´arvore de decis˜ao, ´e um processo de

Representa¸c˜ao gr´afica de uma ´

arvore

duas fases em R. Em primeiro lugar desenha-se a ´arvore e depois coloca-se o texto no desenho. As instru¸c˜oes seguintes fazem isso mesmo,

> plot(´arvore) > text(´arvore)

O resultado obtido desta forma ´e um pouco fraco em termos gr´aficos. Conseguem-se melhores resultados jogando um pouco com os muitos parˆametros destas duas fun¸c˜oes. No sentido de evitarmos estarmos a escrever estes parˆametros sempre que queiramos visualizar uma ´arvore de decis˜ao, vamos criar um fun¸c˜ao para esse efeito,

> mostra.arvore <- function(´arvore) { + plot(´arvore,uniform=T,branch=0)

+ text(´arvore,digits=3,cex=0.65,font=10, pretty=0,fancy=T,fwidth=0,fheight=0) + }

> mostra.arvore(´arvore)

Como se pode ver pela amostra da Figura3(que tamb´em foi produzida com estas duas fun¸c˜oes, mas com parˆametros diferentes), pode-se fazer ainda muito melhor manipulando os parˆametros destas fun¸c˜oes, no entanto tais detalhes saiem fora do ˆambito desta cadeira.

Ap´os a obten¸c˜ao de um modelo de decis˜ao deste tipo, a pergunta ´obvia que surge ´e, Qual a confian¸ca que podemos ter na performance deste modelo?

Uma das formas mais pr´aticas de responder a esta quest˜ao consiste em testar o modelo

Testar a ´arvore

2.2 Elaborar modelos a partir de dados 39

incorrectas, quando comparadas com as dos peritos humanos, cometidas pela ´arvore de decis˜ao.

Uma forma de simular a existˆencia de mais casos para testarmos o nosso modelo,

consiste em dividir os casos que possu´ımos em dois sub-conjuntos: uma para obter o Obter amostras aleat´orias de casos

modelo; e outro para o testar. Vejamos como fazer isso em R,

> amostra.modelo <- sample(1:nrow(dados),as.integer(0.7*nrow(dados))) > dados.modelo <- dados[amostra.modelo,]

> dados.teste <- dados[-amostra.modelo,]

O objectivo da primeira instru¸c˜ao ´e obter uma amostra aleat´oria de n´umeros entre 1 e o n´umero de linhas do data frame dados. O tamanho dessa amostra corresponde a 70% do n´umero de linhas do objecto dados. A fun¸c˜ao sample() permite obter este tipo de resultados. Por exemplo, se pretendessemos obter um vector com 3 n´umeros aleat´orios entre 1 e 10, bastaria fazer,

> v <- sample(1:10,3)

Uma vez obtido um vector com um conjunto de n´umero aleat´orios entre 1 e o n´umero de casos que possu´ımos, podemos usar este vector (amostra.modelo) para indexar o data frame com todos os casos, e deste modo obter um novo data frame contendo um sub-conjunto aleat´orio dos casos dispon´ıveis. Usando as facilidades de indexa¸c˜ao do R (c.f. Sec¸c˜ao 1.8), podemos facilmente obter o complemento deste conjunto, isto ´e os casos restantes. Com estas duas amostras aleat´orias, que s˜ao exclusivas, podemos construir uma ´arvore de decis˜ao e depois test´a-la numa amostra de casos independente, garantindo assim alguma fiabilidade `as nossas estimativas da qualidade do modelo de decis˜ao. Vejamos como proceder,

> ´arvore <- rpart(emprestimo ~.,dados.modelo) > ´arvore

n= 69

node), split, n, loss, yval, (yprob) * denotes terminal node

1) root 69 21 sim (0.3043478 0.6956522)

2) salario=baixo 24 9 nao (0.6250000 0.3750000)

4) montante=alto,medio 16 1 nao (0.9375000 0.0625000) * 5) montante=baixo 8 0 sim (0.0000000 1.0000000) * 3) salario=alto 45 6 sim (0.1333333 0.8666667) *

> previs~oes.modelo <- predict(´arvore,dados.teste) > previs~oes.modelo nao sim 2 0.9375000 0.0625000 5 0.1333333 0.8666667 7 0.1333333 0.8666667 8 0.9375000 0.0625000 11 0.1333333 0.8666667 ...

Repare que, uma vez que usamos um conjunto de dados diferente para obter o modelo,

a ´arvore obtida ´e diferente da anterior. A terceira instru¸c˜ao usa a fun¸c˜ao predict para Obter as previs˜oes de uma ´arvore

obter as previs˜oes da ´arvore para os casos da amostra separada para teste. Repare que o papel desta fun¸c˜ao ´e semelhante `a fun¸c˜ao de decis˜ao que implementamos na Sec¸c˜ao2.1.1, isto ´e, para cada casos de teste emite uma previs˜ao. Neste caso concreto a fun¸c˜ao predict produz um data frame com tantas linhas quantos os casos de teste, e com tantas colunas quantas as decis˜oes poss´ıveis no problema. Para cada caso de teste a fun¸c˜ao produz a probabilidade de cada decis˜ao. Assim, por exemplo, no primeiro caso de teste a ´arvore prevˆe n˜ao conceder cr´edito com cerca de 93.7% de “confian¸ca” e conceder cr´edito com somente 6.2%.

Para calcularmos a percentagem de erros destas decis˜oes da ´arvore, ´e prefer´ıvel obter as decis˜oes de uma outra forma,

> previs~oes.modelo <- predict(´arvore,dados.teste,type=’class’) > previs~oes.modelo

[1] nao sim sim nao sim sim sim sim sim sim sim sim sim sim sim nao sim sim sim [20] nao sim sim sim sim nao sim sim sim sim sim

Levels: nao sim

Com o parˆametro “type=’class’” a fun¸c˜ao predict produz um factor com as de- cis˜oes “definitivas” da ´arvore, em vez das probabilidades de cada classe (decis˜ao). Estas previs˜oes podem agora ser comparadas com os valores verdadeiros dos casos de teste e deste modo obter uma ideia da performance da ´arvore,

> table(dados.teste$emprestimo,previs~oes.modelo) previs~oes.modelo

nao sim

nao 5 3

sim 0 22

A fun¸c˜ao table foi j´a apresentada anteriormente, e permite fazer a tabula¸c˜ao cruzada de dois factores. Neste caso concreto, estamos a comparar os valores da coluna com a decis˜ao dos peritos humanos nos casos de teste (as previs˜oes “correctas”), com as previs˜oes da ´arvore. A informa¸c˜ao resultante ´e normalmente conhecida como a matriz de confus˜ao das previs˜oes do modelo. Ela diz-nos que dos 8 casos em que os peritos

Matriz de confus˜ao

humanos recomendaram n˜ao conceder cr´edito, a ´arvore tamb´em recomendou o mesmo em 5 casos, mas fez a recomenda¸c˜ao errada em 3. Por outro lado, dos 22 casos em que os peritos do banco recomendaram dar cr´edito, a ´arvore disse o mesmo para todos eles. Com esta informa¸c˜ao ´e f´acil calcular a percentagem de decis˜oes erradas da ´arvore, uma

Calcular a percentagem de erros

vez que o resultado da fun¸c˜ao table ´e uma matriz,

> m.conf <- table(dados.teste$emprestimo,previs~oes.modelo) > perc.erro <- 100 * (m.conf[1,2]+m.conf[2,1]) / sum(m.conf) > perc.erro

[1] 10

Em primeiro lugar coloc´amos o resultado da fun¸c˜ao table usada acima, num objecto chamado m.conf. Em seguida, calculamos a percentagem de previs˜oes erradas usando a informa¸c˜ao da matriz de confus˜ao. A percentagem de decis˜oes corresponde a somar todos os n´umeros da matriz que n˜ao est˜ao na diagonal (pois estas s˜ao as decis˜oes acertadas), e dividir esta soma pela soma total de todos os n´umeros (que de facto ´e o n´umero total de decis˜oes tomadas). Repare que a solu¸c˜ao apresentada ´e espec´ıfica para um problema com duas decis˜oes poss´ıveis, pois de contr´ario ter´ıamos mais c´elulas da matriz que corresponderiam a decis˜oes erradas.

Podemos facilitar o nosso uso futuro das ´arvores do R criando uma fun¸c˜ao que realize toda a parte de

PARTE OPCIONAL

avalia¸c˜ao,

> avalia.´arvore <- function(´arv,dados.teste,objectivo=ncol(dados.teste)) { + prevs <- predict(´arv,dados.teste)

+ m.conf <- table(dados.teste[,objectivo],predict(´arv,dados.teste,type=’class’)) + erro <- 100*sum(m.conf[col(m.conf) != row(m.conf)]) / sum(m.conf)

+ list(previs~oes=prevs, matriz.confus~ao=m.conf, perc.erro=erro) + }

> resultados <- avalia.´arvore(´arvore,dados.teste) > resultados $previs~oes nao sim 2 0.9375000 0.0625000 5 0.1333333 0.8666667 7 0.1333333 0.8666667 8 0.9375000 0.0625000 11 0.1333333 0.8666667 13 0.1333333 0.8666667 20 0.1333333 0.8666667 ... ...

2.2 Elaborar modelos a partir de dados 41 $matriz.confus~ao nao sim nao 5 3 sim 0 22 $perc.erro [1] 10

Repare que esta fun¸c˜ao j´a n˜ao tem a limita¸c˜ao do n´umero de decis˜oes ser duas, mencionada acima. De facto, com a estrat´egia seguida conseguimos calcular a percentagem de erro qualquer que seja o n´umero de decis˜oes (classes). A soma dos elementos fora da diagonal pode parecer um pouco “rebuscada”. O que fizemos foi, tirar partido das capacidades de indexa¸c˜ao do R, e de duas fun¸c˜oes (col() e row()) que produzem uma matriz com os n´umeros das colunas, respectivamente linhas, dos elementos de uma matriz. Assim, a leitura da constru¸c˜ao sum(m.conf[col(m.conf) != row(m.conf)]) ´e: somar os elementos da matriz m.conf que est˜ao em posi¸c˜oes em que o n´umero da coluna ´e diferente (o operador !=) do n´umero da linha, ou seja os elementos fora da diagonal da matriz!

A fun¸c˜ao avalia.´arvore tem algumas novidades em rela¸c˜ao `as que vimos anteriormente. A primeira ´e Parˆametros com valores por defeito

a forma do seu terceiro argumento. Por vezes existem situa¸c˜oes em que uma fun¸c˜ao tem parˆametros que na maioria das vezes v˜ao ser usados com o mesmo valor. Nestas situa¸c˜oes, em vez de obrigar o utilizador da fun¸c˜ao a, sempre que utiliza a fun¸c˜ao, incluir esses parˆametros que quase sempre tˆem o mesmo valor, o R permite-nos evitar este trabalho indicando um valor por defeito para esses argumentos. Deste modo, se o utilizador n˜ao explicitar nenhum valor para esses parˆametros o R vai usar esse valor por defeito. Para indicar o valor por defeito de um argumento basta, quando se cria a fun¸c˜ao, `a frente do argumento pˆor um sinal igual e o valor por defeito, como acontece com o parˆametro objectivo da nossa fun¸c˜ao. Vejamos ent˜ao qual a ideia no nosso exemplo concreto. Como pretendemos que a nossa fun¸c˜ao avalia.´arvore funcione para qualquer problema de decis˜ao, e n˜ao s´o este da concess˜ao de cr´edito, n˜ao sabemos `a partida qual o nome da coluna do data frame com os dados, que corresponde `a vari´avel de decis˜ao. Assim, decidimos assumir que, se nada for dito pelo utilizador, a vari´avel de decis˜ao ´e a ´ultima coluna do data frame. Esse ´e o papel do parˆametro objectivo. Ele por defeito ´e um n´umero que corresponde ao n´umero de colunas do data frame. Se o utilizador estiver a testar um problema em que a vari´avel objectivo n˜ao esteja na ´ultima coluna, ent˜ao ter´a que o explicitar ao usar a fun¸c˜ao, como no exemplo seguinte,

> res <- avalia.´arvore(outra, outros.dados, objectivo=1)

Neste exemplo o utilizador indica `a fun¸c˜ao que a vari´avel objectivo est´a na primeira coluna do data frame. A outra novidade da fun¸c˜ao avalia.´arvore ´e a de que ela d´a como resultado uma lista com trˆes compo- nentes. A primeira componente, chamada previs˜oes cont´em as decis˜oes com respectivas probabilidades para

No documento Faculdade de Economia (páginas 35-41)

Documentos relacionados