Text Classification with NLP: Tf-Idf vs Word2Vec vs BERT
Text Classification with NLP: Tf-Idf vs Word2Vec vs BERT |
Ringkasan
## for dataimport jsonimport pandas as pdimport numpy as np## for plottingimport matplotlib.pyplot as pltimport seaborn as sns## for processingimport reimport nltk## for bag-of-wordsfrom sklearn import feature_extraction, model_selection, naive_bayes, pipeline, manifold, preprocessing## for explainerfrom lime import lime_text## for word embeddingimport gensimimport gensim.downloader as gensim_api## for deep learningfrom tensorflow.keras import models, layers, preprocessing as kprocessingfrom tensorflow.keras import backend as K## for bert language modelimport transformersHimpunan data terkandung ke dalam file json, jadi pertama-tama saya akan membacanya menjadi daftar kamus dengan json dan kemudian mengubahnya menjadi Dataframe pandas.
lst_dics = []
with open('data.json', mode='r', errors='ignore') as json_file:
for dic in json_file:
lst_dics.append( json.loads(dic) )
## print the first one
lst_dics[0]
The original dataset contains over 30 categories, but for the purposes of this tutorial, I will work with a subset of 3: Entertainment, Politics, and Tech.
## create dtf
dtf = pd.DataFrame(lst_dics)
## filter categories
dtf = dtf[ dtf["category"].isin(['ENTERTAINMENT','POLITICS','TECH']) ][["category","headline"]]
## rename columns
dtf = dtf.rename(columns={"category":"y", "headline":"text"})
## print 5 random rows
dtf.sample(5)
Untuk memahami komposisi himpunan data, saya akan melihat distribusi univariat target dengan menunjukkan frekuensi label dengan plot batang.
fig, ax = plt.subplots()
fig.suptitle("y", fontsize=12)
dtf["y"].reset_index().groupby("y").count().sort_values(by=
"index").plot(kind="barh", legend=False,
ax=ax).grid(axis='x')
plt.show()
Himpunan data tidak seimbang: proporsi berita Teknologi sangat kecil dibandingkan dengan yang lain, ini akan membuat model mengenali berita Teknologi agak sulit.
Sebelum menjelaskan dan membangun model, saya akan memberikan contoh prapemrosesan dengan membersihkan teks, menghapus kata-kata berhenti, dan menerapkan lemmatisasi. Saya akan menulis fungsi dan menerapkannya ke seluruh kumpulan data.
'''Preprocess a string.:parameter:param text: string - name of column containing text:param lst_stopwords: list - list of stopwords to remove:param flg_stemm: bool - whether stemming is to be applied:param flg_lemm: bool - whether lemmitisation is to be applied:returncleaned text'''def utils_preprocess_text(text, flg_stemm=False, flg_lemm=True, lst_stopwords=None):## clean (convert to lowercase and remove punctuations andcharacters and then strip)text = re.sub(r'[^\w\s]', '', str(text).lower().strip())## Tokenize (convert from string to list)lst_text = text.split()## remove Stopwordsif lst_stopwords is not None:lst_text = [word for word in lst_text if word not inlst_stopwords]## Stemming (remove -ing, -ly, ...)if flg_stemm == True:ps = nltk.stem.porter.PorterStemmer()lst_text = [ps.stem(word) for word in lst_text]## Lemmatisation (convert the word into root word)if flg_lemm == True:lem = nltk.stem.wordnet.WordNetLemmatizer()lst_text = [lem.lemmatize(word) for word in lst_text]## back to string from listtext = " ".join(lst_text)return text
Bag Of Words
Model Bag-of-Words sederhana: ia membangun kosakata dari korpus dokumen dan menghitung berapa kali kata-kata itu muncul di setiap dokumen. Dengan kata lain, setiap kata dalam kosakata menjadi fitur dan dokumen diwakili oleh vektor dengan panjang kosakata yang sama ("sekantong kata"). Misalnya, mari kita ambil 3 kalimat dan mewakilinya dengan pendekatan ini:
Seperti yang dapat Anda bayangkan, pendekatan ini menyebabkan masalah dimensi yang signifikan: semakin banyak dokumen yang Anda miliki, semakin besar kosakatanya, sehingga matriks fitur akan menjadi matriks yang sangat jarang. Oleh karena itu, model Bag-of-Words biasanya didahului dengan preprocessing penting (word cleaning, stop words removal, stemming/lemmatization) yang bertujuan untuk mengurangi masalah dimensi.
Istilah frekuensi belum tentu merupakan representasi terbaik untuk teks. Bahkan, Anda dapat menemukan di korpus kata-kata umum dengan frekuensi tertinggi tetapi sedikit kekuatan prediktif atas variabel target. Untuk mengatasi masalah ini ada varian lanjutan dari Bag-of-Words yang, alih-alih penghitungan sederhana, menggunakan istilah frekuensi–frekuensi dokumen terbalik (atau Tf–Idf). Pada dasarnya, nilai suatu kata meningkat secara proporsional untuk dihitung, tetapi berbanding terbalik dengan frekuensi kata dalam korpus.
Mari kita mulai dengan Rekayasa Fitur, proses untuk membuat fitur dengan mengekstrak informasi dari data. Saya akan menggunakan vectorizer Tf-Idf dengan batas 10.000 kata (jadi panjang kosakata saya adalah 10k), menangkap unigram (yaitu "baru" dan "york") dan bigram (yaitu "new york"). Saya akan memberikan kode untuk vectorizer hitungan klasik juga:
## Count (classic BoW)
vectorizer = feature_extraction.text.CountVectorizer(max_features=10000, ngram_range=(1,2))
## Tf-Idf (advanced variant of BoW)
vectorizer = feature_extraction.text.TfidfVectorizer(max_features=10000, ngram_range=(1,2))
Now I will use the vectorizer on the preprocessed corpus of the train set to extract a vocabulary and create the feature matrix.
corpus = dtf_train["text_clean"]
vectorizer.fit(corpus)
X_train = vectorizer.transform(corpus)
dic_vocabulary = vectorizer.vocabulary_
The feature matrix X_train has a shape of 34,265 (Number of documents in training) x 10,000 (Length of vocabulary) and it’s pretty sparse:
sns.heatmap(X_train.todense()[:,np.random.randint(0,X.shape[1],100)]==0, vmin=0, vmax=1, cbar=False).set_title('Sparse Matrix Sample')
In order to know the position of a certain word, we can look it up in the vocabulary:
word = "new york"
dic_vocabulary[word]
If the word exists in the vocabulary, this command prints a number N, meaning that the Nth feature of the matrix is that word.
Post a Comment for "Text Classification with NLP: Tf-Idf vs Word2Vec vs BERT"