SAUDAÇÕES!

Seja bem vindo à página do professor Pedro Albuquerque. Para saber mais sobre meu currículo, disciplinas ministradas e interesses de pesquisa, navegue no menu disponível no topo da página.
Mostrando postagens com marcador Java. Mostrar todas as postagens
Mostrando postagens com marcador Java. Mostrar todas as postagens

sexta-feira, 15 de abril de 2016

Usando a biblioteca LIBSVM no R.


Máquinas de Suporte Vetorial tem tido um grande apelo nas aplicações práticas. Nesse post, seguiremos a mesma ideia do post anterior mas agora, utilizaremos uma biblioteca já existente escrita em Java para a execução do SVM.

A biblioteca a ser utilizada é denominada LIBSVM. O primeiro passo é obter o código fonte e armazená-lo em alguma pasta na sua máquina. Os arquivos estão na pasta denominada Java.

O primeiro passo é fazer a leitura dos dados de interesse no R. Utilizaremos aqui os dados já apresentados no post acerca do Risco de Crédito.

Algumas etapas são necessárias para se preparar o arquivo para o LIBSVM:

#Limpa o Workspace
rm(list=ls())
#Importa os dados German.csv 
setwd("C:\\Blog\\java")
library(RCurl)
URL <- "https://dl.dropboxusercontent.com/u/36068691/Blog/german.csv"
x <- getURL(URL)
dados <- read.csv(textConnection(x))
#Separa o vetor de resposta
RESPONSE<-dados$RESPONSE
#Troca zero por -1
RESPONSE[RESPONSE==0]<- -1
#Remove a coluna RESPONSE
dados<-dados[,-32]
O formato exigido pelo LIBSVM deve seguir o formato: [categoria] [coluna1]:[valor1] [coluna2]:[valor2] .... Nesse sentido, fazemos:
#Função para formato libSVM
libsvm<-function(x){
  tt<-cbind(t(x),1:length(x))
  tt<-tt[tt[,1]>0,]
  str<-paste(c(rbind(tt[,2],":",tt[,1]," ")),collapse ="")
  return(str)
} 

#Cria as strings
str<-""
for(i in 1:nrow(dados)){
  x<-dados[i,]
  str<-rbind(str,libsvm(x))
}
str<-str[-1,]

#Adiciona a resposta
txt<-cbind(RESPONSE,str)
txt<-apply(txt,1,function(x) paste(x[1],x[2]))
write.table(txt,"C:/Blog/german",quote=F,row.names=F,col.names=F)
O arquivo german gerado já estará no formato do LIBSVM. Observação: A criação do arquivo german no formato esparso também pode ser gerado utilizando-se as funções read.matrix.csr e write.matrix.csr do pacote e1071. É preciso compilar agora o arquivo svm_train.java e gerar o arquivo svm_train.class antes de prosseguir. Pode utilizar o Eclipse para isso. O próximo passo é utilizar a função svm_train da biblioteca LIBSVM:
#Em seguida executamos a função java
parms<-c("-s 0 "," -t 3 "," -d 3 "," -g 1 "," german "," saida")
system(paste("java svm_train",paste(parms,collapse = "")))
Os resultados da análise são apresentados no console:

terça-feira, 15 de março de 2016

Utilizando rJava em aplicações estatísticas.


Java é uma das linguagens mais utilizadas atualmente, principalmente devido ao uso de máquinas virtuais na execução do código, o que permite versatilidade nos mais diversos sistemas operacionais, bem como também velocidade.

O primeiro passo para a utilização do pacote rJava é a instalação do Java SE Development Kit (JDK).

Considere o seguinte exemplo:

#Limpa o Workspace
rm(list=ls())

#Gera dois vetores com distribuição normal:
vet1<-rnorm(1000,1,1)
vet2<-rnorm(1000,3,4)
Suponha que desejamos calcular a distância entre cada um dos pares de elementos e armazená-las em uma matriz de dimensão $1000\times1000$. É possível realizar essa operação eficientemente no R utilizando os membros da família apply ou o pacote foreach. Nesse exercício, no entanto, vamos realizar essa operação utilizando o Java e loops aninhados. O código em Java pode ser desenvolvido usando alguma IDE. Uma boa sugestão é utilizar o Eclipse na construção dos códigos em Java. O código em Java utilizado é apresentado a seguir:
public class LoopsAninhados {
 //Construtor default do JAVA.
 public static void main(String[] args) {
  
 }
 //Método para a construção da matriz de distâncias
 private double [ ] [ ] DistanciaComputo(double[] vetor1, double[] vetor2){
  //Cria a matriz de distâncias
  double [ ] [ ] matRes = new double[vetor1.length][vetor2.length];
  //Faz o loop aninhado
  for(int i=0;i < vetor1.length;i++){                       
   for(int j=0; j< vetor2.length;j++){            
    double d=Math.sqrt(Math.pow(vetor1[i]-vetor2[j],2));
    matRes[i][j]=d;
   }
  }
  return(matRes);
 }
}

Esse código pode ser simplesmente copiado e colado em um arquivo texto e então renomeado para .java .
#Habilita a biblioteca
library(rJava)
#Define quanto de memória estará disponível para a VM
.jinit(parameters="-Xmx1024m")
#Endereço de onde estão os arquivos class gerados
.jaddClassPath("C:/Blog/bin")    
#Endereço do Java e arquivos no class
.jclassPath() 
O próximo passo é enviar os objetos criados anteriormente no R para o Java e então receber o resultado do método LoopsAninhados:
#Inicia o arquivo compilado (LoopsAninhados.class):
loopAninhado <- .jnew("LoopsAninhados")
#Pega a matriz resultante:
distMat <- .jcall(loopAninhado, "[[D", "DistanciaComputo",
                           .jarray(vet1),.jarray(vet2), simplify=T)
O comando .jcall possui os seguintes argumentos:
  1. loopAninhado
  2. Nome do método a ser chamado.
  3. "[[D"
  4. Tipo do objeto a ser retornado. Nesse caso um vetor bidimensional double[ ][ ]. Poderia ser ainda: "S" retorna uma String, "[S" retorna um array de String[], "[[S" retorna um array bidimensional de String [ ][ ], "D" retorna um double, "[D" retorna um array de double[], "Z" retorna um boolean, "[Z" retorna um array de boolean[] e "[[Z" retorna um array bidimensional de boolean [ ][ ].
  5. "DistanciaComputo"
  6. Nome do método a ser invocado.
  7. .jarray(vet1)
  8. Primeiro argumento do método "DistanciaComputo". Observe que o método exige que o argumento seja um array, logo usamos a função .jarray() para passar o objeto do R em um array double[] para o Java.
  9. .jarray(vet2)
  10. Segundo argumento do método "DistanciaComputo". Os argumentos são inseridos na ordem em que foram definidos no método em Java.
  11. simplify=T
  12. Converte o objeto array bidimensional do Java em objetos nativos do R como matrizes.

Ao rodar os comandos percebe-se que o loop aninhando é executado de maneira muito mais rápida do que se fossemos utilizar o R para realizar essa função. Tente fazer uma comparação de tempos... ;-)