אימון

המודל המצורף עובד מיד. מודל שאומן על הדואר שלכם עובד טוב יותר, כי הוא לומד איך ה-ham שלכם נראה: הניוזלטרים שלכם, סגנון הכתיבה של העמיתים שלכם, השפות שאתם מקבלים.

אימון מודל#

מפנים את train לתיקיות של ספאם ו-ham:

Shell
spamscanner train --spam ~/Maildir/.Junk --ham ~/Maildir/cur --ham ~/Maildir/.Archive --out my-model.json

המקורות יכולים להיות:

  • קובצי mbox, גם דחוסים ב-gzip‏ (.mbox.gz),
  • Maildir (התיקיות cur ו-new שלו נקראות, ו-tmp מדולגת),
  • תיקייה של קובצי .eml, שנקראת באופן רקורסיבי,
  • מאגר נתונים: קובץ CSV או JSON Lines עם עמודת טקסט ועמודת תווית (--dataset). עמודות בשם text, ‏message, ‏body, ‏email או content, ו-label, ‏category, ‏class, ‏spam או is_spam מזוהות לבד; אחרת יש להשתמש ב---text-column וב---label-column. תוויות כמו spam, ‏1, ‏phishing ו-ham, ‏0, ‏not_spam, ‏legitimate מובנות.

הודעות כפולות נספרות פעם אחת. כדי לבנות על המודל המצורף במקום להתחיל ממודל ריק, מוסיפים --merge.

שימוש במודל:

Shell
spamscanner scan message.eml --model my-model.json
SPAMSCANNER_MODEL=/var/lib/spamscanner/model.json spamscanner milter
JavaScript
const scanner = new SpamScanner({classifier: '/var/lib/spamscanner/model.json'});

כמה דואר מספיק: כמה מאות הודעות מכל סוג נותנות מודל שימושי, כמה אלפים נותנים מודל טוב. כדאי לשמור על איזון בערך בין השניים, ולהשאיר ב-ham דואר שאין רצון לסנן (איפוסי סיסמה, חשבוניות מהספקים שלכם).

מדידה#

שומרים חלק מהדואר מחוץ לאימון ומודדים עליו:

Shell
spamscanner eval --model my-model.json --spam held-out/spam --ham held-out/ham

המודל המצורף על הודעות SMS ב-21 שפות שמעולם לא ראה, רובן בשפות שהוא כמעט לא מכיר:

Text
Messages: 13028 spam, 92406 ham
Precision: 89.72%   Recall: 11.18%   F1: 19.89%
False positives: 167 (0.18% of ham)   False negatives: 132
Unsure: 91247 (86.54%)

דיוק (Precision) הוא כמה ממה שהוא קורא לו ספאם הוא באמת ספאם; רגישות (Recall), כמה מהספאם הוא תופס. כאן הודעות „לא בטוח” נספרות כספאם שהוחמץ, אף שבסריקה שאר הבדיקות ומודל השפה עדיין יכולים לתפוס אותן. המספר שכדאי לעקוב אחריו הוא החיוביות השגויות: hamדואר רצוי: ההפך מספאם. שסומן כספאם. בהרצה שלמעלה, המודל לא בטוח לגבי רוב ההודעות האלה במקום לטעות בהן, וזו ההתנהגות המכוונת בשפות שיש לו בהן מעט דואר.

--json נותן את אותם מספרים עבור סקריפטים.

למידה מדיווחים#

כשמשתמשים מעבירים דואר אל תיקיית Junk או ממנה, מלמדים את המודל הודעה אחת בכל פעם:

Shell
spamscanner learn spam message.eml --model /var/lib/spamscanner/model.json
spamscanner learn ham message.eml --model /var/lib/spamscanner/model.json

ה-learn הראשון יוצר את הקובץ מהמודל המצורף. דרך HTTP, ‏POST /learn/spam ו-/learn/ham ב-HTTP API עושים אותו הדבר, ו-spamc -L spam עובד מול שרת ה-spamd עם --allow-tell. ה-IMAPSieve של Dovecot יכול לקרוא לכל אחד מהם כשהודעה מועברת.

מתוך Node.js:

JavaScript
await scanner.learn(raw, 'spam');
await scanner.unlearn(raw, 'spam'); // undo, before learning it as ham
scanner.saveModel('/var/lib/spamscanner/model.json');

הודעה שדווחה כמסווגת בטעות צריכה לעבור „ביטול למידה” מהסוג השגוי לפני שהיא נלמדת בסוג הנכון, אם היא נלמדה קודם.

המודל המצורף#

model/classifier.json נבנה על ידי npm run model:train ממאגרי הנתונים הציבוריים האלה ב-Hugging Face, כולם ברישיונות פתוחים:

מאגר נתוניםרישיוןתוכן
FredZhang7/all-scam-spamApache-2.0הודעות ודואר אלקטרוני ב-43 שפות
SetFit/enron_spamקורפוס מחקר ציבוריקורפוס Enron-Spam
alt-gnome/telegram-spamCC0-1.0הודעות Telegram ברוסית
tanaos/synthetic-spam-detection-dataset-german, -italian, -spanishMITהודעות סינתטיות

הוא למד מ-62,480 הודעות ספאם ו-76,489 הודעות ham. הסקריפט מחזיק בצד כל הודעה עשירית, מאמן על השאר ומודד את המסווג לבדו, בלי שאר הבדיקות:

מבחן על הודעות שהוחזקו בצדהודעותדיוקרגישותחיוביות שגויותלא בטוח
אנגלית6,564100.0%97.0%0.0%2.4%
רוסית1,682100.0%97.4%0.0%2.2%
איטלקית1,38998.1%85.3%1.8%10.9%
גרמנית1,30997.7%76.1%2.2%20.7%
ספרדית1,28197.5%82.5%2.6%16.8%
Enron-Spam2,888100.0%93.1%0.0%4.5%
all-scam-spam4,236100.0%88.8%0.0%11.2%
הכול13,84099.2%85.1%0.5%12.4%

כאן ספאם פירושו הסתברות מסווג של 99% ומעלה, הנקודה שבה המסווג לבדו מגיע לסף הספאם. בסריקה, ספאם שהוא פחות בטוח לגביו עדיין מקבל נקודות, ושאר הבדיקות מוסיפות את שלהן.

התוצאות בגרמנית, בספרדית ובאיטלקית מגיעות ממאגרי נתונים סינתטיים, שמכילים הודעות כמעט זהות שתויגו גם כספאם וגם כ-ham: חלק מהשגיאה הזו נמצא בתוויות, לא במודל. דואר בשפות שלכם הוא התיקון הטוב ביותר. המספרים, לכל שפה ולכל מאגר נתונים, נמצאים ב-metadata.metrics של המודל.

שפות נוספות#

npm run model:train -- --with multilingual-sms מוסיף את SMS Spam Multilingual Collection: אוסף SMS Spam Collection בתרגום מכונה ל-21 שפות. הוא לא נכלל במודל המצורף כי כרטיס המאגר שלו מציין רישיון GPL; כדאי לבדוק שזה מתאים לדרך שבה אתם משתפים את המודל. באימון איתו, התוצאות על הודעות שהוחזקו בצד, בשפות שהמודל המצורף כמעט לא מכיר, היו:

שפההודעותדיוקרגישותחיוביות שגויות
סינית430100.0%82.3%0.0%
ערבית430100.0%84.6%0.0%
קוריאנית412100.0%80.4%0.0%
יפנית48696.0%85.7%0.5%
הינדי412100.0%63.9%0.0%
צרפתית48098.6%94.2%0.6%
טורקית220100.0%73.1%0.0%

אימון מחדש#

Shell
npm run model:train                       # downloads the datasets into data/ the first time
npm run model:train -- --no-download      # reuse data/
npm run model:train -- --out /tmp/model.json --max-features 200000

קובץ המודל#

מודל הוא קובץ JSON: מספר הודעות הספאם וה-ham שנלמדו, ולכל מאפיין מגובב, בכמה הודעות ספאם ו-ham הוא הופיע, ממוין ומקודד ב-base64. אין בו מילים ואין בו טקסט של הודעות. --max-features שומר רק את המאפיינים השכיחים ביותר ו---min-count משמיט מאפיינים נדירים, במחיר של דיוק תמורת גודל; המודל המצורף שומר 400,000 מאפיינים בכ-6 MB.

אי אפשר לטעון מודלים מ-Spam Scanner 6 ומגרסאות קודמות: הם גיבבו מאפיינים אחרים. יש לאמן מודל חדש מאותו דואר.

עריכת הדף ב-GitHub · Markdown ·