Anuncios

Bienvenidos sean a este post, hoy veremos muy brevemente un algoritmo.

Anuncios

En el post anterior hablamos sobre como una funcion para ser inteligente necesitaba de un algoritmo que le enseñe como trabajar. Por esta razon, hoy nos centraremos en desarrollar una clase que representara a una maquina de calculos. Este contiene cuatro operaciones arimeticas y a la espera de que le provean ejemplos como se deberia calcular los valores de entrada. Veamos el codigo inicial de nuestra clase:

struct Ejemplo
{
	int entrada1;
	int entrada2;
	int resultado;
};

class MaquinaCalculos
{
public:
	using Ejemplos = std::vector<Ejemplo>;
	void setEjemplos(const Ejemplos& ejemplos);
	int calcular(int a, int b);

private:
	int (*fptr_)(int, int) = nullptr;

private:
	static int sumar(int, int);
	static int restar(int, int);
	static int multiplicar(int, int);
	static int dividir(int, int);
};
Anuncios
Anuncios

Primero definiremos un struct que usaremos como tipo propio de dato donde tendremos tres propiedades. Luego definimos una clase que sera nuestra maquina para calcular. En la parte privada definimos un puntero de funciones para que trabaje con funciones que recibe dos argumentos de tipo int. Tambien establecemos cuatro prototipos estaticos para realizar las cuatro operaciones basicas. En la parte publica primero estableceremos un alias para el tipo vector con el tipo de dato creado anteriormente. El siguiente es un prototipo que se encargara de recibir valores como ejemplos para que en base a estos pueda ir acumulandolos y aprendiendo, sobre esto hablaremos en un momento, y finalmennte tenemos al prototipo del metodo calcular del cual hablamos en el post anterior pero con una sutil diferencia que pronto veremos. Antes de hablar del metodo setEjemplos debemos establecer algunos ejemplos, para ello podemos usar los siguientes valores:

3 4 7
2 2 4
5 5 10
5 4 9
Anuncios
Anuncios

Los primeros dos valores son los datos que usaremos para la operacion y el tercer es el resultado de una operacion con los valores anteriores. La funcion setEjemplos es la encargada de hacer que MaquinaCalculos pueda aprender a usar la funcion arimetica correcta. De la misma manera que podemos darnos cuenta con solo mirar los tres valores, la clase trata de encontrar las operaciones que encajen mejor con los valores pasados. A medida que vaya pasando por los ejemplos, va definiendo cual es la mejor funcion que se debe usar en el metodo calcular cuando sea llamado. Veamos como puede ser su immplementacion:

void MaquinaCalculos::setEjemplos(const Ejemplos& ejemplos)
{
  int contar_sum{0};
  int contar_res{0};
  int contar_mul{0};
  int contar_div{0};
  for (const auto& ejemplo : ejemplos) {
    if (MaquinaCalculos.sumar(ejemplo.entrada1, ejemplo.entrada2) == ejemplo.resultado) {
      ++contar_sum;
    }
    if (MaquinaCalculos.restar(ejemplo.entrada1, ejemplo.entrada2) == ejemplo.resultado) {
      ++contar_res;
    }
    if (MaquinaCalculos.multiplicar(ejemplo.entrada1, ejemplo.entrada2) == ejemplo.resultado) {
      ++contar_mul;
    }
    if (MaquinaCalculos.dividir(ejemplo.entrada1, ejemplo.entrada2) == ejemplo.resultado) {
      ++contar_div;
    }
  }
  // resto del codigo...
}
Anuncios
Anuncios

Esta es la definicion del prototipo para establecer los ejemplos. Primero tenemos una serie de variables que serviran para almacenar la cantidad de veces que coincidio con la operacion,, ya lo veremos en un segunudo. Y todas seran cn el valor inicial de 0. Lo siguiente es un bucle que pasara por todos los ejemplos que recibimos. Pasaremos por cuatro condicionales que comparan el resultado de cada metodo de operaciones de la clase anterior con el tercer valor informado, suponiendo que ya estan definidos estos metodos, si son iguales procede a incrementar la variable correspondiente. Esto hara que la variable con mayor cantidad de coincidencias procede a establecer al metodo correspondiente como predeterminado para cuando sea llamado el metodo calcular. Esto sera parte del codigo que no tenemos en el ejemplo pero con esto realizado, podemos pasar a ver como es la definicion del metodo calcular:

int MaquinaCalculos::calcular(int a, int b)
{
  return fptr_(a, b);
}
Anuncios

Como dijmos el puntero de funciones que devolvemos va a ser el metodo ganador del metodo anterior. Si miramos el listado de ejemplos, este metodo va a ser sumar. Este es un ejemplo muy simple de un algoritmo que aprende.

Anuncios
Anuncios

Con esto, podemos tomar al metodo setEjemplos y renombrarlo a setConjuntoDatos o entrenarConEjemplos o algo similar. El punto del ejemplo con MaquinaCalculos es los que definimos modelo y algoritmo trabajando con esto y poder llamarlo ML. Esto es asi porque aprende de dato, o inclusive desde experiencias. Cada registro en el vector de ejemplos que fueron pasadas a la clase pueden ser considerados como experiencia porque el hecho de ejecutar el calculo mejora con experiencia. Es decir, mientras mas ejemplos le damos con mas confianza al momento de elegir la funcion correcta para ejecutar la tarea, y la tarea es calcular el valor en base a los argumentos informados. El proceso de auto-aprender no es la tarea en si, el aprendizaje es lo que lleva a ejecutar la tarea.

Anuncios
Anuncios

Las tareas son usualmente descriptas tal como el sistema deberia procesar un ejemplo, donde un ejemplo es una coleccion de caracteristicas. A pesar de que, en los terminos de ML, un ejemplo es representado como un vector donde cada entrada es considerada como otra caracteristica. Sin embargo, la eleccion de la estructura de datos del vector es pura coincidencia. Como uno de los principios fundamentales es el entrenamiento de ML, los algoritmos pueden ser categorizados como supervisados o sin supervisar pero de esto hablaremos en el proximo post.

Anuncios

En resumen, hoy hemos visto un algoritmo que aprende, como se compone, y un ejemplo para ver como es el proceso. Espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios

Donación

Es para mantenimento del sitio, gracias!

$1.50