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