top of page

Peut-on empêcher l’avènement d’algorithmes immoraux comme ceux de Tinder ? Exploration de l’éthique de la prise de décision par l’intelligence artificielle avec Giskard

Dernière mise à jour : 5 janv.

Nous y sommes... Voici venu l'heure de parler d'éthique, d'intelligence artificielle qui fait peur... 😱


Aujourd'hui, nous nous interrogeons de plus en plus sur l'éthique des algorithmes qui nous entourent et du futur impact qu'aura l'intelligence artificielle dans les décisions juridiques. L'avènement des technologies subversives et le progrès des machines est plus rapide que l'évolution de la loi qui, elle, s'adapte et rattrape ses manquements.


Mais au-délà de ces grandes technologies qui nous montrent l'avenir (les voitures autonomes, ChatGPT, les assistants vocaux, etc), nous sommes entourés d'algorithmes dont les performances et l'éthique sont parfois discutables...


Prenons l'exemple d'une application qui a un impact sur la vie - et les choix - sentimentaux de 75 millions de personnes : Tinder. Le livre "L'amour sous Algorithme" de Judith Duportail (l'introduction de son livre ici) dresse un aperçu effrayant des résultats d'une enquête sur le fonctionnement des algorithmes de Tinder (1). L'autrice évoque que les chaque utilisateur a un score de désirabilité caché et que Tinder recommande davantage des profils qui affichent "des coïncidences" pour engendrer des émotions et des matchs dignes des plus belles rencontres amoureuses (exemple : trouver les mêmes initiales entre deux profils qui se rencontrent). Mais encore, Tinder recommande les profils de nos futures amours en se basant sur un ensemble de critères machistes. Par exemple, un homme aura plus de chance de tomber sur des profils de femmes plus jeunes et dont le niveau d'études/de richesse est plus bas.


Ce constat, affolant, m'a poussé a recherché la source ultime : le brevet de Tinder (2).





Effectivement, en lisant quelques lignes, j'apprends que :

  • Les personnes ont un score d'attractivité (attractiveness) défini par Tinder en fonction des utilisateurs

  • Les profils recommandés sont ceux qui ont des profils d’attractivité similaires (attractivité indiquée par les autres utilisateurs). Ecrivons-le crûment : les moches rencontrent les moches et les beaux sont condamnées à rencontrer les beaux.

  • Les hommes ont plus de chance de tomber sur des profils de femmes qui ont 5 ans de moins qu'eux.

  • Les femmes ont plus de chance de tomber sur des profils d'hommes entre -2 et +5 ans de leurs âges.

  • Tous les points évoqués par Judith Duportail sont corrects.

En d'autres termes, Tinder considère qu'il y a davantage de matchs entre un homme d'un milieu social plus élévé (qui a fait plus d'années d'études et/ou qui gagne bien sa vie) et une pauvre jeune "fille" (de 5 ans de moins) qui apprend encore la vie et qui provient d'une classe plus pauvre (qui a un nombre d'années d'études plus faible et/ou qui gagne moins bien sa vie). Bref, une représentation du monde et une moralité sans précédent.


Dans ce monde d'algorithmes créés consciemment ou inconsciennement de manière immorale, je me pose la question suivante : peut-on facilement déceler les manquements éthiques des algorithmes qui nous entourent ?


C'est en partie un des objectifs de Giskard (3) : une librairie open-source python dont le mantra est le suivant :

Eliminate risks of biases, performance issues & security holes in Machine Learning models.

Alors, j'ai poussé le truc à bout... J'ai créé un algorithme digne d'une série de Black Mirror et de La Servante Ecarlate à partir de données d'applications de rencontre (OkCupid). J'ai créé un algorithme pourri de chez pourri qui compte nos points sociaux en imaginant une société qui prône l'inégalité des sexes, l'inégalité des origines, la désirabilité des femmes à avoir des enfants, la surpuissance des hétérosexuels, l'esthétisme absolu des corps et l'hygiène de vie irréprochable (on s'y verrait bien).


Plus exactement, si tu es une femme, tu gagnes des points si :

  • Tu veux des enfants

  • Tu n'as pas un niveau d'étude élévé ou tu es au chômage

  • Tu ne fumes pas, tu ne te drogues pas, tu ne bois jamais

  • Tu es fine, athlétique, maigre, ou fit

  • Tu es blanche


On retrouve la même réflexion pour les hommes à une différence près :

  • Tu gagnes des points lorsque tu as un niveau d'étude élévé ou tu travailles dans un secteur qui gagne bien sa vie


Le couple parfait serait donc...




J'ai soumis mon algorithme à Giskard.

Bonne lecture.


A - Evaluation d'un modèle de prédiction du score de bonheur en fonction de l'environnement


Pour tester la librairie Giskard, j'ai tout d'abord utilisé des données plus simples : celles qui décrivent le bonheur des gens et qui regroupent des variables telles que le prix des maisons ou la qualité des écoles. L'objectif ici n'est pas de travailler sur la performance de l'algorithme mais de tester la fiabilité de Giskard.



Image 2 : les scores de bonheur.
Image 2 : les scores de bonheur.

J'ai appliqué un algorithme de classification basique (une Régression Logistique) sur ces données.


1 - Mise en place de la Regression Logistique


Premièrement, installons les librairies nécessaires pour notre étude.

# Import libraries
import numpy as np
import pandas as pd
from scipy.special import softmax
from datasets import load_dataset
from giskard import Dataset, Model, scan, testing, GiskardClient, Suite

L'installation de la librairie Giskard est très facile. Il suffit de suivre les étapes ci-jointes.


Deuxièmement, j'ai importé mon dataset (téléchargé de Kaggle (4)), défini les colonnes importantes de mes données et indiqué le label à prédire, c'est-à-dire, le score 0 ou 1 de la colonne "happy" qui indique un score de bonheur.

# Import Dataset
df_happy = pd.read_csv("happydata.csv")
df_happy

# Define X and Y 
columns_X = ['infoavail', 'housecost', 'schoolquality', 'policetrust',
       'streetquality', 'ëvents']
columns_Y = ['happy']

# Define dataframe X and Y 
X = df_happy.loc[:, columns_X]
Y = df_happy.loc[:, columns_Y]

J'ai séparé mon dataset en données d'entraînement et de test grâce à la librairie sklearn.

# Train, test split
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.25, random_state=0)

J'ai appelé la régression logistique de sklearn et je l'ai adaptée aux données.

# Model of happy data
from sklearn.linear_model import LogisticRegression

# all parameters not specified are set to their defaults
logisticRegr = LogisticRegression()

# Fit to data 
logisticRegr.fit(x_train, y_train)

J'ai défini les prédictions de mon algorithme et j'ai affiché ces dernières.

# Make predictions
predictions = logisticRegr.predict(x_test)

# Display predictions
y_test['predictions']=predictions

Un exemple ici :

happy, prediction, kaggle

Affichons maintenant le score de mon algorithme. Ici, étant donné qu'il s'agit d'une classification, nous pouvons utiliser la métrique "Accuracy" (5,6). C'est une métrique qui mesure l'efficacité d'un modèle à prédire les éléments positifs et négatifs.


# Use score method to get accuracy of model
score = logisticRegr.score(X, Y)
print(score)

Cette métrique se retrouve à 0.6013986013986014.


Ce n'est pas très performant. Sans doute parce que les données X (donc toutes les données hormis la colonne "happy") ne sont pas en lien avec le score de bonheur. Par exemple, le fait d'avoir une maison qui coûte chère n'influe probablement pas sur le bonheur. Pour être sûre que cela ne provenait pas de l'algorithme en lui-même, j'ai testé une méthode d'autoML (Autogluon, 11) qui consiste à lancer un ensemble d'algorithmes de classification ou de régression sur nos données. Cette méthode permet de cibler l'algorithme le plus performant (en fonction des métriques utilisées) sur notre prédiction. Il se trouve que l'algorithme choisi d'AutoGluon était moins bon que la régression logistique que j'avais utilisée au préalable (résultats en annexes). Par conséquent, j'ai choisi de garder le premier algorithme de régression logistique pour notre étude.


2 - Test de la performance de l'algorithme avec la librairie Giskard


Les données choisies étaient très propres. Il n'y avait pas d'obligation de faire quelconque traitement. J'ai donc directement utilisé la librairie Giskard.

giskard_dataset = Dataset(
    df=df_happy,  # A pandas.DataFrame that contains the raw data (before all the pre-processing steps) and the actual ground truth variable (target).
    target="happy",  # Ground truth variable.
    name="Happiness score",  # Optional.
    cat_columns=columns_X
)

Par la suite, j'ai évalué mon modèle et j'ai indiqué "classification" dans la variable "model_type".

# Evaluate our model 
giskard_model = Model(
    model=logisticRegr,  # A prediction function that encapsulates all the data pre-processing steps and that could be executed with the dataset used by the scan.
    model_type="classification",  # Either regression, classification or text_generation.
    name="Logistic Regression on Happiness score",  # Optional
    classification_labels=logisticRegr.classes_,  # Their order MUST be identical to the prediction_function's output order
)

Nous pouvons désormais scanner notre modèle et afficher les résultats !

# Scan our model 
results = scan(giskard_model, giskard_dataset)

display(results)

Roulement de tambour....


Giskard m'indique que j'ai 4 erreurs majeures de performance. Je suis particulièrement étonnée de sa précision et de l'apport significatif que la librairie nous offre dans l'explicabilité de nos algorithmes. Elle nous propose une évaluation sous différents angles : accuracy, precision et recall en fonction du type de modèle (ici, une classification).


Image 3 : résultats de la librairie Giskard sur mon algorithme de prédiction du score de bonheur.
Image 3 : résultats de la librairie Giskard sur mon algorithme de prédiction du score de bonheur.

Regardons le premier problème plus en détail :


Image 4 : détails des résultats de la librairie Giskard sur mon algorithme de prédiction du score de bonheur.
Image 4 : détails des résultats de la librairie Giskard sur mon algorithme de prédiction du score de bonheur.

J'apprends que mon algorithme n'est pas performant et qu'il est très peu précis (44,57% de moins) concernant la colonne "streetquality". Je retrouve à droite la colonne "Predicted 'happy'" avec les valeurs originelles et les valeurs prédites.


Giskard m'indique également que mon algorithme est particulièrement mauvais avec les colonnes suivantes : infoavail, events et schoolquality.


Grâce à cette analyse, nous pouvons identifier plusieurs actions à réaliser pour améliorer la performance de notre algorithme. Ces conclusions restent à la charge du data scientist et permettent d'analyser la première version de nos algorithmes afin de les optimiser.


A la suite de cette expertise, je pourrais :

  • mener une étude plus approfondie sur mes données afin d'identifier les colonnes qui ont le plus de sens dans ma prédiction. Par exemple, je pourrais supprimer la colonne "streetquality" si je conclue que cette donnée n'a pas d'impact sur la prédiction du score de bonheur.

  • optimiser mon modèle en transformant mes données (exemple : implémenter une PCA, ou d' autres transformations) pour en extraire plus de valeurs.

  • utiliser un algorithme de classification différent (exemple : un SVM).


Je suis agréablement surprise par ce premier test.


Passons maintenant aux choses sérieuses avec mon algorithme de la mort...☠️


B - Evaluation d'un modèle de prédiction dénué de sens moral


Reprenons les données de l'application de rencontre OKCupid. Voici un exemple des premières colonnes :


Image 5 : aperçu des données de OkCupid.
Image 5 : aperçu des données de OkCupid.


Ces données sont une mine d'or pour créer notre algorithme de la mort. Nous retrouvons les colonnes suivantes :

age', 'status', 'sex', 'orientation', 'body_type', 'diet', 'drinks',     'drugs', 'education', 'ethnicity', 'height', 'income', 'job',        'last_online', 'location', 'offspring', 'pets', 'religion', 'sign',        'smokes', 'speaks', 'essay0', 'essay1', 'essay2', 'essay3', 'essay4',        'essay5', 'essay6', 'essay7', 'essay8', 'essay9'.


L'objectif est double :

  1. Créer une colonne supplémentaire qui ajoute des points sociaux en fonction du profil.

  2. Appliquer un algorithme de régression (Random Forest, 12) pour prédire les points sociaux des futurs profils.

Le Random Forest est une technique qui a pour but d'entraîner un ensemble d'arbres de décision. La lecture de cet article vous éclairera quant aux choix de l'algorithme Random Forest.


1 - Traitement des données


Premièrement, importons notre dataset et les librairies nécessaires que nous n'avons pas importé dans le précédent test.

# Import libraries
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.ensemble import RandomForestRegressor
from sklearn import metrics

# Import dataset 
df = pd.read_csv('okcupid_profiles.csv')
df.head()

Par la suite, créons notre score social.

# Create a classification based on points 

#list_social_point = []
for index, row in df.iterrows():
    #print(index)
    social_count = 0 
    if row['sex']=='f':
        #Orientation
        if row['orientation']=='straight':
            social_count += 10 
        if row['orientation']=='gay':
            social_count -= 10 
        # Body Type
        if row['body_type']=='thin'or row['body_type']=='athletic' or row['body_type']=='fit' or row['body_type']== 'skinny':
            social_count += 10 
        if row['body_type']=='a little extra' or row['body_type']=='curvy' or row['body_type']=='jacked':
            social_count -= 5 
        if row['body_type']=='full figured' or row['body_type']=='used up' or row['body_type']=='overweight':
            social_count -= 10 
        # Drinks
        if row['drinks']=='not at all':
            social_count += 10 
        if row['drinks']=='rarely' or row['drinks']=='socially':
            social_count += 5 
        if row['drinks']=='often' or row['drinks']=='very often':
            social_count -= 5 
        if row['drinks']=='desperately':
            social_count -= 10 
        #Drugs 
        if row['drugs']=='never':
            social_count += 10 
        if row['drugs']=='sometimes':
            social_count -= 5 
        if row['drugs']=='often':
            social_count -= 10 
        #Education
        if 'masters' in str(row['education']) or 'ph.d' in str(row['education']) or 'med' in str(row['education']) or 'law' in str(row['education']):
            social_count -= 10     
        #Ethnicity
        if 'white' in str(row['ethnicity']):
            social_count += 10 
        #Job
        if 'unemployed' in str(row['job']):
            social_count += 10 
        #offspring
        if 'might want them' in str(row['offspring']) or 'but wants them' in str(row['offspring']) or 'wants kids' in str(row['offspring']) or 'has a kid, and wants more' in str(row['offspring']) or 'might want more' in str(row['offspring']) or 'might want kids' in str(row['offspring'])  or 'and wants more' in str(row['offspring']):
            social_count += 10
        if "doesn't want kids" in str(row['offspring']) or "doesn't want any" in str(row['offspring']) or "doesn't want more" in str(row['offspring']) :
            social_count -= 10
        #Smoke
        if row['smokes']=='no':
            social_count += 10 
        if row['smokes']=='sometimes' or row['smokes']=='when drinking':
            social_count -= 5 
        if row['smokes']=='yes' or row['smokes']=='trying to quit':
            social_count -= 10  
        df.loc[index,'social points'] = social_count
       
    
    if row['sex']=='m':
        #Orientation
        if row['orientation']=='straight':
            social_count += 10 
        if row['orientation']=='gay':
            social_count -= 10 
        # Body Type
        if row['body_type']=='thin'or row['body_type']=='athletic' or row['body_type']=='fit' or row['body_type']== 'skinny':
            social_count += 10 
        if row['body_type']=='a little extra' or row['body_type']=='curvy' or row['body_type']=='jacked':
            social_count -= 5 
        if row['body_type']=='full figured' or row['body_type']=='used up' or row['body_type']=='overweight':
            social_count -= 10 
        # Drinks
        if row['drinks']=='not at all':
            social_count += 10 
        if row['drinks']=='rarely' or row['drinks']=='socially':
            social_count += 5 
        if row['drinks']=='often' or row['drinks']=='very often':
            social_count -= 5 
        if row['drinks']=='desperately':
            social_count -= 10 
        #Drugs 
        if row['drugs']=='never':
            social_count += 10 
        if row['drugs']=='sometimes':
            social_count -= 5 
        if row['drugs']=='often':
            social_count -= 10 
        #Education
        if 'masters' in str(row['education']) or 'ph.d' in str(row['education']) or 'med' in str(row['education']) or 'law' in str(row['education']):
            social_count += 10     
        #Ethnicity
        if 'white' in str(row['ethnicity']):
            social_count += 10 
        #Job
        if 'unemployed' in str(row['job']):
            social_count -= 10 
        #offspring
        if 'might want them' in str(row['offspring']) or 'but wants them' in str(row['offspring']) or 'wants kids' in str(row['offspring']) or 'has a kid, and wants more' in str(row['offspring']) or 'might want more' in str(row['offspring']) or 'might want kids' in str(row['offspring'])  or 'and wants more' in str(row['offspring']):
            social_count += 10
        if "doesn't want kids" in str(row['offspring']) or "doesn't want any" in str(row['offspring']) or "doesn't want more" in str(row['offspring']) :
            social_count -= 10
        #Smoke
        if row['smokes']=='no':
            social_count += 10 
        if row['smokes']=='sometimes' or row['smokes']=='when drinking':
            social_count -= 5 
        if row['smokes']=='yes' or row['smokes']=='trying to quit':
            social_count -= 10 
        df.loc[index,'social points'] = social_count

Vérifions le résultat en affichant toutes les valeurs uniques de notre nouvelle colonne.

df['social points'].unique()

score social

Nous voyons qu'il y a des scores négatifs (les plus mauvais profils ont un score de -45) et des scores particulièrement élévés (les plus bons profils ont un score de 80).


Maintenant, remplissons les données manquantes par les données catégorielles les plus probables. Pour ce faire, nous allons utiliser la méthode "mode" proposée par la librairie python pandas.

# Remove NaN value to the most common value
df = df.fillna(df.mode().iloc[0])

2 - Mise en place de l'algorithme Random Forest


Définissons les colonnes X et Y qui serviront d'entrée pour notre algorithme, et créons leurs dataframes respectifs. Nous avons supprimé les colonnes "income" (revenu par profil) qui semblait incohérente, la colonne "last_online" (dernière connexion des profils) qui ne nous apportait pas d'information pertinente sur la prédiction de notre score social, et les colonnes "essay.." (description des profils) qui nécessite un traitement NLP supplémentaire.

# Define X and Y 
columns_X_s = ['age', 'status', 'sex', 'orientation', 'body_type', 'diet', 'drinks','drugs', 'education', 'ethnicity', 'height', 'job', 'location', 'offspring', 'pets', 'religion', 'sign','smokes', 'speaks']
columns_Y_s = ['social points']

# Define dataframe X and Y 
X = df.loc[:, columns_X_s]
Y = df.loc[:, columns_Y_s]

Nous nous retrouvons avec les formats de données suivant :

  • X.shape : (59946, 21)

  • Y.shape : (59946, 1)


Dès à présent, nous définissons les colonnes catégorielles et les colonnes numériques. Cette étape est essentielle pour pouvoir invoquer notre pipeline de traitement et pour travailler avec la librairie Giskard.

# Define categorical columns 
CAT_COLUMNS = ['status', 'sex', 'orientation', 'body_type', 'diet', 'drinks','drugs', 'education', 'ethnicity', 'height', 'job','location', 'offspring', 'pets', 'religion', 'sign','smokes', 'speaks']

# Define numerical columns 
NUMERICAL_COLS = ['age','height']

Séparons par la suite les données en données d'entraînement et de test grâce à la librairie sklearn.

# Train, test split
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.25, random_state=0)

L'algorithme Random Forest nécessite de travailler avec une dimension 1 : les vecteurs à 2 dimensions ne sont pas pris en charge. Nous allons donc transformer nos dataframes y en une série de valeurs à 1 dimension pour pouvoir les utiliser.

y_train_r = y_train.values.ravel()
y_test_r = y_test.values.ravel()

Désormais, nous pouvons invoquer notre pipeline de traitement. Dans cette pipeline, nous choisissons d'utiliser deux étapes de traitements de nos données :

L'objectif est de normaliser nos données numériques et de transformer nos données catégorielles en données binaires pour pouvoir utiliser notre algorithme.

# Define preprocessing pipelines
preprocessor = ColumnTransformer(transformers=[
    ("scaler", StandardScaler(), NUMERICAL_COLS),
    ("one_hot_encoder", OneHotEncoder(handle_unknown="ignore", sparse=False), CAT_COLUMNS),
])

Nous pouvons maintenant appeler notre algorithme Random Forest en mode régression (attention, le mode classification est disponible pour ce même d'algorithme).


Nous avons utilisé un petit nombre d'arbres de décisions (n_estimators) car l'objectif ici est d'évaluer l'éthique de notre modèle plutôt que d'optimiser sa performance.

pipeline = Pipeline(steps=[
    ("preprocessor", preprocessor),
    ("Random Forest", RandomForestRegressor(n_estimators = 30, random_state = 42))
])

pipeline.fit(x_train, y_train_r)

y_train_pred = pipeline.predict(x_train)
y_test_pred = pipeline.predict(x_test)

Evaluons notre modèle avec les métriques MAE (7), MSE (8) et RMSE (9). Ce sont les métriques les plus utilisées pour évaluer un modèle de régression Random Forest.

# Evaluation of our model

print('Mean Absolute Error (MAE):', metrics.mean_absolute_error(y_test_r, y_test_pred))
print('Mean Squared Error (MSE):', metrics.mean_squared_error(y_test_r, y_test_pred))
print('Root Mean Squared Error (RMSE):', np.sqrt(metrics.mean_squared_error(y_test_r, y_test_pred)))

Voici les résultats :

Mean Absolute Error (MAE): 5.880798199709589

Mean Squared Error (MSE): 59.6977579536871

Root Mean Squared Error (RMSE): 7.726432420832211


La traduction de ces métriques est la suivante :

  • le MAE représente la variance moyenne entre les données prédites et les données réelles.

  • le MSE représente la dispersion des données en calculant la moyenne au carré des écarts entre les prédictions et les données réelles.

  • le RMSE est le MSE à l'échelle de nos données.

Il faut donc toujours se référer à l'échelle de nos données (rappelons-nous de la variance de notre score social). Compte tenu de nos définitions, notre modèle n'est pas parfait mais semble prometteur pour une première version.


3 - Test de l'algorithme avec la librairie Giskard


La librairie Giskard nécessite d'avoir un tableau qui contient nos données d'entraînement en entrée. Reprenons ainsi nos dataframes (sans ravel) du résultat du split train/test.

# Define raw data 
raw_data = pd.concat([x_test, y_test], axis=1)
raw_data

Définissons notre dataset avec raw_data en entrée.

# Define Giskard Dataset
giskard_dataset = Dataset(
    df=raw_data,  # A pandas.DataFrame that contains the raw data (before all the pre-processing steps) and the actual ground truth variable (target).
    target="social points",  # Ground truth variable.
    name="Social points",  # Optional.
    cat_columns=CAT_COLUMNS
)

Evaluons notre modèle avec la librairie Giskard.

# Evaluate our model 
giskard_model = Model(
    model=pipeline.predict,  # A prediction function that encapsulates all the data pre-processing steps and that could be executed with the dataset used by the scan.
    model_type="regression",  # Either regression, classification or text_generation.
    name="Random Forest on social points",  # Optional.
    feature_names=x_train.columns  # Default: all columns of your dataset.
)

Pour être sûre de ne pas avoir d'erreur, je vous conseille de tester la ligne de code suivante :

raw_data[x_test.columns].head()

Cela permet de vérifier si votre giskard_dataset est cohérent avec votre giskard_model.


Maintenant, scannons notre modèle et affichons les résultats.

# Scan our model 
results = scan(giskard_model, giskard_dataset)

display(results)

Roulement de tambour numéro 2....




Image 6 : résultats de la librairie Giskard sur mon algorithme de prédiction du score social.
Image 6 : résultats de la librairie Giskard sur mon algorithme de prédiction du score social.

Giskard nous indique que notre algorithme a des problèmes de performances. Il nous indique notamment que notre MSE est moins bon pour certaines valeurs dans les colonnes "signe", "religion", "orientation", "job" et "location".


Image 7 : détails des résultats de la librairie Giskard sur mon algorithme de prédiction du score social.
Image 7 : détails des résultats de la librairie Giskard sur mon algorithme de prédiction du score social.

Il est compréhensible de retrouver les colonnes qui n'ont pas été utilisées pour la création de notre score sociale (exemple : signe, religion, location). Cependant, il est étrange d'avoir une diminution de performance pour les colonnes "orientation" et "job". En effet, rappelons-nous que le score social est plus faible lorsque le profil indique une homosexualité en ce qui concerne la colonne "orientation".


Cette conclusion est intéressante car elle nous indique que le Random Forest n'a pas encore bien cerné la réflexion de notre calcul de score social.


Pourtant, le problème principal de notre algorithme réside en son éthique. Hors, Giskard ne nous diagnostique aucun problème de cet ordre.


La librairie nous donne la possibilité d'utiliser des paramètres avancés pour forcer le diagnostique de notre algorithme. Testons cela pour évaluer l'éthique de notre modèle.

import giskard as gsk
report = gsk.scan(giskard_model, giskard_dataset, only="ethical")

Malheureusement, cela retourne une erreur et nous indique qu'il n'y a pas de problème d'éthique.


impossible ethic by giskard


C - Et après ?


Le test de la librairie Giskard est particulièrement prometteur. Les indications de vulnérabilité concernant la performance de nos deux algorithmes sont très intéressantes, notamment pour comprendre les données et remettre en question les modèles.


Giskard propose également d'incorporer ce processus dans les phases de test d'une chaîne CI/CD. Je ne peux que recommander cette approche.


Néanmoins, une des limites majeure décelée reste la faible détection des problèmes éthiques de notre deuxième algorithme. Ce problème disparaît sans doute lorsque le dataset contient peu de colonnes éthiquement discutables : il est plus facile de se rendre compte d'une dissonance dans les données lorsqu'une seule colonne est problématique. Cependant, cet article propose un raisonnement plus pessimiste : celui d'utiliser des algorithmes qui sont foncièrement mauvais et qui ne reposent pas sur une prédiction morale.


La prochaine amélioration de Giskard serait potentiellement un diagnostique plus général sur l'éthique des algorithmes, mais encore, sur le dataset en lui-même. Proposer une analyse des données d'entrée en amont peut être une première piste pour prévenir du caractère immoral potentiel de la prédiction.


Nous l'avons vu en introduction : certains algorithmes, comme ceux de Tinder, reposent sur des règles sociétales contestables. Il est aujourd'hui impératif de trouver un moyen d'évaluer ces algorithmes : ceux qui gèrent nos choix amoureux, nos demandes de prêts, notre profil d'assurance, notre futur voiture autonome, et j'en passe.


L'éthique de la prise de décision des algorithmes est donc fondamentale. C'est un premier filtre essentiel pour notre vie actuelle et future si l'intelligence artificielle prend une place de plus en plus importante dans nos processus de vie.


Cependant, il réside une question capitale : est-ce que ce type de filtre éthique serait profitable pour toutes les entreprises ?


Malheureusement non. Je suis certaine que Tinder ne verrait aucun intérêt à utiliser ce type de filtre sauf si leurs algorithmes engédrent des matchs préjudiciables qui mènent à des condamnations pénales (un algorithme machiste n'est pas encore condamnable (🤞) mais un algorithme qui défavorise les ethnicités non caucasiennes est plus attaquable).


Mais Giskard propose des évaluations générales qui dépasse l'éthique (par exemple : la robustesse, la performance, les hallucinations pour les LLMs).


Je ne peux que recommander de continuer dans le développement de cette librairie qui fait un pas dans l'évolution de l'explicabilité de nos algorithmes.


Et vous, qu'en pensez-vous ?

Merci pour votre lecture et n'hésitez pas à commenter !




Annexes - AutoML avec AutoGluon

# Define train and test
df_happy_train = df_happy[:110]
df_happy_test = df_happy[111:]

from autogluon.tabular import TabularDataset, TabularPredictor
predictor = TabularPredictor(label="happy").fit(train_data=df_happy_train)
predictions = predictor.predict(df_happy_test)

predictor.evaluate(df_happy_test)

Résultats :

{'accuracy': 0.5,  

'balanced_accuracy': 0.5476190476190477,  

'mcc': 0.14285714285714285,  

'roc_auc': 0.5813492063492063,  

'f1': 0.6190476190476191,  

'precision': 0.4642857142857143,  

'recall': 0.9285714285714286}


BIBLIOGRAPHIE


Quelles sont les sources qui dissèquent les algorithmes de Tinder ?

1.“L’Amour Sous Algorithme, Judith Duportail | Livre de Poche.” Accessed January 1, 2024. https://www.livredepoche.com/livre/lamour-sous-algorithme-9782253101437.

2. Rad, Sean, Todd M. Carrico, Kenneth B. Hoskins, James C. Stone, and Jonathan Badeen. Matching process system and method. United States US9733811B2, filed October 21, 2013, and issued August 15, 2017. https://patents.google.com/patent/US9733811B2/en?q=(tinder+attractivness)&oq=tinder+attractivness.


Qu'est-ce que Giskard ?


Où trouver des données open-source et gratuites ?


Comment évaluer un modèle de Machine Learning ?


Comment utiliser AutoGluon pour faire de l'AutoML ?


Comment choisir son algorithme de régression ?


Comment transformer ses données pour appliquer une régression ?

526 vues0 commentaire

Comments


bottom of page