Update spam autolearn behaviour
This commit is contained in:
@@ -87,8 +87,8 @@ pub struct ClassifierConfig {
|
|||||||
pub min_spam_samples: u64,
|
pub min_spam_samples: u64,
|
||||||
pub auto_learn_reply_ham: bool,
|
pub auto_learn_reply_ham: bool,
|
||||||
pub auto_learn_card_is_ham: bool,
|
pub auto_learn_card_is_ham: bool,
|
||||||
pub auto_learn_spam_score: f32,
|
pub auto_learn_spam_trap: bool,
|
||||||
pub auto_learn_ham_score: f32,
|
pub auto_learn_spam_rbl_count: u32,
|
||||||
pub hold_samples_for: u64,
|
pub hold_samples_for: u64,
|
||||||
pub train_frequency: Option<u64>,
|
pub train_frequency: Option<u64>,
|
||||||
pub log_scale: bool,
|
pub log_scale: bool,
|
||||||
@@ -489,12 +489,12 @@ impl ClassifierConfig {
|
|||||||
auto_learn_reply_ham: config
|
auto_learn_reply_ham: config
|
||||||
.property_or_default("spam-filter.trusted-reply.learn", "true")
|
.property_or_default("spam-filter.trusted-reply.learn", "true")
|
||||||
.unwrap_or(true),
|
.unwrap_or(true),
|
||||||
auto_learn_spam_score: config
|
auto_learn_spam_trap: config
|
||||||
.property_or_default("spam-filter.classifier.auto-learn.spam-score", "8.0")
|
.property_or_default("spam-filter.classifier.auto-learn.spam-trap", "true")
|
||||||
.unwrap_or(8.0),
|
.unwrap_or(true),
|
||||||
auto_learn_ham_score: config
|
auto_learn_spam_rbl_count: config
|
||||||
.property_or_default("spam-filter.classifier.auto-learn.ham-score", "-8.0")
|
.property_or_default("spam-filter.classifier.auto-learn.spam-rbl-count", "2")
|
||||||
.unwrap_or(-8.0),
|
.unwrap_or(2),
|
||||||
hold_samples_for: config
|
hold_samples_for: config
|
||||||
.property_or_default::<Duration>("spam-filter.classifier.samples.hold-for", "180d")
|
.property_or_default::<Duration>("spam-filter.classifier.samples.hold-for", "180d")
|
||||||
.unwrap_or(Duration::from_secs(180 * 24 * 60 * 60))
|
.unwrap_or(Duration::from_secs(180 * 24 * 60 * 60))
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ impl SpamFilterAnalyzeScore for Server {
|
|||||||
// Calculate final score
|
// Calculate final score
|
||||||
let mut results = vec![];
|
let mut results = vec![];
|
||||||
let mut header_len = 60;
|
let mut header_len = 60;
|
||||||
|
let mut is_spam_trap = false;
|
||||||
|
let mut rbl_count = 0;
|
||||||
|
|
||||||
for tag in &ctx.result.tags {
|
for tag in &ctx.result.tags {
|
||||||
let score = match self.core.spam.lists.scores.get(tag) {
|
let score = match self.core.spam.lists.scores.get(tag) {
|
||||||
@@ -68,6 +70,11 @@ impl SpamFilterAnalyzeScore for Server {
|
|||||||
}
|
}
|
||||||
None | Some(SpamFilterAction::Disabled) => 0.0,
|
None | Some(SpamFilterAction::Disabled) => 0.0,
|
||||||
};
|
};
|
||||||
|
if tag == "SPAM_TRAP" {
|
||||||
|
is_spam_trap = true;
|
||||||
|
} else if score > 1.0 && tag.starts_with("RBL_") {
|
||||||
|
rbl_count += 1;
|
||||||
|
}
|
||||||
ctx.result.score += score;
|
ctx.result.score += score;
|
||||||
header_len += tag.len() + 10;
|
header_len += tag.len() + 10;
|
||||||
if score != 0.0 || !tag.starts_with("X_") {
|
if score != 0.0 || !tag.starts_with("X_") {
|
||||||
@@ -145,11 +152,8 @@ impl SpamFilterAnalyzeScore for Server {
|
|||||||
let _ = write!(&mut headers, "X-Spam-LLM: {category} ({explanation})\r\n",);
|
let _ = write!(&mut headers, "X-Spam-LLM: {category} ({explanation})\r\n",);
|
||||||
}
|
}
|
||||||
|
|
||||||
let class = if final_score >= self.core.spam.scores.spam_threshold {
|
let is_spam = final_score >= self.core.spam.scores.spam_threshold;
|
||||||
"spam"
|
let class = if is_spam { "spam" } else { "ham" };
|
||||||
} else {
|
|
||||||
"ham"
|
|
||||||
};
|
|
||||||
|
|
||||||
if avg_confidence != 0.0 {
|
if avg_confidence != 0.0 {
|
||||||
let _ = write!(
|
let _ = write!(
|
||||||
@@ -163,18 +167,16 @@ impl SpamFilterAnalyzeScore for Server {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Autolearn
|
// Autolearn SPAM
|
||||||
let mut train_spam = None;
|
let mut train_spam = None;
|
||||||
let config = self.core.spam.classifier.as_ref().unwrap();
|
if is_spam
|
||||||
if config.auto_learn_spam_score > 0.0 && final_score >= config.auto_learn_spam_score {
|
&& self.core.spam.classifier.as_ref().is_some_and(|c| {
|
||||||
if !ctx.result.has_tag("PROB_SPAM_HIGH") {
|
(c.auto_learn_spam_trap && is_spam_trap)
|
||||||
train_spam = Some(true);
|
|| (c.auto_learn_spam_rbl_count > 0
|
||||||
}
|
&& rbl_count >= c.auto_learn_spam_rbl_count)
|
||||||
} else if config.auto_learn_ham_score < 0.0
|
})
|
||||||
&& final_score <= config.auto_learn_ham_score
|
|
||||||
&& !ctx.result.has_tag("PROB_HAM_HIGH")
|
|
||||||
{
|
{
|
||||||
train_spam = Some(false);
|
train_spam = Some(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
SpamFilterAction::Allow(SpamFilterScore {
|
SpamFilterAction::Allow(SpamFilterScore {
|
||||||
|
|||||||
Reference in New Issue
Block a user