Kaggle competition: Otto Group Product Classification Challenge
<SOS> metric: MulticlassLoss Kaggle data source: otto-group-product-classification-challenge<split>
from pathlib import Path
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
import lightgbm as lgb_org
import optuna.integration.lightgbm as lgb
train = train[:5000]<predict_on_test>
base_dir = Path(
 "/kaggle/input/otto-group-product-classification-challenge/"
)
s_outputs, e_outputs, a_s_outputs, a_e_outputs, s_chars, e_chars, t_predicts = predict_submission(train, model, device=device)
 train['predict'] = t_predicts
train['s_target'] = s_outputs
train['e_target'] = e_outputs
train['a_s_target'] = s_outputs
train['a_e_target'] = e_outputs
train['s_char'] = s_chars
train['e_char'] = e_chars<filter>
def read_csv(path):
df = pd.read_csv(path)
 for col in df.columns:
if col.startswith("feat_"):
df[col] = df[col].astype("int32")
 return df
train[train.sentiment == 'positive'][50:100]<set_options>
df = read_csv(str(base_dir / "train.csv"))
%matplotlib inline
pd.set_option('max_colwidth', 40 )<define_variables>
class_to_order = dict()
order_to_class = dict()
for idx, col in enumerate(df.target.unique()):
order_to_class[idx] = col
class_to_order[col] = idx
df["target_ord"] = df["target"].map(class_to_order )
IS_PSEUDO_LABELLING = False
IS_USING_PSEUDO_LABELS = False
IS_SUBSTITUTING_URLS = False
IS_GETTING_BEST_LOGITS = False
IS_PREDICTING_TRAIN = False
IS_POSTPROCESSING = False
IS_AUGMENT_SYNONYM = False
IS_ADDING_SENTIMENT_WORDS = True
IS_INCLUDING_EXTRA_DATA = False
IS_EXPECTATION_MAXIMISE = True<define_variables>
feature_columns = [
col for col in df.columns if col.startswith("feat_")
 ]
target_column = ["target_ord"]
MAX_LEN = 192
PATH = '.. /input/tf-roberta/'
tokenizer = tokenizers.ByteLevelBPETokenizer(
 vocab_file=PATH+'vocab-roberta-base.json',
merges_file=PATH+'merges-roberta-base.txt',
lowercase=True,
add_prefix_space=True 
)
 PAD_ID = 1
SEED = 88888
tf.random.set_seed(SEED)
 np.random.seed(SEED)
 sentiment_id = {'positive': 1313, 'negative': 2430, 'neutral': 7974}<load_from_csv>
X_train, X_val, y_train, y_val = train_test_split(
 df[feature_columns], df[target_column],
test_size=0.3, random_state=42,
stratify=df[target_column]
)
train = pd.read_csv('.. /input/tweet-sentiment-extraction/train.csv' ).fillna('')
 train.head()<load_from_csv>
dtrain = lgb_org.Dataset(X_train, y_train)
 dval = lgb_org.Dataset(X_val, y_val )
if IS_INCLUDING_EXTRA_DATA:
extra_data = pd.read_csv('.. /input/complete-tweet-sentiment-extraction-data/tweet_dataset.csv' ).fillna('')
 extra_data = extra_data[(~extra_data.aux_id.isin(train['textID'].values)) &(extra_data.selected_text != '')].reset_index(drop=True)
 extra_data.textID = extra_data.aux_id
extra_data.sentiment = extra_data.new_sentiment
extra_data = extra_data[['textID', 'text', 'selected_text', 'sentiment']]
train = pd.concat([train, extra_data] ).reset_index(drop=True )<string_transform>
params = dict(
 objective="multiclass",
metric="multi_logloss",
num_class=9,
seed=42, 
)
 best_params, tuning_history = dict() , list()
booster = lgb.train(params, dtrain, valid_sets=dval,
verbose_eval=0,
best_params=best_params,
early_stopping_rounds=5,
tuning_history=tuning_history)
 print("Best Params:", best_params)
 print("Tuning history:", tuning_history )
if IS_AUGMENT_SYNONYM:
random.seed(SEED)
 with open('.. /input/englishengen-synonyms-json-thesaurus/eng_synonyms.json')as json_file:
synonyms_dict = json.load(json_file)
 def get_synonym_word(text, first_selected, last_selected):
attempts = 0
old_word = ''
new_word = ''
possible_words = text.split()
while len(possible_words)> 0 and attempts < 5:
word_choice = random.choice(possible_words)
 if word_choice in synonyms_dict and len(synonyms_dict[word_choice])> 0:
if not(( word_choice in first_selected and len(word_choice)!= len(first_selected)) and(word_choice in last_selected and len(word_choice)!= len(last_selected))):
old_word = word_choice
new_word = random.choice(synonyms_dict[old_word])
 break
attempts += 1
return old_word, new_word
def get_synonym_row(row, changes):
text = row['text']
selected_text = row['selected_text']
sentiment = row['sentiment']
point_id = row['textID'] + 'aug' + str(changes)
 if len(text)> 0:
for i in range(changes):
word_to_replace, replacement_word = get_synonym_word(text, selected_text.split() [0], selected_text.split() [-1])
 if word_to_replace in selected_text.split() :
old_selected_text = selected_text
selected_text = selected_text.replace(word_to_replace, replacement_word)
 text = text.replace(old_selected_text, selected_text, 1)
 else:
text = text.replace(word_to_replace, replacement_word)
 return text, selected_text, sentiment, point_id
aug_rows = [train]
for changes in [1]:
new_rows = []
for index, row in train.iterrows() :
text, selected_text, sentiment, point_id = get_synonym_row(row, changes)
 new_rows.append([point_id, text, selected_text, sentiment])
 aug_train = pd.DataFrame(new_rows, columns=['textID', 'text', 'selected_text', 'sentiment'])
 aug_rows.append(aug_train)
 train = pd.concat(aug_rows ).sort_index(kind='merge' ).reset_index(drop=True )<load_from_csv>
df_test = read_csv(str(base_dir / "test.csv"))
if IS_USING_PSEUDO_LABELS:
pseudo_labelled_set = pd.read_csv('.. /input/tweetsentimentextraction2020completepseudo/extra_data.csv' ).fillna('')[['textID', 'text', 'selected_text', 'sentiment']]
pseudo_labelled_folds = []
for k in range(5):
pseudo_labelled_folds.append(pseudo_labelled_set.iloc[k::5].reset_index(drop=True))
pseudo_labelled_folds[4].head()<load_from_csv>
pred = booster.predict(df_test[feature_columns] )
if IS_PSEUDO_LABELLING:
test = pd.read_csv('.. /input/complete-tweet-sentiment-extraction-data/tweet_dataset.csv' ).fillna('')
 test = test[~test.aux_id.isin(train['textID'].values)].reset_index(drop=True)
 test['textID'] = test['aux_id']
sent_con = {'empty' : 'neutral', 'sadness' : 'negative', 'worry' : 'negative', 'neutral' : 'neutral', 'fun' : 'positive', 'happiness' : 'positive', 'hate' : 'negative', 'surprise' : 'neutral', 'relief' : 'positive', 'enthusiasm' : 'neutral', 'anger' : 'negative', 'boredom' : 'negative', 'love' : 'positive'}
test['sentiment'] = test.apply(lambda x: x.new_sentiment if len(x.new_sentiment)> 0 else sent_con[x.sentiment], axis=1)
 test[['textID', 'text', 'sentiment']]
else:
test = pd.read_csv('.. /input/tweet-sentiment-extraction/test.csv' ).fillna('')
 test.head()<define_variables>
for idx, col in order_to_class.items() :
df_test[col] = pred[:,idx]
<train_model><EOS> 
df_test[["id"] + [f"Class_{i}" for i in range(1, 10)]].to_csv('submission.csv', index=False )