analytics

martes, 17 de enero de 2017

Java Regresión Lineal Código


Java Regresión Lineal Código



Encontramos un buen ejemplo Java de la recta de regresión aquí, donde se explica adecuadamente. Vamos a poner el código Java para el cálculo de la regresión lineal dada una nube de puntos. Listo para un copy/paste. Es sencillo.



// funcion y= ax+b
    public static double[] calcRectaRegresionYsobreX(double[] lasX, 
double[] lasY) {
        double[] retVal = new double[3];
        double mediaX = calcMedia(lasX);
        double mediaY = calcMedia(lasY);
        double varianzaX = (calcMediaDeLosCuadrados(lasX) - Math.pow(mediaX, 2));
        double varianzaY = (calcMediaDeLosCuadrados(lasY) - Math.pow(mediaY, 2));
        double covarianza = calcMediaDeLosProductos(lasX, lasY) - (mediaX * mediaY);
        double diviCovaX = covarianza / varianzaX;

        retVal[0] = diviCovaX;                     
// aqui devuelve la pendiente de la recta
        retVal[1] = -(diviCovaX * mediaX) + mediaY;   
// aqui devuelve el parametro independiente
        if ((Math.sqrt(varianzaX) * Math.sqrt(varianzaY))==0){
            retVal[2]=1;
        } else {
            retVal[2] = covarianza / (Math.sqrt(varianzaX) * 
Math.sqrt(varianzaY)); // esto es la correlacion r
        }
        return retVal;
    }

    // funcion x= ay + b
    public static double[] calcRectaRegresionXsobreY(double[] lasX, double[] lasY) {
        double[] retVal = new double[3];
        double mediaX = calcMedia(lasX);
        double mediaY = calcMedia(lasY);
        double varianzaX = (calcMediaDeLosCuadrados(lasX) - Math.pow(mediaX, 2));
        double varianzaY = (calcMediaDeLosCuadrados(lasY) - Math.pow(mediaY, 2));
        double covarianza = calcMediaDeLosProductos(lasX, lasY) - (mediaX * mediaY);
        double diviCovaY = covarianza / varianzaY;

        retVal[0] = diviCovaY;                     
// aqui devuelve la pendiente de la recta
        retVal[1] = -(diviCovaY * mediaY) + mediaX;   
// aqui devuelve el parametro independiente
        retVal[2] = covarianza / (Math.sqrt(varianzaX) * 
Math.sqrt(varianzaY)); // esta es la correlacion r
        return retVal;
    }

    public static double calcMedia(double[] valores) {
        double retVal = 0;
        for (int i = 0; i < valores.length; i++) {
            retVal += valores[i];
        }
        return retVal / valores.length;
    }

    public static double calcMediaDeLosCuadrados(double[] valores) {
        double retVal = 0;
        for (int i = 0; i < valores.length; i++) {
            retVal += Math.pow(valores[i], 2);
        }
        return retVal / valores.length;
    }

    public static double calcMediaDeLosProductos(double[] valores1, 
double[] valores2) {
        double retVal = 0;
        for (int i = 0; i < valores1.length; i++) {
            retVal += valores1[i] * valores2[i];
        }
        return retVal / valores1.length;
    }
    


Simplemente, llamaremos al método calcRectaRegresionYSobreX pasándole un array de valores de X y un array de valores de Y (es decir, en definitiva, una lista de puntos).



Retorno de la función

Para una función y=ax+b , esta función nos devolverá un vector de doubles de la siguiente manera.

posición[0] = pendiente de la recta (a)
posición[1] = término independiente (b)
posición[2] = correlación (grado de unión de -1 a 1)

Así de sencillo. Ya tenemos la función de la recta de regresión de la nube de puntos dada y el índice de correlación.

Si necesitas una explicación más detallada, prueba aquí.

lunes, 9 de enero de 2017

Timer y TimerTask, crear un scheduler


Uso de Timer y TimerTask para crear un scheduler

reloj


Vamos a ver como podemos implementar un Scheduler, o en castellano, un planificador de tareas. Emplearemos la clase Timer y la clase TimerTask. Para nosotros va a ser un hilo en permanente ejecución que podrá ejecutar tareas cuando se le programe, de manera puntual o de manera periódica. Este hilo principal o Scheduler, será singleton (una sola instancia en cada ejecución). Esto último lo conseguimos haciendo su constructor privado y accediendo a la instancia a través del método getInstance().

Es fácil




public class Scheduler implements Runnable {


    private Timer t;
    private static Scheduler scheduler = null;

    
    private Scheduler() {    
        t = new Timer();
    }

    public static Scheduler getInstance() {
        if (scheduler == null) {
            scheduler = new Scheduler();
        }
        return scheduler;
    }

    
    
    @Override
    public void run() {
        
        
        System.out.println("Ejecutando scheduler");        

        TareaCapturar tc =  new TareaCapturar();
        
        // ejecución periódica cada 10 min
t.schedule(tc.getCaptureTask(), 1000, 1000*60*10);
        // una ejecución puntual a los diez segundos de iniciarse 
        t.schedule(tc.getCaptureTask(), 1000*10); 
        
    }

    public void reIniciar(){
        t.cancel();
        t = new Timer();
    }

}


Ahora vamos a ver la clase TareaCapturar, la cual es la que contiene la tarea (TimerTask) que se ejecutará cada vez que el Timer del Scheduler la invoque. Cada vez que se ejecute la tarea, lo hará en un hilo independiente, de esta manera se consigue mayor fiabilidad en la ejecución.


public class TareaCapturar {
    
    
     public TimerTask getCaptureTask() {
        TimerTask tarea = new TimerTask() {

            @Override
            public void run() {
                
                
                // aquí vendrá el código de la tarea
                
                
            };
        };
        return tarea;
     }


Por lo tanto, tenemos un scheduler que se ejecutará permanentemente, e irá invocando en el tiempo nuevos hilos que ejecutarán la tarea implementada en la clase TareaCapturar. Una manera sencilla y ordenada de gestionar ejecuciones periódicas.


lunes, 2 de enero de 2017

Servidor de sockets TCP-IP


Servidor de Sockets TCP-IP



Ahora vamos a ver como crear un servidor de sockets por tcp-ip, es decir, una pequeña aplicación que estará permanentemente "escuchando" en un puerto a la espera de conexiones entrantes por dicho puerto. Cuando llegue una petición, crearemos un hilo con un nuevo cliente que ejecutará el tratamiento correspondiente a la nueva petición.

Para empezar, vamos a ver como quedaría la clase de ServerSockets



import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import org.apache.log4j.Logger;

public class SocketServer implements Runnable {
    
    private ServerSocket serverSocket;
    private boolean socketReadActive;
    private int timeOut;
    final static Logger mainLog = Logger.getLogger(SocketServer.class);

    public  SocketServer(int port, int timeOut) {
        try{
            this.socketReadActive = true;
            this.serverSocket = new ServerSocket(port);
            this.timeOut = timeOut;
        } catch (IOException ex) {
            mainLog.error("SocketServer (): IOException" ,ex);
            this.closeSocketServer();
        }
    }

    public void run() {
         
     
        while (this.socketReadActive) {
            try {
                    Socket clientSocket = this.serverSocket.accept();
                    Client client = new Client(clientSocket, this.timeOut);
                    new Thread(client).start();                    
                    mainLog.debug("Connected client: " + clientSocket.getInetAddress() + ":" + clientSocket.getPort());
            } catch (Exception ex) {
                mainLog.error("run (): Exception" ,ex);
                this.closeSocketServer();
            }
        }
    }

    public void closeSocketServer() {
        this.socketReadActive = false;
        try {
            if (this.serverSocket != null) {
                this.serverSocket.close();
                this.serverSocket = null;
            }
        }
        catch(Exception ex){
            mainLog.error("closeSocketServer (): Exception" ,ex);
        }
    }
}



Como veis, es sencillo. Un Thread que se ejecuta constantemente a la escucha de nuevas conexiones entrantes. Cuando llega una conexión entrante, instancia un cliente Client, cuyo código será



import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.log4j.Logger;


public class Client implements Runnable{

 final static Logger mainLog = Logger.getLogger(Client.class);
 
 private Socket clientSocket;
 private int timeout;
 
 public Client(Socket clientSocket, int timeout){
  this.clientSocket = clientSocket;
  this.timeout = timeout;
  
 }
 
 
 @Override
 public void run() {
  
  // set timestamp al socket de cliente
  try {
   this.clientSocket.setSoTimeout(timeout);
  } catch (SocketException e) {
   mainLog.error("Client run error " , e);
  }
  
  // procesar la petición
   BufferedReader input;
  try {
   
   input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
   String trama = input.readLine();
   
   
   try{
    
    // AQUI vendría el código de tratamiento de la petición

   } catch (Exception e){    
    mainLog.error("Client run error conectando a BD " , e);
   }
   
   
  } catch (Exception e) {      
   mainLog.error("Client run error abriendo socket ",e);
  }
          

 }


}

Sencillo cliente que se ejecuta en un hilo aparte (cada nuevo cliente será un hilo distinto), lo cual permite múltiples ejecuciones de cliente paralelas. El código de tratamiento de la petición ya depende del caso concreto.