Spaces:
Sleeping
Sleeping
| 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") |