-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsyntethic_exps.py
More file actions
182 lines (159 loc) · 8.18 KB
/
Copy pathsyntethic_exps.py
File metadata and controls
182 lines (159 loc) · 8.18 KB
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
from utils import *
import numpy as np
import pandas as pd
from scipy import stats
from statsmodels.stats.multitest import multipletests
from competitors.data_handling_competitors import gete2wlandw2el
from competitors.data_handling_competitors import seed_everything
from real_exps import parse_args
from iaa_api import InterAnnotatorAgreementAPI
def obtain_df(data):
"""
Given a dictionary, returns a dataframe Pandas in a readable format.
"""
records = []
for key1, value1 in data.items():
for key2, value2 in value1.items():
record = {'key1': key1, 'key2': key2}
record.update(value2)
records.append(record)
df = pd.DataFrame(records)
df.columns = ['T value', 'vu value', 'Oracle MAP', 'Estimated MAP','MACE', 'LA_op', 'LA_tp', 'BWA'] #'MV', 'IWMV', 'Dawid-Skene', 'MACE', 'GLAD']
return df
def accuracy(true_Y: list, aggregated: list):
"""
Method to compute the accuracy
"""
final = 0
for true, noisy in zip(true_Y, aggregated):
if true == noisy:
final +=1
return final/len(true_Y)
def to_toloka(input_data:list):
"""
Transforms the annotation in a format list of lists to a dataframe readable by Toloka.
"""
results = []
for item, single_annotation in enumerate(input_data):
for worker, label in enumerate(single_annotation):
results.append({'task': item, 'worker': worker, 'label': label})
return pd.DataFrame(results, index=None)
def to_LA(input_data:list):
"""
Transforms the annotation in a format list of lists to dicts
which can be used by competitors.
"""
e2wl, w2el, label_set = gete2wlandw2el(None, input_data)
return e2wl, w2el, label_set
def generate_exps(num_classes:int, num_samples:int, vu: np.array,
H:int, T:np.array, return_toloka:bool=False):
"""
Given:
H: number of annotators
num_classes: number of classes
num_samples: number of samples which need to be annotated
vu: distribuution of the classes
T: noise transition matrix
Generates the required experiments."""
true_labels = generate_true_labels(C=num_classes, N=num_samples, D=vu)
data = generate_annotations(true_labels, T, H=H, obtain_list=True,
check_conditions=False)
if return_toloka:
toloka = to_toloka(data)
return data, true_labels, toloka
else:
return data, true_labels
if __name__ == '__main__':
results = {}
toloka_methods = ['Dawid-Skene', 'MACE', 'GLAD']
other_methods = ['la_one_pass', 'la_two_pass', 'BWA', 'MV', 'IWMV']
H = 3
num_classes = 2
num_samples = 10000
vu_values = np.array([[0.1,0.9]])
T_values = np.array([np.array([[0.8,0.2], [0.2,0.8]]), np.array([[0.51,0.49], [0.49,0.51]]),
np.array([[0.9,0.1], [0.1,0.9]]), np.array([[0.6,0.4], [0.4,0.6]]),
np.array([[0.7,0.3], [0.3,0.7]]),
np.array([[0.6,0.4], [0.25,0.75]]), np.array([[0.6,0.4], [0.1, 0.9]])])
args = parse_args()
if args.seed_values == [42]:
all_p_values = {}
seed = 42
seed_everything(seed=seed)
for index, T in enumerate(T_values):
results[index] = {}
for index_vu, vu in enumerate(vu_values):
results[index][index_vu] = {}
data, true_labels, toloka_data = generate_exps(num_classes=num_classes, num_samples=num_samples, vu=vu,
H=H, T=T, return_toloka=True)
oracle_results = list(oracle_MAP(data, T, np.array([vu, 1-vu])).values())
results[index][index_vu]['Oracle MAP'] = {}
results[index][index_vu]['Oracle MAP']['Result'] = accuracy(true_labels, oracle_results)
iaa = InterAnnotatorAgreementAPI(data)
iaa._build_t_matrix()
estimated_map = list(oracle_MAP(data, iaa._t_hat, np.array(iaa._label_distribution)).values())
results[index][index_vu]['Estimated MAP'] = {}
results[index][index_vu]['Estimated MAP']['Result'] = accuracy(true_labels, estimated_map)
if estimated_map != oracle_results:
t_value, p_value = stats.wilcoxon(estimated_map, oracle_results)
else:
t_value, p_value = -1, -1
results[index][index_vu]['Estimated MAP']['T value'] = round(t_value, 6)
all_p_values['Estimated MAP'] = p_value
e2wl, w2el, label_set = to_LA(data)
for method in other_methods:
result = obtain_competitor_results(method, e2wl, w2el, label_set, binary=True)
results[index][index_vu][method] = {}
results[index][index_vu][method]['Result'] = accuracy(true_labels, result)
if result != oracle_results:
t_value, p_value = stats.wilcoxon(result, oracle_results)
else:
t_value, p_value = -1, -1
results[index][index_vu][method]['T value'] = round(t_value, 6)
all_p_values[method] = round(p_value, 6)
for method_name in toloka_methods:
method = obtain_toloka_method(method_name)
result = method.fit_predict(toloka_data)
results[index][index_vu][method_name] = {}
results[index][index_vu][method_name]['Result'] = accuracy(true_labels, result)
if result.values.tolist() != oracle_results:
t_value, p_value = stats.wilcoxon(result.astype(int), oracle_results)
else:
t_value, p_value = -1, -1
results[index][index_vu][method_name]['T value'] = round(t_value, 6)
all_p_values[method_name] = round(p_value, 6)
rejected , corrected_p_values, _, _ = multipletests(list(all_p_values.values()), alpha=0.05, method='bonferroni')
for (name, value), reject in zip(all_p_values.items(), rejected):
results[index][index_vu][name]['Stat Sig'] = reject
print(results)
df = flatten_synthetic_results(results)
df = df.round(decimals=4)
os.makedirs('results', exist_ok=True)
df.to_csv(f'results/synthetic_results_H_{H}_N_{num_samples}.csv', index=False)
else:
for seed in args.seed_values:
results[seed] = {}
for index, T in enumerate(T_values):
results[seed][index] = {}
for index_vu, vu in enumerate(vu_values):
results[seed][index][vu] = {}
data, true_labels, toloka_data = generate_exps(num_classes=num_classes, num_samples=num_samples, vu=vu,
H=H, T=T, return_toloka=True)
oracle_results = list(oracle_MAP(data, T, np.array([vu, 1-vu])).values())
results[seed][index][vu]['Oracle MAP'] = accuracy(true_labels, oracle_results)
iaa = InterAnnotatorAgreementAPI(data)
iaa._build_t_matrix()
estimated_map = list(oracle_MAP(data, iaa._t_hat, np.array(iaa._label_distribution)).values())
results[seed][index][vu]['Estimated MAP'] = accuracy(true_labels, estimated_map)
e2wl, w2el, label_set = to_LA(data)
for method in other_methods:
result = obtain_competitor_results(method, e2wl, w2el, label_set, binary=True)
results[seed][index][vu][method] = accuracy(true_labels, result)
for method_name in toloka_methods:
method = obtain_toloka_method(method_name)
result = method.fit_predict(toloka_data)
results[seed][index][vu][method_name] = accuracy(true_labels, result)
df = get_synthetic_table_with_std(results)
df = df.round(decimals=4)
os.makedirs('results', exist_ok=True)
df.to_csv(f'results/synthetic_results_H_{H}_N_{num_samples}.csv')