학습
번들 모델은 설치하자마자 동작합니다. 직접 받은 메일로 학습한 모델은 더 잘 동작합니다. 뉴스레터, 동료의 글, 받는 메일의 언어처럼 실제로 받는 ham이 어떤 모습인지 배우기 때문입니다.
모델 학습#
train에 스팸 폴더와 ham받기를 원하는 메일: 스팸의 반대입니다. 폴더를 지정합니다.
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를 추가합니다.
모델 사용:
spamscanner scan message.eml --model my-model.json
SPAMSCANNER_MODEL=/var/lib/spamscanner/model.json spamscanner milterconst scanner = new SpamScanner({classifier: '/var/lib/spamscanner/model.json'});필요한 메일의 양: 각 종류마다 수백 개면 쓸 만한 모델이, 수천 개면 좋은 모델이 됩니다. 두 종류의 양을 대략 맞추고, 필터링되면 안 되는 메일(비밀번호 재설정, 거래처에서 받은 청구서)은 ham에 넣어 두십시오.
성능 측정#
일부 메일은 학습에서 빼 두고 그 메일로 측정합니다.
spamscanner eval --model my-model.json --spam held-out/spam --ham held-out/ham번들 모델이 본 적 없는 21개 언어의 SMS 메시지로 측정한 결과입니다. 대부분 모델이 거의 모르는 언어입니다.
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%)정밀도는 스팸이라고 판정한 것 중 실제 스팸의 비율이고, 재현율은 스팸 중 잡아낸 비율입니다. 여기서는 unsure 메시지를 놓친 스팸으로 계산하지만, 실제 검사에서는 나머지 검사와 언어 모델이 여전히 잡아낼 수 있습니다. 주의해서 볼 숫자는 오탐, 즉 스팸으로 표시된 ham입니다. 위 결과에서 모델은 이 메시지 대부분에 대해 틀린 것이 아니라 확신하지 못했습니다. 메일을 거의 학습하지 못한 언어에 대해 의도한 동작입니다.
--json은 스크립트용으로 같은 숫자를 출력합니다.
신고 기반 학습#
사용자가 메일을 Junk 폴더로 옮기거나 Junk 폴더에서 꺼내면, 메시지를 하나씩 모델에 학습시킵니다.
spamscanner learn spam message.eml --model /var/lib/spamscanner/model.json
spamscanner learn ham message.eml --model /var/lib/spamscanner/model.json처음 learn을 실행하면 번들 모델로 파일을 만듭니다. HTTP로는 HTTP API의 POST /learn/spam과 /learn/ham이 같은 일을 하며, --allow-tell을 사용한 spamd 서버에서는 spamc -L spam이 동작합니다. Dovecot의 IMAPSieve는 메시지를 옮길 때 둘 중 하나를 호출할 수 있습니다.
Node.js에서:
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-spam | Apache-2.0 | 43개 언어의 메시지와 이메일 |
| SetFit/enron_spam | 공개 연구용 말뭉치 | Enron-Spam 말뭉치 |
| alt-gnome/telegram-spam | CC0-1.0 | 러시아어 Telegram 메시지 |
| tanaos/synthetic-spam-detection-dataset-german, -italian, -spanish | MIT | 합성 메시지 |
스팸 메시지 62,480개와 ham 메시지 76,489개로 학습했습니다. 스크립트는 열 번째마다 메시지를 학습에서 제외하고, 나머지로 학습한 뒤, 다른 검사 없이 분류기만으로 성능을 측정합니다.
| 제외한 테스트 세트 | 메시지 | 정밀도 | 재현율 | 오탐 | unsure |
|---|---|---|---|---|---|
| 영어 | 6,564 | 100.0% | 97.0% | 0.0% | 2.4% |
| 러시아어 | 1,682 | 100.0% | 97.4% | 0.0% | 2.2% |
| 이탈리아어 | 1,389 | 98.1% | 85.3% | 1.8% | 10.9% |
| 독일어 | 1,309 | 97.7% | 76.1% | 2.2% | 20.7% |
| 스페인어 | 1,281 | 97.5% | 82.5% | 2.6% | 16.8% |
| Enron-Spam | 2,888 | 100.0% | 93.1% | 0.0% | 4.5% |
| all-scam-spam | 4,236 | 100.0% | 88.8% | 0.0% | 11.2% |
| 전체 | 13,840 | 99.2% | 85.1% | 0.5% | 12.4% |
여기서 스팸은 분류기 확률이 99% 이상인 경우를 뜻합니다. 분류기 단독으로 스팸 임계값에 이르는 지점입니다. 실제 검사에서는 분류기가 덜 확신하는 스팸도 점수를 받으며, 나머지 검사도 점수를 더합니다.
독일어, 스페인어, 이탈리아어 결과는 합성 데이터 세트에서 나왔습니다. 이 데이터 세트에는 거의 같은 메시지가 스팸과 ham 양쪽으로 레이블되어 있으므로, 오류의 일부는 모델이 아니라 레이블에 있습니다. 가장 좋은 해결책은 직접 받는 언어의 메일입니다. 모든 언어와 데이터 세트별 수치는 모델의 metadata.metrics에 있습니다.
추가 언어#
npm run model:train -- --with multilingual-sms를 실행하면 SMS Spam Collection을 21개 언어로 기계 번역한 SMS Spam Multilingual Collection이 추가됩니다. 이 데이터 세트의 카드에는 GPL 라이선스가 표시되어 있어 번들 모델에서는 제외했습니다. 모델을 공유하는 방식에 맞는지 확인하십시오. 이 데이터 세트를 포함해 학습했을 때, 번들 모델이 거의 모르는 언어의 제외 테스트 결과는 다음과 같았습니다.
| 언어 | 메시지 | 정밀도 | 재현율 | 오탐 |
|---|---|---|---|---|
| 중국어 | 430 | 100.0% | 82.3% | 0.0% |
| 아랍어 | 430 | 100.0% | 84.6% | 0.0% |
| 한국어 | 412 | 100.0% | 80.4% | 0.0% |
| 일본어 | 486 | 96.0% | 85.7% | 0.5% |
| 힌디어 | 412 | 100.0% | 63.9% | 0.0% |
| 프랑스어 | 480 | 98.6% | 94.2% | 0.6% |
| 터키어 | 220 | 100.0% | 73.1% | 0.0% |
다시 학습#
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는 드문 특징을 버려, 정확도를 조금 내주고 크기를 줄입니다. 번들 모델은 약 6MB에 특징 400,000개를 담고 있습니다.
Spam Scanner 6 이하의 모델은 불러올 수 없습니다. 다른 특징을 해시했기 때문입니다. 같은 메일로 새 모델을 학습하십시오.