Haider9786/nlp-threat-classifier

GitHub: Haider9786/nlp-threat-classifier

基于TF-IDF与经典机器学习算法的二元钓鱼邮件文本分类实践项目,提供完整的训练流程与Streamlit演示界面。

Stars: 0 | Forks: 0

# NLP 威胁情报文本分类器 **技术栈:** Python | scikit-learn | NLTK | TF-IDF | Streamlit | Docker | GitHub Actions **领域:** 钓鱼检测 | NLP/ML | SOC 工具 ## 项目概述 这是一个二元文本分类器,使用经典的 NLP 和机器学习技术将电子邮件内容标记为**钓鱼**或**安全**。作为一个实践项目而构建,旨在将文本预处理、TF-IDF 特征提取和监督模型比较应用于真实的安全用例,并提供 Streamlit 界面用于实时演示。 这是一个用于作品集/学习的项目,而不是已部署的生产系统。下方的 README 真实反映了实际构建和测量的内容——没有任何夸大或预期的数据。 ## 数据集 - **来源:** Kaggle [`subhajournal/phishingemails`](https://www.kaggle.com/datasets/subhajournal/phishingemails) - **大小:** 18,650 行原始数据 → 删除包含缺失值的行后剩余 18,634 行 - **使用的列:** `Email Text`,`Email Type`(映射为二元标签:0 = 安全,1 = 钓鱼) - **标签分布:** 11,322 安全 / 7,312 钓鱼 ## 流程 ``` Raw email text (CSV) | v Preprocessing - lowercase, strip URLs - remove non-alphabetic characters - remove stopwords, drop tokens <= 2 chars - Porter stemming | v TF-IDF vectorization (max 5,000 features) | v Train/test split (80/20, stratified) | v GridSearchCV (5-fold, stratified) over: - Multinomial Naive Bayes - Logistic Regression - Linear SVM | v Best model selected by held-out test accuracy | v Streamlit app for live classification ``` ## 结果 所有三个模型都通过 `GridSearchCV` 进行了 5 折分层交叉验证的微调,然后在保留的 20% 测试集(3,726 个样本)上进行了评估。 | 模型 | 最佳参数 | 测试准确率 | 精确率 (加权) | 召回率 (加权) | F1 (加权) | |---|---|---|---|---|---| | Naive Bayes | alpha=1.0 | 95.81% | 0.96 | 0.96 | 0.96 | | **Logistic Regression** | **C=10.0** | **96.75%** | **0.97** | **0.97** | **0.97** | | Linear SVM | C=1.0 | 96.62% | 0.97 | 0.97 | 0.97 | **Logistic Regression (C=10) 是表现最好的模型**,略微优于微调后的 SVM。这在事先有些出乎意料,因为 SVM 是 TF-IDF 文本分类中更常被提及的选择,这种情况只有在运行了交叉验证和超参数网格搜索(而不是依赖默认设置)后才变得清晰。这是一个微小但真实的例子,说明了为什么微调比想当然更重要。 混淆矩阵(Logistic Regression,测试集): ``` Predicted Safe Predicted Phishing Actual Safe 2186 78 Actual Phishing 43 1419 ``` ## 项目结构 ``` nlp-threat-classifier/ ├── config.yaml # central config: paths, model params, CV folds ├── requirements.txt ├── setup.py # installable package (pip install -e .) ├── Dockerfile ├── .dockerignore ├── .github/ │ └── workflows/ │ └── ci.yml # runs pytest on every push/PR to main ├── data/ │ ├── Phishing_Email.csv # raw Kaggle dataset │ └── cleaned_dataset.csv # generated by preprocess.py ├── src/ │ └── threat_classifier/ │ ├── __init__.py │ ├── utils.py # config loader, logging setup │ ├── preprocess.py # text cleaning pipeline │ ├── train.py # CV + grid search + model training │ └── app.py # Streamlit UI ├── tests/ │ ├── test_preprocess.py │ └── test_utils.py ├── models/ │ ├── best_model.pkl │ └── vectorizer.pkl └── logs/ └── app.log # generated at runtime ``` ## 运行说明 ### 本地设置 ``` git clone https://github.com/Haider9786/nlp-threat-classifier cd nlp-threat-classifier python -m venv venv venv\Scripts\activate # Windows # source venv/bin/activate # macOS/Linux pip install -r requirements.txt pip install -e . ``` ### 从头运行 pipeline ``` python src\threat_classifier\preprocess.py # cleans raw data -> data/cleaned_dataset.csv python src\threat_classifier\train.py # trains + tunes models -> models/*.pkl streamlit run src\threat_classifier\app.py # launches the web UI ``` ### 运行测试 ``` pytest tests/ -v ``` ### Docker 包含一个 `Dockerfile` 用于可复现的构建: ``` docker build -t threat-classifier . docker run -p 8501:8501 threat-classifier ``` **注意:** Docker 构建尚未在此机器上进行过端到端验证——如果您遇到问题,请回退到上面的本地设置,并将此 Dockerfile 视为一个正在进行的工作。 ### CI GitHub Actions 工作流(`.github/workflows/ci.yml`)会在每次推送到 `main` 和 pull request 时自动运行测试套件。 ## 工程笔记 - **配置驱动,而非硬编码。** 所有路径、模型超参数和 CV 设置都存在于 `config.yaml` 中,而不是分散在各个脚本里。 - **使用日志而非 print 语句。** 每个脚本都会将带有时间戳和级别的日志记录到控制台和 `logs/app.log` 中。 - **错误处理。** 缺失的文件、缺失的列和空输入都会被明确捕获并给出清晰的提示信息,而不是抛出原始的堆栈跟踪。 - **经过测试。** 核心预处理逻辑(URL 剥离、停用词移除、词干提取,以及 `None`/空输入等边缘情况)和配置加载均由单元测试覆盖。 - **已打包。** 代码库可安装(`pip install -e .`),因此模块可以干净地导入(`from threat_classifier.preprocess import clean_text`),而不必依赖相对路径的 hack。 ## 真实的局限性 - 这是一个在单一公开数据集上训练的**二元**分类器(安全 vs 钓鱼)。它尚未针对实时/真实世界的电子邮件流量,或旨在规避基于关键字特征的对抗性钓鱼企图进行验证。 - TF-IDF + 线性模型无法捕获依赖视觉/品牌欺骗、基于附件的 payload 或发件人头异常的钓鱼行为——本项目仅查看邮件正文文本。 - 不存在 SOAR/SIEM 集成;这被列为未来可能的发展方向,而不是当前功能。 - Docker 镜像虽已定义,但尚未确认能顺利构建和运行——请参阅上方的注意说明。 ## 可能的后续步骤 - 添加一个 `predict.py` CLI,用于在 Streamlit UI 之外进行脚本化/批量分类 - 验证并记录 Docker 构建过程 - 尝试使用保留的“困难样本”测试集,以探查在原始 Kaggle 分布之外的鲁棒性 - 探索轻量级 transformer 基线(例如 DistilBERT),作为 TF-IDF + 线性模型的比较基准
标签:Apex, Kubernetes, Python, scikit-learn, Streamlit, 文本分类, 无后门, 机器学习, 访问控制, 请求拦截, 逆向工具, 钓鱼检测