Creando un detector de Fake News desde 0

Roberto Esteves
6 min readAug 8, 2022

--

Fuente:https://unamglobal.unam.mx/wp-content/uploads/2018/06/fakenews-990x556.jpg

Este artículo pretende dar una breve visión general de cómo realizar la clasificación de textos para detectar “Fake News” .

Utilizaremos un conjunto de datos llamado “Noticias Falsas” publicado en Kaggle -> https://www.kaggle.com/datasets/arseniitretiakov/noticias-falsas-en-espaol

Vamos a importar algunos paquetes necesarios antes de empezar a trabajar con el dataset que consiste en aproximadamente 2000 artículos de noticias.

El objetivo de este artículo es explorar el proceso de entrenamiento y prueba de un clasificador de texto para este problema, utilizando este conjunto de datos y un algoritmo implementado con sklearn.

Y aprenderemos a construir un frontend utilizando Streamlit

Vamos a revisar rápidamente los pasos para llevar a cabo esta tarea:

1 .- Cargar Librerías

2.- Cargar Datasets de entrenamiento con noticias falsas y verdaderas

3.- Preprocesar y Limpiar el texto

4.- EDA ( Análisis Exploratorio de Datos )

5.- Vectorizar el texto

6.- Construir el modelo de clasificación

7.- Guardar el modelo como pkl

8.- Construir el frontend con streamlit

1.- Cargar Librerías

import warnings
warnings.filterwarnings('ignore')
import numpy as np
import pandas as pd # pandas para trabajar arhivos CSV
# matplotlib librería de desarrollar gráficas
import matplotlib as mpl
import matplotlib.cm as cm
import matplotlib.pyplot as plt
# importar librerías para la extracción de características
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
# pre-procesarmiento de texto
import string
import re
# importar el clasificador desde sklearn
from sklearn.naive_bayes import MultinomialNB
# importar las métricas de evauación
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix
from sklearn import metrics
# importar la librería para separar nuestros datos en entrenamiento y prueba
from sklearn.model_selection import train_test_spli
from sklearn.utils import shuffle
from sklearn.pipeline import Pipeline
#importar librería para obtener las stopwords y trabajar con textosimport nlt
from nltk.tokenize import word_tokeniz
from nltk.corpus import stopword
from nltk.stem.wordnet import WordNetLemmatizer
wordnet = WordNetLemmatizer()
regex = re.compile('[%s]' % re.escape(string.punctuation))

2.- Cargar Datasets de entrenamiento con noticias falsas y verdaderas

true = pd.read_csv(r"/content/onlytrue1000.csv")
fake = pd.read_csv(r"/content/onlyfakes1000.csv")
# Asignamos primero las etiquetas de clase en variables de resultado binarias por comodidad. 1 para Real, y 0 para Falsastrue["class"] = 1
fake["class"] = 0

3.- Preprocesar y Limpiar el texto

Los pasos típicos consisten en la tokenización, convertir a minúsculas, la eliminación de stopwords, signos de puntuación, etc.,

También se pueden llevar a cabo otros procesos, como el stemming o la lematización.

En este ejercicios, vamos a realizar los siguientes pasos: eliminación de signos puntuación, números y stopwords.

El proceso de limpieza lo pueden ver en el código -> https://github.com/restevesd/Clasificador/blob/main/Art%C3%ADculo_Julio.ipynb

4.- EDA ( Análisis Exploratorio de Datos )

Para hacer un EDA sobre nuestro dataset de entrenamiento utilizamos un gráfico de Boxplot para entender la composición de lo textos que vamos a utilizar

Podemos evidenciar que en la noticias falsas tenemos más caracteres y palabras por artículo y en cambio las noticias Reales utilizan un mínimo de caracteres y palabras mayor por artículo.

El promedio de palabras y caracteres es similar en ambos tipos de noticias

Analizando las palabras más utilizadas de ambos tipos de noticias vemos que en las noticias falsas se repite “gobierno”, “españa” y otros términos que podrían ser eliminados como “si”, “ser”, “tras”, etc

En las noticia reales se destaca la palabra “madrid”, “gobierno”, “persona” y también tenemos palabras que podrían ser eliminadas como “segun” y “tras”

5.- Vectorizar el texto

¿ Cómo extraer las características de un texto ?

Para este ejemplo vamos a utilizar dos técnicas:

  • CountVectorizer
  • TfidfVectorizer

CountVectorizer

CountVectorizer es una gran herramienta proporcionada por la biblioteca scikit-learn en Python.

Se utiliza para transformar un texto dado en un vector sobre la base de la frecuencia(conteo) de cada palabra que aparece en todo el texto.

Esto es útil cuando tenemos varios textos de este tipo y deseamos convertir cada palabra de cada texto en vectores(para usar en análisis de texto).

CountVectorizer crea una matriz en la que cada palabra única está representada por una columna de la matriz, y cada muestra de texto del documento es una fila en la matriz.

El valor de cada celda no es más que el recuento de la palabra en esa muestra de texto en particular.

# Vectorizar los datasets de entrenamiento y prueba
vect = CountVectorizer() # instantiate a vectoriezer
X_train_dtm = vect.fit_transform(X_train)# utilizarlo para extraer características de los datos de entrenamiento# transformar los datos de prueba (utilizando las características de los datos de entrenamiento)
X_test_dtm = vect.transform(X_test)
# dimensiones del dataset de prueba y entrenamiento
print(X_train_dtm.shape, X_test_dtm.shape)

TF-IDF

Utilizar simplemente un conteo de cuantas veces aparece una palabra no refleja realmente la importancia de esa palabra en un documento.

Por ejemplo, si una palabra está presente con frecuencia en todos los documentos de un corpus, la cantidad de apariciones en diferentes documentos no es útil para discriminar entre diferentes documentos.

En cambio, si una palabra sólo está presente en unos pocos documentos, su valor de recuento en esos documentos puede ayudar a discriminarlos del resto de los documentos. Así pues, la importancia de una palabra, es decir, su valor de característica, para un documento no sólo depende de la frecuencia con la que está presente en ese documento, sino también de su presencia global en el corpus. Esta noción de importancia de una palabra en un documento se recoge en un esquema, conocido como esquema de ponderación de frecuencia de términos-frecuencia inversa de documentos (tf-idf ).

# Vectorizar los datasets de entrenamiento y prueban_features = 1500
vect_tfidf = TfidfVectorizer(max_df=0.90, min_df=2, max_features=n_features)
# utilizarlo para extraer características de los datos de entrenamient
oX_train_dtm_tfidf = vect_tfidf.fit_transform(X_train)
# transformar los datos de prueba (utilizando las características de los datos de entrenamiento)
X_test_dtm_tfidf = vect_tfidf.transform(X_test)
# dimensiones del dataset de prueba y entrenamiento
print(X_train_dtm_tfidf.shape, X_test_dtm_tfidf.shape)

6.- Construir el modelo de clasificación

Ahora estamos listos para desarrollar un modelo de clasificación.

Pasos:

  1. Dividir los datos en conjuntos de entrenamiento y de prueba (75% de entrenamiento, 25% de prueba)
  2. Extraer las características de los datos de entrenamiento utilizando CountVectorizer y TfidfVectorizer.
  3. Transformar los datos de prueba en el mismo vector de características que los datos de entrenamiento.
  4. Entrenar el clasificador
  5. Evaluar el clasificador

Entrenando el modelo de Clasificación

Usando CountVectorizer

#Entrenar el clasificador y predecir para los datos de prueba
nb = MultinomialNB() #instanciamos un modelo de Naive Bayes
nb.fit(X_train_dtm, y_train) #entrenamos el modelo
y_pred_class = nb.predict(X_test_dtm) # predecir si una noticia es falsa o no sobre el dataset X_test_dtm

Evaluar Modelo

Podemos ver que en el dataset de prueba tenemos un 82% de aciertos para noticias falsas y un 77% de aciertos para noticias verdaderas

Usando TfidfVectorizer

#Entrenar el clasificador y predecir para los datos de prueba
nb_tfidf = MultinomialNB() # instanciar Multinomial Naive Bayes model
nb_tfidf.fit(X_train_dtm_tfidf, y_train) # Entrenar el modeloy_pred_class_tfidf = nb_tfidf.predict(X_test_dtm_tfidf) # predecir si una noticia es falsa o no sobre el dataset X_test_dtm_tfidf

Evaluar Modelo

Podemos ver que en el dataset de prueba tenemos un 75% de aciertos para noticias falsas y un 80% de aciertos para noticias verdaderas

7.- Guardar el modelo como pkl

Una vez que hemos obtenido el mejor modelo utilizando CountVectorizer, procedemos a guardarlo como un archivo binario para usarlo más adelante

#guardamos el modelo y guardamos el vectorizador de textoimport picklepickle.dump(nb, open('model.pkl', 'wb')) #exportar modelo
pickle.dump(vect, open('carecteristicas.pkl', 'wb')) #exportar feature extraction

Resumen

Pueden revisar el código completo en https://github.com/restevesd/Clasificador/blob/main/Art%C3%ADculo_Julio.ipynb

Aquí revisamos como implementar un clasificador de texto para detectar posibles noticias falsas a partir de un texto, usando dos tipos de vectorizador de texto y un modelo de machine learning.

En el siguiente artículo les enseñaré a construir un frontend usando Streamlit

Pueden ver el frontend que vamos a construir aquí -> https://restevesd-clasificador-app-kh2fa9.streamlitapp.com/

Contactos

Mail: hola@masappec.com

--

--