File size: 8,163 Bytes
1dbac36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#!/usr/bin/env python3
"""
EA Baselines Comparison - All baselines with and without EvoRM
Uses ref_pairs order for entity selection.
"""
import os, sys, json, time, shutil
from datetime import datetime

sys.path.insert(0, '/root/autodl-tmp/AdaCoAgentEA')
sys.path.insert(0, '/root/autodl-tmp/AdaCoAgentEA/Area2')
sys.path.insert(0, '/root/autodl-tmp/AdaCoAgentEA/baselines/evorm_wrappers')

os.environ["OPENAI_API_BASE"] = "https://hk.xty.app/v1"
os.environ["OPENAI_API_KEY"] = "sk-7a7Ev4VcVyysPLT5hqtqIVD6PybzJ1ZlEIVZddIR3NtZvPgK"

DATA_DIR = "/root/autodl-tmp/AdaCoAgentEA/data/icews_wiki"
RESULTS_DIR = "/root/autodl-tmp/AdaCoAgentEA/results"
ALIGNED_FILE = os.path.join(DATA_DIR, "message_pool", "aligned_entities.txt")
REF_PAIRS_FILE = os.path.join(DATA_DIR, "ref_pairs")
IMPORTANT_FILE = os.path.join(DATA_DIR, "message_pool", "important_entities.txt")
RETRIEVER_FILE = os.path.join(DATA_DIR, "message_pool", "retriever_outputs.txt")
EVORM_STATE = os.path.join(DATA_DIR, "evorm_state")

os.makedirs(RESULTS_DIR, exist_ok=True)

def load_ref_pairs():
    pairs = {}
    with open(REF_PAIRS_FILE, 'r') as f:
        for line in f:
            parts = line.strip().split('\t')
            if len(parts) == 2:
                try:
                    pairs[int(parts[0])] = int(parts[1])
                except:
                    pass
    return pairs

def compute_metrics(ref_subset=None):
    aligned = set()
    if os.path.exists(ALIGNED_FILE):
        with open(ALIGNED_FILE, 'r') as f:
            for line in f:
                parts = line.strip().split('\t')
                if len(parts) == 2:
                    try:
                        aligned.add((int(parts[0]), int(parts[1])))
                    except:
                        continue
    if ref_subset:
        ref_set = set(ref_subset.items())
    else:
        ref_set = set(load_ref_pairs().items())
    if not ref_set:
        return {'error': 'No ref pairs'}
    tp = len(aligned & ref_set)
    fp = len(aligned - ref_set)
    fn = len(ref_set - aligned)
    return {
        'Hits@1': round(tp / max(1, len(ref_set)), 4),
        'MRR': round(tp / max(1, len(ref_set)), 4),
        'Precision': round(tp / max(1, tp + fp), 4),
        'Recall': round(tp / max(1, tp + fn), 4),
        'F1': round(2 * tp / max(1, 2*tp + fp + fn), 4),
        'TP': tp, 'FP': fp, 'FN': fn,
        'Total_Ref': len(ref_set),
        'Total_Aligned': len(aligned),
    }

def clear_state():
    if os.path.exists(EVORM_STATE):
        shutil.rmtree(EVORM_STATE)
    if os.path.exists(ALIGNED_FILE):
        os.remove(ALIGNED_FILE)

def setup_subset(n_entities, ref_map):
    """Create subset using ref_pairs order."""
    ref_order = []
    with open(REF_PAIRS_FILE, 'r') as f:
        for line in f:
            parts = line.strip().split('\t')
            if len(parts) == 2:
                try:
                    e1 = int(parts[0])
                    if e1 not in ref_order:
                        ref_order.append(e1)
                except:
                    pass
    actual_n = min(n_entities, len(ref_order))
    subset_kg1 = set(ref_order[:actual_n])
    subset_lines = []
    with open(RETRIEVER_FILE, 'r') as f:
        for line in f:
            parts = line.strip().split('\t')
            if len(parts) == 2:
                try:
                    if int(parts[0]) in subset_kg1:
                        subset_lines.append(line)
                except:
                    pass
    with open(IMPORTANT_FILE, 'w') as f:
        f.writelines(subset_lines)
    subset_ref = {e1: ref_map[e1] for e1 in subset_kg1 if e1 in ref_map}
    return subset_ref

def run_adacoagent_baseline(data_dir, use_evorm=False):
    """Run AdaCoAgentEA (baseline or +EvoRM)."""
    clear_state()
    import tokens_cal
    tokens_cal.global_tokens = 0
    t0 = time.time()
    if use_evorm:
        from LLM1_label_selector import align_entities
    else:
        from LLM1_label_selector_baseline import align_entities
    aligned = align_entities(data_dir, from_m3=False)
    elapsed = time.time() - t0
    return aligned, elapsed, tokens_cal.global_tokens

def main():
    n_entities = 200  # Subset size for comparison
    ref_map = load_ref_pairs()
    print(f"Loaded {len(ref_map)} reference pairs")
    
    subset_ref = setup_subset(n_entities, ref_map)
    print(f"Subset: {len(subset_ref)} entities with ref pairs")
    
    # Baselines to run
    baselines = [
        ('AdaCoAgentEA', 'adacoagent'),
        ('ZeroCoT', 'zerocot'),
        ('Self-Consistency', 'self_consistency'),
        ('ChatEA', 'chatea'),
        ('Collaboration-Hard', 'cohard'),
    ]
    
    import tokens_cal
    
    results = []
    for bl_name, bl_key in baselines:
        for use_evorm in [False, True]:
            mode = f"{bl_name}{' + EvoRM' if use_evorm else ''}"
            print(f"\n{'='*50}")
            print(f"  {mode}")
            print(f"{'='*50}")
            
            clear_state()
            setup_subset(n_entities, ref_map)  # Re-setup after clear_state
            
            try:
                tokens_cal.global_tokens = 0
                t0 = time.time()
                
                if bl_key == 'adacoagent':
                    if use_evorm:
                        from LLM1_label_selector import align_entities
                    else:
                        from LLM1_label_selector_baseline import align_entities
                    aligned = align_entities(DATA_DIR, from_m3=False)
                elif bl_key == 'zerocot':
                    from zero_cot import align_entities as zc
                    aligned = zc(DATA_DIR, use_evorm=use_evorm)
                elif bl_key == 'self_consistency':
                    from self_consistency import align_entities as sc
                    aligned = sc(DATA_DIR, use_evorm=use_evorm)
                elif bl_key == 'chatea':
                    from chat_ea import align_entities as ce
                    aligned = ce(DATA_DIR, use_evorm=use_evorm)
                elif bl_key == 'cohard':
                    from cohard import align_entities as ch
                    aligned = ch(DATA_DIR, use_evorm=use_evorm)
                else:
                    raise ValueError(f"Unknown: {bl_key}")
                
                elapsed = time.time() - t0
                tokens = tokens_cal.global_tokens
                metrics = compute_metrics(ref_subset=subset_ref)
                
                result = {
                    'method': mode,
                    'aligned_pairs': len(aligned),
                    'time_seconds': round(elapsed, 1),
                    'tokens': tokens,
                    'tokens_per_pair': round(tokens / max(1, len(aligned)), 1),
                    'metrics': metrics,
                }
                results.append(result)
                
                print(f"  Aligned: {len(aligned)}, Time: {elapsed:.1f}s, Tokens: {tokens}")
                print(f"  Hits@1: {metrics['Hits@1']}, Precision: {metrics['Precision']}, Recall: {metrics['Recall']}")
                
            except Exception as e:
                print(f"  FAILED: {e}")
                import traceback
                traceback.print_exc()
    
    # Save
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    result_file = os.path.join(RESULTS_DIR, f"baselines_comparison_{timestamp}.json")
    with open(result_file, 'w') as f:
        json.dump({
            'experiment': 'EA Baselines Comparison',
            'dataset': 'ICEWS-WIKI',
            'n_entities': n_entities,
            'results': results,
        }, f, indent=2)
    
    # Summary
    print(f"\n{'='*80}")
    print("BASELINES COMPARISON SUMMARY")
    print(f"{'='*80}")
    print(f"{'Method':<35} {'Hits@1':>8} {'Prec':>8} {'Recall':>8} {'F1':>8} {'Tokens':>10} {'Time':>8}")
    print("-" * 80)
    for r in results:
        m = r['metrics']
        print(f"{r['method']:<35} {m['Hits@1']:>8.4f} {m['Precision']:>8.4f} "
              f"{m['Recall']:>8.4f} {m['F1']:>8.4f} {r['tokens']:>10} {r['time_seconds']:>7.1f}s")
    
    print(f"\nResults: {result_file}")

if __name__ == '__main__':
    main()