ML concept: Beyond Bag-of-Words: Structural Email Features
Pure text features miss structural signals a phishing email almost always carries. Combining TF-IDF text features with hand-engineered structural features, mismatched display and actual link URLs, sender domain age, HTML-to-plain-text ratio, count of urgency words ("immediately," "suspended," "verify now"), consistently outperforms either feature family alone.
Case study: Business Email Compromise: When Phishing Has No Malware At All
The FBI's Internet Crime Complaint Center (IC3) reported roughly $2.9 billion in adjusted losses from business email compromise (BEC) complaints in its 2023 Internet Crime Report, making BEC one of the two costliest categories of cybercrime it tracks. A BEC attack often contains no malicious attachment and no malware payload at all, only a carefully worded email impersonating an executive or vendor, requesting an urgent wire transfer. This is precisely why the structural and linguistic features built in this unit, urgency language, sender-display mismatches, unusual request patterns, matter as much as, or more than, any file-based signal: many of the costliest phishing attacks in the world have no file to analyse in the first place.
- Extract TF-IDF features from the subject and body text.
- Extract structural features: link-domain mismatch, sender domain age, urgency word count, HTML ratio, attachment presence.
- Concatenate both feature sets into a single vector per email (
scipy.sparse.hstackfor mixed sparse/dense features). - Train and evaluate exactly as in Unit 2, using the same train/test split discipline.
- Inspect feature importances, as in the chart above, to confirm the model is learning genuine signal, not an artefact of this particular dataset.
Caution: Feature Leakage
A dataset of phishing emails scraped from a public reporting feed may contain a feature that is a side effect of how the data was collected, not a property of phishing itself, for example, every phishing sample arriving with a specific mail header the reporting tool adds. A model trained on that dataset will look excellent and fail immediately in production, because it learned the collection artefact, not phishing. Always ask, for every strong feature: could this value exist for a reason unrelated to the label?
Try it yourself: Build Your Own Structural Feature
Using any public phishing-email dataset or a small one you construct from your own spam folder (with personal data stripped), write a function that returns True if an email's visible link text and its actual href target point to different domains. Add it as a feature to the pipeline above and check whether it appears near the top of the feature-importance ranking.
Key takeaway
Feature engineering, not classifier choice, is usually what separates a strong security model from a weak one. Network-flow features summarise packet-level behaviour into fixed vectors; static malware features, especially entropy, expose structure without ever running a file; phishing detection combines TF-IDF text features with structural signals like sender-link mismatches, because many of the costliest real attacks, such as business email compromise, carry no malware payload to analyse at all.

