File size: 5,226 Bytes
254d04b |
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
import json
import hashlib
from knowledge_tile_generator import create_knowledge_tile
from reasoning_chain_extractor import extract_reasoning_chain
from coordinate_mapper import map_reasoning_to_medical_space
from iath_encoder import IathEncoder
from iath_decoder import IathDecoder
def generate_sample_tile() -> dict:
"""
検証用のサンプルKnowledge Tileを生成します。
"""
dummy_response = {
'thinking': 'まず、心筋梗塞の定義から始めます。これは心筋への血流が途絶えることで心筋が壊死する状態です。次に、診断のゴールドスタンダードであるトロポニン測定について考慮します。これは~という理由で重要です。さらに心電図の変化も重要な所見です。ST上昇が見られる場合、急性期と判断されます。',
'response': '急性心筋梗塞は、迅速な診断と治療が求められる救急疾患です。診断は主に、臨床症状(胸痛など)、心電図変化(ST上昇など)、心筋逸脱酵素(特にトロポニン)の上昇を三本柱として行われます。アルゴリズムとしては、まず疑いがあれば直ちに12誘導心電図を記録し、バイタルサインを確認します。ST上昇があれば、緊急カテーテル治療の適応を考慮します。<参考資料> 日本循環器学会ガイドライン2023',
}
topic = "心筋梗塞の急性期診断"
reasoning = extract_reasoning_chain(dummy_response)
coordinates = map_reasoning_to_medical_space(reasoning)
knowledge_tile = create_knowledge_tile(dummy_response, coordinates, topic)
return knowledge_tile
def verify_lossless_compression(original_tile: dict) -> dict:
"""
指定されたKnowledge Tileの可逆圧縮を検証します。
エンコード -> デコードを実行し、結果がオリジナルと一致するか確認します。
"""
encoder = IathEncoder()
decoder = IathDecoder()
# ステップ1: エンコード
try:
compressed_data = encoder.encode_tile(original_tile)
original_size = len(json.dumps(original_tile, ensure_ascii=False).encode('utf-8'))
except Exception as e:
return {"status": f"✗ エンコード失敗: {e}", "is_lossless": False}
# ステップ2: デコード
try:
decompressed_tile = decoder.decode_tile(compressed_data)
except Exception as e:
return {"status": f"✗ デコード失敗: {e}", "is_lossless": False}
# ステップ3: ハッシュを比較して可逆性を検証
# NOTE: デコード処理では一部のフィールド(source, historyなど)が復元されないため、
# それらのフィールドを比較対象から除外した上でハッシュを計算します。
def get_comparable_hash(tile_data: dict) -> str:
# 比較対象のキーを限定
keys_to_compare = ["metadata", "content", "coordinates", "verification"]
comparable_data = {key: tile_data.get(key) for key in keys_to_compare}
# 安定したハッシュ生成のため、キーでソートしてJSON化
serialized = json.dumps(comparable_data, sort_keys=True, ensure_ascii=False)
return hashlib.sha256(serialized.encode('utf-8')).hexdigest()
original_hash = get_comparable_hash(original_tile)
decompressed_hash = get_comparable_hash(decompressed_tile)
is_lossless = original_hash == decompressed_hash
status = "✓ 完全な可逆圧縮" if is_lossless else "✗ 情報損失あり"
report = {
"is_lossless": is_lossless,
"status": status,
"original_hash": original_hash,
"decompressed_hash": decompressed_hash,
"original_size": original_size,
"compressed_size": len(compressed_data),
"compression_ratio": f"{(len(compressed_data) / original_size):.2%}" if original_size > 0 else "N/A",
}
return report
if __name__ == "__main__":
print("--- 可逆圧縮検証開始 ---")
# 1. サンプルタイルを生成
print("1. サンプルKnowledge Tileを生成中...")
sample_tile = generate_sample_tile()
# 2. 可逆圧縮を検証
print("2. エンコード -> デコードを実行し、可逆性を検証中...")
verification_report = verify_lossless_compression(sample_tile)
# 3. 結果を表示
print("\n--- 可逆圧縮検証結果 ---")
print(f"ステータス: {verification_report['status']}")
print(f" 可逆性: {verification_report['is_lossless']}")
print(f" 元データのハッシュ: {verification_report['original_hash']}")
print(f" 復元データのハッシュ: {verification_report['decompressed_hash']}")
print(f" 元の推定サイズ: {verification_report['original_size']} bytes")
print(f" 圧縮後のサイズ: {verification_report['compressed_size']} bytes")
print(f" 圧縮率: {verification_report['compression_ratio']}")
if not verification_report['is_lossless']:
print("\n[!] ハッシュが一致しませんでした。エンコーダーとデコーダーの実装を確認してください。")
|