
针对网络攻击日志,通过分词+词嵌入(含L2归一化)处理文本,结合结构化字段(日志级别、协议类型)编码、IP地址转换(IP2Vec/地理位置)与复杂时序特征(自相关、周期性),经特征选择后构建输入特征集用于异常检测。
需分四部分处理日志特征,确保特征集完整性:
文本特征(攻击描述):
非结构化文本需先分词(如jieba拆解“DDoS攻击导致服务器宕机”为“DDoS”“攻击”等),再通过词嵌入(如Word2Vec/BERT)将词转为语义向量(如300维),最后对向量做L2归一化(如text_vec / np.linalg.norm(text_vec)),确保不同长度文本的特征向量可比性,保留“DDoS”等关键攻击类型信息。
结构化字段(日志级别、协议类型):
日志中的结构化字段(如日志级别“ERROR”“WARNING”、协议类型“TCP”“UDP”)需转换为数值或独热编码(如“ERROR”→1,“WARNING”→0;“TCP”→1,“UDP”→0),作为离散特征增强区分度(如“ERROR级别”的攻击更紧急)。
IP地址特征:
将IP地址转换为数值向量(如IP2Vec将IP转为128维向量)或提取地理位置(国家、地区),作为额外特征(如“美国IP的攻击”与“中国IP的攻击”的区分),并处理未知/异常IP(如填充默认向量或标记缺失)。
时序特征(时间戳):
对时间戳序列计算复杂统计量,而非仅滑动窗口的简单频率:
statsmodels.tsa.stattools.acf);scipy.signal.periodogram);| 方法 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| TF-IDF | 词频-逆文档频率(统计词重要性) | 简单统计,反映词权重 | 基础文本特征,快速构建 | 无法捕捉语义,对长文本效果有限 |
| Word2Vec/BERT | 词嵌入(语义向量) | 向量表示,捕捉词间语义关系 | 高级文本特征,识别复杂攻击类型 | 需预训练或训练,计算量稍大 |
| 方法 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 滑动窗口统计(频率) | 单位时间内的攻击次数(如1小时) | 简单统计,反映突发性 | 识别突发攻击(如DDoS) | 窗口大小影响结果(需调优) |
| 自相关系数 | 计算时间序列的自相关 | 深度时序模式挖掘 | 识别依赖性攻击(如连续多次攻击) | 需计算统计量,计算量稍大 |
| 周期性检测 | 识别时间序列的周期模式 | 捕捉固定时间攻击模式 | 识别周期性攻击(如每日固定时间攻击) | 需检测周期,参数调优(如窗口大小) |
假设日志包含description(攻击描述)、level(日志级别)、protocol(协议类型)、ip(IP地址)、timestamp(时间戳)字段,伪代码展示特征提取流程:
import numpy as np
from sklearn.preprocessing import OneHotEncoder
from gensim.models import Word2Vec
from ip2location import IP2Location
def extract_features(log):
# 1. 文本特征:分词+词嵌入+L2归一化
tokens = jieba.cut(log['description'])
word2vec = Word2Vec.load('word2vec_model')
text_vec = np.mean([word2vec.wv[token] for token in tokens if token in word2vec.wv], axis=0)
text_vec = text_vec / np.linalg.norm(text_vec) # L2归一化
# 2. 结构化字段:日志级别、协议类型编码
level_encoder = OneHotEncoder()
level_vec = level_encoder.fit_transform([[log['level']]]).toarray()
protocol_encoder = OneHotEncoder()
protocol_vec = protocol_encoder.fit_transform([[log['protocol']]]).toarray()
# 3. IP地址特征:IP2Vec转换
ip2loc = IP2Location.IP2Location()
ip_info = ip2loc.get_ip_info(log['ip'])
if ip_info:
ip_vec = ip2loc.get_ip_vector(log['ip']) # 128维向量
else:
ip_vec = np.zeros(128) # 未知IP填充默认向量
# 4. 时序特征:自相关系数+周期性检测
ts = np.array(log['timestamp'])
autocorr = np.correlate(ts, ts, mode='full')[len(ts)-1:] / len(ts) # 自相关计算
autocorr = autocorr[-1] # 取最后一个值(当前时刻自相关)
from scipy.signal import periodogram
freq, power = periodogram(ts, fs=1/3600) # fs=1/小时
periodicity = freq[np.argmax(power)] # 主周期频率
# 5. 合并特征
features = np.concatenate([
text_vec,
level_vec.flatten(),
protocol_vec.flatten(),
ip_vec,
[autocorr, periodicity]
])
return features
“面试官您好,针对网络攻击日志,我会设计一个分步特征提取流程。首先处理文本部分:对攻击描述进行分词(比如用jieba 0.62.2),然后转换为词向量(比如用Word2Vec 3.8.5,将每个词映射为向量,再取平均得到文本向量),并对这个向量做L2归一化,确保不同长度的文本特征向量具有可比性。接着处理结构化字段,比如日志级别(如“ERROR”或“WARNING”)转换为独热编码(如“ERROR”是[1,0]),协议类型(如“TCP”或“UDP”)也做独热编码,作为离散特征。然后处理IP地址,通过IP2Vec将其转换为128维向量,或者提取地理位置(如国家、地区),并处理未知IP(比如填充默认向量)。接下来处理时序特征,计算过去24小时的自相关系数(用statsmodels库的acf函数,捕捉连续攻击的依赖性)和周期性检测(用scipy的periodogram函数,识别每日固定时间的攻击模式),而不是仅计算单位时间的攻击频率。最后,将文本向量、结构化字段编码、IP向量、时序特征拼接起来,形成结构化特征向量,用于训练异常检测模型。这样既保留了文本中的语义信息(如攻击类型关键词),又考虑了攻击的时序模式和IP的地理信息,能更全面地识别异常。”
IP地址如何处理未知或异常IP?
回答:未知IP或异常IP可填充默认向量(如全0)或标记缺失(如添加“unknown”标签),避免数据缺失影响模型。
时序特征的自相关计算具体如何实现?
回答:使用统计库函数(如statsmodels.tsa.stattools.acf)计算序列的自相关系数,通过窗口参数(如86400秒,即24小时)调整,捕捉不同时间尺度的依赖性。
特征选择如何筛选重要特征?
回答:用L1正则化(如Lasso)结合交叉验证筛选重要特征,减少维度,避免过拟合,同时验证特征有效性。