seanxch5/JE_anomaly_detection

GitHub: seanxch5/JE_anomaly_detection

将经典审计启发式规则与 Isolation Forest 机器学习相结合,为日记账分录生成单一排序综合风险得分,帮助审计人员快速定位最值得关注的异常分录。

Stars: 0 | Forks: 0

# 日记账分录异常检测 这是一款风险分析工具,旨在标记值得审计人员关注的日记账分录。它将经典的审计启发式规则与无监督机器学习层相结合,为每条分录生成一个单一的排序风险得分。 ## 为什么开发此工具 日记账分录(JE)测试是财务报表审计和舞弊风险评估的标准环节。该工具无需人工为每条分录逐一核对五个独立的危险信号,而是将基于规则的审计启发式算法与机器学习异常检测器结合为一个综合得分,从而使最需要人工关注的分录能够浮现在单一排序列表的顶部。 该项目在风险与鉴证实习期间开发,是一个将数据科学应用于真实审计工作流的作品集项目。 ## 方法论 本 notebook 实现了五个检测层: | 测试 | 捕获内容 | |---|---| | 本福特法则 | 首位数字在总体层面的统计异常,这是数据造假的标志 | | 整数检测 | 金额为可疑的整数(例如恰好为整千)的分录 | | 职责分离 | 由同一人创建并审批交易的分录 | | 期末聚类 | 期末前异常的分录量激增(“突击处理”) | | Isolation Forest (ML) | 基于规则的测试可能遗漏的,在金额、时间和创建者/审批者模式组合中出现的异常 | 这些检测层被组合为一个加权的**综合风险得分**。权重的设定基于专业判断,反映出一个控制失效(SOD)比单纯的整数问题更严重。同时,对于被 ML 模型视为极端异常值的分录会给予额外加分,这样即使某条分录没有触发任何单一规则,近乎确定的异常也能浮出水面。 ## 数据要求 本 notebook 需要一个位于 `data/journal_entries.csv` 的 CSV 文件,并包含以下列: ``` entry_id, line_type, account, amount, date, created_by, approved_by ``` 列名目前被**硬编码**为该 schema。这是一个经过深思熟虑的、常见的范围界定决定,因为大多数内部审计/风险工具都是针对某一个特定源系统的导出格式构建的,而不是泛化以处理任意 schema。如果数据集的命名约定不同(例如使用 `editor` 而不是 `created_by`),则在运行前需要重命名以使其匹配。 ## 基于真实标签审查的关键发现 本数据集为合成数据(由本仓库中的 `generate_data.py` 生成),其中故意注入了已知异常:15 个 SOD 违规、25 个整数金额分录以及期末聚类调整。完整运行该 notebook 确认,每个基于规则的测试都准确恢复了其植入的数量(25/25 整数金额,15/15 SOD),并且期末聚类测试正确地将 2025 年第一季度识别为唯一具有统计异常的季度(每天 10.0 条分录,而干净基线为 5.49,阈值为 10.0)。 由于除了合成注入的数据外,没有独立标记的舞弊数据集,因此作为合理性检查,对排名靠前的分录也进行了人工审查: - **ML 层捕捉到了仅靠规则无法清晰标记的内容:** Isolation Forest 异常得分最高的分录是针对同一账户恰好 $7,230,000.00 的借记项,这些分录由不同的人在不同的日期提交,这种模式与重复或伪造的分录一致。 - **SOD 标记需要改进:** 在当前的实现中,无论交易金额大小,它都只进行简单的 0/1 触发,因此一条小额的自审分录目前的得分几乎与一条大额分录相同。这被记录为一个已知的局限性,下一步改进方向是引入基于交易金额的权重。 完整的分析(包括确切的数据)请参见 notebook 的第 9 节。 ## 项目结构 ``` ├── je_anomaly_detection.ipynb # Full analysis, all five tests + composite score + findings ├── generate_data.py # Builds the synthetic journal_entries.csv with known injected anomalies ├── README.md ├── data/ │ └── journal_entries.csv └── output/ ├── benford_chart.png ├── isolation_forest_chart.png └── iso_score_histogram.png ``` ## 运行说明 ``` pip install pandas numpy scikit-learn matplotlib jupyter python generate_data.py # generates data/journal_entries.csv jupyter notebook je_anomaly_detection.ipynb ``` ## 局限性与后续步骤 - 列名被硬编码为该项目的 schema(参见数据要求) - SOD 标记尚未按交易金额加权 - 独立脚本 `composite_test_score.py` 使用的是简化的期末占位符,而非 notebook 中经过校准的异常季度检测;这两者应该进行统一 - Isolation Forest 目前在整个代码库中使用了两个不同的 `contamination` 值进行了两次拟合(0.02 用于探索性可视化,0.05 用于综合得分);有必要进行标准化 - 综合得分权重基于专业判断得出,未经过基于标记结果的统计学验证 - 极端异常值阈值(0.95)仅在小样本上进行了检查;有必要在更大数据集上进行重新验证 ## 作者 Sean,波士顿学院 — 数学专业(辅修:数据科学与金融)
标签:Apex, NoSQL, 孤立森林, 审计工具, 异常检测, 本福特定律, 机器学习, 杀软绕过, 欺诈检测, 逆向工具, 风险分析