J'ai essayé d'implémenter le filtre anti-spam bayésien de Robinson avec python

introduction

La chose la plus gênante lors de la vérification du fonctionnement du filtre anti-spam bayésien de Robinson écrit en PHP était le calcul du chi carré. Après avoir recherché diverses choses, un programme python écrit par Robinson lui-même est sorti. Je n'aimais pas ça, alors j'ai ajouté un traitement pour vérifier le calcul php, et quand j'ai remarqué, j'ai fait une classe de filtre bayésien.

Je ne pouvais pas trouver autant la mise en œuvre du filtre anti-spam bayésien de Robinson, même si je l'ai recherchée sur Google, alors j'ai décidé de le publier pour le moment. Je suis nouveau dans Python, donc je suis désolé si je fais beaucoup d'erreurs. Nous vous souhaitons la bienvenue. J'espère que cela aide quelqu'un. Au fait, je n'ai pas l'intention de revendiquer le droit d'auteur, alors s'il vous plaît, aimez-le en le faisant bouillir ou en le cuisant.

Cliquez ici pour une explication japonaise du filtre Basian. http://akademeia.info/index.php?%A5%D9%A5%A4%A5%B8%A5%A2%A5%F3%A5%D5%A5%A3%A5%EB%A5%BF

programme

""" Robinson's Spam filter program
This program is inspired by the following article
http://www.linuxjournal.com/article/6467?page=0,0
"""
import math

class RobinsonsBayes(object):
    """RobinsonsBayes
        This class only support calculation assuming you already have training set.
    """
    x = float(0.5) #possibility that first appeard word would be spam
    s = float(1)   #intensity of x
    def __init__(self,spam_doc_num,ham_doc_num):
        self.spam_doc_num = spam_doc_num
        self.ham_doc_num = ham_doc_num
        self.total_doc_num = spam_doc_num+ham_doc_num
        self.possibility_list = []

    def CalcProbabilityToBeSpam(self,num_in_spam_docs,num_in_ham_docs):
        degree_of_spam = float(num_in_spam_docs)/self.spam_doc_num;
        degree_of_ham  = float(num_in_ham_docs)/self.ham_doc_num;

        #p(w)
        probability = degree_of_spam/(degree_of_spam+degree_of_ham);

        #f(w)
        robinson_probability = ((self.x*self.s) + (self.total_doc_num*probability))/(self.s+self.total_doc_num)
        return robinson_probability

    def AddWord(self,num_in_spam_docs,num_in_ham_docs):
        probability = self.CalcProbabilityToBeSpam(num_in_spam_docs,num_in_ham_docs)
        self.possibility_list.append(probability)
        return probability

    #retrieved from
    #http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/064/6467/6467s2.html
    def chi2P(self,chi, df):
        """Return prob(chisq >= chi, with df degrees of freedom).
        df must be even.
        """
        assert df & 1 == 0

        # XXX If chi is very large, exp(-m) will underflow to 0.
        m = chi / 2.0
        sum = term = math.exp(-m)
        for i in range(1, df//2):
            term *= m / i
            sum += term
        # With small chi and large df, accumulated
        # roundoff error, plus error in
        # the platform exp(), can cause this to spill
        # a few ULP above 1.0. For
        # example, chi2P(100, 300) on my box
        # has sum == 1.0 + 2.0**-52 at this
        # point.  Returning a value even a teensy
        # bit over 1.0 is no good.
        return min(sum, 1.0)

    def CalcNess(self,f,n):
        Ness = self.chi2P(-2*math.log(f),2*n)
        return Ness

    def CalcIndicator(self):
        fwpi_h=fwpi_s=1
        for fwi in self.possibility_list:
            fwpi_h *= fwi
            fwpi_s *= (1-fwi)

        H = self.CalcNess(fwpi_h,3)
        S = self.CalcNess(fwpi_s,3)

        #Notice that the bigger H(Hamminess) indicates that the document is more likely to be SPAM.
        I = (1+H-S)/2
        return I

if __name__ == '__main__':
    """
        This is a exapmple of checking if "I have a pen" is a spam.

        Following program assuming like:
            - We have 10 spam documents and 10 ham documents in our hand.
            - Number of "I" in spam documents is 1 and that of ham documents is 5
            - Number of "have" in spam documents is 2 and that of ham documents is 6
            - Number of "a" in spam documents is 1 and that of ham documents is 2
            - Number of "pen" in spam documents is 5 and that of ham documents is 1

        By the way, "I have a pen" is an sentence the most of Japanese learn in the first English class.
        Enjoy!
    """

    #init class by giving the number of document
    RobinsonsBayes = RobinsonsBayes(10,10)

    #Add train data of words one by one
    print "I   : "+str(RobinsonsBayes.AddWord(1,5))
    print "have: "+str(RobinsonsBayes.AddWord(2,6))
    print "a   : "+str(RobinsonsBayes.AddWord(1,2))
    print "pen : "+str(RobinsonsBayes.AddWord(5,1))

    #calculate Indicater
    print "I (probability to be spam)"
    print RobinsonsBayes.CalcIndicator()
    print ""

Recommended Posts

J'ai essayé d'implémenter le filtre anti-spam bayésien de Robinson avec python
J'ai essayé d'utiliser l'optimisation bayésienne de Python
J'ai essayé d'implémenter la régression logistique de Cousera en Python
Implémenté en Python PRML Chapitre 1 Estimation bayésienne
Implémentation de SimRank en Python
Liste de filtres en Python
J'ai essayé d'implémenter la fonction gamma inverse en python
Implémentation de Shiritori en Python
J'ai essayé d'implémenter la recherche de priorité de largeur avec python (file d'attente, dessin personnalisé)
J'ai implémenté une commande de remplacement de type Vim dans Slackbot #Python
Implémentation de Supreme Solver dans Python 3
Je comprends Python en japonais!
Ce que j'ai appris en Python
J'ai essayé d'implémenter l'algorithme de calcul séquentiel non biaisé de Donald Knuth en Python
Implémentation de la segmentation d'image en python (Union-Find)
GPyOpt, un package d'optimisation bayésienne en Python
[Python] J'ai essayé d'implémenter un échantillonnage de Gibbs marginalisé
Règles d'apprentissage Widrow-Hoff implémentées en Python
J'ai écrit Fizz Buzz en Python
Implémentation de la méthode de propagation d'étiquettes en Python
J'ai essayé d'étudier le processus avec Python
Scikit-learn ne peut pas être installé en Python
J'ai écrit la file d'attente en Python
Implémentation des règles d'apprentissage Perceptron en Python
J'ai essayé la notification de ligne en Python
Implémenté en 1 minute! LINE Notify en Python
J'ai écrit la pile en Python
J'ai mis Python 2.7 dans Sakura VPS 1 Go.
J'ai essayé d'implémenter PLSA en Python
Livre de canard implémenté en Python "Modélisation statistique Bayes avec Stan et R"
Un client HTTP simple implémenté en Python
J'ai essayé d'implémenter la permutation en Python
J'ai fait un programme de gestion de la paie en Python!
Implémenté en Python PRML Chapitre 7 SVM non linéaire
J'ai essayé d'implémenter PLSA dans Python 2
J'ai essayé d'implémenter la régression linéaire bayésienne par échantillonnage de Gibbs en python
Je ne peux pas déboguer les scripts python dans Eclipse
Réécrire le nœud de filtre de SPSS Modeler avec Python
J'ai essayé d'implémenter ADALINE en Python
Je voulais résoudre ABC159 avec Python
J'ai essayé d'implémenter PPO en Python
Implémenté dans Python PRML Chapter 5 Neural Network
J'ai cherché un nombre premier avec python
Mise en œuvre du tri Stuge dans Python 3 (tri à bulles et tri rapide)
J'ai créé un outil de mot de passe en Python.
CheckIO (Python)> Éléments non uniques> J'ai essayé de mettre en œuvre
Implémentation de DQN avec TensorFlow (je voulais ...)
Pourquoi ne puis-je pas installer matplotlib avec python! !!
J'ai fait un module en langage C qui filtre les images chargées par Python
Je veux faire le test de Dunnett en Python
Un mémo que j'ai écrit un tri rapide en Python
Python: j'ai pu récurer en lambda
Je veux créer une fenêtre avec Python
J'ai essayé de jouer à un jeu de frappe avec Python
Quand j'essaye matplotlib en Python, il dit 'cairo.Context'
J'ai essayé de simuler "Birthday Paradox" avec Python
J'ai essayé la méthode des moindres carrés en Python
Implémenter la récurrence et l'exploration commémoratives dans Python and Go
J'ai étudié en détail le traitement des variables en python