Comment puis-je classer le texte en tenant compte de l'ordre des mots, au lieu d'utiliser simplement une approche par sac de mots?

10

J'ai créé un classificateur Naive Bayes qui utilise la technique du sac de mots pour classer les messages de spam sur un babillard. Cela fonctionne, mais je pense que je pourrais obtenir de bien meilleurs résultats si mes modèles tenaient compte des ordonnances et des phrases. (ex: «filles» et «en direct» peuvent ne pas déclencher un score de spam élevé, même si les «filles en direct» sont très probablement des ordures). Comment créer un modèle prenant en compte l'ordre des mots?

J'ai envisagé de stocker des n-grammes (check-out, out-these-live, these-live-girls), mais cela semble augmenter radicalement la taille du dictionnaire dans lequel je garde le score et provoque une incohérence en tant que phrases avec très un libellé similaire mais un ordre différent s'écoulera.

Je ne suis pas lié à la classification bayésienne, mais j'aimerais quelque chose qu'une personne sans solide expérience en statistique pourrait grok et mettre en œuvre.

Yerk
la source
Les modèles n-gram sont souvent la voie à suivre lorsque l'on considère l'ordre des mots. voir en.wikipedia.org/wiki/N-gram
brentlance

Réponses:

6

Il existe un hack très simple pour incorporer l'ordre des mots dans une implémentation de modèle de sac de mots existante. Traitez certaines des phrases, comme les biogrammes fréquemment utilisés (par exemple New York) comme une unité, c'est-à-dire un seul mot au lieu de les traiter comme des entités distinctes. Cela garantira que "New York" est différent de "York New". Vous pouvez également définir des bardeaux de mots d'ordre supérieur comme pour n = 3,4, etc.

Vous pouvez utiliser le Lucene ShingleFilter pour décomposer le texte de votre document en bardeaux comme étape de prétraitement, puis appliquer le classificateur sur ce texte décomposé.

import java.io.*;
import org.apache.lucene.analysis.core.*;
import org.apache.lucene.analysis.*;
import org.apache.lucene.analysis.shingle.ShingleFilter;
import org.apache.lucene.analysis.standard.*;
import org.apache.lucene.util.*;
import org.apache.lucene.analysis.util.*;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.charfilter.*;
import org.apache.lucene.analysis.core.WhitespaceTokenizer;

class TestAnalyzer extends Analyzer {

    TestAnalyzer() {
        super();
    }

    protected TokenStreamComponents createComponents( String fieldName, Reader reader ) {
        String token;
        TokenStream result = null;

        Tokenizer source = new WhitespaceTokenizer( Version.LUCENE_CURRENT, reader );
        result = new ShingleFilter(source, 2, 2);

        return new TokenStreamComponents( source, result );

    }
}

public class LuceneTest {

    public static void main(String[] args) throws Exception {

        TestAnalyzer analyzer = new TestAnalyzer();

        try {
            TokenStream stream = analyzer.tokenStream("field", new StringReader("This is a sample sentence."));
            CharTermAttribute termAtt = stream.addAttribute(CharTermAttribute.class);

            stream.reset();

            // print all tokens until stream is exhausted
            while (stream.incrementToken()) {
                System.out.println(termAtt.toString());
            }

            stream.end();
            stream.close();
         }
         catch (Exception ex) {
             ex.printStackTrace();
         }

    }
}
Debasis
la source
2

Il existe un tas de techniques. Vous avez déjà mentionné n-gramme, puis il y a la combinaison de mots et d'autres. Mais le principal problème (au moins de votre point de vue) est que lorsque la fonctionnalité devient plus complexe (comme le n-gramme), le nombre de fonctionnalités augmente considérablement. C'est gérable. Fondamentalement, avant la classification, vous devez marquer vos caractéristiques, puis seuil à un certain score. de cette façon, les fonctionnalités (ou dans votre cas, les n-grammes) qui sont notées en dessous d'un certain niveau sont omises et le nombre de fonctionnalités devient gérable. quant à la notation. Il existe de nombreuses façons (dont la sélection dépend de votre application) de noter les fonctionnalités. Vous pouvez commencer par "séparation BiNormal", "chi square", "Information Gain" et etc. Je ne sais pas si cette réponse vous aide mais si vous êtes intéressé je peux élaborer ...

J'ai oublié, dans la combinaison de mots, vous mettez une fenêtre de taille m sur le texte et extrayez chaque combinaison de n mots. bien sûr n

Nima Shayanfar
la source