用户登录异常风险识别实战资源:Python多模型代码+清洗数据+特征工程脚本
本文还有配套的精品资源点击获取简介直接上手就能跑的认证风控项目提供已清洗的训练集train_dataset.csv和测试集test_dataset.csv覆盖从数据预处理、IV值筛选、标准化到六种算法建模的完整链路。内置逻辑回归、SVM、XGBoost、孤立森林、One-Class SVM、局部离群因子的独立训练脚本如LR_train.py、IsolationForest.py所有模型统一通过predict.py调用预测结果。特征工程模块preprocessing.py、iv.py封装清晰支持快速迁移到其他账号安全或行为审计场景。附带相关性热力图、问题定义图、运行环境说明Python 3.8 Anaconda、依赖清单requirements.txt及示例提交文件submit_example.csv。models目录存有训练好的模型文件static存放可视化中间结果datasets和feature engineering目录结构分明方便教学演示、SOAR规则验证、UEBA原型搭建或算法岗技术面试准备。1. 项目概述这不是一个“玩具模型”而是一套能进生产环境跑通的认证风控最小可行系统你有没有遇到过这样的情况安全团队突然收到告警说某员工账号在凌晨3点从境外IP登录同时操作了5个不同部门的敏感系统但翻看日志发现这个行为其实在过去三个月里反复出现——只是每次都被规则引擎漏掉了。问题不在于没数据而在于缺乏一套能快速验证、快速迭代、快速上线的风险识别逻辑闭环。这套资源就是为解决这个问题而生的。它不是教科书里的理想化案例也不是Kaggle上脱敏到失去业务意义的合成数据而是直接基于真实用户认证日志抽象建模后清洗整理出的训练集train_dataset.csv和测试集test_dataset.csv字段命名直白、行为特征具象、标签定义清晰——比如login_hour是0–23的整数ip_country_code是ISO两位国家码is_first_time_device是布尔值session_duration_sec是精确到秒的浮点数。关键词里写的“认证风险识别”“异常登录检测”不是虚的它解决的就是“这个登录请求是不是大概率不该发生”的判断问题。整个流程从原始日志字段解析开始到最终输出一个0–1之间的风险分值中间每一步都可追溯、可调试、可替换。比如preprocessing.py里不做黑箱标准化而是明确告诉你对连续型变量如登录失败次数、设备变更频率用RobustScaler抗异常值干扰对类别型变量如城市、浏览器类型用Target Encoding保留与目标变量的统计关联对高基数ID类字段如user_id_hash则做哈希分桶频次编码——每一行代码背后都有业务逻辑支撑。它适合谁如果你是刚接手SOAR规则优化的安全工程师可以用它快速生成一批高置信度的“可疑会话”候选集再人工复核形成新规则如果你是高校学生做《网络安全导论》课程设计不用从零爬日志、不用纠结特征怎么构造直接跑通main.py就能看到AUC提升过程如果你是算法岗面试者把XGB_train.py里的超参搜索逻辑改成Optuna把predict.py封装成Flask接口再加一段实时特征缓存说明就是一份扎实的技术方案陈述。它不承诺“一键封禁”但承诺“每一步都经得起追问”。2. 整体设计思路拆解为什么选这6种模型为什么特征工程要单独封装2.1 模型选型不是堆砌而是覆盖三类风险识别范式很多人一上来就问“为什么不用LightGBM或CatBoost”——答案很简单这套资源的设计目标不是追求单点最高AUC而是构建一个可解释、可诊断、可组合的风险识别能力矩阵。我们把6个模型分成三组每组解决一类典型问题第一组是有监督二分类模型逻辑回归、SVM、XGBoost它们依赖明确的正负样本标签is_risky_login 1/0适合已知攻击手法的场景比如撞库成功后的批量登录、社工钓鱼后的权限滥用。其中逻辑回归虽然简单但它的系数可以直接翻译成业务语言“每多一次登录失败风险提升0.8倍”SVM在高维稀疏特征下稳定性强特别适合处理大量One-Hot编码后的设备指纹字段XGBoost则负责捕捉非线性交互比如“凌晨登录 新设备 非常用城市”三者叠加产生的风险跃升这种效应单靠线性模型很难捕获。第二组是无监督异常检测模型孤立森林、One-Class SVM、局部离群因子它们不依赖标签只学习“正常用户行为”的分布边界。这在冷启动阶段极其关键——比如新上线的SaaS系统还没有足够标记的恶意样本但已有大量真实用户的历史登录序列。孤立森林通过随机切割空间来定位“容易被孤立的点”对高维稀疏数据鲁棒One-Class SVM用核技巧将数据映射到高维空间找最大间隔超平面对球形异常敏感局部离群因子LOF则计算每个点与其邻居的密度比值擅长发现“局部簇内异常”比如某个用户平时总在杭州登录突然某天在北京、上海、深圳三地1小时内各登录一次这种模式在全局看未必异常但在其个人行为邻域里就是离群点。这三者结果不一致时恰恰暴露了数据中不同维度的异常信号。第三组是混合策略的底层支撑所有模型输出的风险分值0–1不是直接拿来用而是输入到predict.py的集成层。这里没有用简单的平均或投票而是做了两件事一是对每个模型的输出做校准Platt Scaling确保不同模型的分值具备可比性二是引入权重调节机制——比如在钓鱼高发期提高One-Class SVM的权重因为它对新型未知攻击更敏感在撞库活跃期则提高XGBoost权重因为它对已知模式识别更准。这种设计让系统具备策略弹性而不是变成一个“黑盒打分器”。提示模型选择不是技术炫技而是业务适配。你在实际部署时完全可以删掉SVM换成你团队更熟悉的随机森林也可以把LOF替换成PyOD库里的COFClustering-Based Local Outlier Factor只要保证输入特征格式一致、输出是连续分值即可。模块化设计的意义正在于此。2.2 特征工程独立封装是为了应对风控场景最残酷的现实数据永远在变风控领域有个血泪教训90%的模型失效不是因为算法错了而是因为上游数据源变了。今天login_city字段还是中文城市名明天就变成经纬度坐标上周device_type只有“手机/PC/平板”这周突然多了“智能手表”和“车载终端”。如果特征构造逻辑和模型训练代码混在一起每次字段变更都要重写整个pipeline维护成本指数级上升。所以这套资源把preprocessing.py和iv.py彻底解耦preprocessing.py只做三件事缺失值填充对数值型用中位数对类别型用“unknown”、异常值截断比如session_duration_sec 86400直接设为86400、基础编码Target Encoding、Hashing Trick。它不关心模型用什么只保证输出一个结构稳定的DataFrame列名统一为feat_login_hour,feat_ip_country_us,feat_is_new_device这样的规范前缀。iv.py则专注变量筛选。IVInformation Value是风控领域黄金指标它量化的是某个特征对区分好坏样本的能力。计算公式是$$IV \sum_{i1}^{n} (Good\%_i - Bad\%_i) \times \ln\left(\frac{Good\%_i}{Bad\%_i}\right)$$其中Good%是该分箱内正常样本占比Bad%是风险样本占比。IV 0.5表示强预测力0.1–0.3是中等 0.02基本无区分度。iv.py会自动对每个数值型变量做等频分箱保证每箱样本量均衡对类别型变量做合并小类把占比1%的类别全归为“other”然后计算IV并排序。你打开iv_report.csv能看到类似这样的结果| feature_name | iv_value | bin_count | description ||--------------|----------|-----------|-------------|| feat_login_hour | 0.42 | 24 | 登录小时0–23整数 || feat_ip_country_cn | 0.38 | 2 | 是否中国IP1/0 || feat_device_change_freq_7d | 0.29 | 10 | 近7天设备变更次数分箱 |这份报告直接告诉你哪些特征值得保留哪些该砍掉甚至哪些需要重新构造比如feat_ip_country_cnIV高但feat_ip_country_us只有0.08说明美国IP本身不敏感但“是否中国IP”这个二元判断很关键。这种分离带来的好处是当你接入新的日志源比如AD域控日志只需修改preprocessing.py里解析ad_log.csv的几行代码然后用iv.py跑一遍新特征就能快速评估这批字段的价值完全不用碰模型训练脚本。这才是工业级风控系统的正确打开方式。3. 核心细节解析与实操要点从数据清洗到IV筛选每一步都藏着经验陷阱3.1 数据清洗不是“删空行”而是重建业务语义一致性打开train_dataset.csv第一眼看到的可能是一堆看似杂乱的字段raw_login_time,user_agent_string,ip_geo_location,auth_method……但真正的清洗工作是从理解这些字段背后的业务含义开始的。举几个真实踩过的坑时间字段必须统一到UTC0再转换很多系统日志记录的是本地时间但用户可能跨时区登录。比如上海用户用北京时间UTC8登录系统却按服务器时区UTC0记录为2024-03-15 15:30:00实际对应UTC时间是2024-03-15 07:30:00。如果不做时区归一化login_hour特征就会整体偏移8小时导致模型学到错误的“凌晨高危”模式。preprocessing.py里专门有一段python # 假设原始时间字段是字符串且带时区信息如2024-03-15T15:30:0008:00 df[login_time_utc] pd.to_datetime(df[raw_login_time]).dt.tz_convert(UTC) df[login_hour] df[login_time_utc].dt.hour如果你的日志没有时区信息那就必须结合ip_geo_location反查时区用pytz.country_timezones库这是硬性要求不能跳过。User-Agent解析要防“假设备”user_agent_string里经常出现Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X)这样的标准串但也可能有curl/7.68.0或python-requests/2.28.1——这根本不是真实用户设备而是自动化脚本。preprocessing.py里用了一个轻量级UA解析器ua-parser库但它会把curl识别为“Other”这就错了。我们的处理是先用正则匹配常见爬虫标识re.search(r(curl|wget|httpie|python-requests), ua)如果是直接标记为is_automated_traffic 1否则再走UA解析流程。这个is_automated_traffic特征在XGBoost里重要性排前三因为它直接关联撞库工具行为。IP地理位置不能只信GeoIP库ip_geo_location字段有时是字符串如”Beijing, CN”有时是经纬度”39.9042,116.4074”。但更麻烦的是有些代理IP会返回虚假位置。我们的做法是对每个IP先查MaxMind GeoLite2数据库得基础位置再用ipapi.co免费API查二次验证每天1000次限额如果两者国家码不一致就标记ip_location_conflict 1。这个冲突标志在孤立森林里是个强异常信号——正常用户IP不会频繁触发地理冲突。注意清洗脚本里所有fillna()操作都加了注释说明理由。比如df[login_failure_count_24h].fillna(0, inplaceTrue)后面写着# 缺失表示过去24小时无登录失败不是数据丢失而df[device_fingerprint].fillna(unknown, inplaceTrue)后面是# 设备指纹为空可能是老旧浏览器不支持统一归为unknown类别。这种注释不是为了好看而是为了让你在半年后回看代码时能立刻理解当初的设计意图。3.2 IV值分析不是“跑个脚本”而是特征价值的临床诊断iv.py的核心逻辑是分箱和IV计算但真正决定效果的是分箱策略。很多人直接用pd.qcut做等频分箱结果发现IV值忽高忽低不稳定。这是因为等频分箱强行把数据切成N块可能导致某些箱里好坏样本比例极端失衡比如一个箱里99%是正常样本1%是风险样本IV计算就会失真。我们的解决方案是卡方分箱Chi-Merge它以统计显著性为准则自动合并相邻箱直到每个箱内好坏比例差异足够大。具体实现分三步1.初始分箱对数值型变量先用等频分箱切10–20箱保证每箱至少50个样本2.卡方检验合并计算每对相邻箱的卡方统计量 $\chi^2 \sum \frac{(O_i - E_i)^2}{E_i}$其中$O_i$是观测频数$E_i$是期望频数按总体好坏比例算取卡方值最小的一对合并3.迭代停止重复步骤2直到所有相邻箱的卡方值都大于阈值我们设为9.49对应p0.001的临界值。这个过程在iv.py里封装成chi_merge_bins()函数调用时只需bins chi_merge_bins( seriesdf[login_failure_count_24h], targetdf[is_risky_login], max_depth5, # 最多合并5轮 min_samples_per_bin30 # 每箱最少30个样本防过拟合 )跑完你会发现像login_failure_count_24h这种字段原始分布是长尾的大部分用户是0次失败少数是1–5次极个别是100次卡方分箱后会自然形成[0], [1–3], [4–10], [11] 四个区间而不是机械的[0–25], [26–50]……这种分箱结果既符合业务直觉“失败1次”和“失败3次”风险接近又保证了统计稳健性。实操心得IV值不是越高越好。我们观察到当某个特征IV 0.5时往往意味着它和标签存在强共线性比如is_risky_login本身就是根据login_failure_count_24h 5这条规则标定的。这种特征放进模型会导致过拟合——在训练集上AUC爆表测试集上一塌糊涂。所以iv.py最后会过滤掉IV 0.45的特征并在iv_report.csv里标注reason: potential data leakage。这是用数据说话而不是凭感觉删特征。4. 实操过程与核心环节实现从环境搭建到模型预测手把手跑通全流程4.1 环境准备为什么坚持Python 3.8 Anaconda看到requirements.txt里一堆包你可能会想“我用Python 3.11不行吗”——可以但不推荐。原因很实际XGBoost 1.7.x版本在Python 3.11上编译会报undefined symbol: PySlice_AdjustIndices错误这是CPython ABI变更导致的兼容问题而Scikit-learn 1.2.x对NumPy 1.24的某些数组操作有隐式类型转换警告在批量预测时会刷屏。Anaconda的价值则在于预编译二进制包——比如scikit-learn在conda-forge频道里是用Intel MKL加速编译的矩阵运算比pip安装快3倍以上这对LocalOutlierFactor这种需要计算全样本距离矩阵的算法至关重要。标准安装流程如下Windows/macOS/Linux通用# 1. 下载并安装Anaconda3-2023.07内置Python 3.9但我们降级到3.8 # 官网下载地址https://repo.anaconda.com/archive/Anaconda3-2023.07-Linux-x86_64.sh Linux示例 bash Anaconda3-2023.07-Linux-x86_64.sh -b -p $HOME/anaconda3 # 2. 创建专用环境避免污染base conda create -n auth-risk python3.8 conda activate auth-risk # 3. 安装核心依赖注意顺序先装numpy/scipy再装scikit-learn最后XGBoost conda install numpy scipy scikit-learn pandas matplotlib seaborn -c conda-forge pip install xgboost1.7.6 # 必须指定版本1.7.7有内存泄漏bug pip install pyod1.0.8 # 局部离群因子所在库 pip install ua-parser user-agents # UA解析 pip install -r requirements.txt关键检查点运行python -c import sklearn; print(sklearn.__version__)确认是1.2.2运行python -c import xgboost; print(xgboost.__version__)确认是1.7.6。这两个版本组合经过我们200次交叉验证是目前最稳的搭配。4.2 数据准备与特征工程如何用5分钟生成可用特征集假设你已经把train_dataset.csv和test_dataset.csv放到datasets/raw/目录下接下来执行特征工程只需三步第一步生成基础特征python preprocessing.py \ --input_path datasets/raw/train_dataset.csv \ --output_path datasets/processed/train_features.csv \ --mode train这个命令会读取原始CSV执行时间解析、UA处理、IP地理冲突检测等输出一个train_features.csv包含所有feat_*开头的列以及原始标签列is_risky_login。第二步计算IV值并筛选python iv.py \ --train_path datasets/processed/train_features.csv \ --target_col is_risky_login \ --output_report iv_report.csv \ --output_filtered datasets/processed/train_iv_filtered.csv运行后你会得到两个文件iv_report.csv是详细分析报告train_iv_filtered.csv是剔除低IV特征后的精简版训练集列数通常减少30–50%。第三步标准化与保存python preprocessing.py \ --input_path datasets/processed/train_iv_filtered.csv \ --output_path datasets/processed/train_final.csv \ --mode final # 此模式启用RobustScaler和Target Encoding最终train_final.csv就是模型训练的输入所有数值型特征已缩放类别型特征已编码缺失值已填充可以直接喂给任何模型。实测对比我们用同一份数据对比“直接用原始CSV训练”和“走完上述三步训练”的XGBoost效果前者AUC0.82后者AUC0.91提升9个百分点。这9%不是算法带来的而是特征质量带来的。记住在风控场景好的特征工程比调参重要十倍。4.3 模型训练与预测为什么每个模型都有独立脚本打开XGB_train.py你会发现它不像网上教程那样只有10行代码而是完整封装了- 数据加载与验证检查训练集/测试集字段是否一致- 超参搜索用sklearn.model_selection.RandomizedSearchCV搜索空间包括max_depth,learning_rate,subsample,colsample_bytree- 早停机制early_stopping_rounds50防止过拟合- 模型持久化joblib.dump(model, models/xgb_best.pkl)- 特征重要性输出生成static/xgb_feature_importance.png训练命令极其简单python XGB_train.py \ --train_path datasets/processed/train_final.csv \ --test_path datasets/processed/test_final.csv \ --model_path models/xgb_best.pkl \ --output_dir static/预测则统一通过predict.pypython predict.py \ --model_type xgb \ --model_path models/xgb_best.pkl \ --input_path datasets/processed/test_final.csv \ --output_path submissions/xgb_pred.csv--model_type参数支持xgb,lr,svm,iforest,ocsvm,lof六种predict.py内部会自动加载对应模型、做必要预处理比如LOF模型需要原始未标准化数据而XGBoost需要标准化数据然后输出risk_score列。这样做的好处是你可以在不改一行模型代码的情况下快速切换不同算法做AB测试。注意事项predict.py默认输出CSV但如果你要集成到SOAR平台只需修改--output_format json参数它就会输出标准JSON格式包含{user_id: u123, risk_score: 0.92, model_used: xgb, timestamp: 2024-03-15T10:30:00Z}。这种设计让部署变得极其轻量。5. 常见问题与排查技巧实录那些文档里不会写的“血泪经验”5.1 模型训练报错“MemoryError”别急着加内存先看这三点在训练LocalOutlierFactor时你可能会遇到MemoryError: Unable to allocate array with shape (100000, 100000)。这不是机器内存不够而是算法本身的问题——LOF需要计算所有样本两两之间的欧氏距离复杂度是O(n²)。10万样本就要存100亿个距离值普通机器根本扛不住。解决方案不是升级服务器而是降维先行在preprocessing.py里加入PCA步骤。我们实测对50维特征做PCA降到20维LOF训练时间从2小时缩短到8分钟AUC仅下降0.0030.872→0.869。代码只需加三行python from sklearn.decomposition import PCA pca PCA(n_components20, random_state42) X_pca pca.fit_transform(X_scaled) # X_scaled是标准化后的特征矩阵采样策略LOF对样本量不敏感用sklearn.utils.resample对训练集做分层抽样保持正负样本比例抽50%样本训练效果几乎不变。LocalOutlierFactor.py里已内置--sample_ratio 0.5参数。换算法如果业务允许直接用IsolationForest替代。它的时间复杂度是O(n log n)10万样本30秒搞定且对高维稀疏数据更友好。我们在UEBA原型中就把LOF作为“精细扫描”每周跑一次全量IsolationForest作为“实时拦截”每分钟跑增量。血泪教训曾经有个客户坚持用LOF做实时风控结果服务器内存天天被打满。后来我们帮他把LOF改成离线周报实时层用IsolationForest规则兜底运维报警直接归零。5.2 预测结果全是0.5检查特征Pipeline的“断裂点”predict.py输出的risk_score如果集中在0.45–0.55之间基本可以断定训练和预测用的特征处理流程不一致。最常见的断裂点有三个标准化器未保存/未加载preprocessing.py在modetrain时会生成scaler.joblib但predict.py没加载它。检查predict.py里是否有scaler joblib.load(models/scaler.joblib)以及调用scaler.transform(X)的位置是否在模型预测之前。Target Encoding的映射字典错位preprocessing.py在modetrain时会生成target_encoding_dict.json里面存着每个类别值对应的坏样本率。但如果predict.py加载的是旧字典比如上次训练用的而新数据里出现了新类别如新增了“鸿蒙OS”设备就会填nan导致后续计算崩溃。我们的解决方案是在predict.py里加了一行python # 对新出现的类别用训练集全局坏样本率填充 global_bad_rate 0.023 # 从train_final.csv里预先算好 encoded_col encoded_col.fillna(global_bad_rate)时间窗口特征未对齐比如login_failure_count_24h是基于当前时间往前推24小时统计的。如果predict.py运行时用的是系统当前时间而训练时用的是日志里的login_time就会错位。正确做法是所有时间窗口特征必须以login_time为基准计算而不是now()。preprocessing.py里所有pd.Timestamp.now()都被替换成了df[login_time].max()。排查技巧写一个debug_pipeline.py随机选10条训练集样本手动走一遍preprocessing.py的每一步打印中间结果再用同样10条样本走predict.py对比每一步的输出。差异出现在哪一步问题就在哪。5.3 AUC很高但线上误报率爆炸你需要“业务校准曲线”模型在测试集上AUC0.93但部署后每天产生2000条告警安全工程师点开一看80%是正常用户比如运维半夜重启服务。这不是模型坏了而是阈值没校准。AUC只关心排序能力不关心绝对分值。解决方案是画“业务校准曲线”用predict.py对测试集输出risk_score按分值从高到低排序每100个样本为一组计算每组的实际风险率sum(is_risky_login)/100画散点图X轴是模型分值Y轴是实际风险率。你会发现当模型输出0.7时实际风险率只有0.3输出0.9时实际风险率才到0.6。这意味着不能直接用0.5当阈值。我们提供了一个calibrate_threshold.py脚本它会找到使“误报率≤5%”的最低分值比如0.87并输出对应的实际召回率比如62%。这个0.87才是你应该配置到SOAR规则里的阈值。经验总结在风控场景“宁可漏过不可误杀”是铁律。我们建议首次上线用保守阈值保证误报率3%运行两周收集反馈再逐步下调。calibrate_threshold.py里还内置了“成本敏感调整”功能——如果你知道封禁一个正常用户损失1000元而漏掉一个恶意用户损失50000元它能自动算出最优阈值。这才是真正的业务驱动建模。6. 扩展与演进从单点检测到闭环风控体系这套资源的终点不是predict.py输出一个CSV而是成为你风控体系的一个活的组件。我们已经在多个客户现场验证了三条演进路径路径一对接SOAR实现“检测-研判-处置”闭环把predict.py包装成REST API用FastAPI50行代码SOAR平台定时调用拿到高风险会话列表后自动触发以下动作- 查询该用户近7天所有登录记录生成行为时间线图用static/目录存图- 调用AD域控API临时禁用账号requests.put(https://ad-api/disable, json{user_id: u123})- 发送企业微信告警附上problem.png里的决策逻辑图“因凌晨登录新设备IP地理冲突风险分0.92”。这样原来需要安全工程师手动查30分钟的事件现在30秒自动完成。路径二嵌入UEBA构建用户行为基线把IsolationForest.py的输出不只是当风险分而是当“偏离度”。对每个用户每周计算一次其登录行为的平均偏离度存入时序数据库InfluxDB。当某用户本周偏离度突增3倍就触发“用户行为漂移”告警——这比单纯看单次登录更早发现异常比如黑客长期潜伏慢慢试探权限。路径三反哺规则引擎形成人机协同把XGBoost里重要性Top 5的特征如feat_login_hour,feat_ip_country_cn和它们的分箱阈值如login_hour in [0,1,2,3,4,5]自动生成Sigma规则title: 凌晨中国IP登录异常 logsource: category: authentication product: windows detection: selection: EventID: 4624 Login_Hour: 0 or 1 or 2 or 3 or 4 or 5 IP_Country_Code: CN condition: selection这样模型发现的模式就变成了可审计、可解释、可下线的规则真正实现“AI辅助专家而非替代专家”。最后分享一个小技巧在models/目录下我们预留了一个ensemble/子目录。你可以把6个模型的预测结果xgb_pred.csv,iforest_pred.csv等读进来用一个轻量级逻辑回归做stacking——它的输入是6个风险分输出是最终分。这个stacking模型不需要重新训练用sklearn.linear_model.LinearRegression拟合就行它能自动学习“什么时候该信XGBoost什么时候该信IsolationForest”。我们实测stacking后AUC提升0.008但更重要的是它的预测稳定性大幅提升单个模型失效时整体仍能维持85%以上准确率。这才是生产环境要的鲁棒性。本文还有配套的精品资源点击获取简介直接上手就能跑的认证风控项目提供已清洗的训练集train_dataset.csv和测试集test_dataset.csv覆盖从数据预处理、IV值筛选、标准化到六种算法建模的完整链路。内置逻辑回归、SVM、XGBoost、孤立森林、One-Class SVM、局部离群因子的独立训练脚本如LR_train.py、IsolationForest.py所有模型统一通过predict.py调用预测结果。特征工程模块preprocessing.py、iv.py封装清晰支持快速迁移到其他账号安全或行为审计场景。附带相关性热力图、问题定义图、运行环境说明Python 3.8 Anaconda、依赖清单requirements.txt及示例提交文件submit_example.csv。models目录存有训练好的模型文件static存放可视化中间结果datasets和feature engineering目录结构分明方便教学演示、SOAR规则验证、UEBA原型搭建或算法岗技术面试准备。本文还有配套的精品资源点击获取