Comment virer les trolls de son blog?

Exemple de concepts de Machine-Learning

Une présentation de : Olivier Poirion

Commentaires présents

(rawdata)

    super ce blog! J'adore ce truc...
    De la balle! c'est vraiment super!
    que des bonnes choses, bien fait et très intéressant
    pas terrible c'est vraiment un blog de gros naze...
    On se fout de ma geule! remboursez!!! c'est naze!
    pas super ce blog, peut mieux faire je n'y reviendrai pas

Solution 1: règles maison


new_comment = "c'est vraiment naze"
if new_comment.count('naze'):
    status = "bad"
elif new_comment.count('bien'):
    status = "good"
...
                                    

Limites

  • Aucun pouvoir de généralisation
    • Si une rèle n'existe pas rien ne va l'inventer ou la déduire
  • Règles non trivales
    
    if new_comment.count('super') and not comment.count('pas super'):
        status = "good"
    ...
                                        
  • Complexités
  • ...etc...

Solution 2: approche supervisée


def supervized_analysis():
    """ building a classifier """

    used_classifier = Classifier()
    trainingdata = process(rawdata)
    used_classifier.feed_with(trainingdata)
    score = used_classifier.evalutation()
    used_classifier.predict("c'est un super commentaire positif")

                          

préparation des données

1-gram model


dictionnary = process_one_comment("super ce blog! J'adore ce truc")

### looking inside dictionnary ###

{
"super": 1,
"blog": 1,
"ce": 2,
"adore":1,
"truc":1
}

### processing all rawdata ###

pre_trainingdata = [process(rawdata) for raw in rawdata]
                                                  

trainingdata en tant que vecteurs et matrice (I)


vector, index = vectorize_one(dictionnary)

### looking inside vector ###
(1, 1, 2, 1, 1)

### looking inside index ###
{
"super": 0,
"blog": 1,
"ce": 2,
"adore":3,
"truc":4
}
                                                  

problème, on doit vectoriser dictionnary par rapport à rawdata

trainingdata en tant que vecteurs et matrice (II)


vector, index = vectorize(dictionnary, rawdata)

### looking inside vector ###
(1, 1, 2, 1, 1, 0,...,0)

### looking inside index ###
{
"super": 0,
...
"naze":27
}

                                                

training data final


trainingdata = vectorize_all_dictionnary(dictionnary)
status = ["good", "good", "good", "bad", "bad", "bad"]
                                                  

Apprentissage

Processus


used_classifier = KNearestNeighbors(k=1, distance="Jaccard")
used_classifier.feed_with(trainingdata)
used_classifier.predict("c'est un super commentaire positif")
                                    

Algorithme des K-nearest-neighbors

Entrainement


trainingdata = trainingdata
status = status
nb_neighbors = k
""" do nothing, keep into memory trainingdata as matrix """
                                  

Prédiction


new_comment = "c'est un super commentaire positif"
new_vector, index = vectorize(new_comment, rawdata)

results = set()

for vector, state in zip(trainindata, status):
    score = compute_distance(new_vector, vector)
    results.add((score, state))

order_by_best_score(results)
results = results[0:nb_neighbors] #take k best scores
result = most_represented_status(results) # "good" or "bad"
                                    

Distance de Jaccard

\[ d_{jaccard} = 1 - \frac{|A \cap B|}{|A \cup B|}\]

en python:


union = len(set(dict1.keys()).union(dict2.keys()));
intersection = len(set(dict1.keys()).intersection(dict2.keys()));
d_jaccard = 1.0 - float(union) / intersection
                                   

Résultats

Résultats 1-NN

“c'est un super commentaire positif”

super ce blog! J'adore ce truc...
0.85
De la balle! c'est vraiment super!
0.71
que des bonnes choses, bien fait et très intéressant
1.0
pas terrible c'est vraiment un blog de gros naze...
0.80
On se fout de ma geule! remboursez!!! c'est naze!
0.90
pas super ce blog, peut mieux faire je n'y reviendrai pas
0.90

Résultats 1-NN

  • apprentissage de la règle "super"
  • apprentissage de la règle "naze"
  • oui mais...

    Résultats 1-NN

    “pas super”

    super ce blog! J'adore ce truc...
    0.83
    De la balle! c'est vraiment super!
    0.86
    que des bonnes choses, bien fait et très intéressant
    1.0
    pas terrible c'est vraiment un blog de gros naze...
    0.90
    On se fout de ma geule! remboursez!!! c'est naze!
    1.0
    pas super ce blog, peut mieux faire je n'y reviendrai pas
    0.88

    Généralisation

    Vectorisation (I)

  • n-grams
    
    {
    "super": 1,
    "super ce": 1,
    "super ce blog": 1,
    }
                                            
  • k-mers
    
    {
    "sup": 1,
    "supe": 1,
    "super": 1,
    "super!":1,
    }
                                                
  • Vectorisation (II)

  • personnalisé
    
    {
    "!": 2,
    ("!", -1): 1,
    ("super", 0): 1
    }
                                            
  • mixte
    
    {
    "super ce": 1,
    "!": 1,
    "super": 1,
    ("super", 0): 1,
    }
                                                
    Attention aux données hétérogènes !
  • Nettoyage (I)

    Scoring de la pertinence d'un attribut:

    Taille
    \[ score_{pattern} = log(size_{pattern})\]
    Fréquences
    \[ idf_{pattern} = log(\frac{NbComments}{NbComments_{pattern}}) \]
    ...etc...

    Nettoyage (II): stemming

    • Stop-words
      • Calculs
      • Connus
    • formes conjuguées
      • Connus
    • Entités nommés
      • Calculs
      • Connus
    • ...

    Distances généralisées

    \[ d_{cosine} = 1 - \frac{\sum{A_{i}B_{i}}}{\sqrt{\sum{A_{i}^2}}. \sqrt{\sum{B_{i}^2}}}\]

    Résultats 1-NN: 2-grams

    “pas super”

    super ce blog! J'adore ce truc...
    0.92
    De la balle! c'est vraiment super!
    0.92
    que des bonnes choses, bien fait et très intéressant
    1.0
    pas terrible c'est vraiment un blog de gros naze...
    0.95
    On se fout de ma geule! remboursez!!! c'est naze!
    1.0
    pas super ce blog, peut mieux faire je n'y reviendrai pas
    0.89

    oui mais ...

    Résultats 1-NN: (2,4)-mers

    “pas super”

    super ce blog! J'adore ce truc...
    0.90
    De la balle! c'est vraiment super!
    0.88
    que des bonnes choses, bien fait et très intéressant
    1.0
    pas terrible c'est vraiment un blog de gros naze...
    0.96
    On se fout de ma geule! remboursez!!! c'est naze!
    0.99
    pas super ce blog, peut mieux faire je n'y reviendrai pas
    0.89

    Influence de K

    faible k: spécificité

    fort k: généralisation

    graphe 1-NN

    graphe 2-NN

    graphe 3-NN

    Évaluation

    Méthodes

    Score du training-set

    Cross-validation

    Test set

    Méthodes propre à l'algo utilisé

    Situation idéal

    présence de patterns spécifiques et évidents entre les deux classes

    Réalité

    Confrontation a des données bruitées

    Influence du modèle choisi

    Distance euclidienne

    Distance de Jaccard

    Attention! (I)

    Fames vitae
    'Augue magna a sociis consequat dui sed sit est ve donec nulla per eget
    Donex viate gravida
    Velit dolor nullam sociis suscipit parturient aliquam
    Lorem velit
    Magna nulla dui non sed ad mattis dapibus ut mi

    Attention! (II)

    Aucun pattern!

    • score attendu: 50%
    • score direct pour 1-nn: 100%
    • score direct pour 2-nn: 75%
    • score direct pour 3-nn: 67%
    • ...

    Surestimation du vrai score (Mauvaise méthode d'évaluation)

    modèle 1-nn trop spécifique ( overfitting )

    Pour conclure...

    Apprendre à apprendre!

    Existe-t-il quelque chose à apprendre?

    \[modèle = \{algorithme, vectorisation\}\]

    \[succès = f(donnés, modèle, paramètres) \]


    Considérations techniques de l'algorithme


    Machine-learning <=> science
    (mais pas de raison d'avoir peur!)

    Ce que je déconseille

    1. Ne pas bien connaître sont training-set
    2. Utiliser un algo trendy que l'on ne comprend pas
      (i.e. réseaux de neurones pour de la classif de texte)
    3. Copier un bout de code d'un tuto en injectant ses données
    4. Espérer que cela marche!

    Pour aller plus loin...

    Clés théoriques

    • Probabilités (bayesiennes)
    • distances et espace vectoriel
    • mesures de l'erreur
    • overfitting
    • décomposition biais-variance
    • fléau de la dimension
    • régularisation
    • ...

    Algorithmes

    • arbre de décision
    • perceptron
    • gradient descent
    • régression logistique
    • Random forest
    • ...

    Soluce (version alpha)

    • 60 / 80 commentaires hétérogènes
    • vectorisation:
      • 1-3 grams
      • 1-3 mers
    • algorithme : (3-5)-Neighrest Neighbors
    • code

    code

    liens

    Merci!