2800 字
14 分钟
基于特征标准化流水线与高斯朴素贝叶斯的恶意网站识别研究

针对现代网络钓鱼攻击的高频与隐蔽特性,本文提出了一种基于高斯朴素贝叶斯(Gaussian Naive Bayes)的自动化识别模型,并引入特征标准化流水线(Standardization Pipeline)解决了多量纲数值特征导致的预测偏差问题。实验采用包含 23.5 万样本的 PhiUSIIL 数据集,通过对 54 项 URL 维度特征的深度挖掘与预处理优化,模型在测试集上表现卓越。结果显示,优化后的流水线模型召回率(Recall)保持在 99.96%,误报数(False Positives)从原始数据的 687 例锐减至 17 例,ROC-AUC 达到 0.9998。该研究证明了轻量级生成式模型在经过严格特征工程处理后,能够在大规模实时检测场景中兼顾高精度与低延迟。

算法理论基础#

高斯朴素贝叶斯原理#

朴素贝叶斯分类器基于条件独立性假设,即给定类别 yy,各特征 xix_i 相互独立。其分类决策依据后验概率最大化原则:

y^=arg⁡max⁡yP(y)∏i=1nP(xi∣y)\hat{y} = \arg\max_{y} P(y) \prod_{i=1}^n P(x_i|y)

对于连续型特征,本研究采用高斯概率密度函数:

P(xi∣y)=12πσy2exp⁡(−(xi−μy)22σy2)P(x_i | y) = \frac{1}{\sqrt{2\pi\sigma_y^2}} \exp\left( -\frac{(x_i - \mu_y)^2}{2\sigma_y^2} \right)

其中 μy\mu_y 和 σy\sigma_y 分别是类别 yy 对应特征的均值和标准差。该模型的参数量级与特征维度呈线性关系,具有极高的计算效率。

特征工程与实验设计#

数据集与特征#

实验使用 PhiUSIIL Phishing URL (Website) 数据集,该数据集提取了 56 项关键特征,主要分为以下四个维度:

URL 静态结构特征#

  • 基础维度:包括 URLLength、DomainLength、TLDLength 等,用于识别异常长的混淆域名。
  • 混淆度分析:IsDomainIP(检测是否直接使用IP作为域名)、CharContinuationRate(字符连续率)、NoOfObfuscatedChar(混淆字符数)以及 ObfuscationRatio(混淆比例)。这些特征直接反映了攻击者逃避视觉审查的手段。

统计概率特征#

  • 信誉建模:TLDLegitimateProb(顶级域名合法概率)和 URLCharProb(字符概率分布)。通过统计学方法量化 URL 与已知安全域名的偏离度。
  • 复杂度特征:NoOfLettersInURL、NoOfDegitsInURL 及其对应的比例(Ratio),用于捕捉非典型字符分布。

页面内容与行为特征#

  • 前端代码统计:LineOfCode(代码行数)、LargestLineLength(最长行长度),反映页面复杂程度。
  • 语义一致性:DomainTitleMatchScore 和 URLTitleMatchScore,衡量域名与页面标题的相关性。恶意网站往往通过不匹配的标题来蹭热度或误导。
  • 交互逻辑:NoOfURLRedirect(跳转次数)、NoOfPopup(弹窗数)、NoOfiFrame(框架嵌套数)以及 HasExternalFormSubmit(是否存在跨域表单提交)。这些特征是判断钓鱼页面行为的核心指标。

行业敏感度特征#

  • 关键词倾向:Bank、Pay、Crypto 等布尔特征,标记页面是否涉及金融或加密货币,显著提升了对高风险钓鱼页面的识别权重。

预处理流水线设计#

在 56 个特征中,FILENAME、URL、Domain、TLD 和 Title 属于文本元数据(Metadata),不直接参与数学运算。本研究设计的流水线流程如下:

特征剥离:将上述文本字段提取为辅助审计信息,仅保留 50 个数值特征输入模型。

标准化:

由于 LineOfCode(数值可达数千)与 IsHTTPS(0或1)量纲差异巨大,流水线通过下式将所有特征拉回同一尺度:

z=x−μσz = \frac{x - \mu}{\sigma}

分层抽样:确保模型在 label(标签项)分布上保持训练与测试的一致性。

代码实现#

完整代码参见:Malicious-Website-Detection

为了确保实验的可重复性及生产环境的兼容性,项目通过 config.py 实现了路径与参数的解耦。特别地,通过 METADATA_COLS 显式定义了非计算类字段,确保模型输入层的高度纯净。核心代码如下所示:

# 基础路径配置
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DATA_PATH = os.path.join(BASE_DIR, 'data', 'PhiUSIIL_Phishing_URL_Dataset.csv')
MODEL_SAVE_PATH = os.path.join(BASE_DIR, 'saved_models')
# 实验参数配置
RANDOM_STATE = 42 # 随机种子,固定此数值可保证每次运行的数据拆分结果一致
TEST_SIZE = 0.2 # 测试集占比 20%
# 数据列配置
# 标签列:1代表合法,0代表钓鱼
LABEL_COL = 'label'
# 元数据列:不参与数学计算的文本信息
METADATA_COLS = ['FILENAME', 'URL', 'Domain', 'TLD', 'Title']

在复杂的机器学习流水线中,最佳实践是将数据读取与数据转换分离。编写了 get_raw_splits() 函数,其核心目标是保持数据的“原始性”,将所有数值变换(如标准化)留给后续的 Pipeline 统一处理,从而避免训练集信息泄露给测试集。核心代码如下所示:

def get_raw_splits():
"""
仅负责基础的数据加载和分层拆分,保持数据的原始性。
预处理步骤将由后续的 Pipeline 统一管理。
"""
# 读取原始数据
df = pd.read_csv(DATA_PATH)
# 特征选择:剔除非数值文本列和标签列
# drop函数用于删除指定的列
X = df.drop(columns=METADATA_COLS + [LABEL_COL])
y = df[LABEL_COL]
# 数据拆分
# stratify=y 确保训练集和测试集中0和1的比例与原始数据一致
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=TEST_SIZE,
random_state=RANDOM_STATE,
stratify=y
)
return X_train, X_test, y_train, y_test, df

main() 函数定义了从数据输入到模型落地(Production-ready)的完整生命周期。通过 Pipeline 架构,我们确保了模型在训练和预测时使用完全一致的逻辑。

def main():
# 1. 获取原始拆分数据
# 调用前期定义的模块,确保数据分层抽样
X_train, X_test, y_train, y_test, raw_df = get_raw_splits()
# 2. 构建流水线 (Pipeline)
# Pipeline 将多个评估器组合成一个。这在处理流程时非常有用。
pipeline = Pipeline([
('scaler', StandardScaler()), # 特征标准化
('nb_classifier', GaussianNB()) # 核心算法:高斯朴素贝叶斯
])
# 3. 训练流水线
# 这一步会按顺序执行流水线中的所有步骤(先转换数据,再训练模型)
print("正在通过流水线训练模型...")
pipeline.fit(X_train, y_train)
# 4. 执行预测
y_pred = pipeline.predict(X_test)
y_prob = pipeline.predict_proba(X_test)[:, 1]
# 5. 指标评估
# 调用 evaluate_model 打印 Precision, Recall, F1 等核心指标
evaluate_model(y_test, y_pred, y_prob, model_name="Gaussian Naive Bayes V1.0")
# 6. 错误追溯分析 (Error Analysis)
# 通过将预测结果对齐原始 DataFrame,筛选出漏报(FN)和误报(FP)样本
fn_df, fp_df = get_error_analysis(X_test, y_test, y_pred, raw_df)
print(f"\n[分析] 漏报样本数 (FN): {len(fn_df)} | 误报样本数 (FP): {len(fp_df)}")
# 7. 整体持久化
if not os.path.exists(MODEL_SAVE_PATH):
os.makedirs(MODEL_SAVE_PATH)
# 注意:保存的是整个 pipeline,而不仅仅是模型权重
save_path = os.path.join(MODEL_SAVE_PATH, "phish_nb_v1.pkl")
joblib.dump(pipeline, save_path)
print(f"\n实验结束,包含预处理逻辑的完整流水线已保存至: {save_path}")

实验结果与误差分析#

评价指标体系定义#

在恶意网站识别的二分类任务中,单纯的准确率(Accuracy)往往无法真实反映模型在处理样本极度不平衡(如合法网站远多于钓鱼网站)时的防御能力。因此,本文引入以下多维度评估指标:

混淆矩阵#

混淆矩阵(Confusion Matrix)是评估分类模型性能的最基础工具,其四个核心维度定义如下:

  • 真正例(True Positive,TP):模型正确判定为“钓鱼网站”的样本数。
  • 真负例(True Negative,TN):模型正确判定为“合法网站”的样本数。
  • 假正例(False Positive,FP):模型将“合法网站”误报为“钓鱼网站”的数量(即误报)。
  • 假负例(False Negative,FN):模型将“钓鱼网站”误判为“合法网站”的数量(即漏报)。

精确率#

精确率(Precision)衡量模型预测为“恶意”的样本中,有多少是真实的恶意网站:

Precision=TPTP+FPPrecision = \frac{TP}{TP + FP}

安全意义:高精确率意味着安全告警的真实性高,减少了对正常访问的干扰(低误报)。

召回率#

召回率(Recall / Sensitivity)衡量在所有真实的恶意网站中,模型成功捕捉到的比例:

Recall=TPTP+FNRecall = \frac{TP}{TP + FN}

安全意义:Recall 是识别系统的核心指标,Recall 为 1.00 意味着模型几乎没有“漏网之鱼”。

F1-Score#

F1 分数是精确率和召回率的调和平均数:

F1=2×Precision×RecallPrecision+RecallF1 = 2 \times \frac{Precision \times Recall}{Precision + Recall}

它综合平衡了误报与漏报,是衡量模型整体稳健性的核心指标。

支持数#

支持数(Support)指的是在测试集中每个类别对应的真实样本数量。在本文实验中,Phishing(0)的 Support 为 20,189,Legitimate(1)的 Support 为 26,970。通过 Support 可以观察数据集是否存在类别倾斜。

ROC 曲线与 AUC 得分#

  • ROC 曲线:以假正率(FPR)为横轴,真正率(TPR,即 Recall)为纵轴绘制的曲线。
  • AUC(Area Under Curve):指 ROC 曲线下的面积。
    • AUC=1AUC = 1:理想模型,完美区分。
    • AUC=0.5AUC = 0.5:等同于随机猜测。

实验结果#

预处理对模型性能的增益分析#

为了量化特征标准化(Standardization)对高斯朴素贝叶斯算法的具体贡献,本研究记录了数据在标准化前后的详细评估指标。实验结果表明,预处理流水线对消除特征量纲偏差、优化决策边界具有极其显著的作用。

标准化前后的实验数据对比#

通过对比 Baseline(未处理)与 Pipeline(标准化)实验,结果如下:

下表展示了模型在 56 个原始特征下(未标准化)与经过标准化流水线处理后的性能表现:

实验组别类别PrecisionRecallF1-ScoreSupportAccuracyAUC
未标准化(Baseline)Phishing(0)0.971.000.98201890.990.9998
Legitimate (1)1.000.970.9926970
标准化后(Proposed)Phishing(0)1.001.001.00201891.000.9998
Legitimate (1)1.001.001.0026970

在未进行标准化的 Baseline 实验中,Phishing 类的 Precision 仅为 0.97,这意味着在识别出的恶意网站中存在约 3% 的误报(主要由 Legitimate 类的 0.97 Recall 引起)。经过标准化预处理后,所有指标均收敛至 1.00。这一转变证明,通过 Z-Score 标准化,模型成功修正了因部分高数值特征(如 LineOfCode 或 LargestLineLength)产生的概率偏移,使模型在保持极高检测灵敏度的同时,几乎消除了“冤假错案”。

值得注意的是,在两组实验中,Phishing(0)类的 Recall 始终保持在 1.00。这表明高斯朴素贝叶斯算法配合 56 个多维度特征(特别是 URLSimilarityIndex 和 HasPasswordField 等强特征),对钓鱼网站的特征捕获具有天然的鲁棒性。无论数据如何平移缩放,模型都能稳健地识别出潜在的恶意威胁。

标准化后的 F1-Score 达到 1.00,标志着模型在精确率与召回率之间达到了完美的平衡点。ROC-AUC 得分稳定在 0.9998,反映出模型在不同判定阈值下均具有极强的类分离度。

结论#

在基于高斯朴素贝叶斯的恶意网站识别体系中,特征标准化流水线是必要项。通过简单的线性变换,我们不仅将模型的准确率提升至极致,更重要的是证明了轻量级算法在数据质量得到保证的前提下,完全有能力应对复杂的网络安全分类任务。

基于特征标准化流水线与高斯朴素贝叶斯的恶意网站识别研究
https://blog.mal-suen.cn/posts/2025/09/207/
作者
Malcolm
发布于
2025-09-20
许可协议
CC BY-NC-SA 4.0