sport-text-classification-ball/Word2Vec.ipynb
jenkins-promoscan f268de4aa1 Upload project
2024-05-19 23:58:06 +02:00

40 KiB
Raw Permalink Blame History

import re
from nltk.tokenize import word_tokenize
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
import gensim
from gensim.models import Word2Vec
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report
import pandas as pd
from keras.src.utils import pad_sequences
from keras.src.legacy.preprocessing.text import Tokenizer
from keras.src.layers import Dropout, Dense, Activation, Embedding, MaxPooling1D, GlobalMaxPooling1D
from keras.src.layers import Conv1D
from keras import Sequential
from keras.optimizers import Adam
from sklearn.metrics import accuracy_score

Data preprocessing

Train data preprocessing

# Loading data
train_data = pd.read_csv('./train/train.tsv/train.tsv', sep='\t', header=None, on_bad_lines='skip')

# Removing unnecessary column
train_data = train_data.drop(train_data.columns[2], axis=1)

# Renaming columns
train_data.columns = ["label", "sentence"]

display(train_data)
label sentence
0 1 Mindaugas Budzinauskas wierzy w odbudowę formy...
1 1 Przyjmujący reprezentacji Polski wrócił do PGE...
2 0 FEN 9: Zapowiedź walki Róża Gumienna vs Katarz...
3 1 Aleksander Filipiak: Czuję się dobrze w nowym ...
4 0 Victoria Carl i Aleksiej Czerwotkin mistrzami ...
... ... ...
98127 1 Kamil Syprzak zaczyna kolekcjonować trofea. FC...
98128 1 Holandia: dwa gole Piotra Parzyszka Piotr Parz...
98129 1 Sparingowo: Korona gorsza od Stali. Lettieri s...
98130 1 Vive - Wisła. Ośmiu debiutantów w tegorocznej ...
98131 1 WTA Miami: Timea Bacsinszky pokonana, Swietłan...

98132 rows × 2 columns

def preprocess(sentence):
    sentence = sentence.lower()
    sentence = re.sub(r'\W', ' ', sentence)
    tokens = word_tokenize(sentence)
    return tokens

train_data["sentence_split"] = train_data["sentence"].apply(preprocess)
display(train_data)
label sentence sentence_split
0 1 Mindaugas Budzinauskas wierzy w odbudowę formy... [mindaugas, budzinauskas, wierzy, w, odbudowę,...
1 1 Przyjmujący reprezentacji Polski wrócił do PGE... [przyjmujący, reprezentacji, polski, wrócił, d...
2 0 FEN 9: Zapowiedź walki Róża Gumienna vs Katarz... [fen, 9, zapowiedź, walki, róża, gumienna, vs,...
3 1 Aleksander Filipiak: Czuję się dobrze w nowym ... [aleksander, filipiak, czuję, się, dobrze, w, ...
4 0 Victoria Carl i Aleksiej Czerwotkin mistrzami ... [victoria, carl, i, aleksiej, czerwotkin, mist...
... ... ... ...
98127 1 Kamil Syprzak zaczyna kolekcjonować trofea. FC... [kamil, syprzak, zaczyna, kolekcjonować, trofe...
98128 1 Holandia: dwa gole Piotra Parzyszka Piotr Parz... [holandia, dwa, gole, piotra, parzyszka, piotr...
98129 1 Sparingowo: Korona gorsza od Stali. Lettieri s... [sparingowo, korona, gorsza, od, stali, lettie...
98130 1 Vive - Wisła. Ośmiu debiutantów w tegorocznej ... [vive, wisła, ośmiu, debiutantów, w, tegoroczn...
98131 1 WTA Miami: Timea Bacsinszky pokonana, Swietłan... [wta, miami, timea, bacsinszky, pokonana, swie...

98132 rows × 3 columns

w2v = gensim.models.Word2Vec(train_data["sentence_split"], vector_size=500, window=5, min_count=2, workers=4)
# number of words in w2v
print(len(w2v.wv))
65861
token = Tokenizer(len(w2v.wv))
token.fit_on_texts(train_data["sentence_split"])
text = token.texts_to_sequences(train_data["sentence_split"])
text = pad_sequences(text)
X_train = np.array(text)
y_train = train_data["label"].to_numpy()
vocabulary_size = len(token.word_index)
print(f"X_train:\n\t{X_train}\ny_train:\n\t{y_train}\nVocabulary size:\n\t{vocabulary_size}")
X_train:
	[[    0     0     0 ...  1630   724 11557]
 [    0     0     0 ...     3   129   594]
 [    0     0     0 ...     4   781 28351]
 ...
 [    0     0     0 ...   390    35    55]
 [    0     0     0 ... 44454 12175   329]
 [    0     0     0 ...   159   455  1172]]
y_train:
	[1 1 0 ... 1 1 1]
Vocabulary size:
	104277
embedding_matrix = np.zeros((vocabulary_size, 500))
for word, i in token.word_index.items():
    if word in w2v.wv:
        embedding_matrix[i] = w2v.wv[word]

Test data preprocessing

X_test_pd = pd.read_csv("test-A/in.tsv", sep="\t", header=None)
X_test_pd = X_test_pd.drop(X_test_pd.columns[1], axis=1)
display(X_test_pd)
X_test_pd.columns = ["sentence"]
X_test_pd['sentence_split'] = X_test_pd['sentence'].apply(preprocess)
X_test = token.texts_to_sequences(X_test_pd['sentence_split'])
X_test = pad_sequences(X_test)
display(X_test_pd)
0
0 ATP Sztokholm: Juergen Zopp wykorzystał szansę...
1 Krowicki z reprezentacją kobiet aż do igrzysk ...
2 Wielki powrót Łukasza Kubota Odradza się zawsz...
3 Marcel Hirscher wygrał ostatni slalom gigant m...
4 Polki do Czarnogóry z pełnią zaangażowania. Sy...
... ...
5443 Biało-czerwona siła w Falun. Oni będą reprezen...
5444 Finał WTA Tokio na żywo: Woźniacka - Osaka LIV...
5445 Oni zapisali się w annałach. Hubert Hurkacz 15...
5446 Poprawia się stan Nikiego Laudy. Austriak może...
5447 Liga Mistrzów. Zabójcza końcówka Interu Mediol...

5448 rows × 1 columns

sentence sentence_split
0 ATP Sztokholm: Juergen Zopp wykorzystał szansę... [atp, sztokholm, juergen, zopp, wykorzystał, s...
1 Krowicki z reprezentacją kobiet aż do igrzysk ... [krowicki, z, reprezentacją, kobiet, aż, do, i...
2 Wielki powrót Łukasza Kubota Odradza się zawsz... [wielki, powrót, łukasza, kubota, odradza, się...
3 Marcel Hirscher wygrał ostatni slalom gigant m... [marcel, hirscher, wygrał, ostatni, slalom, gi...
4 Polki do Czarnogóry z pełnią zaangażowania. Sy... [polki, do, czarnogóry, z, pełnią, zaangażowan...
... ... ...
5443 Biało-czerwona siła w Falun. Oni będą reprezen... [biało, czerwona, siła, w, falun, oni, będą, r...
5444 Finał WTA Tokio na żywo: Woźniacka - Osaka LIV... [finał, wta, tokio, na, żywo, woźniacka, osaka...
5445 Oni zapisali się w annałach. Hubert Hurkacz 15... [oni, zapisali, się, w, annałach, hubert, hurk...
5446 Poprawia się stan Nikiego Laudy. Austriak może... [poprawia, się, stan, nikiego, laudy, austriak...
5447 Liga Mistrzów. Zabójcza końcówka Interu Mediol... [liga, mistrzów, zabójcza, końcówka, interu, m...

5448 rows × 2 columns

Dev data preprocessing

dev_in = pd.read_csv("dev-0/in.tsv", sep="\t", header=None, on_bad_lines='skip')
display(dev_in)
dev_in.columns = ["sentence"]
dev_in['sentence_split'] = dev_in['sentence'].apply(preprocess)
dev_text = token.texts_to_sequences(dev_in['sentence_split'])
dev_text = pad_sequences(dev_text)

dev_expected = pd.read_csv("dev-0/expected.tsv", sep="\t", header=None, on_bad_lines='skip').to_numpy()
display(dev_text)
display(dev_expected)
0
0 Mundial 2018. Były reprezentant Anglii trenere...
1 Liga Mistrzyń: Podopieczne Kima Rasmussena bli...
2 Wyczerpujące treningi biegowe Justyny Kowalczy...
3 Mundial 2018. Zagraniczne media zareagowały na...
4 BCL. Artur Gronek: Musimy grać twardziej. Pope...
... ...
5447 Michał Probierz szuka powodów do optymizmu. "C...
5448 ME 2017 w siatkówce. Znakomita frekwencja. Kib...
5449 Zobacz oficjalny trailer KSW 42 (wideo) Organi...
5450 Rummenigge nie wyklucza, że ktoś odejdzie z Ba...
5451 Sympatyczny gest argentyńskich tenisistów. Obd...

5452 rows × 1 columns

array([[    0,     0,     0, ...,   149,  3657, 28408],
       [    0,     0,     0, ...,  2378, 59831, 31454],
       [    0,     0,     0, ...,   311,   991, 15435],
       ...,
       [    0,     0,     0, ...,     2,  2999, 11543],
       [    0,     0,     0, ...,     4,  1077, 38402],
       [    0,     0,     0, ...,  1001,    39, 18089]])
array([[1],
       [1],
       [0],
       ...,
       [0],
       [1],
       [1]], dtype=int64)

Training the model

opt = Adam(learning_rate=0.0001)
keras_model = Sequential()
keras_model.add(Embedding(vocabulary_size, 500, weights=[embedding_matrix], trainable=False))
keras_model.add(Dropout(0.4))
keras_model.add(Conv1D(50, 3, activation='relu', padding='same', strides=1))
keras_model.add(Conv1D(50, 3, activation='relu', padding='same', strides=1))
keras_model.add(MaxPooling1D())
keras_model.add(Dropout(0.4))
keras_model.add(Conv1D(100, 3, activation='relu', padding='same', strides=1))
keras_model.add(Conv1D(100, 3, activation='relu', padding='same', strides=1))
keras_model.add(MaxPooling1D())
keras_model.add(Dropout(0.2))
keras_model.add(Conv1D(200, 3, activation='relu', padding='same', strides=1))
keras_model.add(Conv1D(200, 3, activation='relu', padding='same', strides=1))
keras_model.add(GlobalMaxPooling1D())
keras_model.add(Dropout(0.4))
keras_model.add(Dense(200))
keras_model.add(Activation('relu'))
keras_model.add(Dropout(0.4))
keras_model.add(Dense(1))
keras_model.add(Activation('sigmoid'))
keras_model.compile(loss='binary_crossentropy', metrics=['acc'], optimizer=opt)
keras_model.fit(X_train, y_train, batch_size=64, epochs=25)

model = keras_model
Epoch 1/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 31s 18ms/step - acc: 0.8497 - loss: 0.2841
Epoch 2/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 28s 18ms/step - acc: 0.9729 - loss: 0.0774
Epoch 3/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 28s 18ms/step - acc: 0.9763 - loss: 0.0695
Epoch 4/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 28s 18ms/step - acc: 0.9790 - loss: 0.0608
Epoch 5/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 30s 20ms/step - acc: 0.9796 - loss: 0.0586
Epoch 6/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 29s 19ms/step - acc: 0.9823 - loss: 0.0494
Epoch 7/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 29s 19ms/step - acc: 0.9831 - loss: 0.0490
Epoch 8/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 29s 19ms/step - acc: 0.9832 - loss: 0.0477
Epoch 9/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 29s 19ms/step - acc: 0.9842 - loss: 0.0437
Epoch 10/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 29s 19ms/step - acc: 0.9848 - loss: 0.0444
Epoch 11/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 29s 19ms/step - acc: 0.9855 - loss: 0.0418
Epoch 12/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 32s 21ms/step - acc: 0.9862 - loss: 0.0420
Epoch 13/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 36s 24ms/step - acc: 0.9860 - loss: 0.0400
Epoch 14/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 32s 21ms/step - acc: 0.9864 - loss: 0.0392
Epoch 15/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 29s 19ms/step - acc: 0.9865 - loss: 0.0387
Epoch 16/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 29s 19ms/step - acc: 0.9871 - loss: 0.0369
Epoch 17/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 29s 19ms/step - acc: 0.9875 - loss: 0.0349
Epoch 18/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 29s 19ms/step - acc: 0.9877 - loss: 0.0357
Epoch 19/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 29s 19ms/step - acc: 0.9888 - loss: 0.0312
Epoch 20/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 28s 19ms/step - acc: 0.9879 - loss: 0.0347
Epoch 21/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 30s 20ms/step - acc: 0.9879 - loss: 0.0326
Epoch 22/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 30s 20ms/step - acc: 0.9881 - loss: 0.0329
Epoch 23/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 30s 19ms/step - acc: 0.9874 - loss: 0.0337
Epoch 24/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 29s 19ms/step - acc: 0.9889 - loss: 0.0307
Epoch 25/25
1534/1534 ━━━━━━━━━━━━━━━━━━━━ 37s 24ms/step - acc: 0.9893 - loss: 0.0290
test_result = model.predict(X_test)
test_predictions = np.where(test_result>=0.50, 1, 0)
pd.DataFrame(test_predictions).to_csv('test-A/out.tsv', sep="\t", index=False, encoding='utf-8') 
171/171 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step

Evaluation

I had problems installing GEval on Windows so I did the evaluation the old fashioned way

dev_result = model.predict(dev_text)
dev_predictions = np.where(dev_result>=0.50, 1, 0)
predictions_df = pd.DataFrame(dev_predictions)
display(predictions_df)
171/171 ━━━━━━━━━━━━━━━━━━━━ 1s 4ms/step
0
0 1
1 1
2 0
3 1
4 1
... ...
5447 1
5448 1
5449 0
5450 1
5451 1

5452 rows × 1 columns

dev_data = pd.read_csv("dev-0/in.tsv", sep="\t", header=None, on_bad_lines='skip')
predictions_df.to_csv('dev-0/out.tsv', sep="\t", index=False, header=None)
dev_data.to_csv('in.tsv', sep="\t", index=False, header=None, encoding='utf-8')
score = accuracy_score(y_true=dev_expected, y_pred=dev_predictions)
print(score)
0.9888114453411592