1:- module(ap_calibration, [evaluate_csv/2, print_evaluation/1]).
9:- use_module(library(csv)). 10:- use_module(library(lists)). 11:- use_module(library(apply)). 12:- use_module(library(pairs)). 13:- use_module(ap_defaults). 14:- use_module(ap_model). 15:- use_module(ap_validation). 16
17evaluate_csv(File, Summary) :-
18 csv_read_file(File, Rows, [functor(row), strip(true)]),
19 Rows = [Header|Data],
20 Header =.. [_|Names0], maplist(to_atom, Names0, Names),
21 findall(Pred-Actual,
22 ( member(Row, Data),
23 Row =.. [_|Values],
24 pairs_keys_values(Pairs, Names, Values),
25 row_scenario(Pairs, S, Actual),
26 ap_model:score(S, R),
27 Pred is R.likelihood/100.0
28 ), PairsPA),
29 summarize(PairsPA, Summary).
30
31row_scenario(Pairs, S, Actual) :-
32 ap_defaults:default_scenario(D),
33 model_feature_keys(Keys),
34 foldl(apply_pair(Pairs), Keys, D, S),
35 ( memberchk(actual_protest-A0, Pairs), ap_validation:safe_number(A0, A1), A1 >= 0.5 -> Actual=1 ; Actual=0 ).
36
37apply_pair(Pairs, Key, S0, S) :-
38 ( memberchk(Key-Raw, Pairs), ap_validation:safe_number(Raw, N) -> put_dict(Key, S0, N, S)
39 ; S = S0
40 ).
41
42model_feature_keys([grievance,trigger,salience,online,coalition,organization,
43 economic_stress,institutional_distrust,incident_shock,recent_precedent,
44 media_attention,public_support,regional_relevance,govt_communication,
45 govt_responsiveness,organizer_control,intervention_pressure,evidence_quality]).
46
47to_atom(X, A) :- atom(X), !, A=X.
48to_atom(X, A) :- string(X), !, atom_string(A, X).
49to_atom(X, A) :- term_to_atom(X, A).
50
51summarize([], _{events:0, accuracy:null, brier:null, warning:'tidak ada data'}).
52summarize(Pairs, Summary) :-
53 length(Pairs, N),
54 findall(C, (member(P-A,Pairs), predicted_class(P,PC), (PC=:=A -> C=1 ; C=0)), Cs),
55 sum_list(Cs, Correct), Accuracy is Correct/N,
56 findall(B, (member(P-A,Pairs), B is (P-A)*(P-A)), Bs), sum_list(Bs, BSum), Brier is BSum/N,
57 Summary = _{events:N, accuracy:Accuracy, brier:Brier,
58 warning:'evaluasi in-sample hanya bermakna bila CSV benar-benar historis dan fitur ditentukan tanpa melihat outcome'}.
59
60predicted_class(P, 1) :- P >= 0.5, !.
61predicted_class(_, 0).
62
63print_evaluation(S) :-
64 format('Events : ~w~n', [S.events]),
65 format('Accuracy: ~w~n', [S.accuracy]),
66 format('Brier : ~w~n', [S.brier]),
67 format('Catatan : ~w~n', [S.warning])
Evaluasi historis sederhana.
CSV harus berisi fitur model dan actual_protest (0/1). Modul ini MENGUJI model, bukan melatih ulang bobot. Ini sengaja agar v0.1 tidak berpura-pura terkalibrasi.