Construcción de una API de predicción con Flask, Inteligencia Artificial y Python

Introducción:

Hola amigos de Internet. Nuevamente, les doy la bienvenida a Mi Diario Python, el mejor blog en español para Aprender Python.
Mientras me tomaba mi octava taza diaria de café. Me di cuenta que nunca he publicado un articulo sobre el desarrollo web con frameworks, como django o flask.
El desarrollo web fue mi primer paso para convertir en programador. Así que me dije a mi mismo:
"¿Por que no unir las dos cosas que me gustan, la web y la inteligencia artificial?"
Y se me ocurrió un pequeño proyecto. Construir una API de predicción. 
Así que eso es lo que haremos en este articulo. Realizaremos un ejemplo fácil y sencillo para la construcción de una API de predicción utilizando Scikit-Learn y el framework Flask. Mezclaremos la inteligencia artificial y el desarrollo web para ver que tan bueno es.
¿Que opinas? Interesante ¿verdad?.
Resultado de imagen para api python

Primero lo primero:

Antes de comenzar, primero lo primero. Para construir esta sencilla API necesitaremos dos herramientas:
Sickit-Learn: librería para la creación de modelos de aprendizaje automáticos.
Puedes instalar Scikit-Learn utilizando PyPi: 
pip install -U scikit-learn


Flask: Flask es un framework muy popular, utilizado para el desarrollo web.
Puedes instalar Flask utilizando PyPi:
pip install -U Flask


¿Qué es Scikit-Learn?

En este articulo no me centrare en dar muchas explicaciones sobre las herramientas que emplearemos.
En este blog podrán encontrar más artículos sobre Scikit-Learn, que tus oportunidades con ella.
Hecha un vistazo a todas nuestras entradas: 

Scikit-Learn en Mi Diario Python

¿Qué es Flask?

Igual que con Scikit-Learn, pueden encontrar artículos buenos (no tanto como los mio) sobre Flask.
Hecha un vistazo a todas nuestras entradas:

Flask en Mi Diario Python  

Creando nuestro modelo:

Muy bien, una vez que dispongamos de todas las herramientas necesarias, podemos proseguir. 
Comenzaremos eligiendo y entrenando un modelo. E este caso utilizaremos el modelo SVM (Maquina de vectores de soporte) y los datos que utilizaremos como ejemplo para que la API los clasifique sera el conjunto de datos Iris.
Sí no entendiste ni pío de lo que acabo de decir, te recomiendo ver nuestros artículos introductorios de Machine Learning con Scikit-Learn.
Empecemos importando las librerías necesarias:
# Importamos los recursos necesarios para la 
# construcción de nuestro modelo
from sklearn.svm import SVC # Importamos el clasificador SVC

"""
train_test_split nos ayudara a seprar nuestro datos. Un conjunto
de entrenamiento y otro de prueba
"""
from sklearn.model_selection import train_test_split 
from sklearn.datasets import load_iris # Conjunto de datos iris
from sklearn.externals import joblib
Luego, oredenamos los datos y entrenamos al modelo:
iris = load_iris()
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target)

# Modelo de predicción
clf = SVC() # Instancia del clasificador

clf.fit(x_train, y_train) # Entrenamos al modelo

"""
Con el método score podemos ver que tan eficaz fue el entrenamiento.
EL porcentaje nos indica que tanto aprendio el modelo.
Le pasamos como argumento los datos de prueba para ver que tan 
acertivo fue.
"""
print(clf.score(x_test, y_test))
0.9736842105263158
Como pueden observar, el resultado fue 97%, esto significa que el modelo acerto el 97% de los casos. No esta nada mal.
Aun que si sabes de Aprendizaje Automático, sabes que se podría mejorar. Aunque en este caso, nos quedaremos con este.
Y por ultimo, guardaremos el modelo entrenado en un archivo, de esta manera podremos utilizar donde y cuando sea necesario:
"""
joblib nos permitira guardar el modelo entrenado en un archivo de texto.
De esta manera nos ahorramos tiempo y recursos en estar creando y entrenando
modelos cada minuto.
"""
# Argumentos: instancia del modelo, nombre del archivo
joblib.dump(clf,"iris-svc-model.pkl")
['iris-svc-model.pkl']
Al ejecutar joblib.dump se creara un nuevo archivo en el directorio en el que estes trabajando llamado "iris-svc-model.pkl", este sera nuestro modelos entrenado.
Y listo, ya disponemos del clasificador. Pero lo que queremos es que cualquiera con acceso a Internet pueda utilizarlo, para ello construiremos nuestra API.

Construyendo nuestra API con Flask:

Muy bien, es momento de crear nuestra API. Sera muy sencillo si conoces conceptos como HTTP y consumo de APIS.
# Importamos lo 3 métodos que utilizaremos
from flask import Flask, request, jsonify

# Importamos joblib para leer el modelo
from sklearn.externals import joblib

# Creamos la instancia de Flask
app = Flask(__name__)
# Abrimos el archivo que contienen el modelo
MODEL = joblib.load('iris-svc-model.pkl')

# Las etiquetas con las cuales se clasificaran nuevos datos
# Sabemos que son los nombres de los 3 tipos de iris
MODEL_LABELS = ['setosa', 'versicolor', 'virginica']
"""
El método predict sera el encargado de clasificar y dar una respuesta
a cualquier IP que le envie una petición.
"""
@app.route('/predict')
def predict():
    """
    Declaramos cuales seran los parametros que recibe la petición
    En este caso son las medidas de la flor a clasificar.
    Longitud y tamaño del petalo y del sepalo.
    """
    sepal_length = request.args.get('sepal_length')
    sepal_width = request.args.get('sepal_width')
    petal_length = request.args.get('petal_length')
    petal_width = request.args.get('petal_width')

    # La lista de caracteristicas que se utilizaran
    # para la predicción
    features = [[sepal_length, sepal_width, petal_length, petal_width]]
    
    # Utilizamos el modelo para la predicción de los datos
    label_index = MODEL.predict(features)
    
    """
    La variable label contendra el resultado de la clasificación.
    """
    label = MODEL_LABELS[label_index[0]]
    
    # Creamos y enviamos la respuesta al cliente
    return jsonify(status='Predicción Completada', prediccion=label)

if __name__ == '__main__':
    # Iniciamos el servidor
    app.run(debug=True)
Luego, ejecutamos el script, y nos dirigimos a la siguiente URL: http://127.0.0.1:5000/predict?sepal_length=5&sepal_width=2.1&petal_length=4.5&petal_width=1.4
Para ver algo como esto:
Y listo, nuestra API esta corriendo. Si te fijas, el resultado a sido "versicolor". Este resultado depende de los valores que se le pasen a los argumentos de la URL: sepal_length, sepal_width, petal_length y petal_width.
Puedes descargar el código completo ingresando al siguiente enlace: https://gist.github.com/LuisAlejandroSalcedo/93d90d1bac7be66a35caf167687d6f24.

Consumo de nuestra API:

Ahora, podemos subir nuestra API a un servidor y hacerlo disponible para todo el mundo.
Que tal si consumimos nuestra API? Realizaremos una pequeña prueba utilizando la librería requests:
import requests

params = {'sepal_length':5,'sepal_width':2.1,'petal_length':4.5,'petal_width':1.4}
response = requests.get('http://127.0.0.1:5000/predict', params=params)

if response.status_code == 200:
    print(response.text)
{
  "clasificacion": "versicolor", 
  "status": "clasificado completado"
}
Y como pueden observar, el resultado es satisfactorio.
¿Que opinas? ¿Te ha sido de ayuda este articulo? ¿Has visto lo fácil que es crear una API con Python? ¿Tienes alguna duda? ¿Te preguntas por que hago tantas preguntas? Deja un buen un comentario.
Mi nombre es Luis, y fue un placer compartir mis conocimientos con todos ustedes :D.
  1. Unknown dice:

    Holaa buen post!! Pero aunque ya dog miss primeros Pasos en python eso todavía no está a mi alcance.
    Una pregunta! Podrías hacer que un programa python analice los números de la lotería de la Florida (ejemplo) lunes (7) martes (9) miércoles (12) y si hay un patrón poder predecir el próximo en este caso +2 +3 +4.. El próximo seria 16.. La predicción.. Seria un buen proyecto. Y ya he intentado hacerlo

    1. Anónimo dice:

      lo tenho he ganado 14 veces

  2. Unknown dice:

    Excelente post, pudiera escribir como hacer clasificación (clúster) no supervisada a imágenes

  3. luis eduardo pulsara riascos dice:

    muy buen documento

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir
White Monkey