| import pandas as pd
|
| import numpy as np
|
| from tqdm import tqdm
|
| import os
|
| import random
|
| import torch
|
| from torch.utils.data import Dataset, DataLoader
|
| from datasets import Dataset as Dataset2
|
| import datasets
|
| from sklearn.model_selection import (
|
| train_test_split,
|
| GroupShuffleSplit,
|
| KFold,
|
| GroupKFold,
|
| StratifiedKFold,
|
| )
|
| from typing import Optional, List, Tuple, Union, Any, Dict
|
| import sys
|
|
|
| sys.path.append("./")
|
| sys.path.append("../")
|
| sys.path.append("../../")
|
|
|
| from ScanDL2.CONSTANTS import PATH_TO_IA, PATH_TO_FIX, SUB_METADATA_PATH, path_to_zuco
|
|
|
|
|
| def load_celer():
|
| path_to_fix = PATH_TO_FIX
|
| path_to_ia = PATH_TO_IA
|
| eyemovement_df = pd.read_csv(path_to_fix, delimiter="\t", low_memory=False)
|
| eyemovement_df["CURRENT_FIX_INTEREST_AREA_LABEL"] = (
|
| eyemovement_df.CURRENT_FIX_INTEREST_AREA_LABEL.replace("\t(.*)", "", regex=True)
|
| )
|
| word_info_df = pd.read_csv(path_to_ia, delimiter="\t")
|
| word_info_df["IA_LABEL"] = word_info_df.IA_LABEL.replace("\t(.*)", "", regex=True)
|
| return word_info_df, eyemovement_df
|
|
|
|
|
| def load_celer_speakers(only_native_speakers: bool = True):
|
| sub_metadata_path = SUB_METADATA_PATH
|
| sub_info = pd.read_csv(sub_metadata_path, delimiter="\t")
|
| if only_native_speakers:
|
| readers_list = sub_info[sub_info.L1 == "English"].List.values
|
| else:
|
| readers_list = sub_info.List.values
|
| return readers_list.tolist()
|
|
|
|
|
| def compute_word_length(arr):
|
|
|
| arr = arr.astype("float64")
|
| arr[arr == 0] = 1 / (0 + 0.5)
|
| arr[arr != 0] = 1 / (arr[arr != 0])
|
| return arr
|
|
|
|
|
| def compute_word_frequency(arr):
|
| arr[arr == np.inf] = np.nan
|
| arr[arr != np.inf] = np.log10(arr[arr != np.inf])
|
| return arr
|
|
|
|
|
| def _collate_instance_helper(
|
| instance,
|
| pad_token_id,
|
| padding_steps,
|
| ):
|
| padding_list = [pad_token_id] * padding_steps
|
| result = instance + padding_list
|
| return result
|
|
|
|
|
| def _collate_batch_helper(
|
| examples,
|
| pad_token_id,
|
| max_length,
|
| return_mask=False,
|
| ):
|
| result = torch.full([len(examples), max_length], pad_token_id, dtype=torch.int64).tolist()
|
| mask_ = torch.full([len(examples), max_length], pad_token_id, dtype=torch.int64).tolist()
|
| for i, example in enumerate(examples):
|
| curr_len = min(len(example), max_length)
|
| result[i][:curr_len] = example[:curr_len]
|
| mask_[i][:curr_len] = [1] * curr_len
|
| if return_mask:
|
| return result, mask_
|
| return result
|
|
|
|
|
| def _dummy_pad_words(
|
| examples,
|
| pad_token_id,
|
| max_length,
|
| ):
|
| padded_examples = list()
|
| for instance in examples:
|
| padded_examples.append(instance + (max_length - len(instance)) * [pad_token_id])
|
| return padded_examples
|
|
|
|
|
| def infinite_loader(data_loader):
|
| while True:
|
| yield from data_loader
|
|
|
|
|
| def celer_zuco_dataset_and_loader(
|
| data,
|
| data_args,
|
| split: str,
|
| deterministic=False,
|
| loop=True,
|
| ):
|
|
|
| dataset = CelerZucoDataset(
|
| dataset=data,
|
| data_args=data_args,
|
| split=split,
|
| )
|
| data_loader = DataLoader(
|
| dataset,
|
| batch_size=data_args.batch_size,
|
| shuffle=not deterministic,
|
| num_workers=0,
|
| )
|
| if loop:
|
| return infinite_loader(data_loader)
|
| else:
|
| return iter(data_loader)
|
|
|
|
|
| def combined_split(data, reader_IDs, sn_IDs, test_size):
|
| """Splits the data so that the test data contains both unseen readers and unseen sentences."""
|
| random.seed(77)
|
| unique_reader_IDs = set(reader_IDs)
|
| unique_sn_IDs = set(sn_IDs)
|
|
|
|
|
| unique_reader_IDs_test = random.sample(
|
| unique_reader_IDs, int(test_size * len(unique_reader_IDs))
|
| )
|
| unique_sn_IDs_test = random.sample(unique_sn_IDs, int(test_size * len(unique_sn_IDs)))
|
|
|
| train_data, test_data = [], []
|
| train_reader_IDs, test_reader_IDs = [], []
|
| train_sn_IDs, test_sn_IDs = [], []
|
|
|
| for i in range(len(data)):
|
| if reader_IDs[i] in unique_reader_IDs_test and sn_IDs[i] in unique_sn_IDs_test:
|
| test_data.append(data[i])
|
| test_reader_IDs.append(reader_IDs[i])
|
| test_sn_IDs.append(sn_IDs[i])
|
| elif reader_IDs[i] not in unique_reader_IDs_test and sn_IDs[i] not in unique_sn_IDs_test:
|
| train_data.append(data[i])
|
| train_reader_IDs.append(reader_IDs[i])
|
| train_sn_IDs.append(sn_IDs[i])
|
| else:
|
| continue
|
|
|
| return train_data, test_data, train_reader_IDs, test_reader_IDs, train_sn_IDs, test_sn_IDs
|
|
|
|
|
| def load_zuco(task: str = None):
|
| dir = path_to_zuco
|
| if task.startswith("zuco1"):
|
| dir = dir + "zuco/"
|
| elif task == "zuco21":
|
| dir = dir + "zuco2/"
|
| dir = os.path.join(dir, f"task{task[-1]}", "Matlab_files")
|
| word_info_path = dir + "/Word_Infor.csv"
|
| word_info_df = pd.read_csv(word_info_path, sep="\t")
|
| scanpath_path = dir + "/scanpath.csv"
|
| eyemovement_df = pd.read_csv(scanpath_path, sep="\t")
|
| return word_info_df, eyemovement_df
|
|
|
|
|
| def get_kfold_indices_scanpath(
|
| splitting_IDs_dict: Dict[str, Union[int, str]],
|
| n_splits: int = 5,
|
| ):
|
| """Function to implement the 'random'/'scanpath' split, in which the test set contains both sentences and
|
| readers that were seen during training. Unfortunately, it is not possible to control for the ratios of both
|
| readers and sentences (as they are co-dependent), so I will make sure that the data is shuffled and at least
|
| the readers are stratified."""
|
|
|
| reader_IDs = splitting_IDs_dict["reader"]
|
| sn_IDs = splitting_IDs_dict["sentence"]
|
|
|
| tuple_ids = [
|
| (idx, reader_ID, sn_ID) for idx, (reader_ID, sn_ID) in enumerate(zip(reader_IDs, sn_IDs))
|
| ]
|
|
|
|
|
| unique_sns_ids = [idx for (idx, reader_ID, sn_ID) in tuple_ids if not sn_ID.startswith("en")]
|
|
|
| universal_sn_ids = [idx for (idx, reader_ID, sn_ID) in tuple_ids if sn_ID.startswith("en")]
|
|
|
|
|
| unique_reader_ids = [
|
| reader_ID for (idx, reader_ID, sn_ID) in tuple_ids if not sn_ID.startswith("en")
|
| ]
|
| universal_reader_ids = [
|
| reader_ID for (idx, reader_ID, sn_ID) in tuple_ids if sn_ID.startswith("en")
|
| ]
|
|
|
|
|
| kfold_unique = StratifiedKFold(n_splits=n_splits, shuffle=True, random_state=77)
|
| kfold_universal = StratifiedKFold(n_splits=n_splits, shuffle=True, random_state=77)
|
| train_idx_unique, test_idx_unique = list(), list()
|
| train_idx_universal, test_idx_universal = list(), list()
|
| kfold_unique.get_n_splits(unique_sns_ids, groups=unique_reader_ids)
|
| kfold_universal.get_n_splits(universal_sn_ids, groups=universal_reader_ids)
|
| for train_idx, test_idx in kfold_unique.split(
|
| X=unique_sns_ids, y=unique_reader_ids, groups=unique_reader_ids
|
| ):
|
| train_idx_unique.append(train_idx)
|
| test_idx_unique.append(test_idx)
|
| for train_idx, test_idx in kfold_universal.split(
|
| X=universal_sn_ids, y=universal_reader_ids, groups=universal_reader_ids
|
| ):
|
| train_idx_universal.append(train_idx)
|
| test_idx_universal.append(test_idx)
|
|
|
|
|
| all_train_idx, all_test_idx = list(), list()
|
|
|
| for train_idx_univ, train_idx_uniq in zip(train_idx_universal, train_idx_unique):
|
| train_idx = np.concatenate([train_idx_univ, train_idx_uniq])
|
| all_train_idx.append(train_idx)
|
| for test_idx_univ, test_idx_uniq in zip(test_idx_universal, test_idx_unique):
|
| test_idx = np.concatenate([test_idx_univ, test_idx_uniq])
|
| all_test_idx.append(test_idx)
|
|
|
| all_idx = [(train_idx, test_idx) for train_idx, test_idx in zip(all_train_idx, all_test_idx)]
|
| return all_idx
|
|
|
|
|
| def get_kfold(
|
| data: List[Tuple[Any]],
|
| splitting_IDs_dict: Dict[str, Union[int, str]],
|
| splitting_criterion: str = "scanpath",
|
| n_splits: int = 5,
|
| ):
|
| if splitting_criterion == "scanpath":
|
|
|
|
|
|
|
| return get_kfold_indices_scanpath(
|
| splitting_IDs_dict=splitting_IDs_dict,
|
| n_splits=n_splits,
|
| )
|
| elif splitting_criterion in ["reader", "sentence"]:
|
| splitting_group = splitting_IDs_dict[splitting_criterion]
|
| kfold = GroupKFold(n_splits=n_splits)
|
| kfold.get_n_splits(data, groups=splitting_group)
|
| return kfold.split(data, groups=splitting_group)
|
| else:
|
| raise NotImplementedError
|
|
|
|
|
| def get_kfold_indices_combined(
|
| data: List[Tuple[Any]],
|
| splitting_IDs_dict: Dict[str, Union[int, str]],
|
| n_splits: int = 5,
|
| ):
|
| kfold_reader = GroupKFold(n_splits=n_splits)
|
| kfold_sentence = GroupKFold(n_splits=n_splits)
|
| kfold_reader.get_n_splits(data, groups=splitting_IDs_dict["reader"])
|
| kfold_sentence.get_n_splits(data, groups=splitting_IDs_dict["sentence"])
|
| reader_indices, sentence_indices = list(), list()
|
| for train_idx, test_idx in kfold_reader.split(data, groups=splitting_IDs_dict["reader"]):
|
| reader_indices.append((train_idx, test_idx))
|
| for train_idx, test_idx in kfold_sentence.split(data, groups=splitting_IDs_dict["sentence"]):
|
| sentence_indices.append((train_idx, test_idx))
|
| return reader_indices, sentence_indices
|
|
|
|
|
| def flatten_data(data: Dict[str, List[Any]]):
|
| flattened_data = list()
|
| for i in range(len(data["sn_sp_repr"])):
|
| flattened_data.append(
|
| (
|
| data["mask"][i],
|
| data["sn_sp_repr"][i],
|
| data["sn_input_ids"][i],
|
| data["indices_pos_enc"][i],
|
| data["sn_sp_fix_dur"][i],
|
| data["sn_repr_len"][i],
|
| data["words_for_mapping"][i],
|
| data["mask_sn_padding"][i],
|
| data["mask_transformer_att"][i],
|
| data["sn_ids"][i],
|
| data["reader_ids"][i],
|
| )
|
| )
|
| return flattened_data
|
|
|
|
|
| def unflatten_data(flattened_data: List[Tuple[Any]], split: str):
|
| dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in flattened_data],
|
| "sn_sp_repr": [instance[1] for instance in flattened_data],
|
| "sn_input_ids": [instance[2] for instance in flattened_data],
|
| "indices_pos_enc": [instance[3] for instance in flattened_data],
|
| "sn_sp_fix_dur": [instance[4] for instance in flattened_data],
|
| "sn_repr_len": [instance[5] for instance in flattened_data],
|
| "words_for_mapping": [instance[6] for instance in flattened_data],
|
| "mask_sn_padding": [instance[7] for instance in flattened_data],
|
| "mask_transformer_att": [instance[8] for instance in flattened_data],
|
| "sn_ids": [instance[9] for instance in flattened_data],
|
| "reader_ids": [instance[10] for instance in flattened_data],
|
| }
|
| )
|
| data_dict = datasets.DatasetDict()
|
| data_dict[split] = dataset
|
| return data_dict
|
|
|
|
|
| def process_celer(
|
| sn_list,
|
| reader_list,
|
| word_info_df,
|
| eyemovement_df,
|
| tokenizer,
|
| args,
|
| split: Optional[str] = "train",
|
| subset_size: Optional[int] = None,
|
| split_sizes: Optional[Dict[str, float]] = None,
|
| splitting_criterion: Optional[str] = "scanpath",
|
| inference: Optional[str] = None,
|
| ):
|
| """
|
| Process the Celer corpus so that it can be used as input to the Diffusion model, where the original sentence (sn)
|
| is the condition and the scan path (sp) is the target that will be noised.
|
| :param sn_list: list of unique sentence IDs in celer
|
| :param reader_list: list of reader IDs in celer
|
| :param word_info_df: pd Dataframe with sentence info
|
| :param eyemovement_df: pd Dataframe with fixation info
|
| :param tokenizer: BertTokenizer
|
| :param args:
|
| :param split: 'train', 'train-test', 'train-test-val', 'train-val'
|
| :param subset_size: for test runs: to not load whole dataset but specified no. of instances
|
| :param split_sizes: proportion of data going into train, test and val
|
| :param splitting_criterion: how the data should be split for testing and validation.
|
| 'reader' = New Reader setting
|
| 'sentence' = New Sentence setting
|
| 'combined' = New Reader/New Sentence setting
|
| 'scanpath' = data is split at random
|
| :param inference: if inference is cross-validation, the data is returned before splitting into train test val
|
| """
|
| SP_ordinal_pos = []
|
| SP_landing_pos = []
|
| SP_fix_dur = []
|
|
|
| data = {
|
| "mask": list(),
|
| "sn_sp_repr": list(),
|
| "sn_input_ids": list(),
|
| "indices_pos_enc": list(),
|
| "sn_repr_len": list(),
|
| "words_for_mapping": list(),
|
| "mask_sn_padding": list(),
|
| "mask_transformer_att": list(),
|
| "sn_ids": list(),
|
| "reader_ids": list(),
|
| }
|
|
|
| max_len = 0
|
|
|
| reader_IDs, sn_IDs = list(), list()
|
|
|
| for sn_id_idx, sn_id in tqdm(enumerate(sn_list), total=len(sn_list)):
|
|
|
| if subset_size is not None:
|
| if sn_id_idx == subset_size + 1:
|
| break
|
|
|
|
|
| sn_df = eyemovement_df[eyemovement_df.sentenceid == sn_id]
|
|
|
|
|
| sn = word_info_df[word_info_df.sentenceid == sn_id]
|
|
|
| sn = sn[
|
| sn["list"] == sn.list.values.tolist()[0]
|
| ]
|
|
|
| sn_str = sn.sentence.iloc[-1]
|
| if (
|
| sn_id == "1987/w7_019/w7_019.295-3"
|
| or sn_id == "1987/w7_036/w7_036.147-43"
|
| or sn_id == "1987/w7_091/w7_091.360-6"
|
| ):
|
|
|
| sn_str = sn_str[:-3] + sn_str[-1:]
|
| if sn_id == "1987/w7_085/w7_085.200-18":
|
| sn_str = sn_str[:43] + sn_str[44:]
|
|
|
|
|
| if isinstance(sn_str, float):
|
| continue
|
|
|
| sn_len = len(sn_str.split())
|
|
|
|
|
| sn_str = "[CLS] " + sn_str + " [SEP]"
|
|
|
| tokenizer.padding_side = "right"
|
|
|
| for sub_id_idx, sub_id in enumerate(reader_list):
|
|
|
| if sub_id_idx == 5:
|
| continue
|
|
|
| sub_df = sn_df[sn_df.list == sub_id]
|
|
|
| sub_df = sub_df.loc[
|
| sub_df.CURRENT_FIX_INTEREST_AREA_LABEL != "."
|
| ]
|
| if len(sub_df) == 0:
|
|
|
| continue
|
|
|
|
|
| sp_word_pos, sp_fix_loc, sp_fix_dur = (
|
| sub_df.CURRENT_FIX_INTEREST_AREA_ID.values,
|
| sub_df.CURRENT_FIX_NEAREST_INTEREST_AREA_DISTANCE.values,
|
| sub_df.CURRENT_FIX_DURATION.values,
|
| )
|
|
|
|
|
|
|
| outlier_indx = np.where(sp_fix_dur < 50)[
|
| 0
|
| ]
|
|
|
| if outlier_indx.size > 0:
|
| for out_idx in range(len(outlier_indx)):
|
| outlier_i = outlier_indx[out_idx]
|
| merge_flag = False
|
|
|
|
|
| if outlier_i == len(sp_fix_dur) - 1 or outlier_i == 0:
|
| merge_flag = True
|
|
|
| else:
|
| if outlier_i - 1 >= 0 and not merge_flag:
|
|
|
| if (
|
| sub_df.iloc[outlier_i].CURRENT_FIX_INTEREST_AREA_LABEL
|
| == sub_df.iloc[outlier_i - 1].CURRENT_FIX_INTEREST_AREA_LABEL
|
| ):
|
| sp_fix_dur[outlier_i - 1] = (
|
| sp_fix_dur[outlier_i - 1] + sp_fix_dur[outlier_i]
|
| )
|
| merge_flag = True
|
|
|
| if outlier_i + 1 < len(sp_fix_dur) and not merge_flag:
|
|
|
| if (
|
| sub_df.iloc[outlier_i].CURRENT_FIX_INTEREST_AREA_LABEL
|
| == sub_df.iloc[outlier_i + 1].CURRENT_FIX_INTEREST_AREA_LABEL
|
| ):
|
| sp_fix_dur[outlier_i + 1] = (
|
| sp_fix_dur[outlier_i + 1] + sp_fix_dur[outlier_i]
|
| )
|
| merge_flag = True
|
|
|
|
|
| sp_word_pos = np.delete(sp_word_pos, outlier_i)
|
| sp_fix_loc = np.delete(sp_fix_loc, outlier_i)
|
| sp_fix_dur = np.delete(sp_fix_dur, outlier_i)
|
| sub_df.drop(sub_df.index[outlier_i], axis=0, inplace=True)
|
| outlier_indx = outlier_indx - 1
|
|
|
|
|
|
|
| if len(sp_word_pos) > 50:
|
| continue
|
|
|
| if len(sp_word_pos) <= 1 and sn_len > 10:
|
| continue
|
|
|
| sp_ordinal_pos = sp_word_pos.astype(
|
| int
|
| )
|
| SP_ordinal_pos.append(sp_ordinal_pos)
|
| SP_fix_dur.append(sp_fix_dur)
|
|
|
|
|
| sp_fix_loc = np.where(sp_fix_loc == ".", np.nan, sp_fix_loc)
|
|
|
| sp_fix_loc = [float(i) for i in sp_fix_loc]
|
|
|
| if (
|
| np.nanmax(sp_fix_loc) > 35
|
| ):
|
| missing_idx = np.where(np.array(sp_fix_loc) > 5)[
|
| 0
|
| ]
|
| for miss in missing_idx:
|
| if sub_df.iloc[miss].CURRENT_FIX_INTEREST_AREA_LEFT in [
|
| "NONE",
|
| "BEFORE",
|
| "AFTER",
|
| "BOTH",
|
| ]:
|
| sp_fix_loc[miss] = np.nan
|
| else:
|
| print(
|
| "Landing position calculation error. Unknown cause, needs to be checked"
|
| )
|
| SP_landing_pos.append(sp_fix_loc)
|
|
|
| encoded_sn = tokenizer.encode_plus(
|
| sn_str.split(),
|
| add_special_tokens=False,
|
| padding=False,
|
| return_attention_mask=False,
|
| is_split_into_words=True,
|
| truncation=False,
|
| )
|
|
|
| sn_word_ids = encoded_sn.word_ids()
|
| sp_word_ids = [0] + sp_ordinal_pos.tolist() + [max(encoded_sn.word_ids())]
|
|
|
| sn_input_ids = encoded_sn["input_ids"]
|
| assert len(sn_word_ids) == len(sn_input_ids)
|
|
|
| max_len = max(max_len, len(sn_word_ids) + len(sp_word_ids))
|
|
|
|
|
| sep_token_sn_word_ids = sn_word_ids[-1]
|
| sep_token_sp_word_ids = sp_word_ids[-1]
|
| sep_token_sn_input_ids = sn_input_ids[-1]
|
|
|
| sn_word_ids = sn_word_ids[:-1]
|
| sp_word_ids = sp_word_ids[:-1]
|
| sn_input_ids = sn_input_ids[:-1]
|
|
|
| while len(sn_word_ids) + len(sp_word_ids) > args.seq_len - 3:
|
| if len(sn_word_ids) > len(sp_word_ids):
|
| sn_word_ids.pop()
|
| sn_input_ids.pop()
|
| elif len(sp_word_ids) > len(sn_word_ids):
|
| sp_word_ids.pop()
|
| else:
|
| sn_word_ids.pop()
|
| sn_input_ids.pop()
|
| sp_word_ids.pop()
|
|
|
|
|
| sn_word_ids.append(sep_token_sn_word_ids)
|
| sp_word_ids.append(sep_token_sp_word_ids)
|
| sn_input_ids.append(sep_token_sn_input_ids)
|
|
|
| sn_sp_repr = sn_word_ids + sp_word_ids
|
|
|
| mask = [0] * len(sn_word_ids)
|
| mask_sn_padding = (
|
| [0] * len(sn_word_ids)
|
| + [1] * len(sp_word_ids)
|
| + [0] * (args.seq_len - len(sn_word_ids) - len(sp_word_ids))
|
| )
|
| mask_transformer_att = (
|
| [1] * len(sn_word_ids)
|
| + [1] * len(sp_word_ids)
|
| + [0] * (args.seq_len - len(sn_word_ids) - len(sp_word_ids))
|
| )
|
|
|
| indices_pos_enc = list(range(0, len(sn_word_ids))) + list(
|
| range(0, args.seq_len - len(sn_word_ids))
|
| )
|
|
|
| sn_repr_len = len(sn_word_ids)
|
| words_for_mapping = sn_str.split() + (args.seq_len - len(sn_str.split())) * ["[PAD]"]
|
|
|
| data["mask"].append(mask)
|
| data["sn_sp_repr"].append(sn_sp_repr)
|
| data["sn_input_ids"].append(sn_input_ids)
|
| data["indices_pos_enc"].append(indices_pos_enc)
|
| data["sn_repr_len"].append(sn_repr_len)
|
| data["words_for_mapping"].append(" ".join(words_for_mapping))
|
| data["mask_sn_padding"].append(mask_sn_padding)
|
| data["mask_transformer_att"].append(mask_transformer_att)
|
| data["sn_ids"].append(sn_id)
|
| data["reader_ids"].append(sub_id)
|
|
|
| reader_IDs.append(sub_id)
|
| sn_IDs.append(sn_id)
|
|
|
|
|
| data["mask"] = _collate_batch_helper(
|
| examples=data["mask"],
|
| pad_token_id=1,
|
| max_length=args.seq_len,
|
| )
|
| data["sn_sp_repr"] = _collate_batch_helper(
|
| examples=data["sn_sp_repr"],
|
| pad_token_id=args.seq_len - 1,
|
| max_length=args.seq_len,
|
| )
|
| data["sn_input_ids"] = _collate_batch_helper(
|
| examples=data["sn_input_ids"],
|
| pad_token_id=tokenizer.pad_token_id,
|
| max_length=args.seq_len,
|
| )
|
|
|
| splitting_IDs_dict = {
|
| "reader": reader_IDs,
|
| "sentence": sn_IDs,
|
| }
|
|
|
| if inference == "cv":
|
| return data, splitting_IDs_dict
|
|
|
| if split == "train":
|
|
|
| dataset = Dataset2.from_dict(data)
|
| train_dataset = datasets.DatasetDict()
|
| train_dataset["train"] = dataset
|
| return train_dataset, splitting_IDs_dict
|
|
|
| else:
|
|
|
|
|
| flattened_data = list()
|
| for i in range(len(data["sn_sp_repr"])):
|
| flattened_data.append(
|
| (
|
| data["mask"][i],
|
| data["sn_sp_repr"][i],
|
| data["sn_input_ids"][i],
|
| data["indices_pos_enc"][i],
|
| data["sn_repr_len"][i],
|
| data["words_for_mapping"][i],
|
| data["mask_sn_padding"][i],
|
| data["mask_transformer_att"][i],
|
| data["sn_ids"][i],
|
| data["reader_ids"][i],
|
| )
|
| )
|
|
|
| if split == "train-test":
|
|
|
| if split_sizes:
|
| test_size = split_sizes["test_size"]
|
| else:
|
| test_size = 0.25
|
|
|
| if splitting_criterion != "scanpath":
|
|
|
| if splitting_criterion == "combined":
|
|
|
| (
|
| train_data,
|
| test_data,
|
| train_reader_IDs,
|
| test_reader_IDs,
|
| train_sn_IDs,
|
| test_sn_IDs,
|
| ) = combined_split(
|
| data=flattened_data,
|
| reader_IDs=splitting_IDs_dict["reader"],
|
| sn_IDs=splitting_IDs_dict["sentence"],
|
| test_size=test_size,
|
| )
|
|
|
| else:
|
|
|
| splitting_IDs = splitting_IDs_dict[splitting_criterion]
|
| gss = GroupShuffleSplit(n_splits=1, test_size=test_size, random_state=77)
|
| for train_index, test_index in gss.split(flattened_data, groups=splitting_IDs):
|
| train_data = np.array(flattened_data)[train_index].tolist()
|
| test_data = np.array(flattened_data)[test_index].tolist()
|
|
|
| else:
|
| train_data, test_data = train_test_split(
|
| flattened_data, test_size=test_size, shuffle=True, random_state=77
|
| )
|
|
|
|
|
| train_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in train_data],
|
| "sn_sp_repr": [instance[1] for instance in train_data],
|
| "sn_input_ids": [instance[2] for instance in train_data],
|
| "indices_pos_enc": [instance[3] for instance in train_data],
|
| "sn_repr_len": [instance[4] for instance in train_data],
|
| "words_for_mapping": [instance[5] for instance in train_data],
|
| "mask_sn_padding": [instance[6] for instance in train_data],
|
| "mask_transformer_att": [instance[7] for instance in train_data],
|
| "sn_ids": [instance[8] for instance in train_data],
|
| "reader_ids": [instance[9] for instance in train_data],
|
| }
|
| )
|
| test_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in test_data],
|
| "sn_sp_repr": [instance[1] for instance in test_data],
|
| "sn_input_ids": [instance[2] for instance in test_data],
|
| "indices_pos_enc": [instance[3] for instance in test_data],
|
| "sn_repr_len": [instance[4] for instance in test_data],
|
| "words_for_mapping": [instance[5] for instance in test_data],
|
| "mask_sn_padding": [instance[6] for instance in test_data],
|
| "mask_transformer_att": [instance[7] for instance in test_data],
|
| "sn_ids": [instance[8] for instance in test_data],
|
| "reader_ids": [instance[9] for instance in test_data],
|
| }
|
| )
|
| train_data_dict = datasets.DatasetDict()
|
| test_data_dict = datasets.DatasetDict()
|
| train_data_dict["train"] = train_dataset
|
| test_data_dict["test"] = test_dataset
|
| return train_data_dict, test_data_dict
|
|
|
| elif split == "train-val":
|
|
|
| if split_sizes:
|
| val_size = split_sizes["val_size"]
|
| else:
|
| val_size = 0.1
|
|
|
| if splitting_criterion != "scanpath":
|
|
|
| if splitting_criterion == "combined":
|
| (
|
| train_data,
|
| val_data,
|
| train_reader_IDs,
|
| val_reader_IDs,
|
| train_sn_IDs,
|
| val_sn_IDs,
|
| ) = combined_split(
|
| data=flattened_data,
|
| reader_IDs=splitting_IDs_dict["reader"],
|
| sn_IDs=splitting_IDs_dict["sentence"],
|
| test_size=val_size,
|
| )
|
| else:
|
| splitting_IDs = splitting_IDs_dict[splitting_criterion]
|
| gss = GroupShuffleSplit(n_splits=1, test_size=val_size, random_state=77)
|
| for train_index, val_index in gss.split(flattened_data, groups=splitting_IDs):
|
| train_data = np.array(flattened_data)[train_index].tolist()
|
| val_data = np.array(flattened_data)[val_index].tolist()
|
|
|
| else:
|
| train_data, val_data = train_test_split(
|
| flattened_data, test_size=val_size, shuffle=True, random_state=77
|
| )
|
|
|
|
|
| train_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in train_data],
|
| "sn_sp_repr": [instance[1] for instance in train_data],
|
| "sn_input_ids": [instance[2] for instance in train_data],
|
| "indices_pos_enc": [instance[3] for instance in train_data],
|
| "sn_repr_len": [instance[4] for instance in train_data],
|
| "words_for_mapping": [instance[5] for instance in train_data],
|
| "mask_sn_padding": [instance[6] for instance in train_data],
|
| "mask_transformer_att": [instance[7] for instance in train_data],
|
| "sn_ids": [instance[8] for instance in train_data],
|
| "reader_ids": [instance[9] for instance in train_data],
|
| }
|
| )
|
|
|
| val_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in val_data],
|
| "sn_sp_repr": [instance[1] for instance in val_data],
|
| "sn_input_ids": [instance[2] for instance in val_data],
|
| "indices_pos_enc": [instance[3] for instance in val_data],
|
| "sn_repr_len": [instance[4] for instance in val_data],
|
| "words_for_mapping": [instance[5] for instance in val_data],
|
| "mask_sn_padding": [instance[6] for instance in val_data],
|
| "mask_transformer_att": [instance[7] for instance in val_data],
|
| "sn_ids": [instance[8] for instance in val_data],
|
| "reader_ids": [instance[9] for instance in val_data],
|
| }
|
| )
|
| train_data_dict = datasets.DatasetDict()
|
| val_data_dict = datasets.DatasetDict()
|
| train_data_dict["train"] = train_dataset
|
| val_data_dict["val"] = val_dataset
|
| return train_data_dict, val_data_dict
|
|
|
| elif split == "train-val-test":
|
|
|
| if split_sizes:
|
| val_size = split_sizes["val_size"]
|
| test_size = split_sizes["test_size"]
|
| else:
|
| val_size = 0.1
|
| test_size = 0.25
|
|
|
| if splitting_criterion != "scanpath":
|
|
|
| if splitting_criterion == "combined":
|
|
|
| (
|
| train_data,
|
| test_data,
|
| train_reader_IDs,
|
| test_reader_IDs,
|
| train_sn_IDs,
|
| test_sn_IDs,
|
| ) = combined_split(
|
| data=flattened_data,
|
| reader_IDs=splitting_IDs_dict["reader"],
|
| sn_IDs=splitting_IDs_dict["sentence"],
|
| test_size=test_size,
|
| )
|
|
|
| train_data, val_data = train_test_split(
|
| train_data, test_size=val_size, random_state=77, shuffle=True
|
| )
|
|
|
| else:
|
| splitting_IDs = splitting_IDs_dict[splitting_criterion]
|
|
|
|
|
| gss = GroupShuffleSplit(n_splits=1, test_size=test_size, random_state=77)
|
| for train_index, test_index in gss.split(flattened_data, groups=splitting_IDs):
|
| train_data = np.array(flattened_data)[train_index].tolist()
|
| test_data = np.array(flattened_data)[test_index].tolist()
|
| train_ids = np.array(splitting_IDs)[train_index].tolist()
|
|
|
|
|
| gss = GroupShuffleSplit(n_splits=1, test_size=val_size, random_state=77)
|
| for train_index, val_index in gss.split(train_data, groups=train_ids):
|
| val_data = np.array(train_data)[val_index].tolist()
|
| train_data = np.array(train_data)[train_index].tolist()
|
|
|
| else:
|
| train_data, test_data = train_test_split(
|
| flattened_data, test_size=test_size, shuffle=True, random_state=77
|
| )
|
| train_data, val_data = train_test_split(
|
| train_data, test_size=val_size, shuffle=True, random_state=77
|
| )
|
|
|
|
|
| train_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in train_data],
|
| "sn_sp_repr": [instance[1] for instance in train_data],
|
| "sn_input_ids": [instance[2] for instance in train_data],
|
| "indices_pos_enc": [instance[3] for instance in train_data],
|
| "sn_repr_len": [instance[4] for instance in train_data],
|
| "words_for_mapping": [instance[5] for instance in train_data],
|
| "mask_sn_padding": [instance[6] for instance in train_data],
|
| "mask_transformer_att": [instance[7] for instance in train_data],
|
| "sn_ids": [instance[8] for instance in train_data],
|
| "reader_ids": [instance[9] for instance in train_data],
|
| }
|
| )
|
| test_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in test_data],
|
| "sn_sp_repr": [instance[1] for instance in test_data],
|
| "sn_input_ids": [instance[2] for instance in test_data],
|
| "indices_pos_enc": [instance[3] for instance in test_data],
|
| "sn_repr_len": [instance[4] for instance in test_data],
|
| "words_for_mapping": [instance[5] for instance in test_data],
|
| "mask_sn_padding": [instance[6] for instance in test_data],
|
| "mask_transformer_att": [instance[7] for instance in test_data],
|
| "sn_ids": [instance[8] for instance in test_data],
|
| "reader_ids": [instance[9] for instance in test_data],
|
| }
|
| )
|
| val_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in val_data],
|
| "sn_sp_repr": [instance[1] for instance in val_data],
|
| "sn_input_ids": [instance[2] for instance in val_data],
|
| "indices_pos_enc": [instance[3] for instance in val_data],
|
| "sn_repr_len": [instance[4] for instance in val_data],
|
| "words_for_mapping": [instance[5] for instance in val_data],
|
| "mask_sn_padding": [instance[6] for instance in val_data],
|
| "mask_transformer_att": [instance[7] for instance in val_data],
|
| "sn_ids": [instance[8] for instance in val_data],
|
| "reader_ids": [instance[9] for instance in val_data],
|
| }
|
| )
|
| train_data_dict = datasets.DatasetDict()
|
| test_data_dict = datasets.DatasetDict()
|
| val_data_dict = datasets.DatasetDict()
|
| train_data_dict["train"] = train_dataset
|
| test_data_dict["test"] = test_dataset
|
| val_data_dict["val"] = val_dataset
|
| return train_data_dict, test_data_dict, val_data_dict
|
|
|
|
|
| class CelerZucoDataset(Dataset):
|
|
|
| def __init__(
|
| self,
|
| dataset,
|
| data_args,
|
| split,
|
| ):
|
| super().__init__()
|
| self.dataset = dataset
|
| self.length = len(self.dataset[split])
|
| self.data_args = data_args
|
| self.split = split
|
|
|
| def __len__(self):
|
| return self.length
|
|
|
| def __getitem__(self, idx):
|
| sample = {
|
| "mask": np.array(self.dataset[self.split][idx]["mask"]),
|
| "sn_sp_repr": np.array(self.dataset[self.split][idx]["sn_sp_repr"]),
|
| "sn_input_ids": np.array(self.dataset[self.split][idx]["sn_input_ids"]),
|
| "indices_pos_enc": np.array(self.dataset[self.split][idx]["indices_pos_enc"]),
|
| "sn_sp_fix_dur": np.array(self.dataset[self.split][idx]["sn_sp_fix_dur"]),
|
| "sn_repr_len": np.array(self.dataset[self.split][idx]["sn_repr_len"]),
|
| "words_for_mapping": self.dataset[self.split][idx]["words_for_mapping"],
|
| "mask_sn_padding": np.array(self.dataset[self.split][idx]["mask_sn_padding"]),
|
| "mask_transformer_att": np.array(self.dataset[self.split][idx]["mask_transformer_att"]),
|
| "sn_ids": self.dataset[self.split][idx]["sn_ids"],
|
| "reader_ids": self.dataset[self.split][idx]["reader_ids"],
|
| }
|
| return sample
|
|
|
|
|
| def process_zuco(
|
| sn_list,
|
| reader_list,
|
| word_info_df,
|
| eyemovement_df,
|
| tokenizer,
|
| args,
|
| split: Optional[str] = "train",
|
| subset_size: Optional[int] = None,
|
| split_sizes: Optional[Dict[str, float]] = None,
|
| splitting_criterion: Optional[str] = "scanpath",
|
| ):
|
| """
|
| Process the ZuCo corpus so that it can be used as input to the Diffusion model, where the original sentence (sn)
|
| is the condition and the scan path (sp) is the target that will be noised.
|
| :param sn_list: list of unique sentence IDs in zuco
|
| :param reader_list: list of reader IDs in zuco
|
| :param word_info_df: pd Dataframe with sentence info
|
| :param eyemovement_df: pd Dataframe with fixation info
|
| :param tokenizer: BertTokenizer
|
| :param args:
|
| :param split: 'train', 'train-test', 'train-test-val', 'train-val'
|
| :param subset_size: for test runs: to not load whole dataset but specified no. of instances
|
| :param split_sizes: proportion of data going into train, test and val
|
| :param splitting_criterion: how the data should be split for testing and validation.
|
| 'reader' = New Reader setting
|
| 'sentence' = New Sentence setting
|
| 'combined' = New Reader/New Sentence setting
|
| 'scanpath' = data is split at random
|
| """
|
| SP_ordinal_pos = []
|
| SP_landing_pos = []
|
| SP_fix_dur = []
|
|
|
| data = {
|
| "mask": list(),
|
| "sn_sp_repr": list(),
|
|
|
| "sn_input_ids": list(),
|
| "indices_pos_enc": list(),
|
| "sn_repr_len": list(),
|
| "words_for_mapping": list(),
|
| "mask_sn_padding": list(),
|
| "mask_transformer_att": list(),
|
| "sn_ids": list(),
|
| "reader_ids": list(),
|
| }
|
|
|
| max_len = 0
|
| all_lens = list()
|
|
|
| reader_IDs, sn_IDs = list(), list()
|
|
|
| for sn_id_idx, sn_id in tqdm(enumerate(sn_list), total=len(sn_list)):
|
|
|
| if subset_size is not None:
|
| if sn_id_idx == subset_size + 1:
|
| break
|
|
|
| sn_df = eyemovement_df[eyemovement_df.sn == sn_id]
|
| sn = word_info_df[word_info_df.SN == sn_id]
|
| sn_str = " ".join(sn.WORD.values)
|
| sn_len = len(sn_str.split())
|
|
|
| tokenizer.padding_side = "right"
|
| sn_str = "[CLS] " + sn_str + " [SEP]"
|
|
|
| for sub_id_idx, sub_id in enumerate(reader_list):
|
|
|
| sub_df = sn_df[sn_df.id == sub_id]
|
|
|
| sub_df = sub_df.loc[sub_df.CURRENT_FIX_INTEREST_AREA_LABEL != ""]
|
| if len(sub_df) == 0:
|
|
|
| continue
|
|
|
| sp_word_pos, sp_fix_loc, sp_fix_dur = (
|
| sub_df.wn.values,
|
| sub_df.fl.values,
|
| sub_df.dur.values,
|
| )
|
|
|
|
|
|
|
| outlier_indx = np.where(sp_fix_dur < 50)[0]
|
| if outlier_indx.size > 0:
|
| for out_idx in range(len(outlier_indx)):
|
| outlier_i = outlier_indx[out_idx]
|
| merge_flag = False
|
| if outlier_i - 1 >= 0 and not merge_flag:
|
|
|
| if (
|
| sub_df.iloc[outlier_i].CURRENT_FIX_INTEREST_AREA_LABEL
|
| == sub_df.iloc[outlier_i - 1].CURRENT_FIX_INTEREST_AREA_LABEL
|
| ):
|
| sp_fix_dur[outlier_i - 1] = (
|
| sp_fix_dur[outlier_i - 1] + sp_fix_dur[outlier_i]
|
| )
|
| merge_flag = True
|
|
|
| if outlier_i + 1 < len(sp_fix_dur) and not merge_flag:
|
|
|
| if (
|
| sub_df.iloc[outlier_i].CURRENT_FIX_INTEREST_AREA_LABEL
|
| == sub_df.iloc[outlier_i + 1].CURRENT_FIX_INTEREST_AREA_LABEL
|
| ):
|
| sp_fix_dur[outlier_i + 1] = (
|
| sp_fix_dur[outlier_i + 1] + sp_fix_dur[outlier_i]
|
| )
|
| merge_flag = True
|
|
|
| sp_word_pos = np.delete(sp_word_pos, outlier_i)
|
| sp_fix_loc = np.delete(sp_fix_loc, outlier_i)
|
| sp_fix_dur = np.delete(sp_fix_dur, outlier_i)
|
| sub_df.drop(sub_df.index[outlier_i], axis=0, inplace=True)
|
| outlier_indx = outlier_indx - 1
|
|
|
|
|
|
|
| if len(sp_word_pos) <= 1 and sn_len > 10:
|
| continue
|
|
|
| sp_ordinal_pos = sp_word_pos.astype(int)
|
| SP_ordinal_pos.append(sp_ordinal_pos)
|
| SP_fix_dur.append(sp_fix_dur)
|
|
|
|
|
|
|
|
|
|
|
| sp_fix_loc = [
|
| float(i) if isinstance(i, int) or isinstance(i, float) else np.nan
|
| for i in sp_fix_loc
|
| if isinstance(i, int) or isinstance(i, float)
|
| ]
|
| SP_landing_pos.append(sp_fix_loc)
|
|
|
|
|
| encoded_sn = tokenizer.encode_plus(
|
| sn_str.split(),
|
| add_special_tokens=False,
|
| padding=False,
|
| return_attention_mask=False,
|
| is_split_into_words=True,
|
| truncation=False,
|
| )
|
|
|
| sn_word_ids = encoded_sn.word_ids()
|
| sp_word_ids = [0] + sp_ordinal_pos.tolist() + [max(encoded_sn.word_ids())]
|
|
|
| sn_input_ids = encoded_sn["input_ids"]
|
| assert len(sn_word_ids) == len(sn_input_ids)
|
|
|
| max_len = max(max_len, len(sn_word_ids) + len(sp_word_ids))
|
| all_lens.append(len(sn_word_ids) + len(sp_word_ids))
|
|
|
|
|
| sep_token_sn_word_ids = sn_word_ids[-1]
|
| sep_token_sp_word_ids = sp_word_ids[-1]
|
| sep_token_sn_input_ids = sn_input_ids[-1]
|
|
|
| sn_word_ids = sn_word_ids[:-1]
|
| sp_word_ids = sp_word_ids[:-1]
|
| sn_input_ids = sn_input_ids[:-1]
|
|
|
| while len(sn_word_ids) + len(sp_word_ids) > args.seq_len - 3:
|
| if len(sn_word_ids) > len(sp_word_ids):
|
| sn_word_ids.pop()
|
| sn_input_ids.pop()
|
| elif len(sp_word_ids) > len(sn_word_ids):
|
| sp_word_ids.pop()
|
| else:
|
| sn_word_ids.pop()
|
| sn_input_ids.pop()
|
| sp_word_ids.pop()
|
|
|
|
|
| sn_word_ids.append(sep_token_sn_word_ids)
|
| sp_word_ids.append(sep_token_sp_word_ids)
|
| sn_input_ids.append(sep_token_sn_input_ids)
|
|
|
| sn_sp_repr = sn_word_ids + sp_word_ids
|
|
|
| mask = [0] * len(sn_word_ids)
|
| mask_sn_padding = (
|
| [0] * len(sn_word_ids)
|
| + [1] * len(sp_word_ids)
|
| + [0] * (args.seq_len - len(sn_word_ids) - len(sp_word_ids))
|
| )
|
| mask_transformer_att = (
|
| [1] * len(sn_word_ids)
|
| + [1] * len(sp_word_ids)
|
| + [0] * (args.seq_len - len(sn_word_ids) - len(sp_word_ids))
|
| )
|
|
|
| indices_pos_enc = list(range(0, len(sn_word_ids))) + list(
|
| range(0, args.seq_len - len(sn_word_ids))
|
| )
|
|
|
| sn_repr_len = len(sn_word_ids)
|
| words_for_mapping = sn_str.split() + (args.seq_len - len(sn_str.split())) * ["[PAD]"]
|
|
|
| data["mask"].append(mask)
|
| data["sn_sp_repr"].append(sn_sp_repr)
|
| data["sn_input_ids"].append(sn_input_ids)
|
| data["indices_pos_enc"].append(indices_pos_enc)
|
| data["sn_repr_len"].append(sn_repr_len)
|
| data["words_for_mapping"].append(" ".join(words_for_mapping))
|
| data["mask_sn_padding"].append(mask_sn_padding)
|
| data["mask_transformer_att"].append(mask_transformer_att)
|
| data["sn_ids"].append(sn_id)
|
| data["reader_ids"].append(sub_id)
|
|
|
| reader_IDs.append(sub_id)
|
| sn_IDs.append(sn_id)
|
|
|
|
|
| data["mask"] = _collate_batch_helper(
|
| examples=data["mask"],
|
| pad_token_id=1,
|
| max_length=args.seq_len,
|
| )
|
| data["sn_sp_repr"] = _collate_batch_helper(
|
| examples=data["sn_sp_repr"],
|
| pad_token_id=args.seq_len - 1,
|
| max_length=args.seq_len,
|
| )
|
| data["sn_input_ids"] = _collate_batch_helper(
|
| examples=data["sn_input_ids"],
|
| pad_token_id=tokenizer.pad_token_id,
|
| max_length=args.seq_len,
|
| )
|
|
|
| splitting_IDs_dict = {
|
| "reader": reader_IDs,
|
| "sentence": sn_IDs,
|
| }
|
|
|
| if split == "train":
|
|
|
| dataset = Dataset2.from_dict(data)
|
| train_dataset = datasets.DatasetDict()
|
| train_dataset["train"] = dataset
|
| return train_dataset
|
|
|
| else:
|
|
|
|
|
| flattened_data = list()
|
| for i in range(len(data["sn_sp_repr"])):
|
| flattened_data.append(
|
| (
|
| data["mask"][i],
|
| data["sn_sp_repr"][i],
|
| data["sn_input_ids"][i],
|
| data["indices_pos_enc"][i],
|
| data["sn_repr_len"][i],
|
| data["words_for_mapping"][i],
|
| data["mask_sn_padding"][i],
|
| data["mask_transformer_att"][i],
|
| data["sn_ids"][i],
|
| data["reader_ids"][i],
|
| )
|
| )
|
|
|
| if split == "train-test":
|
|
|
| if split_sizes:
|
| test_size = split_sizes["test_size"]
|
| else:
|
| test_size = 0.25
|
|
|
| if splitting_criterion != "scanpath":
|
|
|
| if splitting_criterion == "combined":
|
|
|
| (
|
| train_data,
|
| test_data,
|
| train_reader_IDs,
|
| test_reader_IDs,
|
| train_sn_IDs,
|
| test_sn_IDs,
|
| ) = combined_split(
|
| data=flattened_data,
|
| reader_IDs=splitting_IDs_dict["reader"],
|
| sn_IDs=splitting_IDs_dict["sentence"],
|
| test_size=test_size,
|
| )
|
|
|
| else:
|
|
|
| splitting_IDs = splitting_IDs_dict[splitting_criterion]
|
| gss = GroupShuffleSplit(n_splits=1, test_size=test_size, random_state=77)
|
| for train_index, test_index in gss.split(flattened_data, groups=splitting_IDs):
|
| train_data = np.array(flattened_data)[train_index].tolist()
|
| test_data = np.array(flattened_data)[test_index].tolist()
|
|
|
| else:
|
| train_data, test_data = train_test_split(
|
| flattened_data, test_size=test_size, shuffle=True, random_state=77
|
| )
|
|
|
|
|
| train_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in train_data],
|
| "sn_sp_repr": [instance[1] for instance in train_data],
|
| "sn_input_ids": [instance[2] for instance in train_data],
|
| "indices_pos_enc": [instance[3] for instance in train_data],
|
| "sn_repr_len": [instance[4] for instance in train_data],
|
| "words_for_mapping": [instance[5] for instance in train_data],
|
| "mask_sn_padding": [instance[6] for instance in train_data],
|
| "mask_transformer_att": [instance[7] for instance in train_data],
|
| "sn_ids": [instance[8] for instance in train_data],
|
| "reader_ids": [instance[9] for instance in train_data],
|
| }
|
| )
|
| test_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in test_data],
|
| "sn_sp_repr": [instance[1] for instance in test_data],
|
| "sn_input_ids": [instance[2] for instance in test_data],
|
| "indices_pos_enc": [instance[3] for instance in test_data],
|
| "sn_repr_len": [instance[4] for instance in test_data],
|
| "words_for_mapping": [instance[5] for instance in test_data],
|
| "mask_sn_padding": [instance[6] for instance in test_data],
|
| "mask_transformer_att": [instance[7] for instance in test_data],
|
| "sn_ids": [instance[8] for instance in test_data],
|
| "reader_ids": [instance[9] for instance in test_data],
|
| }
|
| )
|
| train_data_dict = datasets.DatasetDict()
|
| test_data_dict = datasets.DatasetDict()
|
| train_data_dict["train"] = train_dataset
|
| test_data_dict["test"] = test_dataset
|
| return train_data_dict, test_data_dict
|
|
|
| elif split == "train-val":
|
|
|
| if split_sizes:
|
| val_size = split_sizes["val_size"]
|
| else:
|
| val_size = 0.1
|
|
|
| if splitting_criterion != "scanpath":
|
|
|
| if splitting_criterion == "combined":
|
| (
|
| train_data,
|
| val_data,
|
| train_reader_IDs,
|
| val_reader_IDs,
|
| train_sn_IDs,
|
| val_sn_IDs,
|
| ) = combined_split(
|
| data=flattened_data,
|
| reader_IDs=splitting_IDs_dict["reader"],
|
| sn_IDs=splitting_IDs_dict["sentence"],
|
| test_size=val_size,
|
| )
|
| else:
|
| splitting_IDs = splitting_IDs_dict[splitting_criterion]
|
| gss = GroupShuffleSplit(n_splits=1, test_size=val_size, random_state=77)
|
| for train_index, val_index in gss.split(flattened_data, groups=splitting_IDs):
|
| train_data = np.array(flattened_data)[train_index].tolist()
|
| val_data = np.array(flattened_data)[val_index].tolist()
|
|
|
| else:
|
| train_data, val_data = train_test_split(
|
| flattened_data, test_size=val_size, shuffle=True, random_state=77
|
| )
|
|
|
|
|
| train_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in train_data],
|
| "sn_sp_repr": [instance[1] for instance in train_data],
|
| "sn_input_ids": [instance[2] for instance in train_data],
|
| "indices_pos_enc": [instance[3] for instance in train_data],
|
| "sn_repr_len": [instance[4] for instance in train_data],
|
| "words_for_mapping": [instance[5] for instance in train_data],
|
| "mask_sn_padding": [instance[6] for instance in train_data],
|
| "mask_transformer_att": [instance[7] for instance in train_data],
|
| "sn_ids": [instance[8] for instance in train_data],
|
| "reader_ids": [instance[9] for instance in train_data],
|
| }
|
| )
|
|
|
| val_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in val_data],
|
| "sn_sp_repr": [instance[1] for instance in val_data],
|
| "sn_input_ids": [instance[2] for instance in val_data],
|
| "indices_pos_enc": [instance[3] for instance in val_data],
|
| "sn_repr_len": [instance[4] for instance in val_data],
|
| "words_for_mapping": [instance[5] for instance in val_data],
|
| "mask_sn_padding": [instance[6] for instance in val_data],
|
| "mask_transformer_att": [instance[7] for instance in val_data],
|
| "sn_ids": [instance[8] for instance in val_data],
|
| "reader_ids": [instance[9] for instance in val_data],
|
| }
|
| )
|
| train_data_dict = datasets.DatasetDict()
|
| val_data_dict = datasets.DatasetDict()
|
| train_data_dict["train"] = train_dataset
|
| val_data_dict["val"] = val_dataset
|
| return train_data_dict, val_data_dict
|
|
|
| elif split == "train-val-test":
|
|
|
| if split_sizes:
|
| val_size = split_sizes["val_size"]
|
| test_size = split_sizes["test_size"]
|
| else:
|
| val_size = 0.1
|
| test_size = 0.25
|
|
|
| if splitting_criterion != "scanpath":
|
|
|
| if splitting_criterion == "combined":
|
|
|
| (
|
| train_data,
|
| test_data,
|
| train_reader_IDs,
|
| test_reader_IDs,
|
| train_sn_IDs,
|
| test_sn_IDs,
|
| ) = combined_split(
|
| data=flattened_data,
|
| reader_IDs=splitting_IDs_dict["reader"],
|
| sn_IDs=splitting_IDs_dict["sentence"],
|
| test_size=test_size,
|
| )
|
|
|
| train_data, val_data = train_test_split(
|
| train_data, test_size=val_size, random_state=77, shuffle=True
|
| )
|
|
|
| else:
|
| splitting_IDs = splitting_IDs_dict[splitting_criterion]
|
|
|
|
|
| gss = GroupShuffleSplit(n_splits=1, test_size=test_size, random_state=77)
|
| for train_index, test_index in gss.split(flattened_data, groups=splitting_IDs):
|
| train_data = np.array(flattened_data)[train_index].tolist()
|
| test_data = np.array(flattened_data)[test_index].tolist()
|
| train_ids = np.array(splitting_IDs)[train_index].tolist()
|
|
|
|
|
| gss = GroupShuffleSplit(n_splits=1, test_size=val_size, random_state=77)
|
| for train_index, val_index in gss.split(train_data, groups=train_ids):
|
| val_data = np.array(train_data)[val_index].tolist()
|
| train_data = np.array(train_data)[train_index].tolist()
|
|
|
| else:
|
| train_data, test_data = train_test_split(
|
| flattened_data, test_size=test_size, shuffle=True, random_state=77
|
| )
|
| train_data, val_data = train_test_split(
|
| train_data, test_size=val_size, shuffle=True, random_state=77
|
| )
|
|
|
|
|
| train_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in train_data],
|
| "sn_sp_repr": [instance[1] for instance in train_data],
|
| "sn_input_ids": [instance[2] for instance in train_data],
|
| "indices_pos_enc": [instance[3] for instance in train_data],
|
| "sn_repr_len": [instance[4] for instance in train_data],
|
| "words_for_mapping": [instance[5] for instance in train_data],
|
| "mask_sn_padding": [instance[6] for instance in train_data],
|
| "mask_transformer_att": [instance[7] for instance in train_data],
|
| "sn_ids": [instance[8] for instance in train_data],
|
| "reader_ids": [instance[9] for instance in train_data],
|
| }
|
| )
|
| test_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in test_data],
|
| "sn_sp_repr": [instance[1] for instance in test_data],
|
| "sn_input_ids": [instance[2] for instance in test_data],
|
| "indices_pos_enc": [instance[3] for instance in test_data],
|
| "sn_repr_len": [instance[4] for instance in test_data],
|
| "words_for_mapping": [instance[5] for instance in test_data],
|
| "mask_sn_padding": [instance[6] for instance in test_data],
|
| "mask_transformer_att": [instance[7] for instance in test_data],
|
| "sn_ids": [instance[8] for instance in test_data],
|
| "reader_ids": [instance[9] for instance in test_data],
|
| }
|
| )
|
| val_dataset = Dataset2.from_dict(
|
| {
|
| "mask": [instance[0] for instance in val_data],
|
| "sn_sp_repr": [instance[1] for instance in val_data],
|
| "sn_input_ids": [instance[2] for instance in val_data],
|
| "indices_pos_enc": [instance[3] for instance in val_data],
|
| "sn_repr_len": [instance[4] for instance in val_data],
|
| "words_for_mapping": [instance[5] for instance in val_data],
|
| "mask_sn_padding": [instance[6] for instance in val_data],
|
| "mask_transformer_att": [instance[7] for instance in val_data],
|
| "sn_ids": [instance[8] for instance in val_data],
|
| }
|
| )
|
| train_data_dict = datasets.DatasetDict()
|
| test_data_dict = datasets.DatasetDict()
|
| val_data_dict = datasets.DatasetDict()
|
| train_data_dict["train"] = train_dataset
|
| test_data_dict["test"] = test_dataset
|
| val_data_dict["val"] = val_dataset
|
| return train_data_dict, test_data_dict, val_data_dict
|
|
|