Log In

Neural Networks and Embeddings for Natural Language Processing

Open In Colab

Outline:

  • Download the Data
  • Prepare Data for Training
  • Logistic Regression Model
  • Feed Forward Nueral Network

Dataset: https://www.kaggle.com/c/quora-insincere-questions-classification

Download the Data

Upload your kaggle.json file to Colab

!ls
sample_data
import os
IS_KAGGLE = 'KAGGLE_KERNEL_RUN_TYPE' in os.environ
if IS_KAGGLE:
    data_dir = '../input/quora-insincere-questions-classification'
    train_fname = data_dir + '/train.csv'
    test_fname = data_dir + '/test.csv'
    sub_fname = data_dir + '/sample_submission.csv'
else:
    os.environ['KAGGLE_CONFIG_DIR'] = '.'
    !kaggle competitions download -c quora-insincere-questions-classification -f train.csv -p data
    !kaggle competitions download -c quora-insincere-questions-classification -f test.csv -p data
    !kaggle competitions download -c quora-insincere-questions-classification -f sample_submission.csv -p data
    train_fname = 'data/train.csv.zip'
    test_fname = 'data/test.csv.zip'
    sub_fname = 'data/sample_submission.csv.zip' 
Warning: Your Kaggle API key is readable by other users on this system! To fix this, you can run 'chmod 600 ./kaggle.json' Downloading train.csv.zip to data 96% 53.0M/54.9M [00:03<00:00, 17.0MB/s] 100% 54.9M/54.9M [00:03<00:00, 16.1MB/s] Warning: Your Kaggle API key is readable by other users on this system! To fix this, you can run 'chmod 600 ./kaggle.json' Downloading test.csv.zip to data 88% 14.0M/15.8M [00:01<00:00, 18.1MB/s] 100% 15.8M/15.8M [00:01<00:00, 12.4MB/s] Warning: Your Kaggle API key is readable by other users on this system! To fix this, you can run 'chmod 600 ./kaggle.json' Downloading sample_submission.csv.zip to data 98% 4.00M/4.09M [00:00<00:00, 6.23MB/s] 100% 4.09M/4.09M [00:00<00:00, 4.61MB/s]
import pandas as pd
raw_df = pd.read_csv(train_fname)
test_df = pd.read_csv(test_fname)
sub_df = pd.read_csv(sub_fname)
raw_df
test_df
sub_df
if IS_KAGGLE:
    sample_df = raw_df
else:
    sample_df = raw_df.sample(100_000, random_state=42)

Prepare Data for Training

Outline:

  • Convert text to TF-IDF Vectors
  • Split training & validation set
  • Convert to PyTorch tensors
import nltk
from nltk.tokenize import word_tokenize
from nltk.stem import SnowballStemmer
from nltk.corpus import stopwords
from sklearn.feature_extraction.text import TfidfVectorizer
nltk.download('punkt')
[nltk_data] Downloading package punkt to /root/nltk_data... [nltk_data] Unzipping tokenizers/punkt.zip.
True
stemmer = SnowballStemmer(language='english')

def tokenize(text):
    return [stemmer.stem(token) for token in word_tokenize(text)]
tokenize("Ain't nothin' (but a heartache)!")
['ai', "n't", 'nothin', "'", '(', 'but', 'a', 'heartach', ')', '!']
nltk.download('stopwords')
[nltk_data] Downloading package stopwords to /root/nltk_data... [nltk_data] Unzipping corpora/stopwords.zip.
True
english_stopwords = stopwords.words('english')
vectorizer = TfidfVectorizer(lowercase=True, 
                             tokenizer=tokenize,
                             stop_words=english_stopwords,
                             max_features=1000)
%%time
vectorizer.fit(sample_df.question_text)
/usr/local/lib/python3.7/dist-packages/sklearn/feature_extraction/text.py:517: UserWarning: The parameter 'token_pattern' will not be used since 'tokenizer' is not None' "The parameter 'token_pattern' will not be used" /usr/local/lib/python3.7/dist-packages/sklearn/feature_extraction/text.py:401: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens ["'d", "'s", 'abov', 'ani', 'becaus', 'befor', 'could', 'doe', 'dure', 'might', 'must', "n't", 'need', 'onc', 'onli', 'ourselv', 'sha', 'themselv', 'veri', 'whi', 'wo', 'would', 'yourselv'] not in stop_words. % sorted(inconsistent)
CPU times: user 25.6 s, sys: 116 ms, total: 25.7 s Wall time: 25.7 s
TfidfVectorizer(max_features=1000,
                stop_words=['i', 'me', 'my', 'myself', 'we', 'our', 'ours',
                            'ourselves', 'you', "you're", "you've", "you'll",
                            "you'd", 'your', 'yours', 'yourself', 'yourselves',
                            'he', 'him', 'his', 'himself', 'she', "she's",
                            'her', 'hers', 'herself', 'it', "it's", 'its',
                            'itself', ...],
                tokenizer=<function tokenize at 0x7f11d04a1680>)
%%time
inputs = vectorizer.transform(sample_df.question_text)
inputs.shape
(100000, 1000)
targets = sample_df.target.values
targets.shape
(100000,)
%%time
test_inputs = vectorizer.transform(test_df.question_text)
from sklearn.model_selection import train_test_split
train_inputs, val_inputs, train_targets, val_targets = train_test_split(inputs, targets, test_size=0.3, random_state=42)
train_inputs.shape, val_inputs.shape
((70000, 1000), (30000, 1000))
train_targets.shape
(70000,)
import torch
from torch.utils.data import TensorDataset, DataLoader
import torch.nn.functional as F
train_tensors = F.normalize(torch.tensor(train_inputs.toarray()).float(), dim=0)
val_tensors = F.normalize(torch.tensor(val_inputs.toarray()).float(), dim=0)
train_tensors.shape, val_tensors.shape
(torch.Size([70000, 1000]), torch.Size([30000, 1000]))
train_ds = TensorDataset(train_tensors, torch.tensor(train_targets))
val_ds = TensorDataset(val_tensors, torch.tensor(val_targets))
batch_size = 128
train_dl = DataLoader(train_ds, batch_size, shuffle=True)
val_dl = DataLoader(val_ds, batch_size)
for inputs_batch, targets_batch in train_dl:
    print('inputs.shape', inputs_batch.shape)
    print('targets.shape', targets_batch.shape)
    print(targets_batch)
    break
inputs.shape torch.Size([128, 1000]) targets.shape torch.Size([128]) tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
import torch.nn as nn
class LogReg(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear1 = nn.Linear(1000, 1)
        
    def forward(self, xb):
        out = self.linear1(xb)
        return out
import numpy as np
from sklearn.metrics import accuracy_score, f1_score
logreg_model = LogReg()
for batch in val_dl:
    batch_inputs, batch_targets = batch
    print('inputs.shape', batch_inputs.shape)
    print('targets', batch_targets)
    
    batch_out = logreg_model(batch_inputs)
    probs = torch.sigmoid(batch_out[:,0])
    preds = (probs >= 0.5).int()
    
    print('outputs', preds)
    print('accuracy', accuracy_score(batch_targets, preds))
    print('f1_score', f1_score(batch_targets, preds))
    break
inputs.shape torch.Size([128, 1000]) targets tensor([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]) outputs tensor([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=torch.int32) accuracy 0.0625 f1_score 0.11764705882352941
def evaluate(model, dl):
    losses, accs, f1s = [], [], []
    for batch in dl:
        inputs, targets = batch
        out = model(inputs)
        
        probs = torch.sigmoid(out[:,0])
        loss = F.binary_cross_entropy(probs, targets.float(), weight=torch.tensor(20.))
        losses.append(loss.item())

        preds = (probs > 0.5).int()
        acc = accuracy_score(targets, preds)
        f1 = f1_score(targets, preds)
        
        accs.append(acc)
        f1s.append(f1)

    return np.mean(losses), np.mean(accs), np.mean(f1s)
def fit(epochs, lr, model, train_loader, val_loader):
    optimizer = torch.optim.Adam(model.parameters(), lr, weight_decay=1e-5)
    history = [] # for recording epoch-wise results
    
    for epoch in range(epochs):
        
        # Training Phase 
        for batch in train_loader:
            inputs, targets = batch
            out = model(inputs)
            probs = torch.sigmoid(out[:,0])
            loss = F.binary_cross_entropy(probs, 
                                          targets.float(), 
                                          weight=torch.tensor(20.))
            loss.backward()
            optimizer.step()
            optimizer.zero_grad()
        
        # Validation phase
        result = evaluate(model, val_loader)
        loss, acc, f1 = result
        print('Epoch: {}; Loss: {:.4f}; Accuracy: {:.4f}; F1 Score: {:.4f}'.format(
            epoch, loss, acc, f1))
        history.append(result)

    return history
logreg_model = LogReg()
history = [evaluate(logreg_model, val_dl)]
history
[(13.971544635042232, 0.06083776595744681, 0.11376128019618044)]
history += fit(5, 0.01, logreg_model, train_dl, val_dl)
Epoch: 0; Loss: 4.3506; Accuracy: 0.9393; F1 Score: 0.0000 Epoch: 1; Loss: 4.0387; Accuracy: 0.9393; F1 Score: 0.0000 Epoch: 2; Loss: 3.7691; Accuracy: 0.9393; F1 Score: 0.0000 Epoch: 3; Loss: 3.5590; Accuracy: 0.9394; F1 Score: 0.0041 Epoch: 4; Loss: 3.3995; Accuracy: 0.9399; F1 Score: 0.0274
history += fit(5, 0.01, logreg_model, train_dl, val_dl)
Epoch: 0; Loss: 3.2747; Accuracy: 0.9407; F1 Score: 0.0723 Epoch: 1; Loss: 3.1925; Accuracy: 0.9425; F1 Score: 0.1543 Epoch: 2; Loss: 3.1292; Accuracy: 0.9433; F1 Score: 0.2069 Epoch: 3; Loss: 3.0856; Accuracy: 0.9444; F1 Score: 0.2700 Epoch: 4; Loss: 3.0486; Accuracy: 0.9449; F1 Score: 0.3002
history += fit(5, 0.01, logreg_model, train_dl, val_dl)
Epoch: 0; Loss: 3.0573; Accuracy: 0.9461; F1 Score: 0.3638 Epoch: 1; Loss: 3.0475; Accuracy: 0.9463; F1 Score: 0.3897 Epoch: 2; Loss: 3.0594; Accuracy: 0.9461; F1 Score: 0.4108 Epoch: 3; Loss: 3.0465; Accuracy: 0.9462; F1 Score: 0.4175 Epoch: 4; Loss: 3.0685; Accuracy: 0.9460; F1 Score: 0.4345
losses = [item[0] for item in history]
import matplotlib.pyplot as plt
plt.plot(losses);
plt.title('Loss')
Text(0.5, 1.0, 'Loss')
Notebook output
f1s = [item[2] for item in history]
plt.plot(f1s)
plt.title('F1 Score')
Text(0.5, 1.0, 'F1 Score')
Notebook output
 
import torch.nn.functional as F
class FeedForwardModel(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear1 = nn.Linear(1000, 512)
        self.linear2 = nn.Linear(512, 256)
        self.linear3 = nn.Linear(256, 128)
        self.linear4 = nn.Linear(128, 1)
        
    def forward(self, xb):
        out = F.relu(self.linear1(xb))
        out = F.relu(self.linear2(out))
        out = F.relu(self.linear3(out))
        out = self.linear4(out)
        return out
ff_model = FeedForwardModel()
history = [evaluate(ff_model, val_dl)]
history
[(13.31828673342441, 0.9392619680851064, 0.0)]
%%time
history += fit(5, 0.001, ff_model, train_dl, val_dl)
Epoch: 0; Loss: 3.1960; Accuracy: 0.9421; F1 Score: 0.4435 Epoch: 1; Loss: 3.1660; Accuracy: 0.9396; F1 Score: 0.4819 Epoch: 2; Loss: 3.2548; Accuracy: 0.9350; F1 Score: 0.4901 Epoch: 3; Loss: 3.5200; Accuracy: 0.9279; F1 Score: 0.4879 Epoch: 4; Loss: 3.5221; Accuracy: 0.9279; F1 Score: 0.4917 CPU times: user 4min 26s, sys: 3.06 s, total: 4min 29s Wall time: 1min 7s
test_tensors = torch.tensor(test_inputs.toarray()).float()
test_ds = TensorDataset(test_tensors)
test_dl = DataLoader(test_ds, batch_size)
def predict(model, dl):
    all_preds = []
    for batch in dl:
        inputs, = batch
        out = model(inputs)
        probs = torch.sigmoid(out)[:,0]
        preds = (probs > 0.5).int()
        all_preds += list(preds.numpy())
    return all_preds
test_preds = predict(ff_model, test_dl)
test_preds[:20]
[1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0]
sub_df
sub_df.prediction = test_preds
sub_df.to_csv('submission.csv', index=None)
!head submission.csv
qid,prediction 0000163e3ea7c7a74cd7,1 00002bd4fb5d505b9161,0 00007756b4a147d2b0b3,1 000086e4b7e1c7146103,0 0000c4c3fbe8785a3090,1 000101884c19f3515c1a,0 00010f62537781f44a47,0 00012afbd27452239059,0 00014894849d00ba98a9,1
!kaggle kernels list
Warning: Your Kaggle API key is readable by other users on this system! To fix this, you can run 'chmod 600 ./kaggle.json' ref title author lastRunTime totalVotes -------------------------------------------------------------- -------------------------------------------------- ------------------ ------------------- ---------- imbikramsaha/01-pytorch-workflow-fundamentals 01 - PyTorch Workflow Fundamentals Bikram Saha 2022-11-23 07:04:51 10 meghadjain/crimecasesspain-edaincvisualizeonmap CrimeCasesSpain_EDAIncVisualizeOnMap MeghaDJain 2022-11-23 09:44:40 5 fuarresvij/jakarta-food-and-drinks-culinary-business-analysis Jakarta food and drinks culinary business analysis L. Farras Vijaya 2022-11-23 07:12:30 17 shilongzhuang/statistical-testing-guide-for-beginners 🤓📊 Statistical Testing Guide for Beginners Shi Long Zhuang 2022-11-23 07:09:48 6 taranmarley/vision-transformer-from-scratch Vision Transformer From Scratch Taran Marley 2022-11-23 03:40:32 26 afrinahossain/computer-vision-in-2022-what-s-the-current-state Computer Vision In 2022:What's the Current State? Afrina Hossain 2022-11-23 07:37:56 11 smailaar/ncome-classifacition-ml İncome_classifacition_ML İsmail ACAR 2022-11-23 08:46:16 2 devharal/titanicsurvival-xgboost TitanicSurvival_XGboost Dev Haral 2022-11-22 19:38:17 18 usharengaraju/gatedtabtransformer-flax GatedTabTransformer-FLAX Tensor Girl 2022-11-23 01:52:11 28 gbertoluci/cyclistic-case-study Cyclistic case study gbertoluci 2022-11-23 09:56:55 1 circleofcare/kaggle-survey-2022-exploratory-data-analysis Kaggle_Survey_2022_Exploratory_Data_Analysis Circle of Care 2022-11-23 09:25:37 1 jiaowoguanren/monkey-classification-pytorch-resnet50 Monkey Classification Pytorch ResNet50 whxna-0615 2022-11-23 06:09:05 3 beforeby/ch6-eda [ch6] EDA BeforeBY 2022-11-23 02:19:33 5 bigourauxquentin/stock-market-project Stock market project BIGOURAUX Quentin 2022-11-23 09:04:42 1 marzihemmati/preprocessing-eda-googleplaystore Preprocessing & EDA(GooglePlayStore) Marzi Hemmati 2022-11-23 08:52:12 1 antoniobrych/digit-recognition-without-cnn-ml-perceptron Digit recognition WITHOUT CNN: ML-Perceptron!! Antonio Brych 2022-11-23 01:55:51 4 kishor1123/genus-classification-without-species-information Genus Classification (without species information) kishor datta gupta 2022-11-23 08:31:21 1 jithinvyas/titanic-survival Titanic Survival Jithin Vyas 2022-11-23 08:13:48 1 lhagiimn/seminar seminar lhagiimn 2022-11-23 09:38:46 1 venkatesh9999/alright-its-fun Alright-its-fun Venkatesh 2022-11-23 08:10:05 18
!kaggle kernels pull