Skip to content

AI Mail Analyzer

mail_analysis

MODEL_SPECS = (ModelSpec('safe_suspicious_30_epochs_model.pth', 2, 'main'), ModelSpec('spam_dangerous_30_epochs_model.pth', 2, 'main'), ModelSpec('safe_30_epochs_model.pth', 2, 'sub'), ModelSpec('unwanted_30_epochs_model.pth', 2, 'sub'), ModelSpec('dangerous_30_epochs_model.pth', 4, 'sub')) module-attribute

ClassificationName

Bases: Enum

SAFE = 0 class-attribute instance-attribute

UNWANTED = 1 class-attribute instance-attribute

DANGEROUS = 2 class-attribute instance-attribute

SubClassificationName

Bases: Enum

INTERNAL = 0 class-attribute instance-attribute

EXTERNAL = 1 class-attribute instance-attribute

SPAM = 2 class-attribute instance-attribute

NEWSLETTER = 3 class-attribute instance-attribute

CLASSIC_PHISHING = 4 class-attribute instance-attribute

CLONE = 5 class-attribute instance-attribute

BLACKMAIL = 6 class-attribute instance-attribute

WHALING = 7 class-attribute instance-attribute

ModelSpec

Bases: NamedTuple

filename instance-attribute

output_dim instance-attribute

group instance-attribute

untar_file(filepath, extract_to)

get_header_dict_list(msg)

getMainClassificationProbabilities(device, safe_suspicious_model, spam_dangerous_model, email_embedding)

getMainClassificationInfo(global_probabilities)

getSubClassificationProbabilities(device, models, email_embedding, main_classification_probabilities)

getSubClassificationInfo(global_sub_probabilities)

get_classification_breakdown(global_probabilities)

Label the raw main-classification array by enum name, e.g. {"SAFE": 0.83, "UNWANTED": 0.12, "DANGEROUS": 0.05}.

get_sub_classification_breakdown(global_sub_probabilities)

Label the raw sub-classification array by enum name.

split_into_sentences(mail_body, max_sentences=40)

Split a mail body into sentence-ish chunks for occlusion analysis.

Caps at max_sentences so a pathologically long body can't turn the per-sentence re-embedding pass in get_contributing_phrases into an unbounded number of model calls.

rank_phrase_impacts(sentences, impacts, top_n=5)

Pair sentences with their occlusion impact, keep only sentences whose removal reduced confidence in the predicted class (impact > 0), and return the top_n by impact descending.

get_contributing_phrases(device, safe_suspicious_model, spam_dangerous_model, vectorizer, mail_body, classification_index, baseline_probability, top_n=5)

Sentence-level occlusion: re-embed the body with each sentence removed and measure how much confidence in the predicted class drops. Sentences whose removal drops confidence the most are the ones driving the classification.

ai_mail_classifier

AIMailClassifier

Bases: Analyzer

filename = self.getParam('attachment.name', 'noname.ext') instance-attribute

filepath = self.getParam('file', None, 'File is missing') instance-attribute

summary(raw)

run()

ResNetMLP

ResNetMLP

Bases: Module

fc1 = nn.Linear(input_dim, input_dim) instance-attribute

fc2 = nn.Linear(input_dim, int(input_dim * 2 / 3)) instance-attribute

fc3 = nn.Linear(int(input_dim * 2 / 3), int(input_dim * 1 / 3)) instance-attribute

fc4 = nn.Linear(int(input_dim * 1 / 3), output_dim) instance-attribute

relu = nn.ReLU() instance-attribute

dropout = nn.Dropout(0.5) instance-attribute

residual_transform = nn.Linear(input_dim, int(input_dim * 1 / 3)) instance-attribute

forward(x)