github-actions[bot]
Sync from GitHub e9a00339708d14fd15e64679f58d1c321b37ea9d
e71990c
Raw
History Blame Contribute Delete
3.53 kB
import re
import ray
import numpy as np
import pandas as pd
from ray.data import Dataset
from sklearn.model_selection import train_test_split
from src.config import STOPWORDS
from typing import Dict,List,Tuple
from transformers import BertTokenizer
def data(dataset_loc: str, num_samples: int = None) -> ray.data.Dataset:
dataset = ray.data.read_csv(dataset_loc)
dataset = dataset.random_shuffle(seed = 1234)
dataset = ray.data.from_items(dataset.take(num_samples)) if num_samples else dataset
return dataset
def stratify_split(
ds: Dataset,
stratify: str,
test_size: float,
shuffle: bool = True,
seed: int = 1234,
) -> Tuple[Dataset, Dataset]:
def _add_split(df: pd.DataFrame) -> pd.DataFrame:
train, test = train_test_split(df, test_size=test_size, shuffle=shuffle, random_state=seed)
train["_split"]= "train"
test["_split"] = "test"
return pd.concat([train,test])
def _filter_split(df: pd.DataFrame, split: str) -> pd.DataFrame:
return df[df["_split"] == split].drop("_split", axis = 1)
grouped = ds.groupby(stratify).map_groups(_add_split, batch_format="pandas")
train_ds = grouped.map_batches(_filter_split, fn_kwargs={"split":"train"}, batch_format="pandas")
test_ds = grouped.map_batches(_filter_split, fn_kwargs={"split":"test"}, batch_format="pandas")
train_ds = train_ds.random_shuffle(seed=seed)
test_ds = test_ds.random_shuffle(seed=seed)
return train_ds, test_ds
def clean_text(text: str) -> str:
# change every words into lower case
text = text.lower()
text = re.sub(r"http\S+", "", text) # remove links (must run before punctuation gets spaced apart below)
# removing stopwords such as "is", "the" and so on
pattern = re.compile(r'\b(' + r"|".join(STOPWORDS)+ r")\b\s*")
text = pattern.sub('', text)
text = re.sub(r"([!\"'#$%&()*\+,-./:;<=>?@\\\[\]^_`{|}~])", r" \1 ", text) # add space
text = re.sub("[^A-Za-z0-9]+", " ", text) # remove other than words and numbers
text = re.sub(" +", " ", text) # remove all extra spaces
text = text.strip() # remove spaces at the start and at the end
return text
_tokenizer_cache = {}
def _get_tokenizer(model_name: str = "allenai/scibert_scivocab_uncased"):
# cache per-process so map_batches workers don't reload the tokenizer on every batch
if model_name not in _tokenizer_cache:
_tokenizer_cache[model_name] = BertTokenizer.from_pretrained(model_name, return_dict=False)
return _tokenizer_cache[model_name]
def tokenize(batch: Dict) -> Dict:
tokenizer = _get_tokenizer()
encoded = tokenizer(batch["text"].tolist(), return_tensors="np", padding = "longest")
return dict(ids=encoded["input_ids"], masks=encoded["attention_mask"], targets=np.array(batch["label"]))
def preprocess(df: pd.DataFrame):
df["text"] = df.text.apply(clean_text)
targets = tokenize(df)
return targets
class CustomPreprocessor():
"""Custom Preprocess."""
def __init__(self, label_decoder = None):
self.label_decoder = label_decoder or {
0: "World",
1: "Sports",
2: "Business",
3: "Sci/Tech"
}
self.class_to_index = {v:k for k, v in self.label_decoder.items()}
def fitting(self, ds):
_ = ds.unique(column="label")
return self
def transforming(self, ds):
return ds.map_batches(
preprocess,
batch_format = "pandas")