Alexander Brock: Artikel-Review: Bayesscher Spam-Filter für Weblogs

0 56

Artikel-Review: Bayesscher Spam-Filter für Weblogs

Alexander Brock
  • programmiertechnik
  1. 0
    Felix Riesterer
    1. 0
      Mathias Brodala
      1. 0
        Alexander Brock
        1. 0
          Mathias Brodala
          1. 0
            Alexander Brock
  2. 1
    Robert Bienert
    1. 0
      Alexander Brock
      1. 1

        kleine anmerkung zum multiplikations-zeichen

        seth_not@home
        • sonstiges
        1. 0
          Alexander Brock
  3. 6
    Vinzenz Mai
    1. 1
      seth
      1. 0
        Alexander Brock
        1. 1
          seth_not@home
        2. 1
          Blaubart
          1. 1

            kleine anmerkung zur kommasetzung

            seth_not@home
            1. 1
              Auge
              1. 0
                seth
                • sonstiges
                1. 0
                  Auge
                  1. 0

                    ole, ole, metadiskussionen ueber komma-diskussionen

                    seth
                    1. 0

                      "ole, ole" ... die alten Schweden, die!

                      Auge
      2. 1
        Blaubart
        1. 1
          seth_not@home
          1. 1
            Blaubart
    2. 0
      Alexander Brock
      1. 3
        Vinzenz Mai
  4. 2
    seth
    1. 0
      Alexander Brock
      1. 1
        seth_not@home
        1. 0
          Alexander Brock
          1. 1
            seth
            1. 0
              Alexander Brock
              1. 1
                seth_not@home
                1. 0
                  Alexander Brock
                  1. 1
                    seth_not@home
                    1. 0
                      Alexander Brock
                      1. 0
                        seth_not@home
                        1. 0
                          Alexander Brock
                          1. 1
                            seth
                            1. 0
                              Alexander Brock
  5. 0
    Alexander Brock
    1. 1
      Robert Bienert
      1. 0
        Alexander Brock
        1. 1
          Robert Bienert
          1. 0
            Alexander Brock
            1. 1
              seth
              1. 0
                Alexander Brock
                1. 1
                  seth
                  1. 0
                    Alexander Brock
                  2. 0
                    O'Brien
    2. 1
      Der Dicki
      1. 0
        Alexander Brock
    3. 0
      Christian Seiler
      1. 0
        Alexander Brock
        1. 0
          Christian Seiler
          1. 0
            Alexander Brock

Hallo Forum,

Ich habe an diesem Wochenende einen Artikel darüber geschrieben, wie man Bayessche Spam-Filter in Weblogs verwenden kann um Kommentarspam auszufiltern, der nun im Review-Verzeichnis liegt und zu dem ich gerne Kritik und Feedback haben möchte, bevor ich ihn "richtig" veröffentliche:

Bayesscher Kommentarspam-Filter

Gruß
Alexander Brock

  1. Lieber Alexander,

    Bayesscher Kommentarspam-Filter

    also mir ist das definitiv zu hoch. Das gebe ich gerne freimütig zu. Diese mathematischen Terme verstehe ich nicht. Die Umsetzung in eine Script-/Programmier-Sprache ebensowenig.

    Mir ist aber klar, dass das Thema SPAM wohl nur mit solchen Ansätzen wirklich wirkungsvoll zu bekämpfen ist. Daher werde ich zu gegebener Zeit auf Dein Werk zurückkommen und versuchen, den Grundgedanken (oder eine von Dir entwickelte Klasse) zu implementieren. Bis dahin... .oO(?)

    Liebe Grüße aus Ellwangen,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
    1. Hallo Felix.

      Bayesscher Kommentarspam-Filter

      also mir ist das definitiv zu hoch. Das gebe ich gerne freimütig zu. Diese mathematischen Terme verstehe ich nicht.

      Same here. Als ich die Formeln sah, schaltete ich innerlich ab und las den Rest gar nicht mehr. Lediglich die Codefetzen am Schluss habe ich dann noch kurz überflogen.

      Einen schönen Montag noch.

      Gruß, Mathias

      --
      ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
      debian/rules
      1. Hallo Forum,

        Same here. Als ich die Formeln sah, schaltete ich innerlich ab und las den Rest gar nicht mehr. Lediglich die Codefetzen am Schluss habe ich dann noch kurz überflogen.

        Ich habe den Artikel überarbeitet, um die Verständlichkeit der Umformungen und der Vorgänge beim Einfügen und Abfragen der Statistiken zu erhöhen.

        Ist mir das gelungen?

        Gruß
        Alexander Brock

        1. Hallo Alexander.

          Same here. Als ich die Formeln sah, schaltete ich innerlich ab und las den Rest gar nicht mehr. Lediglich die Codefetzen am Schluss habe ich dann noch kurz überflogen.

          Ich habe den Artikel überarbeitet, um die Verständlichkeit der Umformungen und der Vorgänge beim Einfügen und Abfragen der Statistiken zu erhöhen.

          Ist mir das gelungen?

          Ich denke, dass ich zu den Formeln keine geeignete Einschätzung geben kann, da ich Mathematik allgemein eher distanziert gegenüber stehe, um es freundlich auszudrücken.

          Wie man deine Klasse zu benutzen hat, erschließt sich mir jedoch sofort.

          Einen schönen Montag noch.

          Gruß, Mathias

          --
          ie:% fl:| br:< va:) ls:& fo:) rl:( n4:~ ss:) de:] js:| mo:| zu:)
          debian/rules
          1. Hallo Forum,

            Ich denke, dass ich zu den Formeln keine geeignete Einschätzung geben kann, da ich Mathematik allgemein eher distanziert gegenüber stehe, um es freundlich auszudrücken.

            Das ist schade, wo die Mathematik doch so ein schönes Spiel ist, das umso mehr Spaß macht je mehr Regeln man kennt :-)

            Wie man deine Klasse zu benutzen hat, erschließt sich mir jedoch sofort.

            Fein, da bin ich schon glücklich *g*

            Gruß
            Alexander Brock

  2. Moin!

    Betrachte meinen Beitrag als eine Art „Oma-Test“ ;-)

    Bayesscher Kommentarspam-Filter

    Dank Wikipedia konnte ich so langsam dahinter steigen, wie Bayes funktioniert. Sehe ich das richtig, dass der von dir beschriebene Filter folgendermaßen arbeitet: Zuerst wird der Kommentar in einzelne Worte zerhackt und anschließend mit Hilfe der (manuellen) Klassifizierung als Spam oder Ham einsortiert, wobei der Score aktualisiert wird. Später, wenn der Filter trainiert ist, liefert mir diese Zahl, summiert über alle Wörter in einem Kommentar, eine Wahrscheinlichkeit, ob der Kommentar Spam oder Ham ist.

    Wie man das genau implementiert ist mir allerdings noch ein wenig unklar.

    Viele Grüße,
    Robert

    1. Hallo Forum,

      Dank Wikipedia konnte ich so langsam dahinter steigen, wie Bayes funktioniert. Sehe ich das richtig, dass der von dir beschriebene Filter folgendermaßen arbeitet: Zuerst wird der Kommentar in einzelne Worte zerhackt und anschließend mit Hilfe der (manuellen) Klassifizierung als Spam oder Ham einsortiert, wobei der Score aktualisiert wird. Später, wenn der Filter trainiert ist, liefert mir diese Zahl, summiert über alle Wörter in einem Kommentar, eine Wahrscheinlichkeit, ob der Kommentar Spam oder Ham ist.

      Ganz genau richtig, wobei zu dieser Zahl noch
      latex*(\ln(N_{Ham})-\ln(N_{Spam}))[/latex] addiert und das Ergebnis in [latex]e^{x}[/latex] eingesetzt wird, um die Wahrscheinlichkeit zu berechnen.

      Wie man das genau implementiert ist mir allerdings noch ein wenig unklar.

      Okay, ich werden den Artikel nochmal überarbeiten und die Implementierung besser erklären.

      Gruß
      Alexander Brock

      1. gudn tach!

        latex*(\ln(N_{Ham})-\ln(N_{Spam}))[/latex]

        bloss eine kleineigkeit: mit [latex]*[/latex] bezeichnet man eigentlich eine faltung und nicht die gewoehnliche multiplikation, die man normalerweise durch einen punkt [latex]\cdot[/latex] symbolisiert, der auch weggelassen werden kann, wenn aus dem kontext trotzdem noch hervorgeht, was gemeint ist.

        (den artikel wuerde ich mir uebrigens gerne mal durchlesen, habe aber heute und morgen kaum zeit.)

        prost
        seth

        1. Hallo Forum,

          bloss eine kleineigkeit: mit [latex]*[/latex] bezeichnet man eigentlich eine faltung und nicht die gewoehnliche multiplikation, die man normalerweise durch einen punkt [latex]\cdot[/latex] symbolisiert, der auch weggelassen werden kann, wenn aus dem kontext trotzdem noch hervorgeht, was gemeint ist.

          Ich habe ihn jetzt weggelassen, danke.

          Ich verwende übrigens die Wikipedia, um die Formeln zu erzeugen,
          ich habe mal versucht die Umformungen in Computer-gerechte Gleichungen Menschen-gerechter darzustellen, indem ich ein bischen anders umforme und die gleichen Variablen gleich einfärbe:

          http://de.wikipedia.org/wiki/Benutzer:Alexander_Brock

          Ist das so besser verständlich?
          Sind die Summen- und Produkt-Zeichen allgemein bekannt oder soll ich die nochmal erklären, oder eine Erklärung verlinken?

          Gruß
          Alexander Brock

  3. Hallo Alexander,

    Bayesscher Kommentarspam-Filter

    es ist schön, wieder einen neuen Artikel zu sehen. Du schreibst über ein Thema, mit dem Du Dich intensiv auseinandergesetzt hast, das Du gut kennst. Das ist _eine_ wichtige Voraussetzung, um einen guten Artikel zu schreiben. Auf der anderen Seite fällt es einem dann schwer, sich in die Lage eines anderen zu versetzen, der sich mit der Materie bisher nicht oder nur flüchtig auseinandergesetzt hat. Du läßt Aspekte weg, Du läßt Erklärungen weg, die Dir trivial erscheinen, dem Neuling in der Materie jedoch diese erst erschließen.

    Was könntest Du besser machen (bitte nicht erschrecken)?

    a) Einleitung: Konzepte von Spamfiltern
       Du hast wunderbares Material zusammengetragen, hübsch gegliedert.
       Nutze dies => gliedere Deine Abschnitte mit entsprechenden Unterüberschriften

    Verschiedene Konzepte
       - Captcha (-varianten)
       - Variation Feldnamen
       - Versteckte Felder

    Hauptabschnitt Bayesfilter
       - Konzept des Bayestheorem in einfachen Worten
         (Nein, nicht die Mathematik)
       - Vorteile
       - Nebenaspekte

    b) Bayestheorem
       Nicht an zweiter Stelle, jedenfalls nicht in dieser Ausführlichkeit.
       Wenn so ausführlich, dann im Anhang, dann gern noch ausführlicher.

    c) Nimm gleich die Spamformel, gleich die Umschreibung mit den Logarithmen
       im Exponenten von e. Die weitere Erläuterung im Anhang

    Das tut Dir weh, vermute ich - verringert meiner Meinung nach jedoch die
    Hemmschwelle, die Deine mathematischen Umformungen erzeugen. Den Hinweis
    "versetzen wir uns zurück in die zehnte Klasse" lass bitte weg. Du weißt
    doch selbst, dass nicht jeder, der auf diese Seiten kommt, bereits sein
    zehntes Schuljahr hinter sich hat. Ich weiß auch nicht, wie es mit dem
    Logarithmus an anderen Schulformen als dem Gymnasium aussieht - und auch
    nicht, wann die Logarithmusgesetze derzeit auf dem Lehrplan stehen. Zu
    meiner Zeit dürfte das zehnte Schuljahr gepasst haben :-)

    d) Beispielimplementierung
       Statt fertiger CREATE TABLE-Statements beschreibe lieber die Tabellen,
       führe Beispieldatensätze (z.B. ein Auszug Deiner eigenen Produktivdaten)
       auf. Genauer gesagt: solche Datensätze, an denen sich ein Beispielbeitrag
       exemplarisch durcharbeiten läßt.

    Warum _keine_ fertigen Statements? Es ist wichtiger, dass man versteht,
       welche Daten abgespeichert werden müssen. Das sind ja nicht besonders
       viele. Dazu lassen Deine Beispieltabellen und -beschreibungen zu wünschen
       übrig:

    Tabelle filter_words
       word VARBINARY(50)
       -- Es ist gute Praxis, SQL-Schlüsselwörter groß zu schreiben, siehe z.B.
       -- MySQL-Handbuch
       -- Warum ausgerechnet VARBINARY, warum genau dieser Datentyp.
       -- Begründe die 50.
       -- die Angabe der Storage-Engine ist überflüssig, oder hast Du bestimmte
       -- Gründe ausgerechnet MyIsam zu verwenden?

    Tabelle filter_stats
       Du schreibst in Deiner Signatur, dass Deine Klasse Texte kategorisieren
       kann. Darunter verstehe ich eine beliebige Anzahl von Kategorien. Deine
       Tabelle spiegelt das nicht wieder. Eine neue Kategorie bedeutet bei Dir
       eine neue Spalte. Das ist normalerweise ein Anzeichen eines ungünstig
       gewählten Tabellendesigns.

    Dann füllst Du sie mit zwei Datensätzen. Viel einfacher hättest Du einfach
       den Initialinhalt der Tabelle hingeschrieben. Einfacher, verständlicher.
       Bei Deinem Design ist zudem der Spaltenname "name" ungünstig, weil
       aussagelos, gewählt. Inkonsequent und inkonsistent die beiden Datensätze:

    "lnum"   ist der (natürliche) Logarithmus der Anzahl der Kommentare
       "lwords" ist der (natürliche) Logarithmus der Anzahl der Wörter

    Fällt Dir etwas auf? Welchen Eintrag solltest Du treffender wählen?
       Inkonsequent der Datentyp: CHAR(5) wäre ausreichend und würde zudem
       Datensätze fester Länge ermöglichen, aber das nur am Rande.
       Wenn Du die Tabelle transponierst, dann werden daraus Spaltenüberschriften
       und Du brauchst Dir keinen Gedanken über einen beschreibenderen Namen zu
       machen :-) Ich weiß, dass das Konsequenzen für Deine ganze Klasse hat,
       aber das sollte machbar sein.

    Mein Hauptanliegen:

    e) Erläutere die verschiedenen Arbeitsschritte an einem Beispiel. Besser noch
       ein Beispiel für Spam, ein Beispiel für Ham. Ein einfaches Beispiel ohne
       komplexe Tokens, ein Text von vielleicht 20 Wörtern Umfang. Die Tabellen
       mit genau die erforderlichen Datensätzen gefüllt, mit Werten aus Deiner
       Praxis.

    In Einzelschritten
         - die Verarbeitung des Textes erläutern,
         - den Spamwert berechnen,
         - die neuen Tabellenwerte ermitteln
       damit auch die Fähigkeit zum Selbstlernen demonstrieren.

    Genau solche Beispiele erleichtern meiner Meinung nach ungemein den Zugang zu
    solchen Techniken, erleichtern den Zugang zur dahinter liegenden Mathematik,
    motivieren vielleicht jemanden, sich damit auseinanderzusetzen, auch wenn
    derjenige sonst nicht viel damit am Hut hat.

    Zusammenfassung:

    • Du hast Dir ein interessantes Thema ausgesucht, von dem Du viel Ahnung hast.
    • Du hast bereits gutes Material gesammelt,
    • Du hast eine ausbaufähige Gliederung.
    • Nutze ein konkretes Beispiel (am besten je eines für Spam und eines für Ham),
        um die praktische Anwendung des Bayes-Theorems aufzuzeigen.
    • Verschiebe die zugrundeliegende Mathematik in die Erklärung _nach_ dem
        Beispiel. Vergleiche dazu andere Artikel:
          a) So sieht es aus/So geht es  (Beispiel)
          b) Das ist die Erklärung dafür (Bayes-Theorem)
          c) Beachte ...                 (Probleme bei der Implementierung)
    • Erläutere bei der Implementierung, was getan werden muss - nicht wie Du es
        speziell gelöst hast (das kann im Kommentar zu Deinem Code stehen).
        Dein PHP-Code ist im Archiv, warum nicht auch Deine SQL-Statements?

    Ich hoffe, ich konnte Dir einige Anregungen geben, durch deren Umsetzung
    Dein Artikel zugänglicher wird - und somit auch Beachtung finden wird. Das
    hast Du sicherlich auch verdient.

    Freundliche Grüße

    Vinzenz

    1. gudn tach!

      a) Einleitung: Konzepte von Spamfiltern
         Du hast wunderbares Material zusammengetragen, hübsch gegliedert.
         Nutze dies => gliedere Deine Abschnitte mit entsprechenden Unterüberschriften

      bei einem so kurzen text wuerde ich sub-unterschriften als fast den-lesefluss-stoerend empfinden. vielleicht die jeweiligen schlagworte kursiv setzen?

      Verschiedene Konzepte
         - Captcha (-varianten)
         - Variation Feldnamen
         - Versteckte Felder

      da zu jedem thema nur ein bis zwei saetze verloren werden, finde ich _eine_ ueberschrift besser.

      Hauptabschnitt Bayesfilter
         - Konzept des Bayestheorem in einfachen Worten
           (Nein, nicht die Mathematik)

      doch! fuer leute, die kein interesse haben, ein paar einfache erklaerungen; und fuer die interessierten wuerde ich einen abschnitt erstellen (keinen anhang bei einem so kurzen text!) und jenen einleiten, dass man ihn ueberspringen solle, wenn man von der mathematik dahinter nichts wissen will. auf die entsprechenden tiefergehenden wikipedia-artikel kannst du ja verlinken.

      - Vorteile
         - Nebenaspekte

      und nachteile!

      b) Bayestheorem
         Nicht an zweiter Stelle, jedenfalls nicht in dieser Ausführlichkeit.
         Wenn so ausführlich, dann im Anhang, dann gern noch ausführlicher.

      das bayes-theorem wird in genau einer zeile abgehandelt. kuerzer geht es kaum. fuer einen anhang ist es jedenfalls zu wenig. imho wuerde ein wikipedia-link aber genuegen. denn so kurz wie es momentan dasteht, versteht wohl kaum jemand, was die aussage des satzes ist, es sei denn er kannte sie schon vorher. in der wikipedia (oder evtl. bei wolfram oder so) ist dann wenigstens noch etwas hintergruendiges zu dem kram geschrieben. fuer "omas" _und_ mathematiker.

      zu c) habe ich nix neues hinzuzufuegen. ein anhang waere halt imho fuer einen so kurzen text ungeeignet. dann besser die variante, die auch haeufig in anderen kurzen online-artikeln angewendet wird, naemlich warnen a la "achtung mathe! wer angst hat, einfach ueberspringen und da und da weiter lesen".

      d) Beispielimplementierung

      das schau ich mir ein ander' mal an. *gaehn*

      noch ein paar formelle anmerkungen:

      • im abschnitt "bayestheorem" (den ich uebrigens anders nennen wuerde), fehlt ein =-zeichen

      • mathematische formeln werden normalerweise direkt in einen satz eingebettet und nicht mit doppelpunkten abgetrennt. die einrueckung ist natuerlich richtig und wichtig, aber der text sollte fluessiger sein, z.b.
        "Die Wahrscheinlichkeit, dass ein Kommentar eine Menge Wörter w enthält[komma!] lässt sich unter der naiven Annahme, dass das Auftreten eines bestimmten Wortes unabhängig von dem Auftreten aller anderen Wörter ist[komma!] durch
          [formel]
        ausdruecken."

      • kommasetzung insg. koennte besser sein.

      • der begriff "bedingte wahrscheinlichkeit" sollte fallen und verlinkt werden.

      • das i in der dritten formel hat mit dem ersten i nichts zu tun, was aber nicht jedem sofort klar wird.

      • bei grossen exponential-ausdruecken ist die schreibweise [latex]\exp(foooooo)[/latex] meist besser lesbar und deswegen der schreibweise [latex]e^{foooooo}[/latex] vorzuziehen.

      • geschweifte klammern als meta-runde klammern sind out. an der tafel moegen sie zwar u.u. sinnvoll sein, aber getext sind sie eher zu vermeiden, weil sie schon andere bedeutungen haben, allen voran "menge". ich empfehle \bigl( und \bigr). mehr dazu siehe wikipedia hilfe:teX

      • streng genommen gehoeren zwischen mathematischen umformungen noch die ausformulierten umformungsschritte. (aber ich gebe zu, dass bei den hiesigen schritten zusaetzlicher text nicht nur redundant, sondern sogar stoerend sein koennte, denn wer keine ahnung von / lust auf mathe hat, wird diese abschnitte eh ueberspringen.)

      prost
      seth

      1. Hallo Forum,

        noch ein paar formelle anmerkungen:

        • im abschnitt "bayestheorem" (den ich uebrigens anders nennen wuerde), fehlt ein =-zeichen

        Richtig, ich werde das beheben.

        • mathematische formeln werden normalerweise direkt in einen satz eingebettet und nicht mit doppelpunkten abgetrennt. die einrueckung ist natuerlich richtig und wichtig, aber der text sollte fluessiger sein, z.b.
          "Die Wahrscheinlichkeit, dass ein Kommentar eine Menge Wörter w enthält[komma!] lässt sich unter der naiven Annahme, dass das Auftreten eines bestimmten Wortes unabhängig von dem Auftreten aller anderen Wörter ist[komma!] durch
            [formel]
          ausdruecken."

        Da die meisten Formeln wesentlich höher als eine Zeile sind würde das den Text zerreißen.

        • kommasetzung insg. koennte besser sein.

        Wo konkret?

        • der begriff "bedingte wahrscheinlichkeit" sollte fallen und verlinkt werden.

        ack

        • das i in der dritten formel hat mit dem ersten i nichts zu tun, was aber nicht jedem sofort klar wird.

        Okay, das wird noch geändert.

        • bei grossen exponential-ausdruecken ist die schreibweise [latex]\exp(foooooo)[/latex] meist besser lesbar und deswegen der schreibweise [latex]e^{foooooo}[/latex] vorzuziehen.

        Ich fand die zweite Schreibweise besser verständlich, exp als e-Funktion kannte ich nur von Programmiersprachen, nicht von der Schul-Mathematik.

        • geschweifte klammern als meta-runde klammern sind out. an der tafel moegen sie zwar u.u. sinnvoll sein, aber getext sind sie eher zu vermeiden, weil sie schon andere bedeutungen haben, allen voran "menge". ich empfehle \bigl( und \bigr). mehr dazu siehe wikipedia hilfe:teX

        ack

        • streng genommen gehoeren zwischen mathematischen umformungen noch die ausformulierten umformungsschritte.

        So?

        Gruß
        Alexander Brock

        1. gudn tach!

          • mathematische formeln werden normalerweise direkt in einen satz eingebettet und nicht mit doppelpunkten abgetrennt. die einrueckung ist natuerlich richtig und wichtig, aber der text sollte fluessiger sein, z.b.
            "Die Wahrscheinlichkeit, dass ein Kommentar eine Menge Wörter w enthält[komma!] lässt sich unter der naiven Annahme, dass das Auftreten eines bestimmten Wortes unabhängig von dem Auftreten aller anderen Wörter ist[komma!] durch
              [formel]
            ausdruecken."

          Da die meisten Formeln wesentlich höher als eine Zeile sind würde das den Text zerreißen.

          und dabei habe ich es extra versucht so zu formulieren, dass du genau das, was du jetzt verstanden hast, nicht so verstehst. ;-)

          selbstverstaendlich sollten die formeln in einer eigenen zeile stehen, aber sie sollten grammatisch im satz eingebettet sein. schau noch mal meinen beispielsatz an. die formel ist in einer separaten zeile, aber davor steht kein doppelpunkt...

          • kommasetzung insg. koennte besser sein.

          Wo konkret?

          naja, an sehr vielen stellen, z.b.
          "Die Motive sind die gleichen wie bei den E-Mails[PUNKT oder semikolon; jaja, komma geht auch] man kann mit wenig Aufwand tausende Kommentare absetzen[KEIN KOMMA] und damit tausende Nutzer in die Versuchung bringen[KOMMA] auf die gesetzten Links zu klicken und irgendetwas zu kaufen oder einfach Werbe-Einnahmen zu generieren."

          mehr zeit kann/moechte ich jetzt nicht investieren. mach ich spaeter.

          • streng genommen gehoeren zwischen mathematischen umformungen noch die ausformulierten umformungsschritte.

          So?

          ja, mit mehr abstand. oder eben ausformuliert:

          unter ausnutzung der eigenschaften logarithmus-funktion kann
            [formel1]
          zu
            [formel2]
          umgeschrieben werden. durch beidseitiger anwendung der exponentialfunktion wird daraus
            [formel1_neu].

          prost
          seth

        2. Tach.

          • kommasetzung insg. koennte besser sein.

          Wo konkret?

          Auch nur ein paar Beispiele:

          "Gegenmaßnahmen müssen her, Antispam-Plugins für Weblogs sprießen wie Pilse aus dem Bierfass [PUNKT] hier sollen einige Konzepte und ihre Vor- und Nachteile dargestellt werden."

          (An einigen Stellen bietet es sich meiner Meinung nach an, ganz einfach den Satz zu beenden, um den Rest in einem neuen Satz unterzubringen.)

          "CAPTCHAs – die kleinen Bilder mit verzerrten Buchstaben, die die Benutzer abtippen sollen [KOMMA] um die Erlaubnis zum Kommentieren zu erhalten – sind vielleicht die häufigste Anti-Spam-Maßnahme [PUNKT] nichtsdestotrotz hindert sie Sehbehinderte an der Teilnahme, nervt die erwünschten Benutzer [KOMMA] und es gibt seitens der Spammer bereits diverse Gegenmaßnahmen."

          "Eine entschärfte Version der CAPCTHA [Buchstabendreher und fehlendes "s"] sind kleine Fragen oder Rechenaufgaben, die von Menschen problemlos, von Computern aber nur sehr schwierig allgemein gelöst werden können [PUNKT oder GEDANKENSTRICH] woher soll der Spambot auch wissen, der wievielte Monat der Januar ist? Wahre Programmierer geben hier vielleicht 0 an [KOMMA] aber das ist ein anderes Problem und soll ein anderes Mal gelöst werden."

          • bei grossen exponential-ausdruecken ist die schreibweise [latex]\exp(foooooo)[/latex] meist besser lesbar und deswegen der schreibweise [latex]e^{foooooo}[/latex] vorzuziehen.

          Ich fand die zweite Schreibweise besser verständlich, exp als e-Funktion kannte ich nur von Programmiersprachen, nicht von der Schul-Mathematik.

          Dann spricht doch nichts gegen die Verwendung von \exp. Schließlich sprichst du mit deinem Artikel Leute an, die sich ebenfalls mit Programmiersprachen beschäftigen. :)

          --
          Once is a mistake, twice is jazz.
          1. gudn tach!

            "nichtsdestotrotz hindert sie Sehbehinderte an der Teilnahme, nervt die erwünschten Benutzer [KOMMA] und es gibt seitens der Spammer bereits diverse Gegenmaßnahmen."

            dieses komma ist (nur nach neuer rechtschreibung) fakultativ. (§§ 72 und 73, amtliche rechtschreibung)

            prost
            seth

            1. Hallo

              "nichtsdestotrotz hindert sie Sehbehinderte an der Teilnahme, nervt die erwünschten Benutzer [KOMMA] und es gibt seitens der Spammer bereits diverse Gegenmaßnahmen."

              dieses komma ist (nur nach neuer rechtschreibung) fakultativ. (§§ 72 und 73, amtliche rechtschreibung)

              Nach http://www.studis-online.de/StudInfo/Glossar/fakultativ.php und anderen Quellen bedeutet "fakultativ" freigestellt, eigenem Ermessen überlassen damit ist das Komma an der Stelle nicht falsch. ;-)

              Ich setze es, das Komma, übrigens vor "und", wenn "und" z.B. einen Nebensatz einleitet. Aber ich richte mich auch, bis auf eine Ausnahme (ß vs. ss), nach der alten Rechtschreibung (soweit ich die beherrsche).

              Tschö, Auge

              --
              Die Musik drückt aus, was nicht gesagt werden kann und worüber es unmöglich ist zu schweigen.
              (Victor Hugo)
              Veranstaltungsdatenbank Vdb 0.1
              1. gudn tach!

                "nichtsdestotrotz hindert sie Sehbehinderte an der Teilnahme, nervt die erwünschten Benutzer [KOMMA] und es gibt seitens der Spammer bereits diverse Gegenmaßnahmen."

                dieses komma ist (nur nach neuer rechtschreibung) fakultativ. (§§ 72 und 73, amtliche rechtschreibung)

                [...] bedeutet "fakultativ" freigestellt, eigenem Ermessen überlassen damit ist das Komma an der Stelle nicht falsch. ;-)

                ja, und genau das wollte ich damit auch sagen: es ist egal, ob dort ein komma steht oder nicht. es ist also kein fehler, es wegzulassen.

                Ich setze es, das Komma, übrigens vor "und", wenn "und" z.B. einen Nebensatz einleitet. Aber ich richte mich auch, bis auf eine Ausnahme (ß vs. ss), nach der alten Rechtschreibung (soweit ich die beherrsche).

                "und" leitet normalerweise keine nebensaetze ein.
                nach der alten regelung musste vor "und" ein komma gesetzt werden, wenn dadurch selbststaendige saetze verbunden wurden. vermutlich meinst du diese regel. die wird halt jetzt durch § 73 ausgehebelt.

                prost
                seth

                1. Hallo

                  [...] bedeutet "fakultativ" freigestellt, eigenem Ermessen überlassen damit ist das Komma an der Stelle nicht falsch. ;-)

                  ja, und genau das wollte ich damit auch sagen: es ist egal, ob dort ein komma steht oder nicht. es ist also kein fehler, es wegzulassen.

                  Also beide Varianten sind nicht fehlerhaft.

                  Ich setze es, das Komma, übrigens vor "und", wenn "und" z.B. einen Nebensatz einleitet. Aber ich richte mich auch, bis auf eine Ausnahme (ß vs. ss), nach der alten Rechtschreibung (soweit ich die beherrsche).

                  "und" leitet normalerweise keine nebensaetze ein.
                  nach der alten regelung musste vor "und" ein komma gesetzt werden, wenn dadurch selbststaendige saetze verbunden wurden. vermutlich meinst du diese regel. die wird halt jetzt durch § 73 ausgehebelt.

                  Deswegen "Aber ich richte mich ... nach der alten Rechtschreibung".

                  Tschö, Auge

                  --
                  Die Musik drückt aus, was nicht gesagt werden kann und worüber es unmöglich ist zu schweigen.
                  (Victor Hugo)
                  Veranstaltungsdatenbank Vdb 0.1
                  1. gudn tach!

                    [komma oder kein komma]

                    Also beide Varianten sind nicht fehlerhaft.

                    richtig. und genau das ist gemeint mit "das komma ist da fakultativ".

                    Ich setze es, das Komma, übrigens vor "und", wenn "und" z.B. einen Nebensatz einleitet. Aber ich richte mich auch, bis auf eine Ausnahme (ß vs. ss), nach der alten Rechtschreibung (soweit ich die beherrsche).

                    "und" leitet normalerweise keine nebensaetze ein.
                    nach der alten regelung musste vor "und" ein komma gesetzt werden, wenn dadurch selbststaendige saetze verbunden wurden. vermutlich meinst du diese regel. die wird halt jetzt durch § 73 ausgehebelt.

                    Deswegen "Aber ich richte mich ... nach der alten Rechtschreibung".

                    ...und darauf bezog sich "die wird halt jetzt durch § 73 ausgehebelt"...

                    also nochmal:

                    in der alten rechtschreibung wurden durch "und" ebensowenig nebensaetze eingeleitet wie in der neuen. ;-)
                    nach der alten regelung musste vor "und" ein komma gesetzt werden, wenn dadurch selbststaendige saetze (keine nebensaetze) verbunden wurden. vermutlich meintest du diese alte regel, als du von "nebensaetzen" sprachst. die ist naemlich alt (also so, wie du es magst) und wird jetzt durch § 73 ausgehebelt.

                    prost
                    seth

                    1. ... selbst, wenn die beiden keine sein sollten.

                      Hallo

                      [komma oder kein komma]

                      Also beide Varianten sind nicht fehlerhaft.

                      richtig. und genau das ist gemeint mit "das komma ist da fakultativ".

                      Sag'n wir doch. :-)

                      prost

                      Hoch die Tassen!

                      Tschö, Auge

                      --
                      Die Musik drückt aus, was nicht gesagt werden kann und worüber es unmöglich ist zu schweigen.
                      (Victor Hugo)
                      Veranstaltungsdatenbank Vdb 0.1
      2. Tach.

        • mathematische formeln werden normalerweise direkt in einen satz eingebettet und nicht mit doppelpunkten abgetrennt. die einrueckung ist natuerlich richtig und wichtig, aber der text sollte fluessiger sein, z.b.
          "Die Wahrscheinlichkeit, dass ein Kommentar eine Menge Wörter w enthält[komma!] lässt sich unter der naiven Annahme, dass das Auftreten eines bestimmten Wortes unabhängig von dem Auftreten aller anderen Wörter ist[komma!] durch
            [formel]
          ausdruecken."

        Das ist Geschmackssache. Konstrukte wie das obige vermeide ich möglichst. Das letzte Wort im Satz ganz allein auf einer einzelnen Zeile ... unästhetisch. Wenn danach wirklich kein Text mehr folgt, stelle ich doch lieber die Formel ans Satzende; meinetwegen auch mit Doppelpunkt.

        Übrigens: Konjunktiv rock! ;)

        "Die Wahrscheinlichkeit, daß ein Kommentar eine Menge Wörter w enthält, läßt sich unter der naiven Annahme, das Auftreten eines bestimmten Wortes sei unabhängig vom Auftreten aller anderen Wörter, ..."

        • der begriff "bedingte wahrscheinlichkeit" sollte fallen und verlinkt werden.

        Sehe ich auch so. Darüber hinaus stelle ich fest, daß insgesamt gar nicht so recht darauf eingegangen wird, was das Bayestheorem hier überhaupt verloren hat. "So sieht es aus: [Formel] ... und dann den Quotienten für P(B|A) in die Bayesformel einsetzen" ist wirklich zu knapp. Eine ausführlichere umgangssprachliche Erläuterung (d. h. nicht in Formeln gegossen oder diese lediglich wiedergebend) deines Vorgehens kann sicher auch den ein oder anderen Mathefeind zum Weiterlesen animieren.

        • geschweifte klammern als meta-runde klammern sind out. an der tafel moegen sie zwar u.u. sinnvoll sein, aber getext sind sie eher zu vermeiden, weil sie schon andere bedeutungen haben, allen voran "menge". ich empfehle \bigl( und \bigr). mehr dazu siehe wikipedia hilfe:teX

        Um die Lesbarkeit noch weiter zu erhöhen, würde ich den Teil, der gar nicht in die Summe gehört, davor schreiben anstatt dahinter:

        [latex]
        \ln(P(Spam)) =
         (i-1) \bigl(
         \ln(N_{Ham}) - \ln(N_{Spam})
         \bigr)
         +
         \sum_{k=1}^{i}{ \bigl(
         \ln(N_{Spam,k}) - \ln(N_{Ham,k})
         \bigr) }
        [/latex]

        --
        Once is a mistake, twice is jazz.
        1. gudn tach!

          "Die Wahrscheinlichkeit, dass ein Kommentar eine Menge Wörter w enthält[komma!] lässt sich unter der naiven Annahme, dass das Auftreten eines bestimmten Wortes unabhängig von dem Auftreten aller anderen Wörter ist[komma!] durch
            [formel]
          ausdruecken."

          Das ist Geschmackssache.

          jein. in der literatur (sowohl buechern als auch papers) wird diese variante bevorzugt und als "besser" angesehen, wobei natuerlich auch stellenweise mal ein "dann gilt: [formel]" oder aehnliches nicht verboten ist.

          Konstrukte wie das obige vermeide ich möglichst. Das letzte Wort im Satz ganz allein auf einer einzelnen Zeile ... unästhetisch.

          wenn's nach diesem einzelnen wort fluessig weitergeht (z.b. mit auch einer weiteren abgesetzten formel), ist das aber gang und gaebe und in den augen der meisten setzer wohl nicht unaesthetisch.

          Wenn danach wirklich kein Text mehr folgt, stelle ich doch lieber die Formel ans Satzende; meinetwegen auch mit Doppelpunkt.

          ok, ich hatte mich zu undeutlich ausgedrueckt.
          die formel am satzende ist ok, sollte aber nicht durch sowas wie "[...], folgendermaßen schreiben: [formel]" abgestrennt werden.

          Übrigens: Konjunktiv rock! ;)

          ack!

          hat das hiesige latex einen bug?
          eigentlich sollte
            [latex]\bigl(\ln\bigr)[/latex]
          und
            [latex]\bigl(
            \ln
            \bigr)[/latex]
          im aussehen eigentlich ununterscheidbar sein.

          prost
          seth

          1. Tach.

            hat das hiesige latex einen bug?
            eigentlich sollte
              [latex]\bigl(\ln\bigr)[/latex]
            und
              [latex]\bigl(
              \ln
              \bigr)[/latex]
            im aussehen eigentlich ununterscheidbar sein.

            Das habe ich mich auch gefragt. Richtiges™ LaTeX baut allerdings keine BRs in eine Formel, wenn man diese im Quelltext über mehrere Zeilen verteilt. Also ist es vielleicht eher ein *Feature* des Plugins ...

            --
            Once is a mistake, twice is jazz.
    2. Hallo Forum,

      Tabelle filter_words
         word VARBINARY(50)
         -- Es ist gute Praxis, SQL-Schlüsselwörter groß zu schreiben, siehe z.B.
         -- MySQL-Handbuch

      Ich mag diese Praxis nicht, ich habe die ganze Zeit das Gefühl, dass meine SQL-Statements mich anschreien.

      -- Warum ausgerechnet VARBINARY, warum genau dieser Datentyp.

      Weil der Fall relevant ist, wenn ich varchar nehme kann ich nicht "Foo" und "foo" gleichzeitig in der Tabelle speichern.

      -- Begründe die 50.

      Relativ großes Maximum, mit dem man herumexperimentieren kann.

      -- die Angabe der Storage-Engine ist überflüssig, oder hast Du bestimmte
         -- Gründe ausgerechnet MyIsam zu verwenden?

      Ja, Performance. In meiner MySQL-Installation ist InnoDB voreingestellt, ich brauche aber weder Transaktionen noch referentielle Integrität, auch nicht wenn mehrere Benutzer gleichzeitig Trainingsdaten einfügen.

      Tabelle filter_stats
         Du schreibst in Deiner Signatur, dass Deine Klasse Texte kategorisieren
         kann. Darunter verstehe ich eine beliebige Anzahl von Kategorien. Deine
         Tabelle spiegelt das nicht wieder. Eine neue Kategorie bedeutet bei Dir
         eine neue Spalte. Das ist normalerweise ein Anzeichen eines ungünstig
         gewählten Tabellendesigns.

      Das ist mir bewusst, aber die Spamfilter-Klasse ist nicht die Text-Kategorisierer-Klasse.

      Der Text-Kategorisierer entstand bevor ich den Satz von Bayes anwenden konnte und verwendet ein krudes mathematisches Konstrukt, das in der nächsten Version ersetzt wird und kann beliebig viele Kategorien ohne Änderung der Tabellen verwalten, erzeugt aber ziemlich viel overhead.

      Der Spamfilter kann nur zwei Kategorien, aber dafür verbraucht er auch relativ wenig Speicherplatz.

      Dann füllst Du sie mit zwei Datensätzen. Viel einfacher hättest Du einfach
         den Initialinhalt der Tabelle hingeschrieben. Einfacher, verständlicher.
         Bei Deinem Design ist zudem der Spaltenname "name" ungünstig, weil
         aussagelos, gewählt. Inkonsequent und inkonsistent die beiden Datensätze:

      "lnum"   ist der (natürliche) Logarithmus der Anzahl der Kommentare
         "lwords" ist der (natürliche) Logarithmus der Anzahl der Wörter

      Fällt Dir etwas auf? Welchen Eintrag solltest Du treffender wählen?
         Inkonsequent der Datentyp: CHAR(5) wäre ausreichend und würde zudem
         Datensätze fester Länge ermöglichen, aber das nur am Rande.

      In dieser Tabelle sind Zeit ihres Lebens nur diese beiden Datensätze, die halt die Anzahl Wörter und die Anzahl Texte speichern. Wo genau ist jetzt das Problem?

      Wenn Du die Tabelle transponierst, dann werden daraus Spaltenüberschriften
         und Du brauchst Dir keinen Gedanken über einen beschreibenderen Namen zu
         machen :-) Ich weiß, dass das Konsequenzen für Deine ganze Klasse hat,
         aber das sollte machbar sein.

      Meinst du so eine Tabelle für die Statistiken?

        
      create table filter_stats (  
       id integer undigned auto_increment primary key,  
       category varchar(10) not null unique,  
       lnum float default 0,  
       lwords float default 0  
      );  
      
      

      Dein PHP-Code ist im Archiv, warum nicht auch Deine SQL-Statements?

      Die SQL-Statements sind im PHP-Code bzw. werden von ihm zusammengebaut, wozu brauche ich da noch gesonderte SQL-Statements?

      Ich hoffe, ich konnte Dir einige Anregungen geben, durch deren Umsetzung
      Dein Artikel zugänglicher wird - und somit auch Beachtung finden wird. Das
      hast Du sicherlich auch verdient.

      Deine Ausführungen zum Aufbau des Artikels werde ich zu Hause nochmal in aller Ruhe durchgehen und den Artikel überarbeiten.

      Gruß
      Alexander Brock

      1. Hallo Alexander,

        bitte entschuldige, dass ich mich wiederhole: Meiner Meinung nach solltest Du
        unbedingt anhand eines Beispiels das Vorgehen und die Wirkung des Spamfilters
        demonstrieren. Dein Artikel gibt darauf bisher leider keinen offensichtlichen Hinweis.
        Ganz besonders wichtig finde ich eine Erläuterung in einfachen Worten, vergleiche meine Anmerkung

        Hauptabschnitt Bayesfilter
           - Konzept des Bayestheorem in einfachen Worten
             (Nein, nicht die Mathematik)

        und ich zitiere aus Blaubarts Beitrag

        Sehe ich auch so. Darüber hinaus stelle ich fest, daß insgesamt gar nicht so recht darauf eingegangen wird, was das Bayestheorem hier überhaupt verloren hat. "So sieht es aus: [Formel] ... und dann den Quotienten für P(B|A) in die Bayesformel einsetzen" ist wirklich zu knapp. Eine ausführlichere umgangssprachliche Erläuterung (d. h. nicht in Formeln gegossen oder diese lediglich wiedergebend) deines Vorgehens kann sicher auch den ein oder anderen Mathefeind zum Weiterlesen animieren.

        der offensichtlich der gleichen Meinung ist. Ein Beispiel zu einer weiteren
        Verbesserung wäre, ich zitiere aus Deinem Artikelentwurf,

        <zitat>
            Wahrscheinlichkeit eines Ereignisses A, in diesem Fall dass ein Kommentar
            von einem Spammer stammt unter der Vorraussetzung dass vorher ein Ereignis B
            stattgefunden hat
        </zitat>

        dass Du Beispiele für dieses Ereignis B anführst, so wie Du dies für das Ereignis A gemacht hast.
        Einfache Tat, große Wirkung.

        zu meinem Abschnitt a) möchte ich noch anmerken, dass mir Änderungen, wie sie
        seth vorgeschlagen hat, angemessener erscheinen als meine.

        Ich möchte noch ein wenig auf Deine Antworten auf meine Fragen und Anregungen
        eingehen:

        -- Es ist gute Praxis, SQL-Schlüsselwörter groß zu schreiben, siehe z.B.
           -- MySQL-Handbuch

        Ich mag diese Praxis nicht, ich habe die ganze Zeit das Gefühl, dass meine SQL-Statements mich anschreien.

        ich mag diese Praxis, ganz besonders wenn keine Syntaxhervorhebung zur Verfügung steht :-)
        Ich schrieb früher auch die HTML-Tags groß.

        -- Warum ausgerechnet VARBINARY, warum genau dieser Datentyp.
        Weil der Fall relevant ist, wenn ich varchar nehme kann ich nicht "Foo" und "foo" gleichzeitig in der Tabelle speichern.

        Siehst Du, das ist ein gutes Beispiel dafür, was ich mit

        Warum _keine_ fertigen Statements? Es ist wichtiger, dass man versteht,
           welche Daten abgespeichert werden müssen. Das sind ja nicht besonders

        meine. Wo kann man in Deinem Artikel lesen, dass dieser Fall relevant ist? Das
        ist mir entgangen. Anderseits irrst Du, wenn Du glaubst, dass deswegen bei
        MySQL die Verwendung von VARBINARY zwingend erforderlich wäre.

        Selbstverständlich kann man auch beim Datentyp VARCHAR "Foo" und "foo" in
        unterschiedlichen Datensätzen der gleichen Spalte abspeichern, auch wenn diese
        Träger des Primärschlüssels ist. Bei MySQL benötigst Du lediglich noch das
        Schlüsselwort BINARY im CREATE-Statement. Somit gibt es (mindestens) zwei
        gleichwertige Wege, das gleiche Ziel zu erreichen.
        Das Ziel sollte im Vordergrund stehen, nicht der Weg dahin.

        Übrigens setzen laut betreffendem Handbuchabschnitt, beide Wege MySQL 4.1.2
        voraus. Du solltest Deinen Artikel dahingehend korrigieren.

        -- Begründe die 50.
        Relativ großes Maximum, mit dem man herumexperimentieren kann.

        Schreibe das:

        "Mit 50 Bytes Nutzspeicher können die fast alle Tokens problemlos abgespeichert werden. Experimentieren Sie mit dieser Grenze!"

        Wie handhabst Du zu lange Token? Bei Spalten variabler Länge dürftest D
        problemlos 200 Byte und mehr verwenden können, ohne dass die Tabelle
        signifikant umfangreicher würde. Der Speicherbedarf bei den Datentypen mit
        variablem Umfang richtet sich ja nach dem tatsächlichen Inhalt, nicht dem
        maximal möglichen.

        -- die Angabe der Storage-Engine ist überflüssig, oder hast Du bestimmte
           -- Gründe ausgerechnet MyIsam zu verwenden?
        Ja, Performance. In meiner MySQL-Installation ist InnoDB voreingestellt, ich brauche aber weder Transaktionen noch referentielle Integrität, auch nicht wenn mehrere Benutzer gleichzeitig Trainingsdaten einfügen.

        Wie groß ist der gemessene Performance-Unterschied der Datenbankzugriffe bei
        den beiden Storage-Engines? Ist das wirklich ein Flaschenhals? Wenn nein,
        fügt die Festlegung der Storage-Engine meiner Meinung nach eine überflüssige
        Information hinzu, die für das Verständnis der Anwendung nicht nützlich ist.
        Lass sie weg - und füge einen Satz zu möglicher Optimierung hinzu.

        Viel wichtiger als das SQL-Statement fände ich jedoch einfach eine
        Beispieltabelle mit ein paar realistischen Daten aus Deiner Praxis.
        Beispieldaten erleichern das Verständnis ungemein. Lies einfach ein paar
        Datenbankthreads hier im Forum(sarchiv).

        Eine neue Kategorie bedeutet bei Dir
           eine neue Spalte. Das ist normalerweise ein Anzeichen eines ungünstig
           gewählten Tabellendesigns.

        Das ist mir bewusst, aber die Spamfilter-Klasse ist nicht die Text-Kategorisierer-Klasse.

        Der Spamfilter kann nur zwei Kategorien, aber dafür verbraucht er auch relativ wenig Speicherplatz.

        Und dennoch ist Dein Tabellendesign falsch gewählt. Dies zeigt der wenig
        geeignete Spaltenname Deiner ersten Spalte.

        Dann füllst Du sie mit zwei Datensätzen. Viel einfacher hättest Du einfach
           den Initialinhalt der Tabelle hingeschrieben. Einfacher, verständlicher.

        Ich sollte dies dreifach unterstreichen.

        "lnum"   ist der (natürliche) Logarithmus der Anzahl der Kommentare
           "lwords" ist der (natürliche) Logarithmus der Anzahl der Wörter

        In dieser Tabelle sind Zeit ihres Lebens nur diese beiden Datensätze, die halt die Anzahl Wörter und die Anzahl Texte speichern. Wo genau ist jetzt das Problem?

        Ganz einfach. Du solltest statt dem aussagelosen "lnum" das angemessene
        "lcomments" verwenden. Es bietet sich an. Es drängt sich auf. Vernünftig
        und einheitlich gewählte Bezeichner erleichtern das Verständnis,
        erleichtern das Lesen von Code.

        Meinst du so eine Tabelle für die Statistiken?

        create table filter_stats (
        id integer undigned auto_increment primary key,
        category varchar(10) not null unique,
        lnum float default 0,
        lwords float default 0
        );

          
        So in etwa. Nur keine SQL-Statements, sondern Inhalt:  
          
        Die Statistiktabelle filter\_stats sieht unmittelbar nach dem Anlegen  
        wie folgt aus:  
          
        category | lcomments | lwords  
        \------------------------------  
        ham      |     0     |    0  
        spam     |     0     |    0  
          
        Diese Tabelle erklärt sich und ihren Aufbau besser als die drei (bzw. zwei)  
        dafür erforderlichen SQL-Statements.  
          
        Die Tabelle wird nie mehr als diese zwei Zeilen haben. Nur die Werte in  
        den Spalten lcomments und lwords verändern sich im Laufe der Zeit.  
          
        Dazu noch ein Beispiel für den Zustand nach dem Trainieren des Filters mit  
        einer angemessenen Beitragsanzahl. Welche das ist, wie die Zahlen aussehen,  
        untermauere mit Daten aus Deiner Praxis. Sowas finde ich anschaulich.  
          
        Zudem plädiere ich bei dieser Tabelle aus "Performancegründen" auf die  
        Verwendung von CHAR im Gegensatz zu VARCHAR. Datensätze gleicher Länge sind  
        vermutlich performanter zu lesen und zu schreiben. \*bg\* [1]  
          
        Zusammenfassend zur wirklich kleinen Datenbank:  
        Gib an, was für das Speichern relevant ist. Überlasse das Wie dem  
        interessierten Leser (zur Übung oder zum Nachlesen im Code).  
          
        Derzeit hast Du außerdem noch einen Syntaxfehler im SQL-Code:  
          
        ~~~sql
          
        insert ignore into filter_words (word)  
         values("foo", "bar");  
        
        

        Hier fehlen eine schließende und eine öffnende Klammer:

        • Halte Dir bitte beim Lesen die Ohren zu :-) -
          
        INSERT IGNORE INTO filter_words  
            (word)  
        VALUES  
            ("foo"),  
            ("bar");  
        
        

        Bitte beachte seths und Blaubarts Vorschläge zur Kommasetzung und ganz
        besonders zum Aufteilen mehrteiliger Sätze in Einzelsätze (durch Punkt
        getrennt). Ich neige ebenfalls zu diesen unnötig langen Sätze. Diese
        sind nicht gut lesbar. Halte es daher mit Tucholsky:

        "Hauptsätze, Hauptsätze, Hauptsätze."

        und mit mir:

        "Beispiele, Beispiele, Beispiele."

        Freundliche Grüße

        Vinzenz

        [1] Bitte interpretiere das folgendermaßen:
            Ich halte dies für genauso unwichtig wie die Wahl der Storage-Engine.
            Um nicht zu relativieren: ich halte beides für unwichtig.

  4. gudn tach!

    momentan steht da

    Sei [latex]N_C[/latex] die Anzahl der Kommentare in der Kategorie [latex]C[/latex] und [latex]N_{C,i}[/latex] die Häufigkeit des Wortes [latex]i[/latex] in den Kommentaren der Kategorie [latex]C[/latex], dann ist die Wahrscheinlichkeit, dass ein Text der Kategorie [latex]C[/latex] das Wort [latex]i[/latex] enthält:

    [latex]P(C,i)=\frac{N_{C,i}}{N_C}[/latex]
    (das "=" fehlt im original immer noch.)

    das ist imho missverstaendlich oder falsch. richtig waere z.b.
    [latex]N_C[/latex] = Anzahl der Kommentare in der Kategorie [latex]C[/latex],
    [latex]N_{C,i}[/latex] = Anzahl der Kommentare der Kategorie [latex]C[/latex], die mind. ein mal das wort [latex]i[/latex] enthaelt.

    unter "haeufigkeit des wortes [latex]i[/latex]" verstehe ich eigentlich die anzahl aller vorkommnisse des wortes [latex]i[/latex]. beispiel:
      c_1="hulla hulla hulla!"
      c_2="hulla, bolla bolla."

    anzahl der kommentare = 2,
    haeufigkeit des wortes "hulla" = 4. (dann wuerde aber die formel keinen sinn machen.)

    anzahl der kommentare, die das wort "hulla" enthalten = 2. P=1, passt. aber meintest du das denn auch? ich verstehe deine notation nicht.
    [latex]P(C,i)[/latex] waere afais die wahrscheinlichkeit, dass ein kommentar der kategorie [latex]C[/latex] angehoert und das wort [latex]i[/latex] enthaelt.

    die erwaehnte "Wahrscheinlichkeit, dass ein Text der Kategorie [latex]C[/latex] das Wort [latex]i[/latex] enthält", waere dagegen eher [latex]P(i|C)[/latex] oder [latex]P_C(i)[/latex] oder sowas. sonst kaeme ja keine gueltige dichte heraus.

    danach schreibst du's ja auch als bedingte wahrscheinlichkeit
      [latex]P(w_1, w_2,\dotsc,w_n|C),[/latex]
    wie ich's eher erwartet haette.

    bzgl. der nachteile der konventionellen bayes-spam-filter habe ich eben noch zwei paper ergoogelt, die mit hilfe von HMMs arbeiten und auf den ersten blick recht vielversprechend aussahen:
    Spam Deobfuscation using a Hidden Markov Model
    Dynamically Weighted Hidden Markov Model for Spam Deobfuscation
    wenigstens die existenz solcher dinge sollten bei dir imho auch erwaehnt werden.

    prost
    seth

    1. Hallo seth,

      Ich habe die Formeln ausgetauscht und die Formulierung deutlicher gemacht.

      bzgl. der nachteile der konventionellen bayes-spam-filter habe ich eben noch zwei paper ergoogelt, die mit hilfe von HMMs arbeiten und auf den ersten blick recht vielversprechend aussahen:
      Spam Deobfuscation using a Hidden Markov Model
      Dynamically Weighted Hidden Markov Model for Spam Deobfuscation

      Ich habe das Problem bei meinen E-Mails nicht, wahrscheinlich weil mein Filter mittlerweile alle Variationen von viagra etc. kennt.

      Der Weblog-Spam ist im Moment noch viel zu primitiv für solche Spielereien, den erwischt völlig problemlos.

      wenigstens die existenz solcher dinge sollten bei dir imho auch erwaehnt werden.

      Richtig, ich bau das noch ein.

      Gruß
      Alexander Brock

      1. gudn tach!

        Ich habe die Formeln ausgetauscht und die Formulierung deutlicher gemacht.

        ok, der konsistenz halber wuerde ich (es wurde ja bereits angesprochen), die "i"s ersetzen, und zwar statt P(i|C) gleich P(w_i|C); das "i" danach wuerde ich durch "n" ersetzen. dann wuerde ich noch die AND-zeichen, die ja nicht jedem gelaeufig sind, durch kommas ersetzen; in der literatur werden afaik auch meist eher kommas oder mengen-schnitt-symbole bevorzugt, also
        [latex]P(w_1,\dotsc,w_n|C)=P(w_1|C)\dotsm P(w_n|C)=\prod_{k=1}^n \frac{N_{C,k}}{N_C}.[/latex]

        und im text danach wuerde ich die formulierung auch noch aendern:
        "Lies: Die Wahrscheinlichkeit, dass ein Kommentar der Kategorie [latex]C[/latex] die Wörter [latex]w_2, w_2, \dotsc, w_n[/latex] enthält[KOMMA] ist gleich dem Produkt aller oben beschriebenen Einzelwahrscheinlichkeiten."

        und weiter

        "Diese Wahrscheinlichkeit berechnet man mit den Wörtern eines gerade eingetroffenen Kommentars sowohl für die Kategorie Ham, also erwünschte Kommentare[KOMMA] als auch für die Kategorie Spam."

        soweit ok; aber den abschnitt

        "Den Quotienten setzt man als P(B|A) in die Bayesformel ein und erhält die Formel für die Spam-Wahrscheinlichkeit des neuen Textes: [...]"

        solltest du naeher erlaeutern.

        prost
        seth

        1. Hallo Forum,

          Die Formeln habe ich umgebaut.

          "Den Quotienten setzt man als P(B|A) in die Bayesformel ein und erhält die Formel für die Spam-Wahrscheinlichkeit des neuen Textes: [...]"

          solltest du naeher erlaeutern.

          Ich habe den Absatz jetzt umgebaut, um nochmal zu verdeutlichen,
          dass man die bedingte Wahrscheinlichkeit erst umkehren muss,
          um zuverlässige Ergebnisse zu erzielen.

          Gruß
          Alexander Brock

          1. gudn tach!

            "Den Quotienten setzt man als P(B|A) in die Bayesformel ein und erhält die Formel für die Spam-Wahrscheinlichkeit des neuen Textes: [...]"

            solltest du naeher erlaeutern.

            Ich habe den Absatz jetzt umgebaut, um nochmal zu verdeutlichen,
            dass man die bedingte Wahrscheinlichkeit erst umkehren muss,
            um zuverlässige Ergebnisse zu erzielen.

            soweit so gut, aber ich finde immer noch, dass nicht klar wird, warum  \frac{\prod...}{\prod...} = P(B|A) sein soll.
            nach der beschreibung oben drueber vermutet man, dass A das ereignis "der neue kommentar ist aus der kategorie spam" und B das ereignis "das wort w_i kommt (oder die woerter w_1,\dotsc,w_n kommen) im neuen kommentar vor" sei. jedoch waere dann erstmal nicht klar, weshalb P(B|A) ein quotient sein soll.
            das sollte besser herausgestellt werden.

            prost
            seth

            1. Hallo Forum,

              soweit so gut, aber ich finde immer noch, dass nicht klar wird, warum  \frac{\prod...}{\prod...} = P(B|A) sein soll.
              nach der beschreibung oben drueber vermutet man, dass A das ereignis "der neue kommentar ist aus der kategorie spam" und B das ereignis "das wort w_i kommt (oder die woerter w_1,\dotsc,w_n kommen) im neuen kommentar vor" sei. jedoch waere dann erstmal nicht klar, weshalb P(B|A) ein quotient sein soll.
              das sollte besser herausgestellt werden.

              Ich hab den Absatz nochmal umgeschrieben.

              Gruß
              Alexander Brock

              1. gudn tach!

                soweit so gut, aber ich finde immer noch, dass nicht klar wird, warum  \frac{\prod...}{\prod...} = P(B|A) sein soll.
                nach der beschreibung oben drueber vermutet man, dass A das ereignis "der neue kommentar ist aus der kategorie spam" und B das ereignis "das wort w_i kommt (oder die woerter w_1,\dotsc,w_n kommen) im neuen kommentar vor" sei. jedoch waere dann erstmal nicht klar, weshalb P(B|A) ein quotient sein soll.
                das sollte besser herausgestellt werden.

                Ich hab den Absatz nochmal umgeschrieben.

                hmm, imho wird dadurch das verstaendnisproblem noch nicht geloest. Vinzenz hat es auch schon mal kurz angesprochen: das ereignis B sollte explizit kurz beschrieben werden, dann waere schon etwas geholfen.
                aber warum \frac{\prod...}{\prod...} = P(B|A) gilt, ist dann immer noch offen und P(Spam) faellt so ein bissl vom himmel.

                prost
                seth

                1. Hallo Forum,

                  hmm, imho wird dadurch das verstaendnisproblem noch nicht geloest. Vinzenz hat es auch schon mal kurz angesprochen: das ereignis B sollte explizit kurz beschrieben werden, dann waere schon etwas geholfen.
                  aber warum \frac{\prod...}{\prod...} = P(B|A) gilt, ist dann immer noch offen und P(Spam) faellt so ein bissl vom himmel.

                  Ich habe das ganze nochmal hergeleitet und komme auf leicht andere Gleichungen (keine Ahnung, was da schief gelaufen ist).

                  Ist das jetzt besser verständlich?

                  Gruß
                  Alexander Brock

                  1. gudn tach!

                    aber warum \frac{\prod...}{\prod...} = P(B|A) gilt, ist dann immer noch offen und P(Spam) faellt so ein bissl vom himmel.

                    Ich habe das ganze nochmal hergeleitet und komme auf leicht andere Gleichungen [...]

                    das beruhigt mich, denn kam auch auf was anderes. aber irgendwie scheinen die formeln immer noch nicht zu stimmen.
                    ich kuerze im folgenden mal w_1,\dotsc,w_n durch W ab.
                    nach bayes gilt doch erst mal nur
                    [latex]P(\text{Spam}|W) = \frac{P(W|\text{Spam})P(\text{Spam})}{P(W)}[/latex]
                    und
                    [latex]P(\text{Ham}|W) = \frac{P(W|\text{Ham})P(\text{Ham})}{P(W)}.[/latex]

                    durch die quotiontenbildung kuerzt sich dann das P(W) heraus und man erhaelt
                    [latex]
                    \frac{P(\text{Spam}|W)}{P(\text{Ham}|W)} = \frac{P(W|\text{Spam})P(\text{Spam})}{P(W|\text{Ham})P(\text{Ham})}
                    [/latex]
                    und damit
                    [latex]
                    \frac{P(\text{Spam}|W)}{P(\text{Ham}|W)} = \frac{P(W|\text{Spam})N_\text{Spam}}{P(W|\text{Ham})N_\text{Ham}}
                    [/latex].

                    wie du damit weiter machen willst, musst du nun selbst wissen.

                    prost
                    seth

                    1. Hallo seth,

                      [latex]P(\text{Spam}|W) = \frac{P(W|\text{Spam})P(\text{Spam})}{P(W)}[/latex]
                      und
                      [latex]P(\text{Ham}|W) = \frac{P(W|\text{Ham})P(\text{Ham})}{P(W)}.[/latex]

                      Richtig, ich hatte blöderweise P(Ham) und P(W) vertauscht.
                      Jetzt kommen auch wieder die alten Formeln raus, nur der Rechenweg ist ein bischen anders.

                      Ist das jetzt allgemein verständlich?

                      Gruß
                      Alexander Brock

                      1. gudn tach!

                        Richtig, ich hatte blöderweise P(Ham) und P(W) vertauscht.
                        Jetzt kommen auch wieder die alten Formeln raus, nur der Rechenweg ist ein bischen anders.

                        ok, dann war bloss die bezeichnung P(Spam) irrefuehrend.

                        jetzt kann man's schon verstehen, aber es ist noch nicht ganz richtig.

                        "Zuletzt wird die Spam- mit der Ham-Wahrscheinlichkeit verglichen indem der Quotient gebildet wird. Man erhält einen vergleichswert V zwischen null und eins, den man als Spam-Wahrscheinlichkeit verwenden kann."

                        V ist aus dem intervall [0,\inf), nicht nur aus dem intervall [0,1].
                        bei V>1 ist die wahrscheinlichkeit groesser, dass es spam ist.
                        bei V<1 ist die wahrscheinlichkeit groesser, dass es ham ist.
                        V=1 macht einen nicht schlauer.

                        und noch zwei kleinigkeiten:
                        im satz "Jetzt wird für beide Kategorien die Umkehrung der bedingten Wahrscheinlichkeit berechnet:" wuerde ich noch einfuegen "mittels des bayestheorems".

                        und du koenntest noch mal irgendwo explizit anmerken, dass das von dir beschriebene modell eben einige sachen ausser acht laesst, z.b. wird per physiker-induktion ("es gilt fuer 1, es gilt fuer 2, also gilt's fuer alle.") von der kategorie-verteilung der _bisher_ eingegangenen e-mails auf die verteilung der _zukuenftig_ eingehenden geschlossen.

                        prost
                        seth

                        1. Hallo Forum,

                          V ist aus dem intervall [0,\inf), nicht nur aus dem intervall [0,1].
                          bei V>1 ist die wahrscheinlichkeit groesser, dass es spam ist.
                          bei V<1 ist die wahrscheinlichkeit groesser, dass es ham ist.
                          V=1 macht einen nicht schlauer.

                          Ich hab das jetzt ausprobiert, die allermeisten Werte liegen zwischen null und eins. Alle Ham-Mails haben einen Wert von 0 oder 0,04.

                          Ich berechne also für meine Test-Daten die Wahrscheinlichkeiten und lade das hundertfachefache gerundet als Integer in zwei Arrays, eines für Ham und eines für Spam und bekomme von array_count_values die Verteilung.

                          Da kommt dann in zweierlei Hinsicht Müll raus:
                          Erstens kann (int)round(100*exp($irgendwas)) niemals eine negative zahl ergeben (dachte ich zumindest).
                          Zweitens kommt die Spam-Wahrscheinlichkeit 0 in den Spams angeblich in 99% aller Fälle vor. Das widerspricht aber meinem Ergebnis von 1.4% false negative.

                          Ich habe den Quellcode meiner Test-Suite mal gepostet:
                          http://nopaste.php-q.net/277083

                          Spam Stats:
                          Array
                          (
                              [-1930988544] => 1
                              [-1903352726] => 1
                              [-1882712973] => 1
                              [-1781909097] => 1
                              [-1680121282] => 1
                              [-1275730988] => 1
                              [-1144230406] => 1
                              [-1129315584] => 1
                              [-972717902] => 1
                              [-798831446] => 1
                              [-703784146] => 1
                              [-541185398] => 1
                              [-325038144] => 1
                              [-71680000] => 1
                              [0] => 2034
                              [1] => 2
                              [8] => 1
                              [39] => 1
                              [213] => 1
                              [276] => 1
                              [217644] => 1
                              [230607] => 1
                              [651551] => 1
                              [12069391] => 1
                              [17116193] => 1
                              [136575566] => 1
                              [204607518] => 1
                              [389060608] => 1
                              [754195036] => 1
                              [881556480] => 1
                              [1058403544] => 1
                              [1108799631] => 1
                              [1255696640] => 1
                              [1444003672] => 1
                              [1559565312] => 1
                              [1634016256] => 1
                              [1665004544] => 1
                              [1670903808] => 1
                              [1928051234] => 1
                              [1967273984] => 1
                              [2081923517] => 1
                          )
                          Ham Stats:
                          Array
                          (
                              [0] => 1365
                              [4] => 1
                          )

                          Gruß
                          Alexander Brock

                          1. gudn tach!

                            Da kommt dann in zweierlei Hinsicht Müll raus:
                            Erstens kann (int)round(100*exp($irgendwas)) niemals eine negative zahl ergeben (dachte ich zumindest).
                            Zweitens kommt die Spam-Wahrscheinlichkeit 0 in den Spams angeblich in 99% aller Fälle vor.

                            exp(x) waechst *trommelwirbel* exponentiell. ;-)
                            durch die konvertierung in int, werden zahlen, die groesser als 2^31-1 sind, nicht mehr so verwaltet, wie man's gerne als normaler mensch haette.
                            siehe http://php.net/int.
                            in deinem fall genuegt es schon, wenn $irgendwas groesser als ln((2^31-1)/100) ist, also z.b. 17. ab dann kommt nie wieder das richtige ergebnis heraus, sondern irgendeine zahl im int-bereich.

                            loesungsansaetze:

                            1. vermeide grosse zahlen (z.b. einfach durch weglassen von exp, ist eh bloss eine skalierung),
                            2. vermeide int oder
                            3. binde ein bignum-paket ein (laaaangsaaaam)

                            wenn du exp weglaesst, macht das ja nix, dann rechnest du eben mit ln(V) und achte darauf, dass der ln nicht auf V angewendet wird, wenn V=0 ist.
                            das wuerde bedeuten:

                            ln(V) ist aus dem intervall (-\infty,\infty), also ganz R.
                            bei ln(V)>0 ist die wahrscheinlichkeit groesser, dass es spam ist.
                            bei ln(V)<0 ist die wahrscheinlichkeit groesser, dass es ham ist.
                            ln(V)=0 macht einen nicht schlauer.

                            eine ganz andere moeglichkeit waere, nicht den quotienten, sondern die differenz zu bilden, dann drueckt man sich zumindest vor grossen zahlen, da V somit nur im intervall [-1,1] liegen kann. ob das praktikabl ist, weiss ich allerdings aus dem stegreif nicht.

                            prost
                            seth

                            1. Hallo Forum,

                              exp(x) waechst *trommelwirbel* exponentiell. ;-)

                              nee, echt?

                              1. binde ein bignum-paket ein (laaaangsaaaam)

                              Das habe ich schon mitbekommen, ich habe das ganze mal mit bcmath auf 5000 Stellen hinter dem Komma rechnen lassen. Nachdem ich dann festgestellt hatte, dass das langsamer als alle SQL-Abfragen zusammen ist habe ich auf die Logarithmen-Formeln umgebaut.

                              wenn du exp weglaesst, macht das ja nix, dann rechnest du eben mit ln(V) und achte darauf, dass der ln nicht auf V angewendet wird, wenn V=0 ist.

                              Das kann nicht vorkommen, die ganze Software rechnet nur noch mit Summen von Logarithmen *g*

                              das wuerde bedeuten:

                              ln(V) ist aus dem intervall (-\infty,\infty), also ganz R.
                              bei ln(V)>0 ist die wahrscheinlichkeit groesser, dass es spam ist.
                              bei ln(V)<0 ist die wahrscheinlichkeit groesser, dass es ham ist.
                              ln(V)=0 macht einen nicht schlauer.

                              Genau, ich habe den Artikel dahingehend überarbeitet und die Software umgebaut.

                              eine ganz andere moeglichkeit waere, nicht den quotienten, sondern die differenz zu bilden, dann drueckt man sich zumindest vor grossen zahlen, da V somit nur im intervall [-1,1] liegen kann. ob das praktikabl ist, weiss ich allerdings aus dem stegreif nicht.

                              Das ergibt wieder diese hässlich kleinen Zahlen, die ich vermeiden wollte und für die man wieder bcmath bräuchte.

                              Gruß
                              Alexander Brock

  5. Hallo,

    Vielen Dank für die sehr ausführliche Kritik.
    Ich habe jetzt endlich die Zeit und Ruhe gefunden das ganze Ding mal richtig zu überarbeiten.

    Bayesscher Kommentarspam-Filter

    1. Mehr Hauptsätze, weniger Nebensätze
    2. Genauere Erklärung des Bayestheorems
    3. Tabellen anstelle von SQL-Statements
    4. Genauere Erklärung der Vorgehensweise
    5. Beschreibung der mathematischen Umformungen
    6. Bessere Kategorien-Tabelle (-> neue Software)
    7. Beispiel-Daten

    Habe ich Kritikpunkte übersehen?
    Habe ich Kritik unzureichend umgesetzt?
    Gibt es noch weitere Kritik?

    Gruß
    Alexander Brock

    1. Moin!

      Bayesscher Kommentarspam-Filter

      1. Genauere Erklärung des Bayestheorems

      In der jetzigen Version hab ich sofort verstanden, worum es geht, ohne groß vorher Statistik noch einmal nachzulesen :-)

      1. Tabellen anstelle von SQL-Statements

      Ich fand die SQL-Statements sehr hilfreich, schließlich stellten die doch die SQL-seitige Implementierung des Spamfilters da, oder?

      1. Genauere Erklärung der Vorgehensweise

      Siehe 3.

      Gibt es noch weitere Kritik?

      Ja: Einige Formeln sind „broken“ (Klammern beginnen mit '{' und enden mit ')'):


      sowie

      Viele Grüße,
      Robert

      1. Hallo Forum,

        1. Genauere Erklärung des Bayestheorems

        In der jetzigen Version hab ich sofort verstanden, worum es geht, ohne groß vorher Statistik noch einmal nachzulesen :-)

        Gut :-)

        1. Tabellen anstelle von SQL-Statements

        Ich fand die SQL-Statements sehr hilfreich, schließlich stellten die doch die SQL-seitige Implementierung des Spamfilters da, oder?

        Ja. Ich habe jetzt beides in die Tabellenzellen geschrieben.

        1. Genauere Erklärung der Vorgehensweise

        Siehe 3.

        Gibt es noch weitere Kritik?

        Ja: Einige Formeln sind „broken“ (Klammern beginnen mit '{' und enden mit ')'):


        sowie

        Also ich kann an der Klammerung nichts falsches finden, außer die angesprochene Problematik wegen der Bedeutung geschweifter Klammern.

        Ich checke jetzt aber neue Formeln mit unterschiedlich großen normalen Klammern ein.

        Gruß
        Alexander Brock

        1. Moin!


          sowie

          Also ich kann an der Klammerung nichts falsches finden, außer die angesprochene Problematik wegen der Bedeutung geschweifter Klammern.

          Wenn man sich die Formel genau anschaut, stellt man fest, dass du Recht hast, aber ich würde aus Gründen der Konsistenz eine Art der (äußeren) Klammerung verwenden, das verwirrt (mich, wen noch?) sonst nur.

          Viele Grüße,
          Robert

          1. Hallo Robert,


            sowie

            Wenn man sich die Formel genau anschaut, stellt man fest, dass du Recht hast, aber ich würde aus Gründen der Konsistenz eine Art der (äußeren) Klammerung verwenden, das verwirrt (mich, wen noch?) sonst nur.

            Ich habe jetzt in beiden Formeln die Summe ans Ende gestellt, so können eigentlich keine Missverständnisse aufkommen, oder?

            Gruß
            Alexander Brock

            1. gudn tach!

              Wenn man sich die Formel genau anschaut, stellt man fest, dass du Recht hast, aber ich würde aus Gründen der Konsistenz eine Art der (äußeren) Klammerung verwenden, das verwirrt (mich, wen noch?) sonst nur.

              Ich habe jetzt in beiden Formeln die Summe ans Ende gestellt, so können eigentlich keine Missverständnisse aufkommen, oder?

              es gibt neben \Big und \Bigg auch \big und \bigg, siehe wp hilfe:tex. normalerweise geht man, wenn moeglich, in kleinen schritten mit der klammergroesse nach oben und faehrt nicht gleich die haemmer auf.

              und noch eine kleinigkeit, die man vermutlich als geschmackssache einstufen kann: texte wie "spam" oder "ham" werden eigentlich auch als \text gesetzt, z.b. N_\text{Ham}.

              prost
              seth

              1. Hallo Forum,

                es gibt neben \Big und \Bigg auch \big und \bigg, siehe wp hilfe:tex. normalerweise geht man, wenn moeglich, in kleinen schritten mit der klammergroesse nach oben und faehrt nicht gleich die haemmer auf.

                Ich finde die Formeln aktuell leserlicher als mit kleineren Abstufungen.
                Die Unterteilung drängt sich dem Auge auf und je weniger der Leser damit beschäftigt ist, Klammer-Größen zu vergleichen, umso besser kann er sich auf den Inhalt konzentrieren.

                und noch eine kleinigkeit, die man vermutlich als geschmackssache einstufen kann: texte wie "spam" oder "ham" werden eigentlich auch als \text gesetzt, z.b. N_\text{Ham}.

                Coole Sache, nicht-krusiv sind die Indizes auch leserlicher.
                Nur die Formeln werden immer uncooler mit \color und \text.

                Gruß
                Alexander Brock

                1. gudn tach!

                  [klammern]

                  Ich finde die Formeln aktuell leserlicher als mit kleineren Abstufungen.
                  Die Unterteilung drängt sich dem Auge auf und je weniger der Leser damit beschäftigt ist, Klammer-Größen zu vergleichen, umso besser kann er sich auf den Inhalt konzentrieren.

                  mag sein, dass das bei leuten, die nicht so haeufig mit formeln zu tun haben, sogar stimmt, weiss ich nicht.
                  die grossen klammern sehen halt bloss nicht so huebsch aus. ;-)

                  und noch eine kleinigkeit, die man vermutlich als geschmackssache einstufen kann: texte wie "spam" oder "ham" werden eigentlich auch als \text gesetzt, z.b. N_\text{Ham}.

                  Coole Sache, nicht-krusiv sind die Indizes auch leserlicher.

                  jetzt muss ich aber noch mal einhaken. nur der text sollte als text ausgezeichnet werden, d.h. das "k" in N_{\text{Ham}, k} sollte _nicht_ als text gesetzt werden.

                  Nur die Formeln werden immer uncooler mit \color und \text.

                  ?

                  prost
                  seth

                  1. Hallo Forum,

                    mag sein, dass das bei leuten, die nicht so haeufig mit formeln zu tun haben, sogar stimmt, weiss ich nicht.

                    Ich hatte Probleme, und ich habe dauernd mit Formeln zu tun.
                    Kann aber auch sein, dass das an meinen Augen liegt.

                    die grossen klammern sehen halt bloss nicht so huebsch aus. ;-)

                    Da bin ich anderer Meinung.

                    und noch eine kleinigkeit, die man vermutlich als geschmackssache einstufen kann: texte wie "spam" oder "ham" werden eigentlich auch als \text gesetzt, z.b. N_\text{Ham}.

                    Coole Sache, nicht-krusiv sind die Indizes auch leserlicher.

                    jetzt muss ich aber noch mal einhaken. nur der text sollte als text ausgezeichnet werden, d.h. das "k" in N_{\text{Ham}, k} sollte _nicht_ als text gesetzt werden.

                    Achso

                    Nur die Formeln werden immer uncooler mit \color und \text.

                    ?

                    Die Formeln werden immer unübersichtlicher, mit der letzten Änderung ist schon wieder eine Klammern pro N_{Spam, k} hinzugekommen.

                    Gruß
                    Alexander Brock

                  2. Hi,

                    jetzt muss ich aber noch mal einhaken. nur der text sollte als text ausgezeichnet werden, d.h. das "k" in N_{\text{Ham}, k} sollte _nicht_ als text gesetzt werden.

                    das ist AFAIR sogar in einer DIN-Norm festgehalten. Grobe Regel: Variablen werden kursiv gesetzt (also auch Laufindizes), beschreibende oder benennende Texte – ebenso wie mathematische Funktionen (cos, ln, ...) – in Steilschrift.

                    Schönen Sonntag noch!
                    O'Brien

                    --
                    Frank und Buster: "Heya, wir sind hier um zu helfen!"
    2. Hallihallo!

      Hey, nach dem Artikel habe ich schon fast verstanden, wie die Theorie dahinter aussieht! Und das, obwohl ich mit Stochastik schon seit jeher auf Kriegsfuss stehe...

      Mir sind beim Lesen Deines Artikels nur drei Kleinigkeiten aufgefallen:

      1. Abschnitt "Konzepte von Spamfiltern", Absatz 9:
            "Der Kommentartext selbst enthält aber oft keine oder nur ein oder zwei URLs enthält."
           -> 2mal "enthält"...
      2. In der Herleitung, direkt unter dem ersten Produkt:
           "ist gleich das Produkt aller aller Einzelwahrscheinlichkeiten."
           -> das "aller" ist doppelt
      3. In der Erklärung Deiner Klasse:
        Ich weiß als Leser jetzt, wie ich händisch einen Text in eine der beiden Kategorien einordnen kann.
        Aber wie frage ich die Klasse, zu welcher Kategorie ein Text wahrscheinlich gehört?
        Ein kleiner Satz würde da IMHO reichen. So, wie es jetzt da steht, kann der Verdacht aufkommen, daß Deine Klasse eher Statistik über die manuelle Sortierung führt, mit dieser Statistik aber im Endeffekt nicht "selbst" arbeitet. Ich hoffe, ich habe mich halbwegs verständlich ausgedrückt...

      Alles in Allem gefällt mir der Artikel. Schwere Kost, fast leicht verdaulich :)

      Viele liebe Grüße,
      Der Dicki

      1. Hallo Forum,

        Mir sind beim Lesen Deines Artikels nur drei Kleinigkeiten aufgefallen:
        [...]

        Danke, die habe ich verbessert/ergänzt :-)

        Gruß
        Alexander Brock

    3. Hallo Alexander,

      Der Artikel an sich gefällt mir gut, nur ein paar Anmerkungen zu Deiner Beispielimplementation ganz am Ende:

      - Du solltest bereits im Artikel erwähnen, dass Deine Code unter der LGPL
         steht und ganz kurz anreißen, was das für den Autor von Software heißt.
         (Mit ein paar wenigen Ausnahmen sind alle Beispiele bei SELFHTML aktuell
         Public Domain - ich habe nichts dagegen, dass Du die LGPL verwendest,
         allerdings sollte das den Leuten auch klar gemacht werden)
       - Es wäre schön, wenn Du ein paar eindeutige Bezeichnerkonventionen
         verwenden würdest, ich zähle nämlich drei verschiedene Arten von
         Methodenbezeichnern:
            * addHam <- 1. Wort klein, 2. Wort groß
            * addwords <- Beide Wörter klein, nicht getrennt
            * get_ranks <- Beide Wörter klein, durch Unterstrich getrennt
       - Ein Space zur Einrückung? Kann sein, dass das für Dich besser ist, aber
         ich kenne eigentlich sonst _niemanden_, der so wenig einrückt. Nimm Tabs
         (dann kann sich's jeder selbst einstellen) oder zumindest 2 Spaces. Ich
         persönlich empfinde 1 Space nämlich als sehr unübersichtlich und die
         großen Einrückungsdiskussionen drehen sich eigentlich immer um Tab vs.
         2 Spaces vs. 4 Spaces vs. 8 Spaces - 1 Space habe ich noch nie gesehen.
       - Mach öfters mal ein paar Leerzeilen, das lockert den Code auf.
       - Ein paar mehr Inline-Kommentare wären nett (ich meine keine Docblocks,
         sondern an besonders wichtigen Stellen kommentare, was genau dort
         geschieht / warum das so passiert)
       - Es ist in meinen Augen sehr verwirrend, dass Du die eine Spalte in Deiner
         Beispielimplementierung ln genannt hast - denn das ist gleichzeitig
         eine MySQL-Funktion, insbs. lustig wird's dann bei sowas wie
            set ln = ln(... + ln)
         und ähnlichem. Benenne die Spalte sinnvollerweise um (z.B. ln_prob oder
         sowas).
       - »dbwrapper« ist in meinen Augen kein guter Name für eine von der Klasse
         »mysql« abgeleiteten Klasse - zumal der Name überhaupt nicht gut
         beschreibt, wofür die Klasse da ist.

      Viele Grüße,
      Christian

      --
      "I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone." - Bjarne Stroustrup
      1. Hallo Christian,

        • Du solltest bereits im Artikel erwähnen, dass Deine Code unter der LGPL
             steht und ganz kurz anreißen, was das für den Autor von Software heißt. [...]

        [x] done

        • Es wäre schön, wenn Du ein paar eindeutige Bezeichnerkonventionen
             verwenden würdest, [...]

        [x] done

        • Ein Space zur Einrückung? Kann sein, dass das für Dich besser ist, aber
             ich kenne eigentlich sonst _niemanden_, der so wenig einrückt. Nimm Tabs
             (dann kann sich's jeder selbst einstellen) oder zumindest 2 Spaces. Ich
             persönlich empfinde 1 Space nämlich als sehr unübersichtlich und die
             großen Einrückungsdiskussionen drehen sich eigentlich immer um Tab vs.
             2 Spaces vs. 4 Spaces vs. 8 Spaces - 1 Space habe ich noch nie gesehen.

        Ich mag weder Tabulatoren, die sind so umständlich zu tippen, noch mehr als ein Leerzeichen, das ist noch umständlicher.

        • Mach öfters mal ein paar Leerzeilen, das lockert den Code auf.
        • Ein paar mehr Inline-Kommentare wären nett (ich meine keine Docblocks,
             sondern an besonders wichtigen Stellen kommentare, was genau dort
             geschieht / warum das so passiert)

        [x] done

        • Es ist in meinen Augen sehr verwirrend, dass Du die eine Spalte in Deiner
             Beispielimplementierung ln genannt hast - denn das ist gleichzeitig
             eine MySQL-Funktion, insbs. lustig wird's dann bei sowas wie
                set ln = ln(... + ln)
             und ähnlichem. Benenne die Spalte sinnvollerweise um (z.B. ln_prob oder
             sowas).

        [x] done

        • »dbwrapper« ist in meinen Augen kein guter Name für eine von der Klasse
             »mysql« abgeleiteten Klasse - zumal der Name überhaupt nicht gut
             beschreibt, wofür die Klasse da ist.

        Ich habe die Klassen jetzt in mysql_connector und v_spam_filter_database umbenannt.

        Gruß
        Alexander Brock

        1. Hallo Alexander,

          • Ein Space zur Einrückung? Kann sein, dass das für Dich besser ist, aber
               ich kenne eigentlich sonst _niemanden_, der so wenig einrückt. Nimm Tabs
               (dann kann sich's jeder selbst einstellen) oder zumindest 2 Spaces. Ich
               persönlich empfinde 1 Space nämlich als sehr unübersichtlich und die
               großen Einrückungsdiskussionen drehen sich eigentlich immer um Tab vs.
               2 Spaces vs. 4 Spaces vs. 8 Spaces - 1 Space habe ich noch nie gesehen.

          Ich mag weder Tabulatoren, die sind so umständlich zu tippen, noch mehr als ein Leerzeichen, das ist noch umständlicher.

          Naja, wie umständlich etwas zu tippen ist ist ja wohl kaum ein Argument bezüglich der Übersichtlichkeit des Codes. Und ich bin normalerweise absolut nicht der Typ, der sich in Coding-Stil-Diskussionen einmischt (ob nun 2 oder 4 oder 8 Leerzeichen ist mir eigentlich egal) - allerdings empfinde ich Dein "nur 1 Leerzeichen" als derart unübersichtlich, dass es mich _deutlich_ mehr Konzentration kostet, bei Deinem Code die Übersicht zu behalten, als bei so gut wie jedem anderen Code, den ich mal lesen musste.

          • »dbwrapper« ist in meinen Augen kein guter Name für eine von der Klasse
               »mysql« abgeleiteten Klasse - zumal der Name überhaupt nicht gut
               beschreibt, wofür die Klasse da ist.

          Ich habe die Klassen jetzt in mysql_connector und v_spam_filter_database umbenannt.

          Tja, damit hast Du die Hälfte meiner Kritik umgesetzt. ;-) Die andere Hälfte war die: Deine Klasse mysql_connector (früher mysql) ist eine OO-Abkapselung der MySQL-Datenbankfunktionen. Wenn Du jetzt eine Klasse davon ableitest, dann sollte im Klassennamen der abgeleiteten Klasse auch die Information auftauchen, dass es sich um eine MySQL-spezifische Klasse handelt - denn Dein einfaches Datenmodell lässt sich in so gut wie jeder relationalen DB umsetzen, die es gibt. Ich käme nämlich vom Namen v_spam_filter_database (oder vorher dbwrapper) *nie* auf die Idee, dass es sich um eine MySQL-spezifische Klasse handelt. Wie wäre es mit v_spam_filter_mysql_storage oder etwas ähnlichem (vielleicht fällt Dir ja etwas kürzeres ein)?

          Viele Grüße,
          Christian

          --
          "I have always wished for my computer to be as easy to use as my telephone; my wish has come true because I can no longer figure out how to use my telephone." - Bjarne Stroustrup
          1. Hallo Christian,

            Naja, wie umständlich etwas zu tippen ist ist ja wohl kaum ein Argument bezüglich der Übersichtlichkeit des Codes.

            Ich finde ein Space absolut gut zu lesen, daher habe ich nie einen Gedanken daran verschwendet, etwas anderes zu verwenden.

            [...] allerdings empfinde ich Dein "nur 1 Leerzeichen" als derart unübersichtlich, dass es mich _deutlich_ mehr Konzentration kostet,[...]

            Wenn du das sagst wird das wohl stimmen, ich habe also den Code neu formatieren lassen.

            Ich habe die Klassen jetzt in mysql_connector und v_spam_filter_database umbenannt.

            Tja, damit hast Du die Hälfte meiner Kritik umgesetzt. ;-)

            Die andere Hälfte hast du nicht wirklich verdeutlicht.

            Die andere Hälfte war die: Deine Klasse mysql_connector (früher mysql) ist eine OO-Abkapselung der MySQL-Datenbankfunktionen.

            Genau. Solche Abkapselungen habe ich auch noch für PDO-SQLite und PostgreSQL. Ich finde es praktisch davon abzuleiten, weil ich diese Standard-Funktionalitäten dauernd brauche.

            Ich käme nämlich vom Namen v_spam_filter_database (oder vorher dbwrapper) *nie* auf die Idee, dass es sich um eine MySQL-spezifische Klasse handelt. Wie wäre es mit v_spam_filter_mysql_storage oder etwas ähnlichem (vielleicht fällt Dir ja etwas kürzeres ein)?

            Nö, mir fällt auch nix kürzeres ein *g*

            Gruß
            Alexander Brock