forked from EuroEval/EuroEval
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate_fone.py
More file actions
150 lines (127 loc) · 4.85 KB
/
create_fone.py
File metadata and controls
150 lines (127 loc) · 4.85 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
# /// script
# requires-python = ">=3.10,<4.0"
# dependencies = [
# "datasets==3.5.0",
# "huggingface-hub==0.24.0",
# "pandas==2.2.0",
# "requests==2.32.3",
# ]
# ///
"""Create the FoNE-mini NER dataset and upload it to the HF Hub."""
import pandas as pd
from datasets import Dataset, DatasetDict, Split, load_dataset
from huggingface_hub import HfApi
def main() -> None:
"""Create the FoNE-mini NER dataset and uploads it to the HF Hub."""
# Define dataset ID
repo_id = "vesteinn/sosialurin-faroese-ner"
# Download the dataset
dataset = load_dataset(path=repo_id, token=True, split="train")
assert isinstance(dataset, Dataset)
# Convert the dataset to a dataframe
df = dataset.to_pandas()
assert isinstance(df, pd.DataFrame)
# Drop all columns except for `tokens` and `ner_tags`
columns_to_drop = [col for col in df.columns if col not in ["tokens", "ner_tags"]]
df.drop(columns=columns_to_drop, inplace=True)
# Add a `text` column
df["text"] = df["tokens"].map(lambda tokens: " ".join(tokens))
# Rename `ner_tags` to `labels`
df.rename(columns={"ner_tags": "labels"}, inplace=True)
# Convert the NER tags from IDs to strings
ner_conversion_dict = {
0: "O", # Original: B-Date
1: "B-LOC", # Original: B-Location
2: "B-MISC", # Original: B-Miscellaneous
3: "O", # Original: B-Money
4: "B-ORG", # Original: B-Organization
5: "O", # Original: B-Percent
6: "B-PER", # Original: B-Person
7: "O", # Original: B-Time
8: "O", # Original: I-Date
9: "I-LOC", # Original: I-Location
10: "I-MISC", # Original: I-Miscellaneous
11: "O", # Original: I-Money
12: "I-ORG", # Original: I-Organization
13: "O", # Original: I-Percent
14: "I-PER", # Original: I-Person
15: "O", # Original: I-Time
16: "O", # Original: O
}
df["labels"] = df["labels"].map(
lambda ner_tags: [ner_conversion_dict[ner_tag] for ner_tag in ner_tags]
)
for token_list, ner_tag_list in zip(df["tokens"], df["labels"]):
# Sanity check that the number of tokens and named entity tags are equal
assert len(token_list) == len(ner_tag_list), (
"The number of tokens and named entity tags are not equal."
)
# Fix invalid I-tags
invalid_i_ner_tags = [
ner_tag
for token_idx, ner_tag in enumerate(ner_tag_list)
if ner_tag.startswith("I-")
and ner_tag_list[token_idx - 1] not in {f"B-{ner_tag[2:]}", ner_tag}
]
while invalid_i_ner_tags:
for invalid_i_ner_tag in invalid_i_ner_tags:
ner_tag_list[ner_tag_list.index(invalid_i_ner_tag)] = (
f"B-{invalid_i_ner_tag[2:]}"
)
invalid_i_ner_tags = [
ner_tag
for token_idx, ner_tag in enumerate(ner_tag_list)
if ner_tag.startswith("I-")
and ner_tag_list[token_idx - 1] not in {f"B-{ner_tag[2:]}", ner_tag}
]
# Sanity check that all I-tags are valid
assert not invalid_i_ner_tags, (
f"The following I- tags are invalid: {invalid_i_ner_tags}."
)
# Create validation split
val_size = 256
val_df = df.sample(
n=val_size,
random_state=4242,
weights=[5.0 if len(set(labels)) > 1 else 1.0 for labels in df["labels"]],
)
# Create test split
test_size = 2048
filtered_df = df.loc[~df.index.isin(val_df.index)]
test_df = filtered_df.sample(
n=test_size,
random_state=4242,
weights=[
5.0 if len(set(labels)) > 1 else 1.0 for labels in filtered_df["labels"]
],
)
# Create train split
train_size = 1024
filtered_df = filtered_df.loc[~filtered_df.index.isin(test_df.index)]
train_df = filtered_df.sample(
n=train_size,
random_state=4242,
weights=[
5.0 if len(set(labels)) > 1 else 1.0 for labels in filtered_df["labels"]
],
)
# Reset the index
train_df = train_df.reset_index(drop=True)
val_df = val_df.reset_index(drop=True)
test_df = test_df.reset_index(drop=True)
# Collect datasets in a dataset dictionary
dataset = DatasetDict(
{
"train": Dataset.from_pandas(train_df, split=Split.TRAIN),
"val": Dataset.from_pandas(val_df, split=Split.VALIDATION),
"test": Dataset.from_pandas(test_df, split=Split.TEST),
}
)
# Create dataset ID
dataset_id = "EuroEval/fone-mini"
# Remove the dataset from Hugging Face Hub if it already exists
HfApi().delete_repo(dataset_id, repo_type="dataset", missing_ok=True)
# Push the dataset to the Hugging Face Hub
dataset.push_to_hub(dataset_id, private=True)
if __name__ == "__main__":
main()