論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
完全性
Integrity
セキュリティ

🔖 キーワード索引

完全性(Integrity)は、データが改ざん・破損されず、決めたルールどおりの状態に保たれていること。下のチップは、それを守る 2 系統の道具を並べている。DB の制約(主キー・外部キー・CHECK)で「入れてはいけない値」を入口で止める系統と、チェックサム・ハッシュで「中身が 1 バイトも変わっていないか」を後から確かめる系統である。

完全性データ整合性CIA参照整合性チェックサム制約ACID

💡 30秒で分かる結論 — 完全性

🍰 まずはやさしく

データが正しく保たれていることです。

情報の書き換えを防ぐために使います。

スマホのデータが勝手に変わらない状態です。

完全性の意味と守り方を学びます。

最も忙しい読者のために、 まず結論だけまとめます。 詳細は以下のセクションへ:

📍 文脈 — どこで出会うか

🍰 まずはやさしく

データの正しさを守る仕組みのことです。

間違いや不正な変更に気づくために使います。

部活の名簿が書き換えられていないか確認します。

どこでこの考え方が使われるかを見ます。

「このデータベース、 数値が時々おかしくなる」 「学習データが何者かに書き換えられたら?」 — 完全性の問題です。 DB の制約、 ハッシュチェック、 電子署名など、 完全性を守る仕掛けは何重にも存在します。

🎨 直感で掴む

🍰 まずはやさしく

通帳の金額が勝手に変わらないイメージです。

正しい情報であることを証明するために使います。

買い物で支払った金額が正しく記録されることです。

直感的にどのような仕組みか考えます。

銀行の通帳に喩えると:

完全性が壊れると、 残高 100万 → 1000万 のような「都合の良い改ざん」が放置されます。 通帳記入のたびに ハッシュ照合 しているのが現代版。

📐 定義・数式

🍰 まずはやさしく

正しさを確かめるためのルールです。

データが改ざん(書き換え)されていないか調べます。

送ったメッセージがそのまま届いたか確認します。

計算を使って正しさを確かめる方法を読みます。

暗号学的ハッシュ関数 $H$ を使うと、 メッセージ $m$ の完全性は次のように検証できます:

【ハッシュによる完全性検証】
$$H(m) = h_{\text{送信時}} \;?\;=\; h_{\text{受信時}}$$
1 bit でも改ざんされれば $H(m)$ が大きく変わるため、 ハッシュ値の一致で完全性を確認できる。
【MAC(メッセージ認証コード)】
$$\mathrm{MAC}_k(m) = H(k \| m) \quad (k\text{は共有鍵})$$

🔬 記号・要素の読み解き

エンティティ整合性
主キーが NULL でなく一意。 各行が一意に識別可能。
参照整合性
外部キーが必ず参照先の主キーに存在。 「孤児」レコードを防ぐ。
ドメイン整合性
列の値が定義された型・範囲に収まる(CHECK 制約)。
ハッシュ(SHA-256 等)
固定長の指紋。 1 bit 改ざんで完全に変わる雪崩効果。
電子署名
送信者の秘密鍵で署名、 公開鍵で検証。 完全性 + 否認防止。

🔬 数式を言葉で読み解く — 詳細版(4 narration + 実値計算)

「完全性(Integrity)」について、 SSDSE-B-2026(47 都道府県統計)を題材に 4 つの実行可能 Python 例を順に追っていきます。 各ブロックは「🎯 目的 → 🐍 コード → 📤 実行結果 → 💬 読み方」の 4 要素を完備しています。

🎯 このコードでやること:SSDSE-B-2026 を読み込み、 行数・列数・欠損数・重複数の 4 大健診で完全性を確認する。 完全性チェックの最初の一歩。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 SSDSE-B-2026(年度) Prefecture(都道府県) 北海道 2,023 北海道 東京都 2,023 東京都 沖縄県 2,023 沖縄県 …(全 47 行)
1
2
3
4
5
6
7
import pandas as pd
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', header=1, encoding='cp932')
latest = df[df['年度']==df['年度'].max()]
print('行数:', len(latest))
print('列数:', len(latest.columns))
print('欠損総数:', latest.isnull().sum().sum())
print('都道府県重複:', latest['都道府県'].duplicated().sum())

📤 実行結果:

行数: 47 列数: 112 欠損総数: 0 都道府県重複: 0

💬 結果の読み方:47 行(全都道府県)・欠損 0・重複 0 — エンティティ整合性とドメイン整合性がともに合格。 e-Stat 由来の公式統計データらしい高品質な状態。

🎯 このコードでやること:ドメイン整合性のチェック:総人口が正で、 男女合計が総人口に一致する 論理整合性も同時確認。 業務ルール由来のチェック例。

1
2
3
4
5
6
latest = latest.copy()
latest['男女合計'] = latest['総人口(男)']+latest['総人口(女)']
latest['差'] = latest['男女合計']-latest['総人口']
print('総人口 < 0 の県:', (latest['総人口']<0).sum())
print('男女合計の差 max:', latest['差'].abs().max())
print(latest.nlargest(3, '差')[['都道府県','総人口','男女合計','差']])

📤 実行結果:

総人口 < 0 の県: 0 男女合計の差 max: 1000 都道府県 総人口 男女合計 差 0 北海道 5092000 5093000 1000 12 青森県 1184000 1185000 1000 24 岩手県 1163000 1164000 1000

💬 結果の読み方:正の値・男女合計の差 max 1000(千人単位の丸め誤差) — ドメイン整合性も合格。 多くの統計データは 千人単位丸めのため厳密一致でなく許容誤差で判定するのが定石。

🎯 このコードでやること:暗号学的完全性:SSDSE-B-2026 ファイル全体の SHA-256 ハッシュを計算し、 改竄検知の指紋とする。 配布や保管時にこのハッシュを別経路で共有。

1
2
3
4
5
6
7
import hashlib
path = 'data/raw/SSDSE-B-2026.csv'
with open(path, 'rb') as f:
    data = f.read()
hash_hex = hashlib.sha256(data).hexdigest()
print(f'file size: {len(data):,} bytes')
print(f'SHA-256: {hash_hex}')

📤 実行結果:

file size: 359,821 bytes SHA-256: 0fdbe5f603bb8e1ee72d83cca77e674cf9b45865d88c8f4fda5eb8046ea6f463

💬 結果の読み方:ファイルが 1 バイトでも変わると SHA-256 ハッシュは全く別の値に。 受信側 / 後日参照側で同じハッシュを再計算→ 一致確認で 改竄なしを保証できる。 重要データの配布で標準的手法。

🎯 このコードでやること:pandera を用いた schema 駆動の完全性検証。 「カラム型・値域・unique」を宣言的に書いておけば、 データが入る度に自動チェックされる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import pandera as pa
from pandera import Column, DataFrameSchema, Check
schema = DataFrameSchema({
  '都道府県': Column(str, Check.str_length(2, 4), unique=True),
  '総人口': Column(int, Check.greater_than(0)),
  '65歳以上人口': Column(int, Check.in_range(50000, 5000000)),
})
try:
    schema.validate(latest)
    print('OK: schema 検証通過')
except pa.errors.SchemaError as e:
    print('FAIL:', e)

📤 実行結果(実測):

OK: schema 検証通過

💬 結果の読み方:pandera で宣言した制約をすべて満たす → 完全性 OK。 制約違反があれば SchemaError で どのカラムのどの値が問題か具体的に通知。 ETL パイプラインに組み込めば異常データを早期検知できる。

🏭 産業界での活用事例 6 件

「完全性」が実務でどう使われているかを 6 業種で具体化。 自分の業務に近いケースから読むと理解が早まります。

▶ 銀行・金融
勘定系 DB の 参照整合性制約 — 口座が存在しない振込先には書き込み不可。 ON DELETE CASCADE で連動削除も。
▶ 医療システム
電子カルテで 患者 ID → 検査結果の整合性。 患者削除時の依存レコードの孤立を防止。
▶ SaaS BtoB
マルチテナント DB で tenant_id 必須+FK 制約により 他社データの混入を完全遮断。
▶ IoT 産業
センサーデータの 順序性・連続性整合性 — タイムスタンプの逆転や欠落を検知。
▶ 行政データ
SSDSE-B-2026 のような 47 都道府県データでレコード件数の妥当性検証(47 行未満なら欠落)。
▶ セキュリティ通信
HMAC・電子署名で送信メッセージの改竄を受信側が検知。 TLS の MAC も同じ思想。

📊 関連手法比較表

「完全性」と隣接する手法・概念を 5 列で構造化。 用途・長所・短所・代表シーンを並べることで使い分けの判断がつきます。

手法・概念主用途長所短所・制約代表シーン
参照整合性外部キー制約FK / ON DELETEDB のみリレーショナル DB
ドメイン整合性値域制約CHECK 制約・型DB のみカラム単位
エンティティ整合性主キー一意性PRIMARY KEY / UNIQUEDB のみ主キー
論理整合性ビジネスルールトリガー・AP 層柔軟・複雑業務ロジック
暗号学的完全性改竄検知SHA-256 / HMAC通信・ファイルメッセージ
時間的整合性時系列の連続性順序チェックタイムスタンプIoT・ログ

📝 演習問題 5 問

理解度を確認するための演習。 まず自力で解いてから解答を開いてください。

Q1. 参照整合性とは何か、 1 行で。
解答を見る
外部キー (FK) で参照する先のレコードが必ず存在する保証。
Q2. ドメイン整合性違反の例を 1 つ。
解答を見る
年齢カラムに -5 や 999 のような値域外の値が入る。 CHECK (age BETWEEN 0 AND 150) で防止。
Q3. SHA-256 ハッシュで完全性を検証する流れ
解答を見る
送信者が SHA-256(本文)→ ハッシュ送付、 受信者が同じ計算→ 一致確認。 1bit でも改竄あれば不一致。
Q4. HMAC とハッシュの違いは
解答を見る
HMAC は 秘密鍵でハッシュを生成 — 送受信者しか作成・検証できない(認証も兼ねる)。
Q5. SSDSE-B-2026 のデータ完全性を Python で 3 行で確認するには?
解答を見る
SSDSE-B-2026 は 47 県 × 12 年度 = 564 行なので、件数は len(df)==564、重複は df.duplicated(['Code','SSDSE-B-2026']).sum()==0(地域コード × 年度が一意)で確かめる。欠損は df.isnull().sum().sum()==0。実際に 3 つとも成り立つ。年度で絞った d = df[df['SSDSE-B-2026']==2023] なら len(d)==47 と d['Prefecture'].is_unique が成り立つが、絞らずに都道府県名の一意性を見ると 12 回ずつ出るので False になる。

📖 関連用語辞典 10 語

「完全性」周辺の 10 語をミニ辞典として整理。 ふと迷ったときの索引に。

参照整合性
外部キー先が存在する保証。
ドメイン整合性
カラム値が定義域に収まる保証。
エンティティ整合性
主キーが NULL でなく一意である保証。
CHECK 制約
値域や条件を SQL で宣言。
FOREIGN KEY
別テーブルの主キーを参照。
UNIQUE 制約
重複を許さない。
NOT NULL
欠損を許さない。
SHA-256
256bit 出力の暗号学的ハッシュ。 衝突困難。
HMAC
鍵付きハッシュで改竄+認証を同時検証。
Hash chain
ブロックチェーンで使う完全性連鎖。

🧮 実値で計算してみる

SQL で完全性を担保する例:

制約SQL 例守る完全性
PRIMARY KEYid INT PRIMARY KEYエンティティ
FOREIGN KEYFOREIGN KEY (user_id) REFERENCES users(id)参照
CHECKCHECK (age >= 0)ドメイン
UNIQUEemail VARCHAR(255) UNIQUE一意性

🧮 数式に値を入れて手で計算する: ルールごとの完全性率

制約で止めるだけでなく、既にあるデータがルールをどれだけ満たしているかを数で表すと、年度やファイルの間で比べられる。ルール r についての完全性率を次のように定める。

$$\text{完全性率}_r = 1 - \frac{\text{ルール } r \text{ に違反した行数}}{\text{全行数 } N}$$

SSDSE-B-2026 の 564 行(47 県 × 12 年度)に、ルール「男 + 女 = 総人口」(A110101 + A110102 = A1101)を当てる。

Stepやること値
1全行数 N と主キー(地域コード, 年度)の重複を数えるN = 564、重複 0(1 つの地域コードに県名は 1 種類だけ)
2許容幅 0(完全一致)で違反行を数える119 行(北海道 2023 年度の 2,405,000 + 2,688,000 = 5,093,000 ≠ 5,092,000 など)
3完全性率を計算する1 − 119 / 564 = 1 − 0.2110 = 0.7890
4千人単位の丸めを許して許容幅 1,000 にする違反 0 行、1 − 0 / 564 = 1.0000

同じデータでも、許容幅を 0 にすると 564 行の約 21% が「違反」に見える。これはデータが壊れているのではなく、男・女・総人口を別々に千人単位で丸めた結果である。完全性率を報告するときは、ルールと許容幅を一緒に書く。

🎯 このコードでやること:Step 1〜4 を pandas で再現し、主キーの重複と、許容幅 0 と 1,000 のときの完全性率を計算する。

📥 入力例 data/raw/SSDSE-B-2026.csv(564 行、使う列: Code・SSDSE-B-2026(年度)・Prefecture・A1101・A110101・A110102) Code 年度 都道府県 A1101(総人口) A110101(男) A110102(女) R01000 2023 北海道 5,092,000 2,405,000 2,688,000 …(全 564 行)
1
2
3
4
5
6
7
8
9
10
11
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
N = len(df)
key_dup = df.duplicated(['Code', 'SSDSE-B-2026']).sum()            # エンティティ整合性
names_per_code = df.groupby('Code')['Prefecture'].nunique().max()  # コードと県名が 1 対 1 か
sex = (df['A110101'] + df['A110102'] - df['A1101']).abs()
print(f'行数 N = {N}, (地域コード,年度) の重複 = {key_dup}, 1 コードあたりの県名の種類 = {names_per_code}')
for tol in [0, 1000]:
    v = (sex > tol).sum()
    print(f'許容幅 {tol:>5}: 男+女≠総人口 の行 = {v:3d}  完全性率 = 1 - {v}/{N} = {1 - v / N:.4f}')
📤 実行例(実測) 行数 N = 564, (地域コード,年度) の重複 = 0, 1 コードあたりの県名の種類 = 1 許容幅 0: 男+女≠総人口 の行 = 119 完全性率 = 1 - 119/564 = 0.7890 許容幅 1000: 男+女≠総人口 の行 = 0 完全性率 = 1 - 0/564 = 1.0000

💬 手計算の Step と同じく N = 564・主キーの重複 0、許容幅 0 では 119 行が違反して完全性率 0.7890、許容幅 1,000 では違反 0 行で 1.0000 になり、Step 3・4 の値と一致する。1 コードあたりの県名が 1 種類なので、地域コードと県名の対応(参照先のマスタに当たる関係)も 12 年間崩れていない。

🐍 Python での扱い

最小再現コード。 文字列 1 行の SHA-256 ハッシュを計算し、同じ内容なら同じ値になることを確かめる(CSV ファイル全体のハッシュは下の 🖼 の節と追加レシピで扱う):

1
2
3
4
5
6
import hashlib
data = b'SSDSE-B-2026 dataset content'
h = hashlib.sha256(data).hexdigest()
print('hash:', h)
# 受信時に再計算して一致確認
assert hashlib.sha256(data).hexdigest() == h, '改ざん検出!'
📤 実行例(実測) hash: ca81943bcbe26ca72965858ea439e2a27a7128506aec175bf8065121eee3396c

💬 SHA-256 は入力が同じなら必ず同じ 64 桁の 16 進数(256 ビット)を返すので、この hash 値は何度実行しても ca81943b… で変わらない。末尾にピリオドを 1 文字足しただけで b5e9a92e… と全く別の値になるため、1 バイトの改ざんでも検出できる。ただしこのコードは同じ data から 2 回計算して比べているので assert は必ず通る。実際の検証では、配布元が別経路で公開したハッシュ値と受信したファイルから計算した値を比べる。

🐍 仕上げの Python レシピ — 追加 2 ブロック

鍵付きハッシュ(HMAC)で改ざんと送信者を同時に確かめる例と、外部キーの参照先が無い「孤児」行を SQL で見つける例。

▶ HMAC で改竄検知+送信者認証

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import hmac, hashlib
secret = b'shared_secret_key_keep_safe'
# 送信側
message = b'transfer:from=A,to=B,amount=10000'
mac = hmac.new(secret, message, hashlib.sha256).hexdigest()
print(f'送信: {message.decode()}')
print(f'MAC: {mac[:32]}...')
# 受信側 (改竄なし)
mac_received = mac
valid = hmac.compare_digest(mac_received, hmac.new(secret, message, hashlib.sha256).hexdigest())
print(f'検証: {"OK" if valid else "改竄検知!"}')
# 受信側 (改竄あり)
tampered = b'transfer:from=A,to=B,amount=99999'
valid2 = hmac.compare_digest(mac_received, hmac.new(secret, tampered, hashlib.sha256).hexdigest())
print(f'改竄テスト: {"OK" if valid2 else "改竄検知!"}')

📤 実行結果:

送信: transfer:from=A,to=B,amount=10000 MAC: 570fba50f80d6dea0cb85cd4943e4709... 検証: OK 改竄テスト: 改竄検知!

💬 金額を 10000 から 99999 に書き換えただけで MAC は 570fba50… とまったく別の値になり、 受け取った MAC と一致しないので「改竄検知!」になる。 鍵 secret を知らない攻撃者は書き換え後の正しい MAC を作れないので、 SHA-256 単体と違って共有鍵を持つ送信者が作ったことまで確かめられる。 比較に == でなく compare_digest を使うのは、 一致した桁数で処理時間が変わるのを防ぐため。

▶ FK orphan 検出のクエリ

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 SSDSE-B-2026(年度) Prefecture(都道府県) 北海道 2,023 北海道 東京都 2,023 東京都 沖縄県 2,023 沖縄県 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import pandas as pd
master = pd.read_csv('data/raw/SSDSE-B-2026.csv', header=1, encoding='cp932')
master = master[master['年度']==master['年度'].max()][['都道府県']]
# 仮想 transaction テーブル (一部 orphan)
tx = pd.DataFrame({'都道府県':['東京都','大阪府','存在しない県A','宮崎県','仮の県B'],
                  '金額':[1000,800,500,600,400]})
# LEFT JOIN で orphan 検出
merged = tx.merge(master, on='都道府県', how='left', indicator=True)
orphans = merged[merged['_merge']=='left_only']
print('参照整合性違反 (orphan FK):')
print(orphans[['都道府県','金額']])
print(f'\n総取引: {len(tx)}件、 orphan: {len(orphans)}件 ({len(orphans)/len(tx):.1%})')

📤 実行結果:

参照整合性違反 (orphan FK): 都道府県 金額 2 存在しない県A 500 4 仮の県B 400 総取引: 5件、 orphan: 2件 (40.0%)

💬 5 件の取引のうち「存在しない県A」(500) と「仮の県B」(400) の 2 件(40%)が 47 都道府県マスタに無い参照で、 LEFT JOIN + indicator の left_only として拾えた。 inner join で集計していたらこの 900 は黙って消えるので、 FK 制約が無い表では結合前にこの確認を挟む。

🖼 図で深掘りする完全性 — 実データ×3 図で可視化

完全性(Integrity)は「データが正確で、 改ざんされておらず、 期待される一貫性を保っている状態」を指す情報セキュリティの基本柱の 1 つである。 ここでは SSDSE-B-2026 都道府県データを題材に、 完全性違反の代表的な兆候(外れ値、 分布の歪み、 グループ間の不一致)を 3 種類の図で可視化し、 「監査ログのレビューでまず何を見るか」を整理する。 完全性は単に「ファイルが破損していない」というファイルシステム上の概念だけでなく、 統計的に「データセット全体が一貫した分布・関係性を保っているか」というデータ品質の問題でもある。

完全性の検証は ハッシュ値・チェックサムなどの暗号学的手法と、 探索的データ解析(EDA)による統計的手法の 2 系統がある。 前者は「ビット単位で同一か」を保証し、 後者は「内容が想定範囲内に収まっているか」を保証する。 本セクションでは後者に焦点を当てる。

🖼 図 1: 散布図 — 「関係性が壊れていないか」を見る

完全性が保たれているデータでは、 既知の構造的関係に従う変数間に 強い線形関係が観察される。 例えば「総人口」と「65歳以上人口」は、 ほぼ比例関係になることが知られている(都道府県ごとの高齢化率が一定の範囲に収まるため)。 もし散布図で 外れ値や反対方向の点が観測されれば、 それは入力ミス・単位誤り・改ざんの可能性を示すシグナルになる。

散布図: 2023 年度 47 都道府県の総人口 vs 65歳以上人口
図 1: SSDSE-B-2026 の総人口(横軸)と65歳以上人口(縦軸)の散布図。 2023 年度の 47 都道府県。 r = 0.991 の強い正の相関で、 回帰直線の傾きは 0.246(総人口 1 万人当たり 65 歳以上 約 0.25 万人)。 直線から最も離れるのは東京都で、 直線より 38 万人少ない。

読み方: 直線的に並んだ点群は「データ全体が一貫した関係に従っている」ことを意味する。 もし 1 点だけ大きく外れているなら、 その県のデータを 個別に再検証する必要がある(実際は東京都が右上に離れ、 回帰直線より 65 歳以上人口が 38 万人少ないが、 これは人口集中と若い人口構成という現実を反映した「正しい外れ値」である)。 完全性監査では「外れ値の存在=改ざん」と即断せず、 外れ値の理由を必ず追跡する。

逆に 散布が円形になる(相関が消える)場合は、 列の入れ違い・ID の取り違え・型変換ミスなどの完全性違反が疑われる。 過去には「県コードが 1 つズレて結合された」結果、 北海道のデータが青森に紐付いていた事例も報告されている。

このコードでやること: SSDSE-B-2026 から総人口・65歳以上人口を読み、 散布図を描いて完全性監査に使う。

📥 入力データ (SSDSE-B-2026 抜粋):

SSDSE-B-2026.csv の主な列
地域コード, 都道府県, 総人口, 65歳以上人口, ...
R01000, 北海道, 5092000, 1681000, ...
R13000, 東京都, 14086000, 3205000, ...
R27000, 大阪府, 8763000, 2424000, ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import os
os.makedirs('html/glossary/figures', exist_ok=True)  # 保存先のフォルダを作っておく
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['Hiragino Sans', 'IPAexGothic', 'DejaVu Sans']
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
df = df[df['年度'] == 2023]        # 最新年度の 47 都道府県に絞る
plt.figure(figsize=(7,5))
plt.scatter(df['総人口'], df['65歳以上人口'], alpha=0.7)
plt.xlabel('総人口 (人)')
plt.ylabel('65歳以上人口 (人)')
plt.title('完全性監査: 総人口 vs 65歳以上人口')
plt.grid(True, alpha=0.3)
plt.savefig('html/glossary/figures/integrity_scatter.png', dpi=120, bbox_inches='tight')
print(f"都道府県数 = {len(df)}")
print(f"相関係数 r = {df['総人口'].corr(df['65歳以上人口']):.3f}")

📤 実行すると次の出力が得られる:

都道府県数 = 47 相関係数 r = 0.991

💬 r=0.991 は「総人口と65歳以上人口はほぼ完全に連動している」ことを示す。 完全性監査では、 この値が 過去の基準値(例: r ≥ 0.95)から大きく乖離した場合、 データ取込パイプラインに異常が発生した可能性を疑う。 月次バッチで r が 0.99 → 0.62 に急落したら、 即座にアラートを上げる運用が望ましい。

🖼 図 2: ヒストグラム — 「分布の形が壊れていないか」を見る

完全性監査の第 2 のレンズは、 分布の形である。 都道府県の人口分布は東京・大阪・神奈川などの大都市圏が突出した 右に長い裾を持つ偏った分布になることが知られている。 もし分布が「左右対称の正規分布」になっていたら、 むしろ「ダミーデータが混入した」「正規化を強制適用された」などの完全性違反が疑われる。

ヒストグラム: 2023 年度 47 都道府県の総人口
図 2: SSDSE-B-2026 の 2023 年度・都道府県別人口のヒストグラム(下のコードと同じ 20 ビン、 幅 約 68 万人)。 最初のビン(54〜121 万人)に 17 県、 次に 11 県が集まり、 東京都 1,409 万人が右端に 1 つだけ離れる。 歪度 2.29・尖度 5.66 の右に長い裾を持つ分布(右裾分布)が観察される。 これは現実の人口集中を反映した「正常な完全性」の証拠である。

読み方: ヒストグラムの形が 右に長い裾(mode が左寄り、 右側に少数の巨大値)になっていれば、 都道府県の人口集中という現実を正しく反映している。 これが 左右対称になっていたら、 何らかの正規化処理が誤って適用された可能性を疑う。 逆に 離散的なピーク(特定の値だけが頻発)が見られたら、 「不明値を平均値で補完した」「全件を中央値で置換した」などの破壊的な前処理が疑われる。

完全性が侵害された典型例として、 監査ログでは以下のパターンを必ずチェックする:

分布の異常考えられる完全性違反対応
単一値に集中欠損補完の暴走、 デフォルト値の混入補完ロジックの監査
負の値の出現符号反転バグ、 型変換ミス入力検証ルールの再確認
極端な外れ値単位誤り(千人 vs 人)、 改ざん該当行を個別検証
分布の急変スキーマ変更の見落としスキーマ履歴の照合

このコードでやること: 都道府県人口のヒストグラムを描き、 分布の形を完全性監査に使う。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 SSDSE-B-2026(年度) A1101(総人口) 北海道 2,023 5,092,000 東京都 2,023 14,086,000 沖縄県 2,023 1,468,000 …(全 47 行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import os
os.makedirs('html/glossary/figures', exist_ok=True)  # 保存先のフォルダを作っておく
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = ['Hiragino Sans', 'IPAexGothic', 'DejaVu Sans']
df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=1)
df = df[df['年度'] == 2023]        # 「都道府県数」を数えるので 1 年分 (47 行) に絞る
plt.figure(figsize=(7,4.5))
plt.hist(df['総人口'], bins=20, color='#42A5F5', edgecolor='#1565C0')
plt.xlabel('総人口 (人)')
plt.ylabel('都道府県数')
plt.title('完全性監査: 人口分布の形')
plt.savefig('html/glossary/figures/integrity_hist.png', dpi=120, bbox_inches='tight')
print(f"歪度 skew = {df['総人口'].skew():.3f}")
print(f"尖度 kurt = {df['総人口'].kurt():.3f}")

📤 実行すると次の出力が得られる:

歪度 skew = 2.293 尖度 kurt = 5.661

💬 歪度 2.29 は「強い右裾」、 尖度 5.66 は「正規分布より尖った峰と重い裾」を示す(pandas の kurt は正規分布を 0 とする超過尖度)。 都道府県の人口集中という構造を正しく反映しており、 完全性に問題なしと判断できる。 もし歪度・尖度がともに 0 付近(正規分布の値)に 急に変化したら、 ダミーデータの混入や正規化の暴走を疑う。 SREチームの監査ダッシュボードでは、 これらの統計量を時系列で記録しておくと早期発見に役立つ。

🖼 図 3: 箱ひげ図 — 「グループ間の一貫性が壊れていないか」を見る

完全性監査の第 3 のレンズは グループ間の比較である。 例えば「東日本」(北海道・東北・関東・中部の 23 都道県)と「西日本」(近畿以西の 24 府県)で 2023 年度の人口分布を比較すると、 大都市圏の存在によりどちらも右裾を持つ。 ただし中央値は東日本 193 万人・西日本 130 万人、 四分位範囲は 319 万人と 84 万人で、 もともと同じではない。 監査で見るのは「グループ間が等しいか」ではなく、 「各グループの箱ひげが前回の取込から急に変わっていないか」である。 もし片方のグループだけ箱ひげが急変すれば、 そのグループのデータ取込に問題が生じた可能性が高い。

箱ひげ図: 2023 年度の東日本と西日本の県人口
図 3: SSDSE-B-2026(2023 年度)の東日本 23 都道県と西日本 24 府県の総人口の箱ひげ図。 外れ値は東日本が東京都・神奈川県、 西日本が大阪府・兵庫県・福岡県。 中央値 193 万人 vs 130 万人、 四分位範囲 319 万人 vs 84 万人と差があるのは実際の人口配置によるもので、 この形を基準として記録しておき、 次回の取込で変わらないかを確かめる。

読み方: 各グループの箱(四分位範囲)の位置と幅、 ヒゲの長さ、 外れ値の数を比較する。 完全性が保たれていれば、 各グループの 外れ値の顔ぶれ・散らばりは前回の取込と同じになる(図 3 なら東日本の外れ値は東京都・神奈川県、 西日本の四分位範囲は約 84 万人)。 例えば「東日本だけ外れ値が急に増えた」「西日本だけ四分位範囲がゼロになった」などの変化があれば、 取込パイプラインの片側だけが破損した可能性を疑う。

これは 監査の網を細かくする工夫である。 全体ヒストグラムでは見逃される「地域単位の完全性違反」を、 箱ひげ図のグループ並列表示で検出できる。 同様に、 月別・四半期別・拠点別の箱ひげ図を並べることで、 「ある月だけ取込が壊れていた」「ある拠点だけ単位が違っていた」といった時間的・空間的な完全性違反を発見できる。

🧪 完全性監査の 3 図セット — 演習

以下の 3 問は、 監査ログのレビュー担当者が現場で実際に直面する場面を想定した演習である。 上で示した 3 図(散布図・ヒストグラム・箱ひげ図)の読み解きスキルを応用してほしい。

演習 1: 散布図の異常

前月までは r=0.99 だった「総人口×65歳以上人口」の相関が、 今月のバッチで r=0.34 に急落した。 散布図を見ると、 北海道(最大の面積)のデータだけが「総人口=10倍、 65歳以上人口=同じ」になっている。 考えられる完全性違反は何か。 また、 即座に取るべき対応を 2 つ挙げよ。

解答例を見る

考えられる完全性違反: (a) 北海道の総人口列だけ「千人」→「人」の単位誤りで 1000 倍になった、 (b) 別データソースの値が誤って「総人口」列に紐付いた、 (c) 改ざん。 取るべき対応: (1) 該当行を即座にデータベースから隔離し、 元データソースと照合、 (2) 取込パイプラインの単位変換ロジックを git diff で確認し、 前回成功時との差分を特定。

演習 2: ヒストグラムの異常

あるユーザー行動ログの「セッション時間(秒)」のヒストグラムを描いたところ、 「30 秒」「60 秒」「120 秒」だけが極端に高いピークになり、 その他の値は均等に少なかった。 完全性監査の観点で、 これはどのような違反を示唆するか。 また、 改ざんと前処理ミスを区別する方法を述べよ。

解答例を見る

違反: タイムアウト値での強制終了が「実際のセッション時間」として記録されている、 または特定の値で丸め込み(rounding)が暴走している。 区別方法: (a) 元データ(生ログ)と DWH 内のデータをハッシュ照合し、 ETL の前後で値が変わっているか確認、 (b) 30 秒・60 秒・120 秒の行に共通する別の属性(例: ユーザーエージェント、 サーバノード)を探し、 規則性があれば前処理ミス、 なければ改ざんを疑う。

演習 3: 箱ひげ図の異常

「東京」「大阪」「名古屋」「福岡」の 4 拠点のサーバから集めた応答時間(ミリ秒)の箱ひげ図を並べたところ、 名古屋拠点だけ「中央値=0、 四分位範囲=0、 外れ値=なし」という不自然な箱になっていた。 他の 3 拠点は正常な右裾分布を示している。 完全性監査の観点で、 何が起きている可能性が高いか。 また、 確認すべき項目を 3 つ挙げよ。

解答例を見る

可能性: 名古屋拠点のデータ取込パイプラインが停止し、 デフォルト値(0)で埋められている。 確認項目: (1) 名古屋拠点のメトリクス収集エージェントのプロセス状態と最終アップロード時刻、 (2) ETL ジョブのログでエラーが発生しているか、 (3) スキーマ変更により名古屋拠点だけが新スキーマに未対応になっていないか。 さらに、 名古屋拠点の値が全件 0 になった日時を特定し、 デプロイ履歴・障害履歴と照合する。

📋 まとめ — 完全性監査の 3 図セット

図種監査の観点異常時のサイン
散布図既知の関係性が保たれているか相関の急変、 反対方向の外れ値
ヒストグラム分布の形が想定通りか単一値集中、 負値、 急な対称化
箱ひげ図グループ間の一貫性片側のグループだけ中央値・IQR が異常

完全性は「ファイルが破損していない」というファイルシステム的概念に閉じず、 「データセット全体が一貫した分布・関係性を保っているか」という統計的概念にまで広げて捉える必要がある。 3 図セットによる EDA は、 暗号学的ハッシュ照合と並行して走らせる 第二防衛線として機能する。 ハッシュは「ビットが変わったか」を見るのに対し、 EDA は「ビットは変わっていないが、 値が想定外になっていないか」を見るからである。

実運用では、 毎月の取込バッチ完了後に 定型レポートとして上記 3 図を自動生成し、 前月との差分を計算して閾値超えがあればアラートを発する仕組みを推奨する。 これにより、 改ざんや前処理バグを 数時間以内に検知できる。 完全性は「事後にハッシュを照合する」だけでは守りきれず、 「事前に分布を監視する」ことで初めて完成する。 本セクションで紹介した 3 図セットは、 そのための最小構成である。

🛡 完全性監査の運用フロー — チェックリスト形式で整理

完全性監査を継続的に運用するには、 「いつ・誰が・何を・どうチェックするか」を 明文化したチェックリストとして整備しておくことが不可欠である。 以下に、 SSDSE のような公的統計データを毎月取り込む運用を想定した標準チェックリストを示す。 監査ログのレビュー担当者は、 このリストに沿って粛々と確認することで、 個人の経験差による検出漏れを最小化できる。

フェーズ確認項目合格基準異常時の対応
取込前提供元ファイルのハッシュ照合SHA-256 が公式値と一致取込中止、 提供元に再送依頼
取込前ファイルサイズ前月比 ±10% 以内差分理由の特定(仕様変更か破損か)
取込中行数期待値(例: 47 都道府県)と完全一致不足行の特定、 補完不可なら取込中止
取込中列数・列名スキーマ定義と完全一致スキーマ変更の告知有無を確認
取込後主キー重複0 件重複行の隔離、 原因調査
取込後欠損率前月比 ±2 ポイント以内急増列の特定、 提供元の仕様変更を確認
取込後基本統計量(平均・標準偏差)前月比 ±5% 以内分布シフトの原因調査
取込後既知の相関係数前月比 ±0.05 以内列の入れ違いを疑い、 散布図で目視確認
公開前分析結果の妥当性レビュー担当者 2 名による独立確認不一致時はソースまで遡って再検証

このチェックリストは 段階防御(defense in depth)の考え方に基づいている。 取込前のハッシュ照合だけ、 あるいは取込後の統計監視だけでは、 完全性侵害を取りこぼす可能性がある。 複数のフェーズで 異なる観点から繰り返し検証することで、 1 つの防御線を突破された場合でも次の防御線で検出できる。 これは情報セキュリティ全般に通じる基本原則である。

🧮 完全性指標 — 数値で「壊れ具合」を測る

完全性は「保たれている/いない」の 2 値ではなく、 程度問題として捉えるとより実用的である。 以下に、 完全性の「壊れ具合」を数値化するための代表的な指標を示す。 これらを ダッシュボードで時系列表示することで、 完全性の経時変化を一目で把握できる。

指標定義理想値監視の意義
完全行率全列に値がある行数 ÷ 全行数≥ 0.95欠損の発生状況
スキーマ一致率期待スキーマと一致する列数 ÷ 全列数1.00予期しないスキーマ変更の検知
値域逸脱率許容範囲外の値を持つセル数 ÷ 全セル数≤ 0.01外れ値・改ざんの兆候
参照整合性違反数外部キーが親テーブルに存在しない行数0テーブル間整合性の喪失
重複率主キー重複行数 ÷ 全行数0取込パイプラインの二重実行
相関ドリフト既知変数間の相関係数の前月差≤ 0.05列の入れ違いの早期検知

これらの指標を組み合わせた「完全性スコア」(例: 各指標を 0-1 に正規化して平均を取る)を毎月計算し、 80 点を下回ったら警告、 60 点を下回ったら取込中止、 という運用ルールを設けておくと、 異常事態に 機械的に対応できる。 人間の判断に依存しすぎると、 多忙な時期に見落としが発生するからである。

なお、 完全性指標の閾値は 事業特性によって調整すべきである。 金融取引データなら欠損率 0.01% でも許容できないが、 ユーザー行動ログなら 5% 程度の欠損は許容範囲かもしれない。 「自社にとって何が許容範囲か」を事業部門と合意しておくことが、 形骸化しない完全性監査の前提条件である。

⚖ 完全性 vs 他のセキュリティ柱 — トレードオフを理解する

情報セキュリティの基本柱である CIA トライアド(Confidentiality 機密性・Integrity 完全性・Availability 可用性)は、 しばしば 互いにトレードオフ関係にある。 完全性を厳密に守ろうとすると、 機密性や可用性が犠牲になることがある。 以下に代表的なトレードオフ事例を示す。

対立軸完全性側の主張対立側の主張バランス案
完全性 vs 可用性疑わしいデータは取込中止サービス停止は不可疑わしい行のみ隔離、 他は提供
完全性 vs 機密性監査ログを詳細記録ログに個人情報を残せないハッシュ化・マスク化したログ
完全性 vs パフォーマンス全行のハッシュを毎回計算レスポンス遅延は許容不可サンプリング監査 + 定期全件監査
完全性 vs 開発速度全変更にレビュー必須緊急パッチを即適用したい変更規模に応じた段階レビュー

「完全性は守らなければならない」という主張は正しいが、 それを 絶対視すると業務が回らなくなる。 完全性監査の設計者は、 事業の他の要請(速度・コスト・ユーザビリティ)とのバランスを常に意識しなければならない。 「最高水準の完全性を目指すが、 それは事業継続を妨げない範囲で」という現実的なゴール設定が重要である。

本セクションで示した 3 図セット・チェックリスト・完全性指標・トレードオフ整理を組み合わせることで、 「現場で運用できる完全性監査の設計」が見えてくる。 完全性は単一の技術や手続きで守られるものではなく、 複数の防御層の組み合わせと、 事業特性に応じた閾値設定と、 継続的な可視化・改善の 3 つが揃って初めて実現される。 本ページの内容を、 自社のデータパイプラインの監査設計の出発点として活用してほしい。

📜 完全性違反の歴史的事例 — 過去から学ぶ

完全性違反は、 技術が高度化した現代でも発生し続けている。 過去の重大事案から教訓を抽出することで、 同じ過ちを繰り返さない仕組みを設計できる。 以下に、 完全性監査の重要性を世に知らしめた代表的な事例カテゴリと、 そこから抽出される教訓を整理する。

事例カテゴリ典型的な発生メカニズム影響範囲抽出される教訓
単位誤り列が「千人」と「人」で混在し、 取込時に統一されず統計値が 1000 倍にズレ、 政策判断を誤らせる単位を列名に明示、 値域検証で検出
時差・タイムゾーンUTC と JST が混在し、 9 時間ズレが発生日次集計が前後にズレ、 異常検知が空振り全タイムスタンプを UTC で統一
文字コード混在Shift-JIS と UTF-8 が混在し、 文字化けマスターデータが破壊され、 検索不能取込時に文字コード変換を強制
スキーマ変更未告知提供元が列順を変更したが通知なし全数値が誤った列に入り、 分析結果が無意味化スキーマハッシュを毎回照合
部分更新の競合2 つの ETL が同時に同一テーブルを更新ロストアップデートで一部レコードが消失排他制御またはトランザクション分離
バックアップ破損バックアップ取得後にハッシュ照合を行わず復旧時にデータ破損が発覚、 業務停止定期的なリストア訓練

これらの事例に共通するのは、 「単一の対策では防げない」という点である。 単位誤りは値域検証で、 時差は UTC 統一で、 スキーマ変更はハッシュ照合で、 それぞれ別個の対策が必要になる。 完全性監査の設計は 失敗パターンの蓄積と表裏一体であり、 過去の事故報告書を継続的に読み返して自社の監査項目を更新していく姿勢が欠かせない。

🧠 完全性と「データの真正性」 — 哲学的な視点

完全性監査を突き詰めていくと、 「そもそも『正しいデータ』とは何か」という哲学的な問いに突き当たる。 例えば、 ある都道府県が公表する人口統計は 住民基本台帳に基づく数値であるが、 住民登録していない居住者(短期滞在外国人・住所不定者など)は含まれていない。 この数値は「行政上の人口」としては正確だが、 「実際にその土地に住んでいる人の数」としては不完全である。

つまり、 完全性は 「何との一致を完全性と呼ぶか」という基準設定に強く依存する。 同じデータでも、 ある目的では完全であり、 別の目的では不完全である。 完全性監査の設計者は、 「自社のデータが何の真実を表現しようとしているか」を常に意識し、 そのギャップを利用者に明示することが求められる。

この視点は、 単なる技術的完全性(ビット単位の一致)を超えた 意味的完全性とも呼べる。 意味的完全性を確保するには、 データ提供元の 定義文書(メタデータ)を必ず取得し、 自社の用途と提供元の定義が一致しているかを確認する必要がある。 これは技術的ハッシュ照合では検出できない、 「人間の解釈」が必要な完全性監査の側面である。

実務的には、 データセットごとに 「データシート」(Datasheet for Datasets, Gebru et al. 2021 で提唱)を整備しておくことが推奨される。 データシートには、 収集目的・収集方法・既知の偏り・推奨される用途・推奨されない用途などを記載する。 これにより、 利用者が「このデータは自分の目的に対して完全か」を判断できる。 完全性監査は、 技術的検証と意味的検証の両輪で完成する。

🔬 演習の追加 — 実践力を試す

発展演習 1: 監査設計

あなたの担当する EC サイトでは、 毎時取り込まれる売上ログに「商品ID・購入数・単価・タイムスタンプ・顧客ID」が含まれる。 完全性監査として、 取込前・取込中・取込後の各フェーズで何をチェックすべきか、 各 2 項目ずつ挙げ、 合格基準と異常時の対応を整理せよ。

発展演習 2: 完全性スコアの設計

前掲の完全性指標 6 種類を 0-1 に正規化し、 平均を取って「完全性スコア」を作るとする。 ただし、 自社では「重複率」と「スキーマ一致率」は致命的なので、 これらが基準を満たさない場合は他の指標が良くても合格とすべきでない。 このような優先度を反映した完全性スコアの計算式を提案し、 その理由を述べよ。

発展演習 3: 意味的完全性

SSDSE-B-2026 の「総人口」列は住民基本台帳に基づく値である。 これを使って「実際にその土地に滞在している人」のサービス需要予測モデルを作ろうとした場合、 完全性の観点でどのような問題が生じるか。 また、 この問題を緩和するために追加で取得すべきデータ・指標を 2 つ挙げよ。

完全性は、 技術・運用・設計・哲学のすべての階層にわたる 多層的な概念である。 本ページの内容を一度読んだだけで完璧に理解できる人は少ないだろう。 実務で監査を運用しながら、 何度も本ページに立ち返って各セクションを読み直し、 自社の文脈に当てはめて咀嚼することを推奨する。 完全性監査の習熟は、 一朝一夕ではなく、 経験と反復の蓄積によって深まっていく。

📚 補論: 完全性確保のための実装パターン集

完全性監査を支える典型的な実装パターンを整理する。 設計者はこれらの中から自社の事業特性に合うものを選択し、 適切に組み合わせる。 「全てを実装すれば完璧」ではなく、 「事業要請とコストのバランスで取捨選択する」のが現実的である。 ここでは代表的な 8 パターンを挙げる。

パターン名仕組み適用シーン実装コスト
ハッシュ照合SHA-256 で前後のビット一致を確認ファイル転送、 アーカイブ低
チェックサムCRC32 等で改変を検知ネットワーク伝送、 行単位検証低
電子署名公開鍵暗号で送信者と内容を保証公的データ配信、 契約書中
監査ログ全変更を WORM ストレージに記録金融、 医療、 法規制対象中
差分検査前回スナップショットとの diff を計算マスターデータ管理中
統計的監視平均・分散・相関の経時変化を監視ビッグデータ、 行動ログ中
参照整合性制約外部キー制約を DB で強制RDB を使う全シーン低
スキーマ検証JSON Schema や Great Expectations で型・範囲を検証ETL パイプライン全般中

これらのパターンは 互いに補完的である。 例えばハッシュ照合だけでは「ハッシュ自体が改ざんされた」場合に検知できないが、 電子署名と組み合わせれば改ざんを検知できる。 統計的監視だけでは「分布は同じだが個別レコードが入れ替わっている」状況を検知できないが、 ハッシュ照合と組み合わせれば検知できる。 完全性監査の設計は、 パターンの組み合わせ最適化問題として捉えると見通しが良くなる。

特に重要なのは、 「人間の介入が必要な層」と「自動化できる層」を分離することである。 ハッシュ照合・スキーマ検証・参照整合性は完全に自動化できるが、 統計的監視のアラート判定や監査ログのレビューには人間の判断が必要になることがある。 自動化層を厚くしすぎると、 アラート疲れで人間が真の異常を見逃すリスクがある。 逆に人間レビュー層を厚くしすぎると、 担当者の負荷が高まり継続できない。 このバランス設計が、 完全性監査の運用設計者の腕の見せ所である。

🎯 完全性監査のアンチパターン — やってはいけないこと

完全性監査の現場でしばしば見られる、 効果が薄い・むしろ害がある「アンチパターン」を整理する。 これらを避けることが、 実効性のある監査体制を構築する第一歩である。

アンチパターン問題点改善方向
アラートの過剰設定毎日数百件のアラートで、 担当者が読まなくなる重大度に応じた段階化、 抑制ルール
監査ログの未活用記録はしているが誰も見ない定期レビュー会の設置、 自動サマリ
完全自動化への過信人間が一切確認しない結果、 想定外を見逃す月次サンプルレビューを必ず実施
監査と業務の分離監査チームが業務を理解せず、 形骸化業務担当者を巻き込んだ運用設計
過去事案の風化同じ事故が数年後に再発事故報告書のナレッジベース化
ツール導入の自己目的化高価なツールを導入したが活用されない小さく始めて段階的に拡張

これらのアンチパターンに共通するのは、 「監査が形式化して実質を失う」という構造である。 完全性監査は「やっています」と言うだけでは意味がなく、 実際にデータの異常を検知できる体制になっているかどうかが全てである。 定期的に 模擬異常データを投入して、 自社の監査体制が確かに検知できるかをテストする「監査の監査」を行うことを強く推奨する。 これは火災訓練と同じ位置づけであり、 本番で機能しない監査体制は無いに等しい。

最後に、 完全性監査は 「データ品質文化」の一部として根付かせることが重要である。 監査チームだけが完全性に責任を持つのではなく、 データを生成する側・利用する側・運用する側のすべてが「自分はデータの完全性に貢献している」という意識を持つことで、 監査体制は初めて自走する。 完全性監査は、 技術投資であると同時に 組織文化への投資である。 本ページの内容が、 読者の所属組織における完全性文化の醸成の一助となれば幸いである。

🧩 完全性監査と機械学習モデルの関係

機械学習モデルの予測精度は、 入力データの完全性に強く依存する。 ガベージインなら必ずガベージアウトになる(Garbage In, Garbage Out)。 完全性が侵害されたデータで学習したモデルは、 一見もっともらしい予測を返すが、 実用に堪えないものになる。 ここでは、 機械学習パイプラインにおける完全性監査の特徴的な観点を整理する。

第 1 に、 学習データと推論データの完全性は別物として管理する必要がある。 学習データは過去の蓄積であり一度監査すれば固定できるが、 推論データはリアルタイムで流入するため、 監査の遅延が許容できない。 学習時には精密な統計的監視を行い、 推論時には軽量なスキーマ検証と値域チェックに留めるという 段差設計が現実的である。

第 2 に、 データドリフトを完全性の延長線上で監視する必要がある。 取込時点では完全性が保たれていても、 時間経過とともに学習データと推論データの分布が乖離していくと、 モデルの精度は徐々に低下する。 これは「データ自体は壊れていないが、 想定環境から外れている」という意味的完全性の問題である。 ドリフト検知(PSI: Population Stability Index 等)を完全性監査の項目に組み込むことで、 モデルの寿命を能動的に管理できる。

第 3 に、 ラベルの完全性は特に注意が必要である。 教師あり学習ではラベルが「正解」として扱われるが、 ラベル付け担当者の判断ミスや基準のブレで、 ラベル自体が不完全であることがある。 「人間が付けたラベルは正しい」という暗黙の前提を疑い、 複数人によるダブルチェック・ラベル一貫性スコア(カッパ係数等)の算出を完全性監査の一環として実施することが望ましい。

第 4 に、 敵対的サンプルへの耐性も完全性の延長として扱える。 攻撃者が意図的に小さな摂動を加えた入力(人間には正常に見える)で、 モデルに誤分類を起こさせる攻撃である。 これは「ビット単位では完全性が保たれているが、 意味的には完全性が侵害されている」極端な事例であり、 敵対的訓練(adversarial training)や入力の前処理による緩和が研究されている。

機械学習システムにおける完全性は、 単なるデータ品質を超えて モデルライフサイクル全体の管理問題となる。 データ取込・学習・評価・デプロイ・推論・再学習という各フェーズで、 完全性の観点を埋め込んでいくことで、 信頼性の高い AI システムを構築できる。 これは MLOps の中核的な関心事の 1 つでもある。

🌟 まとめの一言

完全性は、 セキュリティの基本柱の 1 つでありながら、 機密性や可用性に比べて見過ごされがちな概念である。 しかし、 データドリブンな意思決定が当たり前になった現代において、 完全性が侵害されたデータに基づく判断は組織を誤った方向に導く。 完全性監査は地味な仕事だが、 組織の意思決定の質を底支えする極めて重要な活動である。 本ページで紹介した 3 図セット・チェックリスト・指標・トレードオフ・実装パターン・アンチパターン・機械学習との関係を、 自社の文脈に応じて組み合わせ、 実効性のある完全性監査体制を築いてほしい。

📖 用語の整理 — 完全性関連の周辺概念

完全性を深く理解するには、 周辺概念との位置関係を整理することが役立つ。 以下に、 完全性と関連する代表的な用語を、 重なる範囲と異なる範囲を意識して比較する。 これらの概念は実務でしばしば混同されるため、 自社の用語集として明文化しておくことを推奨する。

用語完全性との重なり完全性との違い
正確性(Accuracy)「正しい値であること」を共有完全性は改変有無も含む、 正確性は値そのものの正しさのみ
一貫性(Consistency)「テーブル間で矛盾がない」を共有完全性は改ざん検知も含む、 一貫性は関係の整合性のみ
真正性(Authenticity)「正規の作成者によるデータ」を共有真正性は発信源の確認、 完全性は内容の不変
否認防止(Non-repudiation)「証跡として使える」を共有否認防止は事後追跡、 完全性は事前保護
信頼性(Reliability)「期待通りに動く」を共有信頼性は再現性、 完全性は不変性

これらの概念は 完全に独立ではなく、 部分的に重なり合う。 例えば「正確で、 改ざんされておらず、 一貫しており、 発信源が確かで、 証跡として使える」状態が、 高度な完全性を備えたデータの理想像である。 個々の概念を分離して議論できる場面(例: 監査要件の細分化)と、 まとめて議論する場面(例: 経営層への報告)を使い分けることが、 概念の力を最大限に引き出すコツである。

本ページで扱った完全性の概念は、 情報セキュリティ標準(ISO/IEC 27001 等)における定義を基礎としつつ、 データサイエンス実務における意味的完全性まで拡張したものである。 標準的な定義と現場での運用ギャップを意識しながら、 自社の事業に最適な完全性概念を構築してほしい。 完全性は静的な定義ではなく、 事業と技術の進化に応じて再定義され続けるべき 動的概念である。

🔁 完全性監査の継続的改善サイクル

完全性監査は「一度設計したら完成」ではなく、 PDCA サイクルで継続的に改善していくべき活動である。 Plan(計画)では監査項目と閾値を定義し、 Do(実行)では実際に監査を回し、 Check(評価)では監査の漏れや誤検知を分析し、 Act(改善)では監査項目や閾値を更新する。 この 4 段階を四半期や半期ごとに繰り返すことで、 監査体制は事業の変化に追随できる。

特に重要なのは Check 段階での 監査の有効性評価である。 過去 1 期間に発生した完全性違反のうち、 何件が自社の監査体制で検知できたか、 何件を見逃したかを定量的に集計する。 見逃し事案については、 「なぜ検知できなかったか」を 5 Whys 分析等で深掘りし、 監査項目への追加・閾値の調整・運用手順の変更といった具体的な改善アクションに繋げる。 これを行わないと、 監査体制は時代遅れになり、 やがて形骸化する。

また、 監査体制の 外部レビューを定期的に受けることも有効である。 自社内のメンバーだけでは気づかない盲点を、 外部の専門家や他社の知見と照らし合わせることで発見できる。 業界団体のベンチマーク調査に参加したり、 監査法人による情報セキュリティ監査を受けたりすることで、 自社の完全性監査体制の成熟度を客観的に評価できる。 外部の視点を取り入れることは、 監査の継続的改善において欠かせない要素である。

完全性監査体制の成熟度は、 一般に以下の 5 段階で評価される: (1) Initial(場当たり的対応)、 (2) Managed(プロセスが文書化されている)、 (3) Defined(組織横断で標準化されている)、 (4) Quantitatively Managed(定量的指標で管理されている)、 (5) Optimizing(継続的改善が組み込まれている)。 自社の現在地を把握し、 1 段階ずつ着実に上げていくことが、 完全性監査の長期的な戦略となる。

本ページで提示した一連の枠組み(3 図セット・チェックリスト・指標・トレードオフ・実装パターン・アンチパターン・機械学習との関係・周辺概念・成熟度モデル)は、 これらの段階を 1 つずつ登っていく際の 共通言語として機能することを意図している。 異なる立場のステークホルダー(経営層・開発者・運用者・データサイエンティスト・監査担当者)が、 同じ用語と枠組みで完全性を議論できることが、 組織横断的な完全性文化の前提である。 用語のすり合わせと枠組みの共有から、 完全性監査の組織展開は始まる。

最終的に、 完全性は 「データに対する組織の誠実さ」を表す指標であるとも言える。 データに含まれる事実を歪めずに保ち、 改ざんを許さず、 一貫性を保ち、 利用者に正直に提供する姿勢は、 そのまま組織が社会に対して負う説明責任の表れである。 完全性監査を地道に続けることは、 単なる技術活動ではなく、 組織の信頼を社会との間で築き上げる 倫理的活動でもある。 この視点を持って、 日々の監査業務に取り組んでほしい。

本ページの最終メッセージは次の 1 文に要約できる: 「完全性は、 一度確立すれば終わるものではなく、 日々の細かな確認の積み重ねによって初めて持続する」。 派手な技術投資より、 地道なチェックリスト運用の方が、 長期的には組織を守る。 本ページが、 読者の所属組織における完全性監査の出発点となり、 さらにはその継続的改善の伴走者となることを願って、 本セクションを締めくくる。 完全性を守るすべての実務家に、 敬意と感謝を表したい。 そして、 本ページの内容を活用して新たな知見を得た読者は、 その知見をぜひ同僚や業界仲間と共有し、 完全性監査の文化を組織横断・業界横断で広げていってほしい。 完全性は、 守る人が多いほど強くなる概念である。

最後に、 本ページで触れた論点をもう一度短く列挙して、 読者の振り返りに供する: (1) 完全性は CIA トライアドの中核要素であり、 「ビット単位の不変性」と「統計的な一貫性」の両方を含む、 (2) 散布図・ヒストグラム・箱ひげ図の 3 図セットで EDA 的に完全性を監査できる、 (3) 取込前・取込中・取込後の各フェーズで段階的にチェックリストを運用する、 (4) 完全行率・スキーマ一致率・値域逸脱率・参照整合性違反数・重複率・相関ドリフトの 6 指標で定量管理する、 (5) 完全性は機密性・可用性・パフォーマンス・開発速度とトレードオフがあり、 事業特性に応じてバランスを設計する、 (6) 8 種類の実装パターン(ハッシュ照合からスキーマ検証まで)を組み合わせて多層防御を構築する、 (7) アラート過剰・監査ログ未活用・完全自動化への過信などのアンチパターンを避ける、 (8) 機械学習システムでは学習データ・推論データ・ラベル・敵対的サンプルの 4 観点で完全性を管理する、 (9) 周辺概念(正確性・一貫性・真正性・否認防止・信頼性)との位置関係を整理する、 (10) PDCA と成熟度モデルで継続的に改善する。 以上 10 点を意識して、 自社の完全性監査体制を点検してみてほしい。

📊 補足: 完全性 (Integrity) の数理と運用

完全性は情報セキュリティの CIA トリアード (機密性 Confidentiality・完全性 Integrity・可用性 Availability) の中核で、 データが「許可されない方法で変更されない」ことを保証する性質である。 数理的にはハッシュ関数 H の衝突困難性 (collision resistance) に依拠し、 SHA-256 の場合 2^128 程度の計算でしか同じハッシュ値を持つ別データを見つけられない。 ブロックチェーンの改ざん耐性も同じ原理で、 各ブロックが直前ブロックのハッシュを含むため、 1 ブロック改変するとそれ以降全てを再計算する必要がある。 デジタル署名 (RSA や ECDSA) は秘密鍵で署名・公開鍵で検証することで、 改ざんと否認防止を同時に達成する。 実務では HMAC や AEAD (GCM/ChaCha20-Poly1305) が標準的に使われ、 通信路の機密性と完全性を同時に守る。 データベースでは外部キー・チェック制約・トリガで論理的整合性を保ち、 トランザクションの ACID (Atomicity, Consistency, Isolation, Durability) で同時実行下の一貫性を保証する。 監査ログでは write-once-read-many (WORM) ストレージや tamper-evident log で改ざん検出を行い、 法的・規制要件 (SOX、 HIPAA、 個人情報保護法、 GDPR) を満たす。 機械学習モデルでは、 学習データの完全性が予測精度を左右し、 データポイズニング攻撃 (label flipping、 backdoor) に対する防御として trusted curation、 robust training、 anomaly detection が必要である。 ファイルシステムでは ZFS や Btrfs の checksum で bit rot (磁気劣化・宇宙線によるビット反転) を検出・自動修復する。 完全性の確保は「事前検証 (validation)」「事中監視 (monitoring)」「事後監査 (audit)」の三段階で多層的に行う必要があり、 一つの技術だけでは不十分である。

⚠️ よくある落とし穴

❌ 制約を OFF にして高速化
バルクロード時に制約を無効化すると、 不整合データが入り込む可能性。 ロード後に必ず再有効化+検証。
❌ MD5/SHA-1 を使う
暗号学的に破られています。 SHA-256 以上を使うこと。
❌ ハッシュだけで認証になると誤解
ハッシュは 完全性 のみ。 「誰が送ったか」の認証には MAC か電子署名が必要。
❌ 分散システムでの一貫性
CAP 定理上、 完全な強一貫性は犠牲を伴う。 BASE / 結果整合性 で妥協する選択。
❌ 学習データの完全性
ML パイプラインで学習データが第三者に書き換えられる「データポイズニング」攻撃。 ハッシュ管理を。

⚠️ 業務ルールの検査はハッシュの代わりにならない — 改ざんを仕込んで確かめる

上の 🐍 で「男女計 = 総人口」のルールが通ることを確かめた。では、ルールが通れば改ざんされていないと言えるか。2023 年度の 47 県の 6 列(総人口・男・女・年齢 3 区分)に、わざと 3 通りの改ざんを入れて、ルール 2 本(男 + 女 = 総人口、年齢 3 区分の和 = 総人口、どちらも千人単位の丸めで ±1,000 まで許す)とハッシュ(SHA-256 の先頭 12 桁)のどちらが気づくかを比べる。

🎯 このコードでやること:2023 年度 47 県の人口 6 列に 3 通りの改ざんを入れ、業務ルール 2 本と SHA-256 の指紋がそれぞれ検出できるかを調べる。

📥 入力例 SSDSE-B-2026 の 2023 年度 47 行 × 6 列(人) 都道府県 A1101(総人口) A110101(男) A110102(女) A1301(15歳未満) A1302(15~64歳) A1303(65歳以上) 東京都 14,086,000 6,914,000 7,172,000 1,513,000 9,368,000 3,205,000 鳥取県 537,000 257,000 280,000 65,000 294,000 179,000 …(全 47 行)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import hashlib
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
d = df[df['SSDSE-B-2026'] == 2023].set_index('Prefecture')
cols = ['A1101', 'A110101', 'A110102', 'A1301', 'A1302', 'A1303']
base = d[cols].copy()

def digest(t):                      # 2023 年度 6 列の指紋
    return hashlib.sha256(t.to_csv().encode()).hexdigest()[:12]

def rules(t, tol=1000):             # 業務ルール 2 本(千人単位の丸めを許容)
    sex = (t['A110101'] + t['A110102'] - t['A1101']).abs() > tol
    age = (t['A1301'] + t['A1302'] + t['A1303'] - t['A1101']).abs() > tol
    return list(t.index[sex | age])

h0 = digest(base)
print('元データ: ルール違反', rules(base), ' 指紋', h0)

cases = {
    'T1 東京都の総人口だけ +50,000':
        lambda t: t.loc['東京都', ['A1101']].add(50000),
    'T2 東京都の総人口・男・65歳以上を +50,000':
        lambda t: t.loc['東京都', ['A1101', 'A110101', 'A1303']].add(50000),
    'T3 鳥取県の総人口と男を +1,000':
        lambda t: t.loc['鳥取県', ['A1101', 'A110101']].add(1000),
}
for name, f in cases.items():
    t = base.copy()
    v = f(t); t.loc[v.name, v.index] = v.values
    hit = rules(t)
    print(f'{name}: ルール検出={hit if hit else "なし"}  指紋一致={digest(t) == h0}')
📤 実行例(実測) 元データ: ルール違反 [] 指紋 9af3ded84b1a T1 東京都の総人口だけ +50,000: ルール検出=['東京都'] 指紋一致=False T2 東京都の総人口・男・65歳以上を +50,000: ルール検出=なし 指紋一致=False T3 鳥取県の総人口と男を +1,000: ルール検出=なし 指紋一致=False

💬 元データはルール違反 0 件で、指紋は 9af3ded84b1a。T1(総人口だけを 5 万人増やす)は男女の和と合わなくなりルールが東京都を検出する。T2 は総人口・男・65 歳以上を同じ 5 万人ずつ増やしたので、男 + 女 も年齢 3 区分の和も総人口と一致したままで、ルールは何も見つけない。T3 は鳥取県の総人口と男を 1,000 人ずつ動かしただけで、丸めの許容幅に収まる。T1〜T3 のどれでも指紋は元と一致しない(False)。

ルールは「辻つまが合っているか」しか見ないので、辻つまを合わせた改ざん(T2)や丸め幅の中の改ざん(T3)は通してしまう。逆にハッシュは「どこが・なぜ」おかしいかを教えてくれない。受け取ったファイルが配布元と同じかはハッシュで、同じファイルの中身が業務上ありえる値かはルールで、と役割を分けて両方使う。

⚠️ 閾値のルールは列ごとに決める — 前年度比 ±5% は出生数では誤警報だらけ

時系列のデータでは「前年度から ±5% を超えて動いたら警告」のような変化量のルールがよく使われる。同じ閾値が列によってどれだけ違う結果になるかを、SSDSE-B-2026 の 12 年度分(47 県 × 11 回の前年度比 = 517 件)で数える。

🎯 このコードでやること:総人口・出生数・死亡数の 3 列について、県ごとに前年度比の変化率を求め、±5%・±10% を超えた件数と 99% 点を数える。

📥 入力例 SSDSE-B-2026 の 564 行(47 県 × 2012〜2023 年度) Code Prefecture SSDSE-B-2026 A1101(総人口) A4101(出生数) A4200(死亡数) R01000 北海道 2023 5,092,000 24,430 75,120 R01000 北海道 2022 5,140,000 26,407 74,437 …(CSV は新しい年度が先。年度で並べ直してから変化率を取る)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
s = df.sort_values(['Code', 'SSDSE-B-2026'])          # CSV は新しい年度が先なので並べ直す
names = {'A1101': '総人口', 'A4101': '出生数', 'A4200': '死亡数'}
for c, jp in names.items():
    r = s.groupby('Code')[c].pct_change().abs()        # 前年度比の変化率(絶対値)
    n = r.notna().sum()
    print(f'{jp}: 前年度比の変化 {n} 件  最大 {r.max():.1%}  '
          f'±5% 超 {(r > 0.05).sum()} 件  ±10% 超 {(r > 0.10).sum()} 件  '
          f'99% 点 {r.quantile(0.99):.1%}')
r = s.groupby('Code')['A4101'].pct_change().abs()
top = s.loc[r.nlargest(3).index, ['Prefecture', 'SSDSE-B-2026', 'A4101']]
print(top.to_string(index=False))
📤 実行例(実測) 総人口: 前年度比の変化 517 件 最大 1.7% ±5% 超 0 件 ±10% 超 0 件 99% 点 1.5% 出生数: 前年度比の変化 517 件 最大 13.0% ±5% 超 134 件 ±10% 超 2 件 99% 点 9.3% 死亡数: 前年度比の変化 517 件 最大 11.2% ±5% 超 65 件 ±10% 超 15 件 99% 点 10.5% Prefecture SSDSE-B-2026 A4101 鳥取県 2023 3263 岩手県 2022 5788 島根県 2023 3759

💬 総人口は 517 件の前年度比のうち最大でも 1.7% しか動かず、±5% のルールは 1 件も警告しない。ところが出生数では 134 件(約 26%)、死亡数では 65 件が ±5% を超える。出生数の最大は鳥取県 2023 年度の 13.0% 減(3,263 人)で、出生数が 3,000〜5,000 人規模の県では数百人の増減で 5% を超えてしまう。±10% に広げると出生数は 2 件、死亡数は 15 件まで減る。

変化量のルールは、改ざんではなく普通の年々の揺れでも警告を出す。閾値は「全列 ±5%」のように一律に決めず、過去の実データの変化率の分布(ここでは 99% 点が総人口 1.5%・出生数 9.3%・死亡数 10.5%)を見て列ごとに決める。警告が多すぎるルールは、そのうち誰も見なくなる。

⚠️ ハッシュはバイト列の指紋で、値の指紋ではない — 保存し直しただけで一致しなくなる

🐍 のブロックでは SSDSE-B-2026.csv ファイル全体の SHA-256 を計算した。この指紋は「ファイルのバイト列」に付くので、数値を 1 つも変えなくても、表計算ソフトや pandas で開いて保存し直す、文字コードを UTF-8 に変える、改行コードを変える、といった操作で別の値になる。受け取った側でハッシュが合わないとき、改ざんなのか保存形式の違いなのかを切り分けるために、値だけから作る指紋(行を地域コード・年度で並べ替え、決まった書式で書き出してからハッシュを取る)を並べて比べる。

🎯 このコードでやること:元の CSV と、値を変えずに保存形式だけ変えた 3 通りのバイト列について、ファイルのハッシュと「値の指紋」を並べて比べる。

📥 入力例 data/raw/SSDSE-B-2026.csv(cp932、1 行目が列コード、2 行目が日本語の列名、564 行 × 112 列、改行 CRLF) SSDSE-B-2026,Code,Prefecture,A1101,A110101,… 年度,地域コード,都道府県,総人口,総人口(男),… 2023,R01000,北海道,5092000,2405000,…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import hashlib, io
import pandas as pd

path = 'data/raw/SSDSE-B-2026.csv'
raw = open(path, 'rb').read()
sha = lambda b: hashlib.sha256(b).hexdigest()[:12]

df = pd.read_csv(io.BytesIO(raw), encoding='cp932', header=[0, 1])
v1 = df.to_csv(index=False, encoding='cp932').encode('cp932')      # 同じ値を書き直す
v2 = df.to_csv(index=False).encode('utf-8')                          # 文字コードだけ変える
v3 = raw.replace(b'\r\n', b'\n') if b'\r\n' in raw else raw.replace(b'\n', b'\r\n')  # 改行だけ変える

def canon(b, enc):              # 値の指紋: 読み込み → 行を(地域コード,年度)で並べ替え → 固定書式
    t = pd.read_csv(io.BytesIO(b), encoding=enc, header=[0, 1])
    t.columns = [c[0] for c in t.columns]
    t = t.sort_values(['Code', 'SSDSE-B-2026']).reset_index(drop=True)
    return sha(t.to_csv(index=False, lineterminator='\n').encode('utf-8'))

print(f'元のファイル      {len(raw):>8,} bytes  バイト列 {sha(raw)}  値 {canon(raw, "cp932")}')
for name, b, enc in [('pandas で書き直し', v1, 'cp932'), ('UTF-8 で保存', v2, 'utf-8'), ('改行コードだけ変更', v3, 'cp932')]:
    print(f'{name:10s} {len(b):>8,} bytes  バイト列 {sha(b)}  値 {canon(b, enc)}')
print('改行コード:', 'CRLF' if b'\r\n' in raw else 'LF')
📤 実行例(実測) 元のファイル 359,821 bytes バイト列 0fdbe5f603bb 値 5a5d3cfea7d3 pandas で書き直し 359,204 bytes バイト列 388bc2e38a21 値 5a5d3cfea7d3 UTF-8 で保存 361,891 bytes バイト列 86ddfde335d6 値 5a5d3cfea7d3 改行コードだけ変更 359,255 bytes バイト列 bd25a010fc51 値 5a5d3cfea7d3 改行コード: CRLF

💬 元のファイルは 359,821 bytes でバイト列の指紋は 0fdbe5f603bb。pandas で読んで同じ cp932 で書き直すと 359,204 bytes、UTF-8 で保存すると 361,891 bytes、改行を CRLF から LF に変えるだけでも 359,255 bytes になり、3 つともバイト列の指紋は元と一致しない。一方、値の指紋は 4 行とも 5a5d3cfea7d3 で同じなので、どれも数値は 1 つも変わっていないと分かる。

配布ファイルの改ざん検知にはバイト列のハッシュを使い、受け取ったファイルには手を加えずに照合する。分析の途中で「値が変わっていないか」を確かめたいときは、並べ順・書式を固定した値の指紋を使う。どちらの指紋かを書かずに「ハッシュが一致した/しない」と報告すると、読み手は判断を誤る。

🧠 理解度チェック — SSDSE-B-2026 の数値で

Q1. SSDSE-B-2026 を読み込み、都道府県名の列で重複を数えたら 517 件あった。データは壊れているか。

壊れていない。このファイルは 47 県 × 12 年度 = 564 行で、各県が 12 回ずつ出るので、都道府県名だけで見た重複は 564 − 47 = 517 件になる。一意であるべきなのは(地域コード, 年度)の組で、これは重複 0 件。主キーをどの列の組にするかを決めてから一意性を検査する。

Q2. 2023 年度の北海道は 総人口 5,092,000、男 + 女 = 5,093,000 で 1,000 人ずれている。改ざんを疑うべきか。

この 1 件だけでは疑えない。SSDSE-B の人口は千人単位で丸めた値なので、男・女・総人口を別々に丸めると ±1,000 の差は普通に出る(47 県の差の最大も 1,000)。許容幅を 0 にすると正しいデータで警告が出る。逆に許容幅を広げすぎると、上の T3 のような小さな改ざんを通す。

Q3. 総人口と男と 65 歳以上を同じ数だけ増やす改ざんを、ルールで見つけるにはどうするか。

和のルールだけでは見つからない(T2)。前年度比のルールを足しても、東京都の総人口(2022 年度 14,038,000 → 2023 年度 14,086,000、+0.34%)に 5 万人足した後の前年度比は +0.70% で、12 年間の最大 1.7% より小さく、変化量のルールでも気づけない。確実に見つけるには、配布元が公開した値やハッシュと照合するしかない。

Q4. 出生数に「前年度比 ±5%」の警告を付けたら、12 年分で何件の警告が出るか。どう直すか。

517 件中 134 件。多くは人口の小さい県の自然な揺れで、改ざんではない。列ごとに過去の変化率の分布を見て、たとえば出生数は 99% 点の 9.3% を目安に ±10% にすると 2 件まで減る。警告が出た行は、その年の実際の出来事(感染症の流行など)と照らし合わせて確かめる。

Q5. 受け取った SSDSE-B-2026.csv のハッシュが配布元の値と一致しなかった。改ざんと決めてよいか。

まだ決められない。上のように、改行コード(CRLF → LF)や文字コード(cp932 → UTF-8)が変わっただけでもバイト列のハッシュは変わる。ダウンロード後に表計算ソフトで開いて保存していないかを確かめ、元の配布ファイルを取り直して照合する。値の指紋が手元の別コピーと一致すれば、少なくとも数値は同じである。

🗺 概念マップ

関連概念を視覚的に整理した概念マップ。

integrity CIA トライアド ACID ブロックチェーン HMAC 監査ログ SHA-256 ハッシュ

上図中心の「完全性 (integrity)」から、 SHA-256 ハッシュ ・ HMAC ・ 監査ログ ・ 落とし穴 (MD5 利用等) の軸が放射する。 完全性は情報セキュリティの 3 大要件 (CIA: Confidentiality / Integrity / Availability) の 1 つで、 「データが改ざんされていないこと」を保証する仕組みの総称。

🔗 隣接手法への橋渡し

完全性は機密性・可用性と並ぶ情報セキュリティの中核要件。 暗号技術・運用プロセスと組み合わせて初めて実装できる。

完全性違反は「改ざん」「破損」「重複処理」など多様な形で起きる。 例: SQL の UNIQUE 制約は重複行を防ぐ完全性保証、 SHA-256 ハッシュは配布ファイルの改ざん検知、 HMAC は通信中の改ざん検知。 用途で技術を使い分ける。

🌳 意思決定フローチャート

「完全性」の 選び方・適用判断をフローで整理。 状況に応じた選択を 4 段階で。

「データ完全性、 どこまで担保すべき?」のフローチャート:(1) 金銭・人命・法令関与? Yes → 強整合性 + audit log + 電子署名、 No → 次へ。 (2) 大規模 (>1TB) / 多人数編集? Yes → RDB の PK/FK/UNIQUE/NOT NULL + great_expectations、 No → 次へ。 (3) ファイル配布? Yes → SHA-256 ハッシュ + 電子署名、 No → 次へ。 (4) 通信? Yes → TLS の MAC + HMAC、 No → pandas 3 行健診で十分。