Clasificación mensajes correo debian parte 3
Despliegue de modelos de clasificación mensajes de correo electrónico de la lista de Debian
Continuando desde la segunda parte donde ya hemos entrenado y obtenido modelos para la clasificación de mensaje ahora continuaremos a "exportarlos" para poder usarlos:
Aplicaremos nuevos mensajes de texto al modelo ya generado y este va a devolver predicciones. En este caso cuando introduzcamos un mensaje de texto, usando el modelo se predice a qué categoría de mensajes de la lista de correos de debian pertenece ese mensaje de texto.
Exportando el modelo¶
En el notebook de la parte 2 (debian-2015-2019-NaiveBayes-RandomForest.ipynb) hay una parte que guarda guarda tres cosas:
- El modelo generado aplicando la técnica.
- La matriz CountVectorizer con el conteo de palabras y ocurrencias.
- El diccionario de categorías y su valor numérico tal y como lo manejamos para entrenar el modelo.
Con estos objetos ya obtenidos al hacer el entrenamiento, usaremos la biblioteca python pickle que serializa objetos python y los guarda en archivos binarios, esos archivos luego se pueden leer desde otro programa o script python y se puede recuperar el objeto python original.
El proceso de guardado se hace en el con:
import pickle pickle.dump(model_multinomialNB, open('./model_multinomialNB.pkl', "wb")) pickle.dump(cv_multinomialNB, open('./cv_multinomialNB.pkl', "wb")) pickle.dump(labelsEncodedNB, open('./labelsEncodedNB.pkl', "wb")) pickle.dump(model_randomForest4, open('./model_randomForest.pkl', "wb")) pickle.dump(cv_randomForest4, open('./cv_randomForest.pkl', "wb")) pickle.dump(labelsEncodedRf4, open('./labelsEncodedRf.pkl', "wb"))
Que guarda en archivos con extensión .pkl
. Algo interesante es que los archivos guardados tienen tamaños variables:
2,3M cv_multinomialNB.pkl 2,3M cv_randomForest.pkl 514 labelsEncodedNB.pkl 514 labelsEncodedRf.pkl 256K model_multinomialNB.pkl 106M model_randomForest.pkl
El archivo serializado model_multinomialNB.pkl
tiene un tamaño de 256KB que corresponde a la técnica Miultinomial Naive Bayes, y el archivo model_randomForest.pkl
de la técnica Random Forest tiene un tamaño de 106MB. El modelo generado por random Forest es como 40 veces más grande y esto se debe a que durante el entrenamiento para el Random Forest se usaron un total de 80 árboles binarios que tomo un tiempo considerablemente mayor en entrenar que la técnica Multinomial Naive Bayes.
Cargando los modelos exportados¶
Ahora vamos a cargar estos modelos generados en otro notebook jupyter, este se puede revisar por completo:
En las primeras partes volvemos a usar pickle para importar los modelos guardados.
# cargando los modelos y otros datos generados anteriormente import pickle model_multinomialNB = pickle.load(open('./model_multinomialNB.pkl', 'rb')) cv_multinomialNB = pickle.load(open('./cv_multinomialNB.pkl', 'rb')) labelsEncodedNB = pickle.load(open('./labelsEncodedNB.pkl', 'rb')) model_randomForest = pickle.load(open('./model_randomForest.pkl', 'rb')) cv_randomForest = pickle.load(open('./cv_randomForest.pkl', 'rb')) labelsEncodedRf = pickle.load(open('lablesEncodedRf.pkl', 'rb'))
Aplicando mensajes y generando nuevas predicciones¶
Se definen algunos mensajes de texto nuevos y los unimos en una lista python:
m1 = "We are looking for a GNU/Linux System Administrator in Charlotte, North Carolina. Other locations near the EST timezone will" m2 = '''Traceback (most recent call last): File ""/tmp/autopkgtest-lxc.5a99fnj6/downtmp/autopkgtest_tmp/tests/test_core/test_sequence.py''' m3 = '''Actually, the GPL only mandates stating *who* made changes and *when*,but not *what* changed. As I see, just adding something like ""Modified by John Doe on 2019.07.25"" on the comment header where the GPL copyright notice lies would suffice"''' m4 = '''E: pybuild pybuild:336: test: plugin distutils failed with: exit code=1: cd /build/snakemake-4.8.0/.pybuild/cpython3_3.6_snakemake/build; python3.6 -m nose tests dh_auto_test: pybuild --test --test-nose -i python{version} -p 3.6 returned exit code 13 make: *** [debian/rules:17: build] Error 25 dpkg-buildpackage: error: debian/rules build subprocess returned exit status 2 I: copying local configuration E: Failed autobuilding of package I: user script /var/cache/pbuilder/build/cow.11501/tmp/hooks/C99_failed_build starting root:/# echo $PATH''' m5 = """I'd take option 2.There ought to be no packages using python-dput (like, srly…), and I see no real reason for anybody to keep using the py2 version after the switch.""" m6 = """Nothing can be done without previous voting phase, we are talking about somewhat important issues that must be taken into considereation before finally giving them a certain direction. Regards BlueBon.""" m7 = """I would be happy to teach anyone, including you, how to sync between weblate and salsa (which mostly involve 'git pull weblate master && git push' with a few clicks on the Weblate admin page to reduce the chance of any git conflict in between)""" # uniendo testMsjs = pd.Series([m1,m2,m3,m4,m5,m6,m7])
Ahora agregamos las palabras nuevas a las matrices de conteo de palabras del entrenamiento anterior como se muestra en [1]:
vect = cv_multinomialNB.transform(testMsjs).toarray()
Usamos el modelo para generar nuevas predicciones:
predictions = model_multinomialNB.predict(vect)
Finalmente vamos a ver a qué categorías corresponden las predicciones.
# mostrando resultados for i in range(len(predictions)): print('m' + str(i+1), '-->', labelsEncodedNB[predictions[i]])
Que muestra:
m1 --> debian-mentors m2 --> debian-python m3 --> debian-legal m4 --> debian-python m5 --> debian-python m6 --> debian-vote m7 --> debian-science
Haciendo lo mismo con el modelo de la técnica Random Forest:
vect = cv_randomForest.transform(testMsjs).toarray() predictions = model_randomForest.predict(vect) for i in range(len(predictions)): print('m' + str(i+1), '-->', labelsEncodedRf[predictions[i]])
Resulta:
m1 --> debian-mentors m2 --> debian-mentors m3 --> debian-legal m4 --> debian-python m5 --> debian-python m6 --> debian-mentors m7 --> debian-mentors
Comentarios finales¶
Ambos modelos han clasificado bien la mayoría de los mensajes de pruebas, con algunas diferencias:
- El mensaje m2 que es un texto con un mensaje de error de python, lo ha clasificado correctamente Naive Bayes pero no Random Forest
- El mensaje m6 que es texto que habla de la necesidad de un proceso de votación antes de decidir algo, lo ha clasificado correctamente el Naive Bayes pero no Random Forest.
- El mensaje m7 se parece más a un mensaje de alguien que se ofrece a enseñar algo, la técnica Random Forest lo ha clasificado correctamente en la categoría debian-mentors, y la técnica Naive Bayes lo considera de la categoría debian-science.
Usando mas allá¶
Lo bueno es que ya tenemos la forma sencilla de importar en cualquier otro programa los modelos generados en el entrenamiento anterior.
Las aplicaciones son muchas por ejemplo como se muestra en [1] se puede desplegar una aplicación web con un formulario donde se introduzca texto y este es clasificado como spam o no spam. También se podría aplicar a un programa clasificador automático de mensajes cuando alguien escribe un correo electrónico cuando en caso de detectar un mensaje que no pertenece a la categoría a la que se esta escribiendo, el programa le avise que podría estar enviando su mensaje a una categoría equivocada.
La clasificación de textos es un área de estudio del aprendizaje automático muy interesante y estas técnicas que usamos demuestran ser muy útiles. Seguramente existen otras técnicas y la combinación de estas que se ajustan a distintos casos.