tasksource 0.0.45__tar.gz → 0.0.47__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tasksource-0.0.45 → tasksource-0.0.47}/PKG-INFO +1 -1
- tasksource-0.0.47/src/tasksource/.ipynb_checkpoints/access-checkpoint.py +112 -0
- tasksource-0.0.47/src/tasksource/.ipynb_checkpoints/preprocess-checkpoint.py +295 -0
- tasksource-0.0.47/src/tasksource/.ipynb_checkpoints/recast-checkpoint.py +115 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource/.ipynb_checkpoints/tasks-checkpoint.py +64 -17
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource/access.py +4 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource/preprocess.py +33 -5
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource/recast.py +4 -2
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource/tasks.py +64 -17
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource.egg-info/PKG-INFO +1 -1
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource.egg-info/SOURCES.txt +3 -0
- tasksource-0.0.47/tasks.md +669 -0
- tasksource-0.0.45/tasks.md +0 -660
- {tasksource-0.0.45 → tasksource-0.0.47}/.github/scripts/release.py +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/.github/workflows/python-publish.yml +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/.github/workflows/release.yml +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/.gitignore +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/CITATION.cff +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/LICENSE +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/README.md +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/mtasks.md +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/pyproject.toml +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/setup.cfg +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource/__init__.py +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource/metadata/__init__.py +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource/metadata/bigbench_groups.py +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource/metadata/blimp_groups.py +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource/metadata/original.txt +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource/metadata/popularity.py +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource/mtasks.py +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource.egg-info/dependency_links.txt +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource.egg-info/requires.txt +0 -0
- {tasksource-0.0.45 → tasksource-0.0.47}/src/tasksource.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
from .preprocess import Preprocessing
|
|
2
|
+
import re
|
|
3
|
+
import pandas as pd
|
|
4
|
+
from . import tasks, recast
|
|
5
|
+
from .metadata import dataset_rank
|
|
6
|
+
from datasets import load_dataset
|
|
7
|
+
import funcy as fc
|
|
8
|
+
import os
|
|
9
|
+
import copy
|
|
10
|
+
from sorcery import dict_of
|
|
11
|
+
from functools import cache
|
|
12
|
+
import random
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class lazy_mtasks:
|
|
16
|
+
def __getattr__(self, name):
|
|
17
|
+
from . import mtasks
|
|
18
|
+
return getattr(mtasks, name)
|
|
19
|
+
|
|
20
|
+
def __dir__(self):
|
|
21
|
+
from . import mtasks
|
|
22
|
+
return dir(mtasks)
|
|
23
|
+
lmtasks=lazy_mtasks()
|
|
24
|
+
|
|
25
|
+
def parse_var_name(s):
|
|
26
|
+
config_name,task_name = None,None
|
|
27
|
+
if '__' in s and '___' not in s: # dataset__task
|
|
28
|
+
dataset_name, task_name = s.split('__')
|
|
29
|
+
elif '__' not in s.replace('___','') and '___' in s: #dataset___config
|
|
30
|
+
dataset_name, config_name = s.split('___')
|
|
31
|
+
elif '___' in s and '__' in s.split('___')[1]: #dataset___config__task
|
|
32
|
+
dataset_name, config_task=s.split('___')
|
|
33
|
+
config_name,task_name = config_task.split('__')
|
|
34
|
+
else: # dataset
|
|
35
|
+
dataset_name = s
|
|
36
|
+
return dataset_name,config_name,task_name
|
|
37
|
+
|
|
38
|
+
def pretty_name(x):
|
|
39
|
+
dn = x.dataset_name.split("/")[-1]
|
|
40
|
+
cn = x.config_name if x.config_name else ""
|
|
41
|
+
tn = x.task_name if x.task_name else ""
|
|
42
|
+
return f"{dn}/{cn}/{tn}".replace('//','/').rstrip('/')
|
|
43
|
+
|
|
44
|
+
@cache
|
|
45
|
+
def list_tasks(tasks_path=f'{os.path.dirname(__file__)}/tasks.py',multilingual=False,instruct=False, excluded=[]):
|
|
46
|
+
if multilingual:
|
|
47
|
+
tasks_path=tasks_path.replace('/tasks.py','/mtasks.py')
|
|
48
|
+
task_order = open(tasks_path).readlines()
|
|
49
|
+
task_order = [x.split('=')[0].rstrip() for x in task_order if '=' in x]
|
|
50
|
+
task_order = [x for x in task_order if x.isidentifier()]
|
|
51
|
+
task_order = fc.flip(dict(enumerate(task_order)))
|
|
52
|
+
|
|
53
|
+
l = []
|
|
54
|
+
_tasks = (lmtasks if multilingual else tasks)
|
|
55
|
+
|
|
56
|
+
for key in dir(_tasks):
|
|
57
|
+
if key not in task_order:
|
|
58
|
+
continue
|
|
59
|
+
value=getattr(_tasks, key)
|
|
60
|
+
if isinstance(value,Preprocessing):
|
|
61
|
+
dataset_name, config_name, task_name = parse_var_name(key)
|
|
62
|
+
dataset_name = (value.dataset_name if value.dataset_name else dataset_name)
|
|
63
|
+
config_name = (value.config_name if value.config_name else config_name)
|
|
64
|
+
hasattr(value,key)
|
|
65
|
+
l+=[{'dataset_name': dataset_name,
|
|
66
|
+
'config_name' : config_name,
|
|
67
|
+
'task_name': task_name,
|
|
68
|
+
'preprocessing_name': key,
|
|
69
|
+
'task_type': value.__class__.__name__,'mapping': value,
|
|
70
|
+
'rank':task_order.get(key,None)}]
|
|
71
|
+
df=pd.DataFrame(l).explode('config_name')
|
|
72
|
+
df = df.sort_values('rank').reset_index(drop=True)
|
|
73
|
+
df['id'] = df.apply(lambda x: pretty_name(x), axis=1)
|
|
74
|
+
df.insert(0, 'id', df.pop('id'))
|
|
75
|
+
del df['rank']
|
|
76
|
+
if instruct:
|
|
77
|
+
df=df[df.id.map(lambda x: not any(a in x for a in recast.improper_labels))]
|
|
78
|
+
df=df[df.id.map(lambda x: not any(x in a for a in excluded))]
|
|
79
|
+
return df
|
|
80
|
+
|
|
81
|
+
#task_df =list_tasks()
|
|
82
|
+
#mtask_df =list_tasks(multilingual=True)
|
|
83
|
+
|
|
84
|
+
def dict_to_query(d=dict(), **kwargs):
|
|
85
|
+
d={**d,**kwargs}
|
|
86
|
+
return '&'.join([f'`{k}`=="{v}"' for k,v in d.items()])
|
|
87
|
+
|
|
88
|
+
def load_preprocessing(tasks=tasks, **kwargs):
|
|
89
|
+
_tasks_df = list_tasks(multilingual=tasks==lmtasks)
|
|
90
|
+
y = _tasks_df.copy().query(dict_to_query(**kwargs)).iloc[0]
|
|
91
|
+
preprocessing= copy.copy(getattr(tasks, y.preprocessing_name))
|
|
92
|
+
for c in 'dataset_name','config_name':
|
|
93
|
+
if not isinstance(getattr(preprocessing,c), str):
|
|
94
|
+
setattr(preprocessing,c,getattr(y,c))
|
|
95
|
+
return preprocessing
|
|
96
|
+
|
|
97
|
+
def load_task(id=None, dataset_name=None,config_name=None,task_name=None,preprocessing_name=None,
|
|
98
|
+
max_rows=None, max_rows_eval=None, multilingual=False, instruct=False, seed=0, **load_dataset_kwargs):
|
|
99
|
+
query = dict_of(id, dataset_name, config_name, task_name,preprocessing_name)
|
|
100
|
+
query = {k:v for k,v in query.items() if v}
|
|
101
|
+
_tasks = (lmtasks if multilingual else tasks)
|
|
102
|
+
preprocessing = load_preprocessing(_tasks, **query)
|
|
103
|
+
|
|
104
|
+
if "trust_remote_code" not in load_dataset_kwargs:
|
|
105
|
+
load_dataset_kwargs["trust_remote_code"] = True
|
|
106
|
+
|
|
107
|
+
dataset = load_dataset(preprocessing.dataset_name, preprocessing.config_name, **load_dataset_kwargs)
|
|
108
|
+
dataset= preprocessing(dataset,max_rows, max_rows_eval)
|
|
109
|
+
dataset.task_type = preprocessing.__class__.__name__
|
|
110
|
+
if instruct:
|
|
111
|
+
dataset=recast.recast_instruct(dataset)
|
|
112
|
+
return dataset
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
from dotwiz import DotWiz
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Union
|
|
5
|
+
import itertools
|
|
6
|
+
import funcy as fc
|
|
7
|
+
import exrex
|
|
8
|
+
import magicattr
|
|
9
|
+
import numpy as np
|
|
10
|
+
import copy
|
|
11
|
+
import datasets
|
|
12
|
+
import time
|
|
13
|
+
|
|
14
|
+
MAX_MC_OPTIONS = 4
|
|
15
|
+
|
|
16
|
+
def get_column_names(dataset):
|
|
17
|
+
cn = dataset.column_names
|
|
18
|
+
if type(cn)==dict:
|
|
19
|
+
return set(fc.flatten(cn.values()))
|
|
20
|
+
else:
|
|
21
|
+
return set(cn)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def sample_dataset(dataset,n=10000, n_eval=1000,seed=0):
|
|
25
|
+
for k in dataset:
|
|
26
|
+
n_k=(n if k=='train' else n_eval)
|
|
27
|
+
if n_k and len(dataset[k])>n_k:
|
|
28
|
+
dataset[k]=dataset[k].train_test_split(train_size=n_k,seed=seed)['train']
|
|
29
|
+
return dataset
|
|
30
|
+
|
|
31
|
+
class Preprocessing(DotWiz):
|
|
32
|
+
default_splits = ('train','validation','test')
|
|
33
|
+
_instances = []
|
|
34
|
+
|
|
35
|
+
def __post_init__(self):
|
|
36
|
+
Preprocessing._instances+=[self]
|
|
37
|
+
|
|
38
|
+
@staticmethod
|
|
39
|
+
def __map_to_target(x,fn=lambda x:None, target=None):
|
|
40
|
+
x[target]=fn(x)
|
|
41
|
+
return x
|
|
42
|
+
|
|
43
|
+
def load(self):
|
|
44
|
+
return self(datasets.load_dataset(self.dataset_name,self.config_name))
|
|
45
|
+
|
|
46
|
+
def __call__(self,dataset, max_rows=None, max_rows_eval=None,seed=0):
|
|
47
|
+
dataset = self.pre_process(dataset)
|
|
48
|
+
|
|
49
|
+
# manage splits
|
|
50
|
+
for k,v in zip(self.default_splits, self.splits):
|
|
51
|
+
if v and k!=v:
|
|
52
|
+
dataset[k]=dataset[v]
|
|
53
|
+
del dataset[v]
|
|
54
|
+
if k in dataset and not v: # obfuscated label
|
|
55
|
+
del dataset[k]
|
|
56
|
+
dataset = fix_splits(dataset)
|
|
57
|
+
|
|
58
|
+
for k in list(dataset.keys()):
|
|
59
|
+
if k not in self.default_splits:
|
|
60
|
+
del dataset[k]
|
|
61
|
+
dataset = sample_dataset(dataset, max_rows, max_rows_eval,seed=seed)
|
|
62
|
+
|
|
63
|
+
# field annotated with a string
|
|
64
|
+
substitutions = {v:k for k,v in self.to_dict().items()
|
|
65
|
+
if (k and k not in {'splits','dataset_name','config_name'}
|
|
66
|
+
and type(v)==str and k!=v)}
|
|
67
|
+
|
|
68
|
+
dataset=dataset.remove_columns([c for c in substitutions.values() if c in dataset['train'].features and c not in substitutions])
|
|
69
|
+
dataset=dataset.rename_columns(substitutions)
|
|
70
|
+
|
|
71
|
+
# field annotated with a function
|
|
72
|
+
for k in self.to_dict().keys():
|
|
73
|
+
v=getattr(self, k)
|
|
74
|
+
if callable(v) and k not in {"post_process","pre_process","load"}:
|
|
75
|
+
dataset=dataset.map(self.__map_to_target,
|
|
76
|
+
fn_kwargs={'fn':v,'target':k})
|
|
77
|
+
|
|
78
|
+
dataset=dataset.remove_columns(
|
|
79
|
+
get_column_names(dataset)-set(self.to_dict().keys()))
|
|
80
|
+
dataset = fix_labels(dataset)
|
|
81
|
+
dataset = fix_splits(dataset) # again: label mapping changed
|
|
82
|
+
dataset = self.post_process(dataset)
|
|
83
|
+
return dataset
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
@dataclass
|
|
87
|
+
class cat(Preprocessing):
|
|
88
|
+
fields:Union[str,list]=None
|
|
89
|
+
separator:str=' '
|
|
90
|
+
|
|
91
|
+
def __call__(self, example=None):
|
|
92
|
+
y=[np.char.array(example[f]) + sep
|
|
93
|
+
for f,sep in zip(self.fields[::-1],itertools.repeat(self.separator))]
|
|
94
|
+
y=list(sum(*y))
|
|
95
|
+
if len(y)==1:
|
|
96
|
+
y=y[0]
|
|
97
|
+
return y
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def pretty(f):
|
|
101
|
+
class pretty_f(DotWiz):
|
|
102
|
+
def __init__(self,*args):
|
|
103
|
+
self.__f_arg = f(*args)
|
|
104
|
+
for a in args:
|
|
105
|
+
setattr(self,'value',a)
|
|
106
|
+
|
|
107
|
+
def __call__(self, *args,**kwargs):
|
|
108
|
+
return self.__f_arg(*args,**kwargs)
|
|
109
|
+
|
|
110
|
+
def __repr__(self):
|
|
111
|
+
return f"{self.__f_arg.__qualname__ .split('.')[0]}({self.value})"
|
|
112
|
+
return pretty_f
|
|
113
|
+
|
|
114
|
+
class dotgetter:
|
|
115
|
+
def __init__(self, path=''):
|
|
116
|
+
self.path=path
|
|
117
|
+
|
|
118
|
+
def __bool__(self):
|
|
119
|
+
return bool(self.path)
|
|
120
|
+
|
|
121
|
+
def __getattr__(self, k):
|
|
122
|
+
return self.__class__(f'{self.path}.{k}'.lstrip('.'))
|
|
123
|
+
|
|
124
|
+
def __getitem__(self, i):
|
|
125
|
+
return self.__class__(f'{self.path}[{i}]')
|
|
126
|
+
|
|
127
|
+
def __call__(self, example=None):
|
|
128
|
+
return magicattr.get(DotWiz(example), self.path)
|
|
129
|
+
|
|
130
|
+
def __hash__(self):
|
|
131
|
+
return hash(self.path)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@dataclass
|
|
135
|
+
class ClassificationFields(Preprocessing):
|
|
136
|
+
sentence1:str='sentence1'
|
|
137
|
+
sentence2:str='sentence2'
|
|
138
|
+
labels:str='labels'
|
|
139
|
+
|
|
140
|
+
@dataclass
|
|
141
|
+
class Seq2SeqLMFields(Preprocessing):
|
|
142
|
+
prompt:str='prompt'
|
|
143
|
+
output:str='output'
|
|
144
|
+
|
|
145
|
+
@dataclass
|
|
146
|
+
class TokenClassificationFields(Preprocessing):
|
|
147
|
+
tokens:str='tokens'
|
|
148
|
+
labels:str='labels'
|
|
149
|
+
|
|
150
|
+
@dataclass
|
|
151
|
+
class MultipleChoiceFields(Preprocessing):
|
|
152
|
+
inputs:str='input'
|
|
153
|
+
choices:Iterable=tuple()
|
|
154
|
+
labels:str='labels'
|
|
155
|
+
choices_list:str=None
|
|
156
|
+
def __post_init__(self):
|
|
157
|
+
for i, c in enumerate(self.choices):
|
|
158
|
+
setattr(self,f'choice{i}',c)
|
|
159
|
+
delattr(self,'choices')
|
|
160
|
+
if not self.choices_list:
|
|
161
|
+
delattr(self,'choices_list')
|
|
162
|
+
|
|
163
|
+
def __call__(self,dataset, *args, **kwargs):
|
|
164
|
+
dataset = super().__call__(dataset, *args, **kwargs)
|
|
165
|
+
if self.choices_list:
|
|
166
|
+
dataset = dataset.filter(lambda x: 1<len(x['choices_list']))
|
|
167
|
+
n_options = min([len(x) for k in dataset for x in dataset[k]['choices_list']])
|
|
168
|
+
n_options = min(MAX_MC_OPTIONS,n_options)
|
|
169
|
+
dataset = dataset.map(self.flatten_choice_list, fn_kwargs={'n_options':n_options})
|
|
170
|
+
|
|
171
|
+
else:
|
|
172
|
+
dataset = dataset.map(self.sample_choices, fn_kwargs={'n_options':MAX_MC_OPTIONS})
|
|
173
|
+
return dataset
|
|
174
|
+
|
|
175
|
+
@staticmethod
|
|
176
|
+
def flatten_choice_list(x, n_options=None):
|
|
177
|
+
n_neg = n_options-1 if n_options else None
|
|
178
|
+
choices = x['choices_list']
|
|
179
|
+
label=x['labels']
|
|
180
|
+
neg = choices[:label] + choices[label+1:]
|
|
181
|
+
pos = choices[label]
|
|
182
|
+
x['labels']=0
|
|
183
|
+
x['choices_list']=[pos]+neg[:n_neg]
|
|
184
|
+
for i,o in enumerate(x['choices_list']):
|
|
185
|
+
x[f'choice{i}']=o
|
|
186
|
+
del x['choices_list']
|
|
187
|
+
return x
|
|
188
|
+
|
|
189
|
+
@staticmethod
|
|
190
|
+
def sample_choices(x, n_options=None):
|
|
191
|
+
choices = [x[c] for c in x if 'choice' in c]
|
|
192
|
+
if not MAX_MC_OPTIONS or len(choices)<=n_options:
|
|
193
|
+
return x
|
|
194
|
+
n_neg = n_options-1 if n_options else None
|
|
195
|
+
label=x['labels']
|
|
196
|
+
neg = choices[:label] + choices[label+1:]
|
|
197
|
+
pos = choices[label]
|
|
198
|
+
x['labels']=0
|
|
199
|
+
choices_list=[pos]+neg[:n_neg]
|
|
200
|
+
for c in list(x):
|
|
201
|
+
if 'choice' in c:
|
|
202
|
+
del x[c]
|
|
203
|
+
for i,o in enumerate(choices_list):
|
|
204
|
+
x[f'choice{i}']=o
|
|
205
|
+
return x
|
|
206
|
+
|
|
207
|
+
@dataclass
|
|
208
|
+
class SharedFields:
|
|
209
|
+
splits:list=Preprocessing.default_splits
|
|
210
|
+
dataset_name:str = None
|
|
211
|
+
config_name:str = None
|
|
212
|
+
pre_process: callable = fc.identity
|
|
213
|
+
post_process: callable = fc.identity
|
|
214
|
+
#language:str="en"
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
@dataclass
|
|
218
|
+
class Classification(SharedFields, ClassificationFields): pass
|
|
219
|
+
|
|
220
|
+
@dataclass
|
|
221
|
+
class MultipleChoice(SharedFields, MultipleChoiceFields): pass
|
|
222
|
+
|
|
223
|
+
@dataclass
|
|
224
|
+
class TokenClassification(SharedFields, TokenClassificationFields): pass
|
|
225
|
+
|
|
226
|
+
@dataclass
|
|
227
|
+
class Seq2SeqLM(SharedFields, Seq2SeqLMFields): pass
|
|
228
|
+
|
|
229
|
+
get=dotgetter()
|
|
230
|
+
constant = pretty(fc.constantly)
|
|
231
|
+
regen = lambda x: list(exrex.generate(x))
|
|
232
|
+
|
|
233
|
+
def name(label_name, classes):
|
|
234
|
+
return lambda x:classes[x[label_name]]
|
|
235
|
+
|
|
236
|
+
def fix_splits(dataset):
|
|
237
|
+
|
|
238
|
+
if len(dataset)==1 and "train" not in dataset:
|
|
239
|
+
k = list(dataset)[0]
|
|
240
|
+
dataset['train'] = copy.deepcopy(dataset[k])
|
|
241
|
+
del dataset[k]
|
|
242
|
+
|
|
243
|
+
if 'auxiliary_train' in dataset:
|
|
244
|
+
del dataset['auxiliary_train']
|
|
245
|
+
|
|
246
|
+
if 'test' in dataset: # manage obfuscated labels
|
|
247
|
+
if 'labels' in dataset['test'].features:
|
|
248
|
+
if len(set(fc.flatten(dataset['test'].to_dict()['labels'])))==1:
|
|
249
|
+
del dataset['test']
|
|
250
|
+
|
|
251
|
+
if 'validation' in dataset and 'train' not in dataset:
|
|
252
|
+
train_validation = dataset['validation'].train_test_split(0.5, seed=0)
|
|
253
|
+
dataset['train'] = train_validation['train']
|
|
254
|
+
dataset['validation']=train_validation['test']
|
|
255
|
+
|
|
256
|
+
if 'validation' in dataset and 'test' not in dataset:
|
|
257
|
+
validation_test = dataset['validation'].train_test_split(0.5, seed=0)
|
|
258
|
+
dataset['validation'] = validation_test['train']
|
|
259
|
+
dataset['test']=validation_test['test']
|
|
260
|
+
|
|
261
|
+
if 'train' in dataset and 'validation' not in dataset:
|
|
262
|
+
train_val = dataset['train'].train_test_split(train_size=0.90, seed=0)
|
|
263
|
+
dataset['train'] = train_val['train']
|
|
264
|
+
dataset['validation']=train_val['test']
|
|
265
|
+
|
|
266
|
+
if 'test' in dataset and 'validation' not in dataset:
|
|
267
|
+
validation_test = dataset['test'].train_test_split(0.5, seed=0)
|
|
268
|
+
dataset['validation'] = validation_test['train']
|
|
269
|
+
dataset['test']=validation_test['test']
|
|
270
|
+
|
|
271
|
+
if 'validation' not in dataset and 'test' not in dataset:
|
|
272
|
+
train_val_test = dataset["train"].train_test_split(train_size=0.90, seed=0)
|
|
273
|
+
val_test = train_val_test["test"].train_test_split(0.5, seed=0)
|
|
274
|
+
dataset["train"] = train_val_test["train"]
|
|
275
|
+
dataset["validation"] = val_test["train"]
|
|
276
|
+
dataset["test"] = val_test["test"]
|
|
277
|
+
|
|
278
|
+
return dataset
|
|
279
|
+
|
|
280
|
+
def fix_labels(dataset, label_key='labels'):
|
|
281
|
+
if type(dataset['train'][label_key][0]) in [int,list,float]:
|
|
282
|
+
return dataset
|
|
283
|
+
labels=set(fc.flatten(dataset[k][label_key] for k in {"train"}))
|
|
284
|
+
if set(labels)=={'entailment','neutral','contradiction'}:
|
|
285
|
+
order=lambda x:dict(fc.flip(enumerate(['entailment','neutral','contradiction']))).get(x,x)
|
|
286
|
+
else:
|
|
287
|
+
order=str
|
|
288
|
+
labels=sorted(labels, key=order)
|
|
289
|
+
dataset=dataset.cast_column(label_key, datasets.ClassLabel(names=labels))
|
|
290
|
+
return dataset
|
|
291
|
+
|
|
292
|
+
def concatenate_dataset_dict(l):
|
|
293
|
+
"""Concatenate a list of DatastDict objects sharing same splits and columns."""
|
|
294
|
+
keys=l[0].keys()
|
|
295
|
+
return datasets.DatasetDict({k: datasets.concatenate_datasets([x[k] for x in l]) for k in keys})
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import random
|
|
2
|
+
from datasets import DatasetDict, Dataset
|
|
3
|
+
from sorcery import dict_of
|
|
4
|
+
import string
|
|
5
|
+
|
|
6
|
+
improper_labels =['recast/recast_kg_relations','linguisticprobing',"lex_glue/scotus",'lexical_relation_classification/ROOT09',"pragmeval/squinky","pragmeval/emobank",'pragmeval/persuasiveness']
|
|
7
|
+
improper_labels += ['glue/stsb', 'sick/relatedness', 'joci', 'utilitarianism', 'amazon_counterfactual/en', 'toxic_conversations', 'ethos/multilabel', 'lex_glue/eurlex', 'lex_glue/unfair_tos', 'app_reviews', 'humicroedit/subtask-1', 'stackoverflow-questions', 'go_emotions/simplified', 'google_wellformed_query', 'has_part', 'blog_authorship_corpus/age', 'promptCoherence', 'Sarcasm_News_Headline', 'auditor_review/demo-org--auditor_review', 'Dynasent_Disagreement', 'Politeness_Disagreement', 'SBIC_Disagreement', 'SChem_Disagreement', 'Dilemmas_Disagreement', 'sts-companion', 'acceptability-prediction', 'chaos-mnli-ambiguity', 'headline_cause/en_simple', 'oasst1_dense_flat', 'civil_comments']
|
|
8
|
+
|
|
9
|
+
improper_labels += ['stsb_multi_mt','MLMA_hate_speech','icl-symbol-tuning-instruct','zero-shot-label-nli']
|
|
10
|
+
|
|
11
|
+
improper_labels += ['essay-scoring','english-grading','HelpSteer','oasst2']
|
|
12
|
+
|
|
13
|
+
def render_options(options):
|
|
14
|
+
options = [f'"{x}"' for x in options]
|
|
15
|
+
return f"{', '.join(options[:-1])} or {options[-1]}"
|
|
16
|
+
|
|
17
|
+
def render_classification(text,options,answer):
|
|
18
|
+
example = 'text_A→text_B' if text.startswith('text_A:') else 'the following'
|
|
19
|
+
inputs = f'With no explanation, label {example} with either {render_options(options)}.\n{text}'
|
|
20
|
+
targets = f"{answer}."
|
|
21
|
+
return dict_of(inputs,targets)
|
|
22
|
+
|
|
23
|
+
def render_token_classification(tokens,options,labels):
|
|
24
|
+
prefix = f'With no explanation, label each line with {render_options(options)} preceded by ":".\n'
|
|
25
|
+
inputs = prefix+"\n".join(tokens)
|
|
26
|
+
targets = "\n".join([':'.join(x) for x in zip(tokens,labels)])
|
|
27
|
+
return dict_of(inputs,targets)
|
|
28
|
+
|
|
29
|
+
def render_multiple_choice(prompt, options, labels):
|
|
30
|
+
inputs=(prompt+'\n' if prompt else '')
|
|
31
|
+
letters = string.ascii_uppercase[:len(options)]
|
|
32
|
+
inputs=f'With no explanation, chose the best option from {render_options(letters)}. {inputs}'
|
|
33
|
+
for letter, option in zip(letters, options):
|
|
34
|
+
inputs+=f'\n{letter}: {option}'
|
|
35
|
+
targets = f'{letters[labels]}.'
|
|
36
|
+
return dict_of(inputs, targets)
|
|
37
|
+
|
|
38
|
+
def negative_sample_options(y, labels,N=4):
|
|
39
|
+
if len(labels)<N:
|
|
40
|
+
return labels
|
|
41
|
+
else:
|
|
42
|
+
return [y]+random.sample([x for x in labels if x!=y], N-1)
|
|
43
|
+
|
|
44
|
+
def shuffle_choices(x):
|
|
45
|
+
choices = sorted([k for k in x if 'choice' in k])
|
|
46
|
+
choices_texts = [x[c] for c in choices]
|
|
47
|
+
correct_choice =choices_texts[x['labels']]
|
|
48
|
+
random.shuffle(choices_texts)
|
|
49
|
+
for c, ct in zip(choices, choices_texts):
|
|
50
|
+
x[c]=ct
|
|
51
|
+
x["labels"]=choices_texts.index(correct_choice)
|
|
52
|
+
return x
|
|
53
|
+
|
|
54
|
+
def recast_dataset_classification_to_mc(dataset,sep="[SEP]",N=4):
|
|
55
|
+
|
|
56
|
+
def recast_split(d,N=N):
|
|
57
|
+
labels = d.features['labels']
|
|
58
|
+
df=d.to_pandas()
|
|
59
|
+
df['inputs'] = df.sentence1
|
|
60
|
+
if "sentence2" in df:
|
|
61
|
+
df['inputs'] +=sep + df.sentence2
|
|
62
|
+
|
|
63
|
+
N=min(N, len(labels.names))
|
|
64
|
+
df['choices']=df.apply(lambda x:negative_sample_options(labels.int2str(x['labels']), labels.names,N),axis=1)
|
|
65
|
+
df['labels']=df.apply(lambda x:x['choices'].index(labels.int2str(x['labels'])),axis=1)
|
|
66
|
+
|
|
67
|
+
for i in range(N):
|
|
68
|
+
df[f'choice{i}']= "This example is " + df.choices.map(lambda x:x[i])
|
|
69
|
+
|
|
70
|
+
choices = [f'choice{i}' for i in range(N)]
|
|
71
|
+
return Dataset.from_pandas(df[['inputs',*choices,'labels']],preserve_index=False)
|
|
72
|
+
|
|
73
|
+
return DatasetDict({k: recast_split(v) for k,v in dataset.items()})
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def recast_instruct(dataset):
|
|
77
|
+
features = dataset['train'].features
|
|
78
|
+
labels = features['labels']
|
|
79
|
+
|
|
80
|
+
if "sentence1" in features:
|
|
81
|
+
task_type='Classification'
|
|
82
|
+
if "choice0" in features:
|
|
83
|
+
task_type = "MultipleChoice"
|
|
84
|
+
if "tokens" in features:
|
|
85
|
+
task_type = "TokenClassification"
|
|
86
|
+
|
|
87
|
+
def recast_MultipleChoice(x):
|
|
88
|
+
x=shuffle_choices(x)
|
|
89
|
+
choices = sorted([k for k in x if 'choice' in k])
|
|
90
|
+
if all([x[c] in x['inputs'] for c in choices]):
|
|
91
|
+
return {"inputs":x['inputs'], 'targets': x[f"choice{x['labels']}"].strip()+"."}
|
|
92
|
+
else:
|
|
93
|
+
return render_multiple_choice(x['inputs'],[x[c] for c in choices],x['labels'])
|
|
94
|
+
|
|
95
|
+
def recast_TokenClassification(x):
|
|
96
|
+
distractors = list(labels.feature.names)
|
|
97
|
+
x_labels = [labels.feature.int2str(y) for y in x['labels']]
|
|
98
|
+
labels_set= list({labels.feature.int2str(y) for y in x['labels']})
|
|
99
|
+
options=list(dict.fromkeys(labels_set+distractors))[:max(len(labels_set),10)]
|
|
100
|
+
return render_token_classification(x['tokens'],options,x_labels)
|
|
101
|
+
|
|
102
|
+
def recast_Classification(x):
|
|
103
|
+
if 'sentence2' in x:
|
|
104
|
+
text=f"text_A: {x['sentence1']}\ntext_B: {x['sentence2']}"
|
|
105
|
+
else:
|
|
106
|
+
text=x['sentence1']
|
|
107
|
+
|
|
108
|
+
answer=labels.int2str(x['labels']).strip()
|
|
109
|
+
options= negative_sample_options(answer, labels._int2str)
|
|
110
|
+
return render_classification(text, options, answer)
|
|
111
|
+
|
|
112
|
+
dataset = dataset.map(eval(f"recast_{task_type}"))
|
|
113
|
+
dataset = dataset.remove_columns([k for k in features if k not in ['inputs','targets']])
|
|
114
|
+
return dataset
|
|
115
|
+
|