Cómo crear un AI-racista sin mucho esfuerzo

Una lección de advertencia.

¡Hagamos un clasificador de tonalidad!

El análisis de sentimientos (análisis de sentimientos) es una tarea muy común en el procesamiento del lenguaje natural (PNL), y esto no es sorprendente. Es importante que una empresa entienda lo que dice la gente: positiva o negativa. Dicho análisis se utiliza para monitorear las redes sociales, los comentarios de los clientes e incluso en el comercio de acciones algorítmico (como resultado, los bots compran acciones de Berkshire Hathaway después de publicar críticas positivas sobre el papel de Anne Hathaway en la última película ).

El método de análisis a veces se simplifica demasiado, pero es una de las formas más fáciles de obtener resultados medibles. Simplemente envíe el texto, y el resultado es positivo y negativo. No es necesario tratar con el árbol de análisis, construir un gráfico u otra representación compleja.

Esto es lo que haremos. Seguiremos el camino de menor resistencia y crearemos el clasificador más simple, que probablemente parezca muy familiar para todos los involucrados en desarrollos relevantes en el campo de la PNL. Por ejemplo, dicho modelo se puede encontrar en el artículo Deep Averaging Networks (Iyyer et al., 2015). No estamos intentando desafiar sus resultados o criticar el modelo; simplemente damos un método bien conocido de representación vectorial de palabras.

Plan de trabajo:

  • Introduzca una representación vectorial típica de palabras para trabajar con significados (significados).
  • Presente conjuntos de datos de entrenamiento y prueba con listas estándar de palabras positivas y negativas.
  • Entrene al clasificador de descenso de gradiente para reconocer otras palabras positivas y negativas basadas en su representación vectorial.
  • Use este clasificador para calcular clasificaciones de tonalidad para oraciones de texto.
  • Para ver el monstruo que hemos creado.

Y luego veremos, "cómo crear un racista AI sin esfuerzos especiales". Por supuesto, no puedes dejar el sistema en una forma tan monstruosa, así que vamos a:

  • Evaluar el problema estadísticamente, para que sea posible medir el progreso a medida que se resuelve.
  • Mejore los datos para obtener un modelo semántico más preciso y menos racista.

Dependencias de software


Este tutorial está escrito en Python y se basa en una pila típica de aprendizaje automático de Python: numpy y scipy para computación numérica, pandas para administración de datos y scikit-learn para aprendizaje automático. Al final, también seaborn matplotlib y seaborn para crear diagramas.

En principio, scikit-learn se puede reemplazar con TensorFlow o Keras, o algo así: también pueden entrenar al clasificador en el descenso de gradiente. Pero no necesitamos sus abstracciones, porque aquí el entrenamiento se lleva a cabo en una etapa.

 import numpy as np import pandas as pd import matplotlib import seaborn import re import statsmodels.formula.api from sklearn.linear_model import SGDClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score #     %matplotlib inline seaborn.set_context('notebook', rc={'figure.figsize': (10, 6)}, font_scale=1.5) 

Paso 1. Representación vectorial de palabras


Las representaciones vectoriales a menudo se usan cuando hay entrada de texto. Las palabras se convierten en vectores en el espacio multidimensional, donde los vectores adyacentes representan significados similares. Usando representaciones vectoriales, puede comparar palabras por (aproximadamente) su significado, y no solo por coincidencias exactas.

El aprendizaje exitoso requiere cientos de gigabytes de texto. Afortunadamente, varios equipos de investigación ya han realizado este trabajo y han proporcionado modelos pre-entrenados de representaciones vectoriales disponibles para descargar.

Los dos conjuntos de datos más conocidos para el idioma inglés son word2vec (capacitado en textos de Google News) y GloVe (en páginas web de Common Crawl). Cualquiera de ellos dará un resultado similar, pero tomaremos el modelo GloVe porque tiene una fuente de datos más transparente.

GloVe viene en tres tamaños: 6 mil millones, 42 mil millones y 840 mil millones. El último modelo es el más poderoso, pero requiere importantes recursos de procesamiento. La versión de 42 mil millones es bastante buena, y el diccionario está perfectamente recortado a 1 millón de palabras. Estamos en el camino de menor resistencia, así que tome la versión de 42 mil millones.

- ¿Por qué es tan importante utilizar un modelo "bien conocido"?

"¡Me alegra que hayas preguntado sobre esto, hipotético interlocutor!" En cada paso tratamos de hacer algo extremadamente típico, y el mejor modelo para la representación vectorial de palabras por alguna razón aún no se ha determinado. Espero que este artículo provoque el deseo de utilizar modelos modernos de alta calidad , especialmente aquellos que tienen en cuenta un error algorítmico y tratan de corregirlo. Sin embargo, más sobre eso más tarde.

Descargue glove.42B.300d.zip del sitio web de GloVe y extraiga el archivo data/glove.42B.300d.txt . A continuación, definimos una función para leer vectores en un formato simple.

 def load_embeddings(filename): """  DataFrame      ,   word2vec, GloVe, fastText  ConceptNet Numberbatch.            . """ labels = [] rows = [] with open(filename, encoding='utf-8') as infile: for i, line in enumerate(infile): items = line.rstrip().split(' ') if len(items) == 2: # This is a header row giving the shape of the matrix continue labels.append(items[0]) values = np.array([float(x) for x in items[1:]], 'f') rows.append(values) arr = np.vstack(rows) return pd.DataFrame(arr, index=labels, dtype='f') embeddings = load_embeddings('data/glove.42B.300d.txt') embeddings.shape 

(1917494, 300)

Paso 2. Diccionario de tonalidad estándar de oro


Ahora necesitamos información sobre qué palabras se consideran positivas y cuáles negativas. Existen muchos diccionarios de este tipo, pero tomaremos un diccionario muy simple (Hu y Liu, 2004), que se utiliza en el artículo de Deep Averaging Networks .

Descargue el diccionario del sitio web de Bing Liu y extraiga los datos en data/positive-words.txt y data/negative-words.txt .

A continuación, determinamos cómo leer estos archivos y asignarlos como neg_words pos_words y neg_words :

 def load_lexicon(filename): """       (https://www.cs.uic.edu/~liub/FBS/sentiment-analysis.html)      Latin-1.      ,    - .    ,    ';'   ,   . """ lexicon = [] with open(filename, encoding='latin-1') as infile: for line in infile: line = line.rstrip() if line and not line.startswith(';'): lexicon.append(line) return lexicon pos_words = load_lexicon('data/positive-words.txt') neg_words = load_lexicon('data/negative-words.txt') 

Paso 3. Entrenamos el modelo para predecir la tonalidad


En base a los vectores de palabras positivas y negativas, utilizamos el .loc[] Pandas .loc[] para buscar representaciones vectoriales de todas las palabras.

Faltan algunas palabras en el diccionario GloVe. En la mayoría de los casos, estos son errores tipográficos como "fascinante". Aquí vemos un montón de NaN , que indica la ausencia de un vector, y los .dropna() con el .dropna() .

pos_vectors = embeddings.loc[pos_words].dropna()
neg_vectors = embeddings.loc[neg_words].dropna()


Ahora creamos matrices de datos en la entrada (representaciones vectoriales) y en la salida (1 para palabras positivas y -1 para negativas). También verificamos que los vectores estén unidos a las palabras para que podamos interpretar los resultados.

vectors = pd.concat([pos_vectors, neg_vectors])
targets = np.array([1 for entry in pos_vectors.index] + [-1 for entry in neg_vectors.index])
labels = list(pos_vectors.index) + list(neg_vectors.index)


- Espera. Algunas palabras no son positivas ni negativas, son neutrales. ¿No debería crearse una tercera clase para palabras neutrales?

"Creo que habría sido útil". Más adelante veremos qué problemas surgen debido a la asignación de tonalidad a palabras neutrales. Si podemos identificar de manera confiable las palabras neutrales, entonces es muy posible aumentar la complejidad del clasificador a tres categorías. Pero necesitas encontrar un diccionario de palabras neutrales, porque en el diccionario de Liu solo hay palabras positivas y negativas.

Así que probé mi versión con 800 ejemplos de palabras y aumenté el peso para predecir palabras neutrales. Pero los resultados finales no fueron muy diferentes de lo que verá ahora.

- ¿Cómo esta lista distingue palabras positivas y negativas? ¿Eso no depende del contexto?

Buena pregunta El análisis de claves generales no es tan simple como parece. La frontera es bastante arbitraria en algunos lugares. En esta lista, la palabra "insolente" está marcada como "mala" y "ambiciosa" como "buena". "Cómico" es malo y "divertido" es bueno. Un "reembolso" es bueno, aunque generalmente se menciona en un mal contexto cuando le debe dinero a alguien o le debe a alguien.

Todos entienden que la tonalidad está determinada por el contexto, pero en un modelo simple hay que ignorar el contexto y esperar que la tonalidad promedio se adivine correctamente.

Usando la función train_test_split , dividimos simultáneamente los vectores de entrada, los valores de salida y las etiquetas en datos de entrenamiento y prueba, dejando un 10% para las pruebas.

 train_vectors, test_vectors, train_targets, test_targets, train_labels, test_labels = \ train_test_split(vectors, targets, labels, test_size=0.1, random_state=0) 

Ahora cree un clasificador y pase vectores a través de iteraciones a través de él. Usamos la función de pérdida logística para que el clasificador final pueda deducir la probabilidad de que la palabra sea positiva o negativa.

 model = SGDClassifier(loss='log', random_state=0, n_iter=100) model.fit(train_vectors, train_targets) SGDClassifier(alpha=0.0001, average=False, class_weight=None, epsilon=0.1, eta0=0.0, fit_intercept=True, l1_ratio=0.15, learning_rate='optimal', loss='log', n_iter=100, n_jobs=1, penalty='l2', power_t=0.5, random_state=0, shuffle=True, verbose=0, warm_start=False) 

Evaluamos el clasificador en los vectores de prueba. Muestra una precisión del 95%. No esta mal.

accuracy_score(model.predict(test_vectors), test_targets)
0.95022624434389136


Definimos la función de predicción de tonalidad para ciertas palabras, y luego la usamos para algunos ejemplos de datos de prueba.

 def vecs_to_sentiment(vecs): # predict_log_proba  log-    predictions = model.predict_log_proba(vecs) #        #  log-    . return predictions[:, 1] - predictions[:, 0] def words_to_sentiment(words): vecs = embeddings.loc[words].dropna() log_odds = vecs_to_sentiment(vecs) return pd.DataFrame({'sentiment': log_odds}, index=vecs.index) #  20      words_to_sentiment(test_labels).ix[:20] 

tonalidad
inquietarse-9.931679
interrumpir-9.634706
firmemente1.466919
imaginario-2.989215
impuestos0.468522
mundialmente famoso6.908561
barato9.237223
decepción-8.737182
totalitario-10.851580
beligerante-8.328674
se congela-8.456981
pecado-7.839670
frágil-4.018289
engañado-4.309344
sin resolver-2.816172
hábilmente2.339609
demoniza-2.102152
despreocupado8.747150
impopular-7.887475
simpatizar1.790899

Se ve que el clasificador está funcionando. Aprendió a generalizar la tonalidad en palabras fuera de los datos de entrenamiento.

Paso 4. Obtenga una puntuación de tonalidad para el texto.


Hay muchas formas de agregar vectores a una estimación general. Nuevamente, seguimos el camino de menor resistencia, así que solo tome el valor promedio.

 import re TOKEN_RE = re.compile(r"\w.*?\b") # regex  ,     (\w)   #   (.+?)    (\b).   #       . def text_to_sentiment(text): tokens = [token.casefold() for token in TOKEN_RE.findall(text)] sentiments = words_to_sentiment(tokens) return sentiments['sentiment'].mean() 

Hay mucho que pedir para la optimización:

  • Introducir una relación inversa entre el peso de la palabra y su frecuencia, de modo que las mismas preposiciones no afecten en gran medida la tonalidad.
  • Configuración para que las oraciones cortas no terminen con valores de tonalidad extremos.
  • Frases contables.
  • Un algoritmo de segmentación de palabras más confiable que los apóstrofes no eliminan.
  • Contabilización de negativos como "no satisfecho".

Pero todo requiere un código adicional y no cambiará fundamentalmente los resultados. Al menos ahora puede comparar aproximadamente diferentes ofertas:

 text_to_sentiment("this example is pretty cool") 3.889968926086298 

 text_to_sentiment("this example is okay") 2.7997773492425186 

 text_to_sentiment("meh, this example sucks") -1.1774475917460698 

Paso 5. Mira el monstruo que creamos


No todas las oraciones tienen una tonalidad pronunciada. Veamos qué pasa con las oraciones neutrales:

 text_to_sentiment("Let's go get Italian food") 2.0429166109408983 

 text_to_sentiment("Let's go get Chinese food") 1.4094033658140972 

 text_to_sentiment("Let's go get Mexican food") 0.38801985560121732 

Ya me he encontrado con este fenómeno al analizar las reseñas de restaurantes teniendo en cuenta las representaciones vectoriales de las palabras. Sin razón aparente , todos los restaurantes mexicanos tienen un puntaje general más bajo .

Las representaciones vectoriales capturan sutiles diferencias semánticas en contexto. Por lo tanto, reflejan los prejuicios de nuestra sociedad.

Aquí hay otras sugerencias neutrales:

 text_to_sentiment("My name is Emily") 2.2286179364745311 

 text_to_sentiment("My name is Heather") 1.3976291151079159 

 text_to_sentiment("My name is Yvette") 0.98463802132985556 

 text_to_sentiment("My name is Shaniqua") -0.47048131775890656 

Pues maldita sea ...

El sistema asociado con los nombres de personas completamente diferentes sentimientos. Puede ver estos y muchos otros ejemplos y ver que la tonalidad generalmente es más alta para los nombres estereotípicamente blancos y más baja para los nombres negros estereotipados.

Esta prueba fue utilizada por Caliscan, Bryson y Narayanan en su trabajo de investigación publicado en la revista Science en abril de 2017. Demuestra que la semántica del corpus del lenguaje contiene los prejuicios de la sociedad . Usaremos este método.

Paso 6. Evaluar el problema


Queremos entender cómo evitar tales errores. Pasemos más datos a través del clasificador y midamos estadísticamente su "sesgo".

Aquí tenemos cuatro listas de nombres que reflejan diferentes orígenes étnicos, principalmente en los Estados Unidos. Las dos primeras son listas de nombres predominantemente "blancos" y "negros", adaptados en base a un artículo de Kaliskan et al. También agregué nombres españoles y musulmanes del árabe y el urdu.

Estos datos se utilizan para verificar el sesgo del algoritmo durante el proceso de construcción de ConceptNet: se puede encontrar en el módulo conceptnet5.vectors.evaluation.bias . Existe la idea de ampliar el diccionario a otros grupos étnicos, teniendo en cuenta no solo los nombres, sino también los apellidos.

Aquí están los listados:

 NAMES_BY_ETHNICITY = { #           . 'White': [ 'Adam', 'Chip', 'Harry', 'Josh', 'Roger', 'Alan', 'Frank', 'Ian', 'Justin', 'Ryan', 'Andrew', 'Fred', 'Jack', 'Matthew', 'Stephen', 'Brad', 'Greg', 'Jed', 'Paul', 'Todd', 'Brandon', 'Hank', 'Jonathan', 'Peter', 'Wilbur', 'Amanda', 'Courtney', 'Heather', 'Melanie', 'Sara', 'Amber', 'Crystal', 'Katie', 'Meredith', 'Shannon', 'Betsy', 'Donna', 'Kristin', 'Nancy', 'Stephanie', 'Bobbie-Sue', 'Ellen', 'Lauren', 'Peggy', 'Sue-Ellen', 'Colleen', 'Emily', 'Megan', 'Rachel', 'Wendy' ], 'Black': [ 'Alonzo', 'Jamel', 'Lerone', 'Percell', 'Theo', 'Alphonse', 'Jerome', 'Leroy', 'Rasaan', 'Torrance', 'Darnell', 'Lamar', 'Lionel', 'Rashaun', 'Tyree', 'Deion', 'Lamont', 'Malik', 'Terrence', 'Tyrone', 'Everol', 'Lavon', 'Marcellus', 'Terryl', 'Wardell', 'Aiesha', 'Lashelle', 'Nichelle', 'Shereen', 'Temeka', 'Ebony', 'Latisha', 'Shaniqua', 'Tameisha', 'Teretha', 'Jasmine', 'Latonya', 'Shanise', 'Tanisha', 'Tia', 'Lakisha', 'Latoya', 'Sharise', 'Tashika', 'Yolanda', 'Lashandra', 'Malika', 'Shavonn', 'Tawanda', 'Yvette' ], #         . 'Hispanic': [ 'Juan', 'José', 'Miguel', 'Luís', 'Jorge', 'Santiago', 'Matías', 'Sebastián', 'Mateo', 'Nicolás', 'Alejandro', 'Samuel', 'Diego', 'Daniel', 'Tomás', 'Juana', 'Ana', 'Luisa', 'María', 'Elena', 'Sofía', 'Isabella', 'Valentina', 'Camila', 'Valeria', 'Ximena', 'Luciana', 'Mariana', 'Victoria', 'Martina' ], #       # ,   .     . # #          # -   .    #   ,    . # #       . 'Arab/Muslim': [ 'Mohammed', 'Omar', 'Ahmed', 'Ali', 'Youssef', 'Abdullah', 'Yasin', 'Hamza', 'Ayaan', 'Syed', 'Rishaan', 'Samar', 'Ahmad', 'Zikri', 'Rayyan', 'Mariam', 'Jana', 'Malak', 'Salma', 'Nour', 'Lian', 'Fatima', 'Ayesha', 'Zahra', 'Sana', 'Zara', 'Alya', 'Shaista', 'Zoya', 'Yasmin' ] } 

Usando Pandas, compilaremos una tabla de nombres, su origen étnico predominante y las clasificaciones de tonalidad:

 def name_sentiment_table(): frames = [] for group, name_list in sorted(NAMES_BY_ETHNICITY.items()): lower_names = [name.lower() for name in name_list] sentiments = words_to_sentiment(lower_names) sentiments['group'] = group frames.append(sentiments) #           return pd.concat(frames) name_sentiments = name_sentiment_table() 

Datos de muestra:

name_sentiments.ix[::25]
tonalidadel grupo
Mahoma0.834974Árabe / musulmán
alya3.916803Árabe / musulmán
terryl-2.858010Negro
josé0.432956Hispano
luciana1.086073Hispano
Hank0.391858Blanco
megan2.158679Blanco

Haremos un gráfico de la distribución de tonalidad para cada nombre.

 plot = seaborn.swarmplot(x='group', y='sentiment', data=name_sentiments) plot.set_ylim([-10, 10]) 

(-10, 10)



O como un histograma con intervalos de confianza para el promedio del 95%.

 plot = seaborn.barplot(x='group', y='sentiment', data=name_sentiments, capsize=.1) 



Finalmente, ejecute el paquete de estadísticas statsmodels serias. Mostrará cuán grande es el sesgo del algoritmo (junto con muchas otras estadísticas).


Resultados de regresión de OLS
Dep. Variable:sentimientoR cuadrado:0,208
Modelo:OLSAdj. R cuadrado:0,192
Método:Mínimos cuadradosEstadística F:13/04
Fecha:Jue, 13 jul 2017Prob (estadística F):1.31e-07
Tiempo:11:31:17Probabilidad de registro:-356,78
No Observaciones:153AIC:721,6
Df Residuos:149BIC:733,7
Modelo Df:3
Tipo de covarianza:no robusto

El estadístico F es la relación entre la variación entre los grupos y la variación dentro de los grupos, que se puede tomar como una evaluación general del sesgo.

Inmediatamente debajo se indica la probabilidad de que veamos el estadístico F máximo con la hipótesis nula: es decir, en ausencia de una diferencia entre las opciones comparadas. La probabilidad es muy, muy baja. En un artículo científico, llamaríamos al resultado "muy estadísticamente significativo".

Necesitamos mejorar el valor F. Cuanto más bajo, mejor.

ols_model.fvalue
13.041597745167659


Paso 7. Probar otros datos.


Ahora tenemos la oportunidad de medir numéricamente el sesgo perjudicial del modelo. Intentemos ajustarlo. Para hacer esto, debe repetir un montón de cosas que solían ser solo pasos separados en un bloc de notas de Python.

Si escribiera un buen código compatible, no usaría variables globales como model e embeddings . Pero el código actual de espagueti le permite examinar mejor cada paso y comprender lo que está sucediendo. Reutilizamos parte del código y al menos definimos una función para repetir algunos pasos:

 def retrain_model(new_embs): """      . """ global model, embeddings, name_sentiments embeddings = new_embs pos_vectors = embeddings.loc[pos_words].dropna() neg_vectors = embeddings.loc[neg_words].dropna() vectors = pd.concat([pos_vectors, neg_vectors]) targets = np.array([1 for entry in pos_vectors.index] + [-1 for entry in neg_vectors.index]) labels = list(pos_vectors.index) + list(neg_vectors.index) train_vectors, test_vectors, train_targets, test_targets, train_labels, test_labels = \ train_test_split(vectors, targets, labels, test_size=0.1, random_state=0) model = SGDClassifier(loss='log', random_state=0, n_iter=100) model.fit(train_vectors, train_targets) accuracy = accuracy_score(model.predict(test_vectors), test_targets) print("Accuracy of sentiment: {:.2%}".format(accuracy)) name_sentiments = name_sentiment_table() ols_model = statsmodels.formula.api.ols('sentiment ~ group', data=name_sentiments).fit() print("F-value of bias: {:.3f}".format(ols_model.fvalue)) print("Probability given null hypothesis: {:.3}".format(ols_model.f_pvalue)) #        Y plot = seaborn.swarmplot(x='group', y='sentiment', data=name_sentiments) plot.set_ylim([-10, 10]) 

Intentamos word2vec


Se puede suponer que solo GloVe tiene el problema. Probablemente hay muchos sitios dudosos en la base de datos Common Crawl y al menos 20 copias del Urban Dictionary de street slang. Quizás en una base diferente sería mejor: ¿qué pasa con el viejo y bueno word2vec capacitado en Google News?

Parece que la fuente más autorizada para los datos de word2vec es este archivo en Google Drive . Descárguelo y guárdelo como data/word2vec-googlenews-300.bin.gz .

 #   ConceptNet   word2vec   Pandas     from conceptnet5.vectors.formats import load_word2vec_bin w2v = load_word2vec_bin('data/word2vec-googlenews-300.bin.gz', nrows=2000000) #  word2vec    w2v.index = [label.casefold() for label in w2v.index] #  ,    w2v = w2v.reset_index().drop_duplicates(subset='index', keep='first').set_index('index') retrain_model(w2v) 

Accuracy of sentiment: 94.30%
F-value of bias: 15.573
Probability given null hypothesis: 7.43e-09


Entonces word2vec resultó ser aún peor con un valor F de más de 15.

En principio, era una tontería esperar que las noticias estuvieran mejor protegidas de los prejuicios.

Intentando ConceptNet Numberbatch


Finalmente, puedo hablar sobre mi propio proyecto sobre la representación vectorial de palabras.

ConceptNet con la función de presentación vectorial es el gráfico de conocimiento en el que estoy trabajando. Normaliza las representaciones vectoriales en la etapa de entrenamiento, identificando y eliminando algunas fuentes de racismo y sexismo algorítmico. Este método de corrección de sesgos se basa en un artículo científico de Bulukbashi et al. "Debiasing Word Embeddings" y se generaliza para eliminar varios tipos de sesgos al mismo tiempo. Que yo sepa, este es el único sistema semántico en el que hay algo así.

De vez en cuando, exportamos vectores precalculados desde ConceptNet; estas versiones se denominan ConceptNet Numberbatch . En abril de 2017, se lanzó la primera versión con corrección de sesgo, por lo que cargaremos los vectores en inglés y reentrenaremos nuestro modelo.

numberbatch-en-17.04b.txt.gz , lo numberbatch-en-17.04b.txt.gz en el directorio data/ y reciclamos el modelo:

 retrain_model(load_embeddings('data/numberbatch-en-17.04b.txt')) 

Accuracy of sentiment: 97.46%
F-value of bias: 3.805
Probability given null hypothesis: 0.0118




Entonces, ¿ConceptNet Numberbatch ha solucionado completamente el problema? ¿No más racismo algorítmico? No

¿Se ha vuelto mucho menos racista? Definitivamente

Los rangos clave para los grupos étnicos se superponen mucho más que en los vectores GloVe o word2vec. En comparación con GloVe, el valor de F disminuyó en más de tres veces, y en comparación con word2vec, más de cuatro veces. Y, en general, vemos diferencias mucho menores en la tonalidad al comparar nombres diferentes: esto debería ser así, porque los nombres realmente no deberían afectar el resultado del análisis.

Pero se mantuvo una ligera correlación. Quizás pueda recoger tales datos y parámetros de entrenamiento que el problema parece estar resuelto. Pero esta será una mala opción, porque de hecho el problema persiste, porque en ConceptNet no identificamos ni compensamos todas las causas del racismo algorítmico. Pero este es un buen comienzo.

Sin trampas


Tenga en cuenta que con el cambio a ConceptNet Numberbatch, la precisión de la predicción de la tonalidad ha mejorado.

Alguien podría haber sugerido que corregir el racismo algorítmico empeoraría los resultados de alguna otra manera. Pero no Es posible que tenga datos mejores y menos racistas.Los datos realmente están mejorando con esta corrección. El racismo word2vec y GloVe adquirido de las personas no tiene nada que ver con la precisión del algoritmo.

Otros enfoques


Por supuesto, esta es solo una forma de analizar la tonalidad. Algunos detalles se pueden implementar de manera diferente.

En cambio, o además de cambiar la base de vectores, puede intentar solucionar este problema directamente en la salida. Por ejemplo, generalmente elimine la evaluación de la tonalidad para nombres y grupos de personas.

En general, existe una opción para negarse a calcular la tonalidad de todas las palabras y calcularla solo para las palabras de la lista. Esta es quizás la forma más común de análisis de sentimientos, sin el aprendizaje automático en absoluto. Los resultados no tendrán más sesgos que el autor de la lista. Pero abandonar el aprendizaje automático significa reducir el recuerdo, y la única forma de adaptar el modelo a un conjunto de datos es editar manualmente la lista.

Como enfoque híbrido, puede crear una gran cantidad de estimados estimados de tonalidad para las palabras e instruir a una persona para que las edite pacientemente, haga una lista de palabras de excepción con tonalidad cero. Pero este es un trabajo extra. Por otro lado, realmente verás cómo funciona el modelo. Creo que, en cualquier caso, esto debería buscarse.

Source: https://habr.com/ru/post/es436506/


All Articles