Haciendo un trabajo significativo con Machine Learning - Clasifique mensajes de desastre

Construya modelos para ayudar a las organizaciones de desastres a salvar la vida de las personas.

Estoy escribiendo este post a la 1 am en Bucarest, Rumania.

¡Hola de nuevo! Bienvenido a mi cuarto contenido sobre Aprendizaje automático. Recientemente he hecho un proyecto que creo que es socialmente significativo. Daré una breve descripción general de todo esto y profundizaré en el código inmediatamente después:)

En este proyecto aplico habilidades de ingeniería de datos para crear una API (interfaz de programación de aplicaciones) que clasifique los mensajes de desastres de varios Fuentes (Twitter, mensajes de texto) en 36 categorías. Este problema de clasificación es un tipo de aprendizaje automático supervisado porque el modelo aprende a clasificar el resultado basándose en el aprendizaje a partir de los datos que recibe. Es decir. ¿Cuál es el mensaje relacionado con: agua, comida, refugio, dinero, etc.? La razón es que cuando ocurre un desastre, hay millones de mensajes enviados y tuiteados para informar sobre ello. Sin embargo, los desastres son atendidos por diferentes organizaciones. La provisión de alimentos podría ser ofrecida por una cierta organización, mientras que apagar los incendios se haría cargo de una organización diferente. Por lo tanto, la utilidad de esta aplicación sería clasificar estos mensajes en varios tipos para que se entienda qué tipo de ayuda es necesaria para un desastre específico.

Estructura del proyecto

Hay tres partes del proyecto: [19659008] ETL Pipeline
Extraiga, transforme y cargue los datos. Esto se refiere a procesar los datos. Es decir, cargué, fusioné y limpié los conjuntos de datos y categorías. Guardé en una base de datos SQLite para que el modelo pueda usarlo en el siguiente paso para entrenar.

  • ML Pipeline
    El pipeline de aprendizaje automático se ocupa de entrenar el modelo y probarlo. La canalización incluye una parte de procesamiento de texto porque trata con las fuentes de texto como se mencionó al principio. También utilicé GridSearchCV para ajustar aún más el modelo y guardarlo como un archivo pickle.
  • Flask Web App
    Run.py process_data y train_classifier son básicamente el canal ETL y ML pipeline incluidos en el espacio de trabajo de la terminal para hacer el trabajo de la aplicación.

 

ETL Pipeline

En la primera parte del proyecto, mi propósito es extraer los datos que necesito, hacer las transformaciones necesarias para poder usarlos más adelante en la construcción de mi algoritmo. Una vez que eché un vistazo a los dos conjuntos de datos que necesito: las categorías y los mensajes, fusioné los dos conjuntos de datos utilizando la identificación común.

 # combina los conjuntos de datos  
 df = messages.merge (categories, on = [‘id’]) 
 df.head ()

Luego dividí las categorías en columnas de categorías separadas y le di a cada columna su nombre de categoría separado.

 # crear un marco de datos de las 36 columnas de categorías individuales 
 categories = df ['categories'] .str.split (& # 039 ;; & # 039 ;, expand =  Verdadero )
 row = categories.head (1)
 category_colnames = row.applymap ( lambda  x: x [:-2]). Iloc [0, :] .tolist ()
  # cambiar el nombre de las columnas de categorías de categorías 
 categories.columns = category_colnames 
 categories .head ()

Debido a que los modelos usan números como entradas, convertí los valores de categoría en solo números 0 o 1.

 para la columna  en  categorías: 
     # establece cada valor ser la la st carácter de la cadena 
 categorías [column] = categorías [column] .astype (str) .str [-1] 
     # convertir columna de cadena a numérico 
 categorías [column] = categorías [column] .astype (int) 
 categories.head ()

Después de transformar las columnas de categoría, realicé cambios en el marco de datos. Reemplazé la columna de categoría original con la nueva columna de categoría.

 # descarte la columna de categoría original de `df` 
 df.drop (& # 039; categories & # 039 ;, axis = 1, inplace =  Verdadero )
  # concatenar el marco de datos original con el nuevo marco de datos de las "categorías"  df = pd.concat ([df, categories]axis = 1)
 df.head ()

] Después de buscar duplicados en mis datos, me deshice de ellos.

 # verifique el número de duplicados 
 df [df.duplicated] .shape
 (170, 40)
  # drop duplica [19659017] df.drop_duplicates (inplace =  True ) 
  # check number of duplicates  
 df [df.duplicated] .count ()

Finalmente guardé el conjunto de datos limpio en un SQLite database.

 # Guarde el conjunto de datos limpio en una base de datos sqlite. 
 engine = create_engine (& # 039; sqlite: ///disaster.db') 
 df.to_sql (& # 039; messages_disaster & # 039 ;, motor, índice =  Falso ) [19659047] ML Pipeline

En la segunda parte del proyecto, creé la tubería de aprendizaje automático que se usó para clasificar los mensajes de desastre en diferentes categorías. La razón para ser llamado “canalización” se debe a que esta herramienta de modelado se compone de varios pasos que procesan entradas para generar las salidas. En este caso, es decir, utilicé tokenización para procesar datos de texto.

 # cargar datos de la base de datos 
 engine = create_engine (& # 039; sqlite: ///disaster.db') 
 df = pd.read_sql_table (& # 039; messages_disaster & # 039 ;, con = engine)
 X = df ['message']  
 Y = df.drop (['message', 'genre', 'id', 'original']axis = 1)
  # Función de tokenización para procesar datos de texto. 
  def  tokenize (text): 
 tokens = word_tokenize (text) 
 lemmatizer = WordNetLemmatizer () 
 clean_tokens = []
     para]] 19659018]  tok  en  clean_tokens: 
 clean_tok = lemmatizer.lemmatize (tok) .lower (). Strip () 
 19659044] El canal de aprendizaje automático tomará la columna de mensajes como clasificación de entrada y salida en las 36 categorías en el conjunto de datos. Este es un problema de  Procesamiento del lenguaje natural;  es decir. Procesando texto para extraer el significado del mensaje. ¿No es asombroso?
 pipeline = Pipeline ([
 (& # 039; vect & # 039 ;, CountVectorizer ()), 
 (& # 039; tfidf & # 039 ;, TfidfTransformer ()), 
 (& # 039; clf & # 039 ;, MultiOutputClassifier (RandomForestClassifier ())) 
])

Al igual que con todos los demás modelos de ML, debemos tener conjuntos de entrenamiento y pruebas. La razón es que no queremos que nuestro modelo tenga un buen rendimiento en el conjunto de capacitación, al tiempo que no podemos clasificar nuestras categorías correctamente cuando ve datos nuevos. Por lo tanto, debemos usar solo un subconjunto de nuestros datos para entrenarlos y ver cómo se realiza en el conjunto de pruebas.

 # Dividir datos en pruebas de tren y pruebas. 
 X_train, X_test, y_train, y_test = train_test_split (X, Y, test_size = 0.2, random_state = 45)
  # Train the model. 
 pipeline.fit (X_train, y_train)

Cuando se trata de probar mi modelo, quiero tener algunas medidas objetivas de rendimiento. A saber, veré la precisión y recuperación de f1 .

 # Pruebe el modelo e imprima el informe de clasificación para cada una de las 36 categorías. 
  def  rendimiento (modelo, X_test, y_test): 
 y_pred = model.predict (X_test) 
     para  i, col  en  enumerar (y_test): [1945901818] imprimir (col) 
 imprimir (informe de clasificación (y_test [col]y_pred [:, i]))
 rendimiento (canalización, X_test, y_test)
solo una instantánea

Cuando se construyen modelos, siempre es una buena idea para buscar la mejora. Intenta ajustar los parámetros del modelo para obtener mejores resultados. Esto es lo que estoy intentando aquí. Es el mismo proceso, pero con una canalización diferente.

 # Mejorar la tubería. 
 pipeline2 = Pipeline ([
 (& # 039; vect & # 039 ;, CountVectorizer ()), 
 (& # 039; best & # 039 ;, TruncatedSVD ()), 
 (& # 039; tfidf & # 039 ;, TfidfTransformer ()), 
 (& # 039; clf & # 039 ;, MultiOutputClassifier (AdaBoostClassifier () ) 
])
  # Entrenar la tubería ajustada.  
 pipeline2.fit (X_train, y_train)
 # Verificar el rendimiento del modelo ajustado. 
 performance (pipeline2, X_test, y_test)

Fui un paso más allá y utilicé un conjunto diferente de parámetros con un cierto rango de valores. Con la ayuda de GridSearchCV el modelo elige los mejores parámetros.

 parameters2 = {
 & # 039; tfidf__use_idf & # 039 ;: ( True  false ), 
 & # 039; clf__estimator__n_estimators & # 039 ;: [50, 100]
 & # 039; clf__estimator__learning_rate & # 039 ;: [1,2]}
 CV2 = GridSearchCV (pipeline2, param_grid = parameters2)
 cv2.fit (X_train, y_train)
 rendimiento (cv2, X_test, y_test)

Construya la API

Finalmente, concluí este proyecto con una API que toma un mensaje de desastre y lo clasifica en las categorías más probables de desastre. De esta manera, podemos ayudar a las organizaciones de desastres a comprender mejor qué tipo de catástrofe ocurrió y qué tipo de ayuda es necesaria.

Palabras de cierre

Si llegó hasta aquí, ¡muchas gracias por leer! Espero que esto te dé una idea de lo útil que puede ser el aprendizaje automático. Y cuán amplia es la gama de sus aplicaciones. Literalmente, podemos salvar vidas de personas sabiendo cómo procesar datos de texto e implementar modelos.

Le deseamos lo mejor y permanezca bendecido:)


Originalmente, estaba haciendo un trabajo significativo con Aprendizaje automático - Clasificar mensajes de desastres publicado en Hacia la ciencia de datos en Medium, donde las personas continúan la conversación resaltando y respondiendo a esta historia.