監査データサイエンス研究の実務応用を考える


こんにちはのろのろでございます。こちらは、会計系Advent Calendarの12月6日分として書いています。記事の内容は監査におけるデータサイエンスの応用研究を調査し、実務的な応用を考えながらまとめたものです。いろいろ手を出しすぎて発散しております。

1 監査データサイエンス

デジタル化が進展し、企業データは財務報告と切り離せない存在になりつつあります。会計監査ではデータサイエンスの手法を応用できる場面が増えてきています。

図1 会計分野におけるデータマイニング研究。括弧内の数値は文献数です。(出典: Amani and Fadlalla. International Journal of Accounting Information Systems 24, p.36.)

図1はAmaniとFadlalla (2017)によって調査された、2017時点までの会計分野ジャーナルやその引用文献のうちデータマイニングを扱っている209の文献の分類を示しています("データマイニング"は"データサイエンス"の少し古い表現でほぼ同義)。"Auditting"は22/209件で監査データサイエンスも会計データサイエンス研究の一つの主要な分野と言えるでしょう。 この記事では監査におけるデータサイエンスに焦点を当てている研究をいくつかピックアップし、いくつかはコードを動かしながら、どのように監査業務に活かしていくかを考えていきます。この記事は包括的な先行研究のレビューではない点はご了承ください。なお、データ分析を用いる監査のことは、Audit analyticsとも呼ばれていますが、"アナリティクス"はビジネス現場での応用の意味合いが強いため、ここでは研究領域として監査(における)データサイエンスと呼びます。

2 財務報告書データへのデータサイエンス

利害関係者のために作成された財務報告書は上場しているのであればインターネットで公開されています。そのため、公開されている財務諸表データを用いた研究は盛んに行われています。

2_1 不正会計予測モデルの概要と実践

まずは不正会計予測モデルについて紹介します。不正会計予測モデルは財務報告書の財務数値やテキスト情報のデータからその財務報告が不正であるかを予測するモデルです。図2はそのイメージを示しています。図の赤の点は不正財務報告書、青の点は正しい財務報告書です。財務報告書の特徴量2つをx軸y軸で図のようにプロットしたとき、赤と青の点をうまく分ける点線をデータから機械学習により推定します。(実際には特徴量は2つ以上あるため高次元でこれが行われます。)

図2 不正会計予測モデルのイメージ図

機械学習モデルにはロジスティック回帰(Dechow et al., 2011)をはじめとして様々なデータサイエンスの予測手法が用いられています。また、日本のデータを使った研究もあります(Song etal., 2016)。ここでは、Baoらによって行われた研究をpythonで実施しながら紹介します(Baoらはmatlabのコードを公開していますが、それをpythonで実装しいくつかの分析例を追加しています)。この研究では不正ラベルを含めたデータセットが公開されており、追試が可能となっています。 github.com

こちらのリポジトリのデータを利用します。

Bao et al., 2020で用いられたデータはニューヨーク証券取引所)、NASDAQ(ナスダック証券取引所)、NYSE American(旧アメリカン証券取引所)等に上場している企業の財務数値であり、このうち、SECのリリースしたAccounting and Auditing Enforcement Releases (AAER)が存在する場合を不正ラベルとしています(AAERの観測と本当に不正があったかは必ずしも整合しているわけではない点は注意が必要です)。 必要なライブラリを準備します。

#python 3.10.12
import lightgbm as lgb # 4.1.0
import pandas as pd # 1.1.3
import numpy as np # 1.26.2
import shap # 0.42.0

from imblearn.ensemble import RUSBoostClassifier # 0.11.0
from sklearn.linear_model import LogisticRegression # 1.3.2
from sklearn.metrics import roc_auc_score,roc_curve,precision_recall_curve,auc,confusion_matrix
import matplotlib.pyplot as plt # 3.7.1

次にデータ(リポジトリ内のdata_FraudDetection_JAR2020.csv)をロードします。

# データの読み込み
filename="PATH_TO_DATASET/data_FraudDetection_JAR2020.csv"
data_FraudDetection_JAR2020=pd.read_csv(filename)

図3 Bao et al., 2020のデータセットの様子

この研究ではRUSBoostというブースティングモデルが用いられ、既存研究のロジスティック回帰やサポートベクターマシンより精度が良いようです。 RUSBoostはAdaboostというアンサンブル法をベースとした手法です。アンサンブル法では学習データからたくさんのサンプルセットを抽出しそれらを順に学習していく中でモデルを改善していくのですが、RUSboostでは、正例(不正な財務データ)の数に等しくなるように、過剰にある負例(正しい財務データ)からサンプリングします。今回のように正例と負例の割合が大きく異なっている場合に有効です。

今回はBao et al. 2020で最もパフォーマンスが良かったRUSBoostに加え、一般的にテーブルデータで高いパフォーマンスを出しやすいLightGBM、論文中で比較対象とされているロジスティック回帰を試してみました。 学習に用いるデータは財務数値の生データをそのまま特徴量として使用しています。(Bao et al., 2020の中で特徴量に比率を用いた場合よりも精度が高いと報告されています。)

roc_auc_list=[] #結果格納用リスト

# LightGBMハイパーパラメータ(チューニングは特にしていません)
param_fixed_lgbm = {
                'boosting_type': 'gbdt',
                'metric': 'binary_logloss',
                'num_iterations': 10000,
                'lambda_l1': 0,
                'lambda_l2': 0,
                'random_seed': 42,
                'objective': 'binary',
                'learning_rate': 0.1,
                'num_leaves': 300,
                'min_data_in_leaf': 50,
                'min_sum_hessian_in_leaf': 20,
                'bagging_fraction': 0.5,
                'bagging_freq': 4,
                'feature_fraction': 0.5
}
# 特徴量カラム(rawデータカラム)
fs_raw_columns_dict={
    'act':'Current Assets, Total',
    'ap':'Account Payable, Trade',
    'at':'Assets, Total',
    'ceq':'Common/Ordinary Equity, Total',
    'che':'Cash and Short-Term Investments',
    'cogs':'Cost of Goods Sold',
    'csho':'Common Shares Outstanding',
    'dlc':'Debt in Current Liabilities, Total',
    'dltis':'Long-Term Debt Issuance',
    'dltt':'Long-Term Debt, Total',
    'dp':'Depreciation and Amortization',
    'ib':'Income Before Extraordinary Items',
    'invt':'Inventories, Total',
    'ivao':'Investment and Advances, Other',
    'ivst':'Short-Term Investments, Total',
    'lct':'Current Liabilities, Total',
    'lt':'Liabilities, Total',
    'ni':'Net Income (Loss)',
    'ppegt':'Property, Plant and Equipment, Total',
    'pstk':'Preferred/Preference Stock (Capital), Total',
    're':'Retained Earnings',
    'rect':'Receivables, Total',
    'sale':'Sales/Turnover (Net)',
    'sstk':'Sale of Common and Preferred Stock',
    'txp':'Income Taxes Payable',
    'txt':'Income Taxes, Total',
    'xint':'Interest and Related Expense, Total',
    'prcc_f':'Price Close, Annual, Fiscal'}

for test_year in range(2003,2014+1):
    rst_dict={'rusboost_auc':None,'lightgbm_auc':None,'logit_auc':None} # 結果格納用dict
    train_end_year=test_year-2 # 学習期間の終点をテスト対象の期間の2年前とする
    data_train=data_FraudDetection_JAR2020.query("fyear <= @train_end_year and fyear >= 1991")
    x_train=data_train[list(fs_raw_columns_dict.keys())] # 特徴量カラムを選択
    y_train=data_train.misstate
    paaer_train_set=set(data_train.p_aaer)
    
    data_test=data_FraudDetection_JAR2020.query("fyear == @test_year")
    x_test=data_test[list(fs_raw_columns_dict.keys())] # 特徴量カラムを選択
    y_test=data_test.misstate
    paaer_test_set=set(data_test.p_aaer)

    mask=y_train.index.isin(paaer_train_set&paaer_test_set) # AAERは連続した年度で観測されるため(遡及するため)評価データと学習データの両方に含まれていた場合には学習データを正常ラベルに置き換える
    y_train.loc[mask]=0

    # RUSboosting
    clf = RUSBoostClassifier(random_state=0,n_estimators=300,learning_rate=0.1,sampling_strategy=1) # 論文著者がハイパーパラメータ探索し最良と思われるものを使用
    clf_fit=clf.fit(x_train, y_train)
    pred_score=clf.predict_proba(x_test)[:,1]
    rst_dict['rusboost_auc']=roc_auc_score(y_test, pred_score)

    # lightgbm
    model_clf_lgbm = lgb.LGBMClassifier(**param_fixed_lgbm)
    model_clf_lgbm.fit(x_train,y_train)
    pred_score_lgbm=model_clf_lgbm.predict_proba(x_test)[:,1]
    rst_dict['lightgbm_auc']=roc_auc_score(y_test, pred_score_lgbm)

    # logit
    lr = LogisticRegression(max_iter=10000)
    lr.fit(x_train, y_train)
    pred_score_lr=lr.predict_proba(x_test)[:, 1]
    rst_dict['logit_auc']=roc_auc_score(y_test, pred_score_lr)
    roc_auc_list.append(rst_dict)

print(pd.DataFrame(roc_auc_list).mean()) # AUCの平均値の表示
    

出力

rusboost_auc    0.697540
lightgbm_auc    0.730373
logit_auc       0.661345

予測は各モデルに実装されている"predict_proba"メソッドを持ちいて0〜1の予測スコアとして出力できます。1に近いほど正例(不正財務報告)である可能性が高いと解釈できます。 予測の精度は評価期間をスライドしながら計算したAUC(偽陽性率(False Positive Rate)を、縦軸に真陽性率(True Positive Rate)をプロットした曲線の曲線下面積で1に近いほど良い)を平均したAUC(時系列におけるクロスバリデーション指標です)で評価しています。

こちらに載っているRUSBoostの平均AUCが0.719なので乱数等の原因で少しずれていますが、ロジスティック回帰よりもAUCが高い点は再現できました。(LightGBMが最もAUCが高い結果となりましたので以降はLightGBMを用います)

後の分析例のためにテストデータを2014年以降として再度LightGBMのモデルを学習します。

test_year=2014
train_end_year=test_year-2 # 学習期間の終点をテスト対象の期間の2年前とする
data_train=data_FraudDetection_JAR2020.query("fyear <= @train_end_year and fyear >= 1991")
x_train=data_train[list(fs_raw_columns_dict.keys())] # 特徴量カラムを選択
y_train=data_train.misstate
paaer_train_set=set(data_train.p_aaer)
data_test=data_FraudDetection_JAR2020.query("fyear >= @test_year")
x_test=data_test[list(fs_raw_columns_dict.keys())] # 特徴量カラムを選択
y_test=data_test.misstate
paaer_test_set=set(data_test.p_aaer)
mask=y_train.index.isin(paaer_train_set&paaer_test_set) # AAERは連続した年度で観測されるため(遡及するため)評価データと学習データの両方に含まれていた場合には学習データを正常ラベルに置き換える
y_train.loc[mask]=0
model_clf_lgbm = lgb.LGBMClassifier(**param_fixed_lgbm)
model_clf_lgbm.fit(x_train,y_train)
pred_score_lgbm=model_clf_lgbm.predict_proba(x_test)[:,1]

2.2 不正会計予測モデルのいくつかの問題

2.2.1 評価指標について

AUCは汎用的な評価指標として良く用いられますが、本来は応用するタスクで求められる指標で評価すべきです。

例として、ある監査法人がクライアントの10%に不正に強い監査人をアサインすると考えます。この状況では、スコア上位10%の企業にどれだけ不正財務データ(正例)が含まれているかが見るべき指標の一つになります。この指標はPrecisionと呼ばれています。

mask=pred_score_lgbm>np.quantile(pred_score_lgbm,0.90) # スコア上位10%以上にフラグを立てる
base_precision=y_test.sum()/len(y_test) # 全体の正例割合
print("base_precision:",base_precision)
lgbm_precision=y_test[mask].sum()/mask.sum()# スコア上位10%の正例割合
print("lgbm_precision:",lgbm_precision)
print("rate:",lgbm_precision/base_precision)# スコア10%に絞ることで正例割合が何倍になるか

出力

base_precision: 0.0007108583614714769
lgbm_precision: 0.003552397868561279
rate: 4.997335701598579

ということでLightGBMのスコア上位10%に絞ることで正例割合を5倍近くまで上げることができました。 一方、取りこぼしの無さを重視する場合には、スコアで絞った中に全体の正例のうちいくつ含まれているかといった指標(真陽性率)で評価します。Recallとも呼ばれています。別のケースでは、例えば、監査契約の受注判断時には機械学習の予測スコアが閾値以下を条件とすることを想定し、例えば、予測スコア0.3以下に絞った場合に正例がどのくらい含まれてしまうかで判断すると良いでしょう。

このように、目的に応じた精度を把握することで、予測スコアにどのくらいの信頼を置いていいかを把握しながら利用していくことができます。

2.2.2 学習データの選択バイアス

学習で用いているデータは1991年〜2008年までの上場企業のデータです。つまり、非上場の財務データにこれを適用しようとすると、平均的な学習データと乖離しています。また、上場企業であっても、2008年以降のデータではそれ以前から経済状況も変わってくるため、平均的に学習データと乖離してしまいます。

このような場合を共変量シフト(Sugiyama et al., 2012)と呼び、ドメイン適応と呼ばれる手法で対応できます。例えば、上の例では非常上企業の財務データや直近の財務データのように適応させたい特徴量データがあれば(不正かどうかの正解ラベルは不要)、重要度重み付き損失を用いて適応させることができます。 LightGBMでは引数"weight"に重要度を渡すことで実施できます。

lgb.LGBMClassifier(**param_fixed_lgbm, weight=importance_weight_array)

この重要度とは適応元の学習データの分布と適応先の学習データの分布の密度比です。適応元の学習データと適応先の学習データの分類をロジスティック回帰モデルに学習させ、その適応先である確率の推定値pを用いて、重要度=(1-p)/pとして代用することもあります。

2.3 不正会計予測モデルの応用

2.3.1 財務諸表全体としてのリスク評価

不正会計予測モデルの出力する予測スコアは監査計画のためのリスク評価や受注判断のためのリスク評価として使用できます。

相対比較をする場合には気にしなくて良いのですが、不正予測スコアそのものを確率として解釈したい場合には、注意が必要です。 不均衡データへの対応としてアップサンプリング/ダウンサンプリングをして正例と負例の割合を変更していると予測スコアが確率とずれてしまう点に注意が必要です(Pozzolo et al., 2015)。こちらの解説がわかりやすいです。

pompom168.hatenablog.com

また、lightGBMなどのアンサンブル法を使っていてもアルゴリズム内のサンプリングに起因しずれてしまうようです。以下のようにscikit-learnのCalibrationCVというライブラリで修正する方法もありますが、筆者の経験ではある程度データがないと綺麗に修正できません。

from sklearn.calibration import calibration_curve,CalibrationDisplay
from sklearn.calibration import CalibratedClassifierCV
lgb_calibrated_model = CalibratedClassifierCV(model_clf_lgbm, method='sigmoid', cv=5)
lgb_calibrated_model.fit(x_train, y_train)

確率予測を行う場合にはダウンサンプリング等を行わずにロジスティック回帰モデルを用いると経験的にずれが生じにくく良いでしょう。

2.3.2 個別アサーションのリスク評価

個別の勘定科目が特徴量に紐づいている場合、不正予測モデルの予測スコアが割り付けられた財務諸表データについて、どの特徴量が決め手となったか(機械学習モデルの判断根拠)を推定することで、個別の勘定科目のリスク評価に役立てることができます。このように判断根拠を推定する方法は説明可能AIという分野で研究が進められています。ここではSHAPという手法で予測値に説明を与えます。SHAPライブラリは他のライブラリへの依存が強いため、使用するpythonのバージョンに注意してください。

import shap 
explainer   = shap.TreeExplainer(model_clf_lgbm)
shap_values = explainer.shap_values(x_train)
ind=3 # 3番目のデータの予測値の説明をウォーターフォール図で示す
shap.plots._waterfall.waterfall_legacy(explainer.expected_value[1], shap_values[1][ind],x_train_rename.iloc[ind,:])

図4 SHAPによる予測スコアの説明

図4は3番目のデータの予測値の説明をウォーターフォール図で示しています(加減算で示せるように予測スコアは対数ロジット変換されています)。 3番目のデータの予測値の対数ロジット値-5.001は、ベースとする平均予測値の対数ロジット値-6.862より1.861多くなっていますが、この主な要因は「Long-term Dept issuarance」(長期の保証債務)や「Price Close, Annual, Fiscal」(会計期間における株価の終値のようです)のように、特徴量の予測値への推定貢献度の和として表すことができます。ただし、必ずしもこれらの特徴量が直接の原因となっているわけではない点(例えば不正が起こりやすい業種の特徴が勘定科目の特徴として観測されている場合がある)には注意が必要です。

さらに、勘定科目が説明可能AIで提示できたとしても、特に不正ラベルを教師データとして学習した不正会計予測モデルの予測スコアは不正リスクに関係するため、監査人は具体的に不正のシナリオを把握する必要があります。その説明可能AIによる特徴量の貢献度だけでなく、判断が類似した教師データを参照することが望ましいです。例えばSHAPによる各特徴量の推定貢献度の相関係数が大きい不正財務データを検索することで、判断根拠の近いデータを参照することができます。その企業を調べることで不正ラベルの原因となった不正事例を把握し、不正リスクを識別するかの判断に活かすことができます。過去の不正についてデータベースを作っていれば検索の手間がかかりません。

2.4 開示レビューへのデータサイエンス

財務数値だけでなく財務報告書そのものに対してのモデルも研究されています。Biesner et al., 2022では財務報告書の段落とチェックリストとのマッチングをsentenceBERTという手法で学習しています。sentenceBERTはtransformerをベースとしたニューラルネットワークの2段階の学習からなり、1つ目はテキストそのものの学習です。直前までの文書から次に続く文の予測や前後の単語からマスキングされた単語を予測するタスクで学習します。2つ目は同じ画像についている複数のキャプション文章の一致(不一致)を学習します。Biesner et al., 2022では2段階目の学習を財務報告書の段落とチェックリストのマッチングとして行います。学習データは財務報告書の段落がチェックリストの内容に該当した場合にフラグをつけるアノテーション監査法人が行なったもののようです。

図5 財務報告書のテキストとチェックリストのマッチングのイメージ(出典:Biesner, D. , Pielka, M. , Ramamurthy, R. , Dilmaghani,T. , Kliem, B. , Loitz, R., Sifa, R. (2022). Zero-Shot Text Matching for Automated Auditing using Sentence Transformers. 21st IEEE International Conference on Machine Learning and Applications, p.1638.)

監査人がチェックリストをもとに財務報告書のレビューを行う場合、チェックリストに関連する箇所を財務報告書から探し、それがチェックリストの内容に準拠しているか確認します。このうちチェックリストに関連する箇所を財務報告書から探す過程はBiesner et al., 2022の手法で自動化することで時間短縮ができると思います。 財務報告書からの情報抽出の研究は、他にもKPI情報抽出(Ramamurthy et al., 2021)やリスク要素の抽出(Tsai and Wang 2017)等があります。これらは自然言語処理分野の知識抽出(固有表現抽出)タスクを財務報告書に応用しています。自然言語処理の研究はchatGPTをはじめとした大規模言語モデルの登場により大きくパフォーマンスを向上させているため、今後この分野のパフォーマンスの向上が期待できます。

3 トランザクションデータへのデータサイエンス

トランザクションデータは企業の経済取引や業務の記録をイベント単位で記録しているデータです。財務報告書は会計に関連するトランザクションを集計して作成されるため、トランザクションデータは財務報告書よりも時間的にも科目的にも細かい情報を持っています。トランザクションデータは膨大になるので監査人が目視でレビューするのは大変です。 トランザクションデータに対する不正検知や異常検知は盛んに研究されてきました。正常トランザクションデータの入力パターンを学習しておくことで、企業が不正なトランザクションを挿入した時に、学習した正常トランザクションのパターンからの異常として検知することが狙っています。例えば、トランザクションデータの異常検知を目的として、クラスタリング(例えばJans et al., 2010)や自己組織化マップを用いた研究(例えばArgyrou 2012)や、プロセスマイニングの手法を転用したもの(例えばEvermann et al., 2017)もあります。近年はニューラルネットワークのパフォーマンス向上により、トランザクションデータの異常検知分野ではAuto-encoder(VAE、GANなどの類似手法含む)の研究がたくさんでてきます。ここではSchreyer et al., 2017を紹介します。

3.1 オートエンコーダを用いたトランザクションデータの異常検知

Schreyer et al., 2017もソースコードpython)とデータセットが公開されており、追試が可能となっています。

github.com

図6 オートエンコーダによるトランザクションデータの異常検知(出典:Schreyer, M., Sattarov, T., Borth, D., Dengel, A.R., & Reimer, B. (2017). Detection of Anomalies in Large Scale Accounting Data using Deep Autoencoder Networks. ArXiv, abs/1709.05254.)

オートエンコーダを用いたトランザクションデータの異常検知は図6のように行われます。図の丸いノード群はニューラルネットワークを示します。トランザクションデータをニューラルネットワークの入力とし、また、出力もトランザクションデータに近づけるように学習します。オートエンコーダのニューラルネットワークの中間層は入力層よりもノードの数が少ないため、入力された情報を一度圧縮し出力を再構成します。この圧縮の過程で入力されるトランザクションデータの潜在的なパターンを学習します。異常判定対象のデータについて、正常データで学習したオートエンコーダで再構成したときの誤差が大きいほど異常度が高いとしています。

3.2 トランザクションデータの異常検知の問題点

トランザクションデータの異常検知で問題になるのが、データ量です。大企業でもない限り、1企業のデータではトランザクションデータの入力規則を十分に学習するには不十分な場合が多いです。複数の企業のデータを使いたいところですが、内部監査で他社のデータを使用することは通常できず、外部監査でも監査人がクライアントのデータをそのまま一緒に使うことは情報管理の観点から問題があります。そこであらかじめトランザクションデータの表現を学習しておいて、下流の監査タスクの精度を高めるアプローチが提案されています(Schreyer et al., 2021)。Schreyer et al., 2021では、SimCLRという自己教師あり学習(オートエンコーダによる学習と目的は同じ)でトランザクションデータの入力規則を事前学習することで、後続する個別の監査タスクの精度を向上させます。事前学習と個別の監査タスクの学習の2段階に分けることで、事前学習に監査対象外のものも含めたトランザクションデータ(例えば監査対象年度より前のトランザクションデータ)を用いてデータ量を補うことができます。

外部監査において、監査人がクライアントのデータをそのまま一緒に使うことは情報管理の観点から難しいのですが、クライアントのデータの秘匿性を維持しながら機械学習モデルを訓練させる手法が研究されています。学習データを異なるサーバーに分散して保存しながら一つの機械学習モデルを学習させる連合学習では、機械学習モデルの学習のための勾配にノイズを加えることで、それぞれの学習データの秘匿性を維持しています。Schreyer et al., 2022はそのフレームワークの一つであるDP-SGDを会計トランザクションデータに応用しています。

3.3 トランザクションデータの異常検知の応用

3.3.1 業務フローや内部統制の理解への応用

プロセスマイニングの手法はトランザクションデータの異常検知に転用されていますが、プロセスマイニングの手法自体を監査で使用することができます。 プロセスマイニングは業務やシステムのログの前後関係からプロセスの構造を抽出する手法です。 例えば、次のようなトランザクションを記録したテーブルがあるとします。

図8 会計トランザクションデータの例

このトランザクションデータは受注トリガーで製品を仕入販売する企業をイメージして作成しています。"case_id"カラムは一つの受注契約にいくつかのトランザクションデータ(仕入、販売、買掛金支払、売掛金回収)を紐づけています。プロセスマイニングはこれらのトランザクションデータの入力規則を視覚的に把握する手法です。入力規則を数え上げる手法はpythonライブラリ"pm4py"を用いて実施できます。

ここでは図8の会計トランザクションデータが"example_log_df"の変数に格納されています。これをpm4pyのフォーマットにすることで可視化することができます。この際に仕分のパターンを横に繋て一つのカラムにまとめています。

import pm4py
import pandas
import datetime as dt

# トランザクションデータセットを作成
example_log=[
    {'case_id':1,'d_account':'仕入','c_account':'買掛金','amount':100,'ts':'2022/1/3 10:00:00'},
    {'case_id':1,'d_account':'買掛金','c_account':'当座預金','amount':100,'ts':'2022/2/20 9:30:00'},
    {'case_id':1,'d_account':'売掛金','c_account':'売上','amount':500,'ts':'2022/1/21 11:00:00'},
    {'case_id':1,'d_account':'当座預金','c_account':'売掛金','amount':500,'ts':'2022/2/18 9:00:00'},
    {'case_id':3,'d_account':'仕入','c_account':'買掛金','amount':500,'ts':'2022/1/5 10:00:00'},
    {'case_id':3,'d_account':'買掛金','c_account':'当座預金','amount':500,'ts':'2022/2/20 9:30:00'},
    {'case_id':3,'d_account':'売掛金','c_account':'売上','amount':800,'ts':'2022/2/23 11:00:00'},
    {'case_id':3,'d_account':'当座預金','c_account':'売掛金','amount':800,'ts':'2022/3/20 9:00:00'},
    {'case_id':4,'d_account':'仕入','c_account':'買掛金','amount':100,'ts':'2022/1/17 10:00:00'},
    {'case_id':4,'d_account':'買掛金','c_account':'当座預金','amount':100,'ts':'2022/2/20 9:30:00'},
    {'case_id':4,'d_account':'売掛金','c_account':'売上','amount':500,'ts':'2022/2/23 11:00:00'},
    {'case_id':4,'d_account':'当座預金','c_account':'売掛金','amount':500,'ts':'2022/3/9 9:00:00'},
    {'case_id':5,'d_account':'仕入','c_account':'買掛金','amount':100,'ts':'2022/2/3 10:00:00'},
    {'case_id':5,'d_account':'買掛金','c_account':'当座預金','amount':100,'ts':'2022/3/20 9:30:00'},
    {'case_id':5,'d_account':'売掛金','c_account':'売上','amount':500,'ts':'2022/2/13 11:00:00'},
    {'case_id':5,'d_account':'当座預金','c_account':'売掛金','amount':500,'ts':'2022/3/18 9:00:00'},
    {'case_id':2,'d_account':'仕入','c_account':'買掛金','amount':200,'ts':'2022/1/23 10:00:00'},
    {'case_id':2,'d_account':'買掛金','c_account':'当座預金','amount':200,'ts':'2022/2/2 9:30:00'},
    {'case_id':2,'d_account':'商品','c_account':'仕入','amount':200,'ts':'2022/1/31 12:59:00'},
    {'case_id':2,'d_account':'仕入','c_account':'商品','amount':200,'ts':'2022/2/1 0:00:00'},
    {'case_id':2,'d_account':'売掛金','c_account':'売上','amount':600,'ts':'2022/2/4 11:00:00'},
    {'case_id':2,'d_account':'当座預金','c_account':'売掛金','amount':600,'ts':'2022/2/12 9:00:00'},
    {'case_id':9,'d_account':'仕入','c_account':'当座預金','amount':100,'ts':'2022/3/3 10:00:00'},# Cに100支払い
    {'case_id':9,'d_account':'当座預金','c_account':'売上','amount':500,'ts':'2022/3/21 11:00:00'},# Aから500収入
    {'case_id':12,'d_account':'仕入','c_account':'当座預金','amount':500,'ts':'2022/3/3 10:00:00'},# Cに500支払い
    {'case_id':12,'d_account':'当座預金','c_account':'売上','amount':800,'ts':'2022/3/21 11:00:00'},# Aから800収入
    {'case_id':10,'d_account':'出資金','c_account':'当座預金','amount':700,'ts':'2022/3/30 9:00:00'},# Bに投資
    {'case_id':7,'d_account':'出資金','c_account':'当座預金','amount':300,'ts':'2022/1/4 9:00:00'},# Bに投資
    {'case_id':6,'d_account':'仕入','c_account':'当座預金','amount':100,'ts':'2022/1/3 10:00:00'},
    {'case_id':6,'d_account':'当座預金','c_account':'売上','amount':500,'ts':'2022/1/7 11:00:00'},
    {'case_id':7,'d_account':'仕入','c_account':'当座預金','amount':100,'ts':'2022/1/9 10:00:00'},
    {'case_id':7,'d_account':'当座預金','c_account':'売上','amount':500,'ts':'2022/1/13 11:00:00'},
    {'case_id':11,'d_account':'仕入','c_account':'当座預金','amount':100,'ts':'2022/1/22 10:00:00'},
    {'case_id':11,'d_account':'当座預金','c_account':'売上','amount':500,'ts':'2022/1/27 11:00:00'},
    {'case_id':8,'d_account':'仕入','c_account':'買掛金','amount':100,'ts':'2022/1/23 10:00:00'},
    {'case_id':8,'d_account':'買掛金','c_account':'当座預金','amount':100,'ts':'2022/2/2 9:30:00'},
    {'case_id':8,'d_account':'商品','c_account':'仕入','amount':100,'ts':'2022/1/31 12:59:00'},
    {'case_id':8,'d_account':'仕入','c_account':'商品','amount':100,'ts':'2022/2/1 0:00:00'},
    {'case_id':8,'d_account':'売掛金','c_account':'売上','amount':500,'ts':'2022/2/4 11:00:00'},
    {'case_id':8,'d_account':'当座預金','c_account':'売掛金','amount':500,'ts':'2022/2/12 9:00:00'},
    {'case_id':12,'d_account':'仕入','c_account':'買掛金','amount':100,'ts':'2022/3/1 10:00:00'},
    {'case_id':12,'d_account':'買掛金','c_account':'当座預金','amount':100,'ts':'2022/3/20 9:30:00'},
    {'case_id':12,'d_account':'売掛金','c_account':'売上','amount':500,'ts':'2022/3/23 11:00:00'},
    {'case_id':13,'d_account':'仕入','c_account':'買掛金','amount':100,'ts':'2022/3/14 10:00:00'},
    {'case_id':13,'d_account':'売掛金','c_account':'売上','amount':500,'ts':'2022/3/25 11:00:00'},
    {'case_id':14,'d_account':'仕入','c_account':'買掛金','amount':300,'ts':'2022/3/22 10:00:00'},
    {'case_id':14,'d_account':'売掛金','c_account':'売上','amount':600,'ts':'2022/3/28 11:00:00'}
]
example_log_df=pd.DataFrame(example_log) # データフレームとして格納
example_log_df['timestamp']=pd.to_datetime(example_log_df.ts) # 時間情報をタイムスタンプ型に変換
example_log_df['account']=example_log_df['d_account']+'/'+example_log_df['c_account'] # 仕分パターンを定義
example_log_df_f = pm4py.format_dataframe(example_log_df, case_id='case_id', activity_key='account', timestamp_key='timestamp') # pm4pyフォーマットに変換

"pm4py"ライブラリではいくつかの手法で可視化できますが、今回はDirectly Follows Graphというパターンの数え上げの手法を試してみます。細かいパターンがある場合にはメジャーなパターンのみを学習させる方法が良いでしょう。 内部統制の監査では、業務プロセスの把握をしますが、業務プロセスのログからパターンを見つけておくと、どのような業務フローがあるかの整理に役立ちます(担当者のヒアリングでは把握漏れが発生する場合もあります)。ただし、この方法を効果的に使うためには、ある案件に紐づく会計処理などのアクションを識別するための案件キーが必要であり、これを管理している会社はかなり少ないのではないかと思います。案件キーがない場合でも、商品ごとや取引先ごとにいくつかの処理がある場合には、商品IDや顧客IDをキーにすることでフローを可視化することが可能になります。

dfg, start_activities, end_activities = pm4py.discover_dfg(example_log_df_f)
pm4py.view_dfg(dfg, start_activities, end_activities)

図9 DFG法によるプロセスの可視化

3.3.2 リスク評価への応用

トランザクションデータへの異常検知は財務報告に関連する取引の全量に対して行うことができ、会計監査におけるリスク評価として導入されつつあります。

例えば、トランザクションデータの入力規則をオートエンコーダに学習させ、オートエンコーダの再構成誤差(異常スコア)が大きい異常なデータについて監査上のリスクの候補にする応用ができます。機械学習の結果を人間が解釈するため、単なる異常スコアだけでなく、説明可能AI等の手法で解釈性を与えると良いでしょう。トランザクションデータは企業活動を取引レベルで記録していることが多く、細かいレベルでのリスク評価が可能になります。また、トランザクションデータに記録されているイベントが財務報告に反映されているかという点で網羅性の検討が可能になります。

3.3.3 仕訳テストへの応用

トランザクションデータへの異常検知の研究は不正なトランザクションの挿入を検知することを主な目的としています。そのため、会計監査のプロセスの一つである仕訳テストが自然な応用先です。仕訳テストは不正な仕訳を検知することを目的にしているため、検出した仕訳は不正対応が求められ監査人のリソースを多く消費します。 そのため、仕訳テストへの応用の際には高い精度が求められます。 トランザクションデータの異常検知モデルを導入する際には監査品質管理として、過去の不正発生時のデータとそうでないデータに対して実施し、精度評価することが重要です。評価指標としては2.2.1で紹介したPrecisionとRecallが適しています。 (現行の監査の基準に例示されているルールベースの仕訳テストで実施した場合の精度を超える場合には導入を検討しても良いと思いますが、ルールベースの仕訳テストの精度が評価されている報告は見たことがありません)

3.3.4 詳細テストや内部統制の運用評価手続への応用

詳細テストは精査(全件調査)か試査(一部を調査して母集団に対する結論を統計的に推論)のアプローチがありますが、トランザクションデータの異常検知モデルで精査を行うことはできません。オートエンコーダをはじめとする機械学習モデルの出力はあくまで仮説の出力であるため、そのデータが誤りであるかは別途検証(証憑突合など)が必要になるからです(精査へのデータサイエンスの応用は証憑突合の自動化などの領域になります)。ここでは試査への応用を考えてみます。

試査は特定項目抽出による試査とサンプリングによる試査があります。トランザクションデータの異常検知による異常判定を特定項目抽出として試査対象とすることができます。ただし、特定項目抽出による試査では異常と判定されていない残余母集団について結局のところ証票突合などの実証手続を検討する必要が生じるため、監査の効率は上がりません(品質は向上します)。ちなみに、PCAOB AS 2401では、重要で異常な取引についてその取引の合理性等を検討するよう規定されており、異常検知されたデータについてはこれに該当するか検討が必要になりそうです。

次に、サンプリングへの応用についてですが、ここでは統計的サンプリングへの応用を考えます。統計的サンプリングは抽出したサンプルを検証し、その結果から母集団の虚偽表示額や内部統制の逸脱数を統計的に推論する方法です。この際のサンプルサイズが監査の効率に大きく影響しますが、例えば内部統制の逸脱の評価では、母集団の逸脱数が許容される逸脱率(例えば9%)と等しいという帰無仮説を、検証したサンプルの標本逸脱数が0件のときに棄却できるように設計されています。標本調査のサンプルサイズは推定したい変数と相関する補助変数を用いることで推定値の誤差を維持しつつサンプルサイズを小さくすることができます。会計監査では虚偽表示リスク(内部統制では内部統制からの逸脱)と関係するスコアリングモデルやクラスタリングができれば、それを補助変数(クラスタリングの場合はカテゴリ変数)として母集団の虚偽表示額(逸脱率)の推定を少ないサンプルサイズで行うことができます。

ここで、母集団全体に対して異常検知モデルで異常スコアを算定したものを補助変数として用いるには、異常検知モデルによる異常度はあくまで異常度であることから潜在虚偽表示リスクとの相関が高いかどうか調べなければなりません。また、クラスタリングにでは、クラスターごとに虚偽表示率がある程度等しいというかどうかが重要です。オートエンコーダによるトランザクションデータの入力規則学習を監査サンプリングへの応用しようとしている研究があります(Schreyer et al., 2020)

図10 オートエンコーダによる監査サンプリング出発点のイメージ図(出典:Schreyer, M., Sattarov, T., Gierbl, A.,Reimer ,B. and Borth, D. (2020). Proceedings of the First ACM International Conference on AI in Finance (45). p.5)

この研究ではオートエンコーダの派生手法であるVQ-VAEの圧縮空間(潜在埋め込み空間)として監査サンプリングの出発点を提供しています。これらの埋め込み空間で近いデータ同士の虚偽表示率が等しいという前提を置くことができれば、監査での応用が期待できそうです。なお、この論文では、統計的サンプリングを意識した評価、すなわち無作為サンプリングに対しての比較やk-meansクラスタリングやルールベースのクラス分けとの比較がされていないため、統計的サンプリングの実用にはこれらの評価が必要です。

現行の監査の基準においても層化抽出や比例抽出などは規定されているものの(PASOB AS 2315)、その際に監査サンプリングで帰無仮説の逸脱率と信頼度を満たすサンプルサイズが少なくて済むかどうかまでわかって初めて単純無作為サンプリングを代替することができます。標本抽出法については理論があるものの、この辺りを監査に落とし込んでいる研究は少なく、データサイエンスの導入にあたりしっかりと整理する必要があると考えています。この場合の評価指標としては、デザイン効果や有効標本サイズ(Kish 1965)で評価するとよいでしょう。

4 その他のデータサイエンスの応用がしやすい領域

個別アサーションの見積りや分析的手続ではデータサイエンスの応用がしやすいです。例えば、引当金の見積額に対する監査人独自の評価範囲に機械学習モデルを利用できます。これらは予測タスクとして研究されていますが、監査用途を強く意識した研究はあまり多くなく、各論になってしまうのでここでは省略します。また、OCR、証憑レビューの自動化、文書検索、衛星データのように監査手段としての技術の応用ができますが、こちらも手段そのものが研究対象となっていますので省略します。

5 まとめ

監査へのデータ分析の適用可能な領域は多く、データサイエンスの様々な手法が活かされています。最近のデータサイエンス領域ではテキストや画像の表現学習のパフォーマンス向上が著しく、特にテキストデータが多く存在する会計データでもパフォーマンス改善が期待できます。一方で、会計データの特徴や監査固有の実務的な問題設定にデータサイエンス分野の手法でアプローチしていくような研究はまだまだ少なく、実用にはもう何段階か研究を進める必要がある印象です。データサイエンスを活かした研究が監査品質と効率性の向上に貢献することを期待しています。

参考文献

[1] Amani, F. A. Amani, Fadlalla, A. M. (2017). Data mining applications in accounting: A review of the literature and organizing framework. International Journal of Accounting Information Systems 24, pp. 32-58.

[2] Dechow, P. M., W. Ge, C. R. Larson, and R. G. Sloan. (2011). Predicting material accounting misstatements. Contemporary Accounting Research 28: pp. 17-82.

[3] Song, M., N. Oshiro, and Shuto, A. (2016). Predicting Accounting Fraud: Evidence from Japan. The Japanese Accounting Review 6: pp. 17-63.

[4] Bao, Y., Ke, B., Li, B., Yu, Y.J., and Zhang, J., (2020). Detecting accounting fraud in publicly traded u.s. Firms using a machine learning approach. Journal of Accounting Research 58, pp. 199–235.

[5] Sugiyama, M., Suzuki, T., and Kanamori, T. (2012). Density ratio estimation in machine learning. Cambridge, UK: Cambridge University Press.

[6] Pozzolo, A. D. , Caelen, O. , Johnson, R. A. and Bontempi, G. (2015). Calibrating Probability with Undersampling for Unbalanced Classification, 2015 IEEE Symposium Series on Computational Intelligence, Cape Town, South Africa, pp. 159-166.

[7] Biesner, D. , Pielka, M. , Ramamurthy, R. , Dilmaghani,T. , Kliem, B. , Loitz, R., and Sifa, R. (2022). Zero-Shot Text Matching for Automated Auditing using Sentence Transformers. 21st IEEE International Conference on Machine Learning and Applications, pp. 1637-1642.

[8] Ramamurthy, R., Pielka, M., Stenzel, R., Bauckhage, C., Sifa, R., Khameneh, T. M., Warning, U., Kliem, .B, and Loitz, R. (2021) ALiBERT: improved automated list inspection (ALI) with BERT. Proceedings of the 21st ACM Symposium on Document Engineering (20), pp. 1–4.

[9] Tsai, M. F. and Wang, C.J. (2017). On the risk prediction and analysis of soft information in finance reports. European Journal of Operational Research 257, pp. 243–250.

[10] Jans, M., Lubaert, N. and Vanhoof, K. (2010). Internal Fraud Risk Reduction: Results of a Data Mining Case Study. In: International Journal of Accounting Information Systems, 11(1). pp. 17-41.

[11] Argyrou, W. (2012). Auditing Journal Entries Using Self-Organizing Map. Proceedings of the Eighteenth Americas Conference on Information Systems.

[12] Evermann, J., Rehse, JR. and Fettke, P. (2017). A Deep Learning Approach for Predicting Process Behaviour at Runtime. In: Dumas, M., Fantinato, M. (eds) Business Process Management Workshops. BPM 2016. Lecture Notes in Business Information Processing (281)

[13] Schreyer, M., Sattarov, T., Borth, D., Dengel, A.R., and Reimer, B. (2017). Detection of Anomalies in Large Scale Accounting Data using Deep Autoencoder Networks. ArXiv, abs/1709.05254.

[14] Schreyer, M., Sattarov, T., and Borth, D. (2021). Multi-view contrastive self-supervised learning of accounting data representations for downstream audit tasks. Proceedings of the Second ACM International Conference on AI in Finance.

[15] Schreyer, M., Sattarov, T., and Borth, D. (2022). Federated and Privacy-Preserving Learning of Accounting Data in Financial Statement Audits. Proceedings of the Third ACM International Conference on AI in Finance.

[16] Schreyer, M., Sattarov, T., Gierbl, A.,Reimer ,B. and Borth, D. (2020). Proceedings of the First ACM International Conference on AI in Finance (45). pp. 1–8.

[17] Kish, L. (1965). Survey Sampling. John Wiley and Sons inc.

[18] Public Company Accounting Oversight Board (PCAOB). (2016). Audit Sampling. AS 2315.