<jupyter_start><jupyter_text>http://tau-data.id/umi/   Modul 07: PendahuluanText Mining I(C) <NAME> - 2019tau-data Indonesia ~ https://tau-data.id ~ <EMAIL>  Pendahuluan Text Mining I: Natural Language Processing & Text Preprocessing  Workshop Schedule Hari ke-4 (Kamis, 30 Jan 2020)**Pendahuluan Natural Language Processing & Text PreProcessing*** 09:00 – 11:00 Text Preprocessing* 11:00 – 12:00	Crawling, Streaming, Scraping* 13:00 – 14:00	Text Analytics* 14:00 – 15.00	Sentiment Analysis* 15:00 – 16.00	Latihan Text Analytics dan Sentiment Analysis Studi Kasus: **Text Analytics data media sosial perbincangan agama di media sosial**  Outline Bahasan NLP :* Tokenisasi* Stemming dan Lemma* Pos tag * WordNet dan WSD  TokenisasiTokenisasi adalah pemisahan kata, simbol, frase, dan entitas penting lainnya (yang disebut sebagai token) dari sebuah teks untuk kemudian di analisa lebih lanjut. Token dalam NLP sering dimaknai dengan &quot;sebuah kata&quot;, walau tokenisasi juga bisa dilakukan ke kalimat, paragraf, atau entitas penting lainnya (misal suatu pola string DNA di Bioinformatika).Mengapa perlu tokenisasi?	Langkah penting dalam preprocessing, menghindari kompleksitas mengolah langsung pada string asal.	Menghindari masalah (semantic) saat pemrosesan model-model natural language.	Suatu tahapan sistematis dalam merubah unstructured (text) data ke bentuk terstruktur yang lebih mudah di olah.[Image Source] Tokenisasi dengan modul NLTKKelebihan:	Well established dengan dukungan bahasa yang beragam	Salah satu modul NLP dengan fungsi terlengkap, termasuk WordNet	Free dan mendapat banyak dukungan akademis.Kekurangan:	&quot;Tidak support&quot;&nbsp;bahasa Indonesia	Murni Python: relatif lebih lambathttps://www.nltk.org/<jupyter_code>import nltk

T = "Hello, Mr. Man. He smiled!! This, i.e. that, is it."
Word_Tokens = nltk.word_tokenize(T)
print(Word_Tokens) # tokenisasi kata
# Bandingkan jika menggunakan fungsi split di Python, apakah bedanya? 
print(T.split())
# Apakah kesimpulan yang bisa kita tarik?
Sentence_Tokens = nltk.sent_tokenize(T)
print(Sentence_Tokens) # Tokenisasi kalimat
# Perhatikan hasilnya, ada berapa kalimat yang di deteksi? setuju?
T = "how are you\n are you okay?"
print(T)
Sentence_Tokens = nltk.sent_tokenize(T)
print(Sentence_Tokens)<jupyter_output>how are you
 are you okay?
['how are you\n are you okay?']<jupyter_text>Diskusi/Latihan:	Apakah tanda baca seperti &quot;?&quot; atau &quot;!&quot; akan memisahkan kalimat?	Apakah tanda &quot;carriage return&quot;/enter/ganti baris memisahkan kalimat?	Apakah &quot;;&quot; memisahkan kalimat?	Apakah tanda dash &quot;-&quot; memisahkan kata? Dalam bahasa Indonesia/Inggris?Tips: Perhatikan bentuk struktur data &quot;output&quot; dari tokenisasi NLTK.Catatan: pindah baris di Python string bisa dilakukan dengan menggunakan symbol &quot;\n&quot;Contoh:<jupyter_code>Txt = "Baris Pertama\nBaris Kedua"
print(Txt)
# Jawaban Latihan di cell ini
# Tekan tombol "ctrl + enter" untuk menjalankan cell-nya
Txt = '...'<jupyter_output><empty_output><jupyter_text>Tokenisasi dengan modul SpacyKelebihan:	Di claim lebih cepat (C-based)	License termasuk untuk komersil	Dukungan bahasa yang lebih banyak dari NLTK (termasuk bahasa Indonesia*)Kekurangan:	Fungsi yang lebih terbatas (dibandingkan NLTK).	Karena berbasis compiler, sehingga instalasi cukup menantang.https://spacy.io/<jupyter_code># Contoh tokenisasi menggunakan Spacy
from spacy.lang.en import English
nlp_en = English()

T = "Hello, Mr. Man. He smiled!! This, i.e. that, is it."
nlp = nlp_en(T)
for token in nlp:
    print(token.text, end =', ')
nlp_en.add_pipe(nlp_en.create_pipe('sentencizer')) # New in latest Spacy

nlp = nlp_en(T)
for kalimat in nlp.sents:
    print(kalimat)
list(range(3))<jupyter_output><empty_output><jupyter_text>Diskusi/Latihan:	Apakah hasil tokenisasi Spacy = NLTK? Mengapa?	Lakukan latihan seperti yang dilakukan sebelumnya dengan modul NLTK, apakah hasilnya sama dengan Spacy?Catatan: Contoh sederhana ini menekankan perbedaan ilmu linguistik dan computational linguistic.  Tokenisasi dengan  TextBlobKelebihan:	Sederhana &amp; mudah untuk digunakan/pelajari.	Textblob objects punya behaviour/properties yang sama dengan string di Python.	TextBlob dibangun dari kombinasi modul NLTK dan (Clips) PatternKekurangan:	Tidak secepat Spacy dan NLTK	Language Model terbatas: English, German, French*Blob : Binary large Object<jupyter_code># Tokenizing di TextBlob
from textblob import TextBlob

T = "Hello, Mr. Man. He smiled!! This, i.e. that, is it."
print(TextBlob(T).words)
kalimatS = TextBlob(T).sentences
print([str(kalimat) for kalimat in kalimatS])<jupyter_output>['Hello, Mr. Man.', 'He smiled!!', 'This, i.e.', 'that, is it.']<jupyter_text>Diskusi/Latihan:	Ada yang berbeda dari hasilnya?&nbsp;Apakah lebih baik seperti ini?Tips: TextBlob biasa digunakan untuk prototyping pada data yang tidak terlalu besar.Catatan: Hati-hati tipe data Blob tidak biasa (objek).<jupyter_code># Saat melakukan coding di Python, selalu perhatikan "tipe data" yang dihasilkan oleh modul.
A = TextBlob(T).sentences
B = TextBlob(T).words
print(A[0], type(A[0]))
print(B[0], type(B[0]))
# Apakah bedanya dengan tipe data str biasa di python?
C = B[0] # <class 'textblob.blob.Word'>
D = 'teks' # tipe string biasa di Python
# "properties" Blob word
print(dir(C))
# "properties" string di Python
print(dir(D))<jupyter_output>['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']<jupyter_text>Tokenisasi tidak hanya language dependent, tapi juga environment dependentTokenization sebenarnya tidak sesederhana memisahkan berdasarkan spasi dan removing symbol. Sebagai contoh dalam bahasa Jepang/Cina/Arab suatu kata bisa terdiri dari beberapa karakter.[Image Source]<jupyter_code># Contoh Tokenizer untuk twitter
from nltk.tokenize import TweetTokenizer

Tokenizer = TweetTokenizer(strip_handles=False, reduce_len=False)
tweet = "@Kirana_Sutanto I am so happpppppppy"
print(Tokenizer.tokenize(tweet))

# Masih salah (i.e. "happpy"), nanti kita akan perbaiki ini dengan "spell check"
# catatan: pada permasalahan "Sentiment analysis" kata yang ditulis panjang seperti diatas 
# bisa mengindikasikan sentiment yang kuat<jupyter_output>['@Kirana_Sutanto', 'I', 'am', 'so', 'happpppppppy']<jupyter_text>Tokenisasi (NLP) Bahasa Indonesia:NLTK belum support Bahasa Indonesia, bahkan module NLP Python yang support bahasa Indonesia secara umum masih sangat langka. Beberapa resources yang dapat digunakan:	KirraLabs: Mix of NLP-TextMining resources	Sastrawi 1.0.1:&nbsp;untuk &quot;stemming&quot; &amp;&nbsp;stopwords&nbsp;bahasa Indonesia.	Daftar Kata Dasar Indonesia:&nbsp;Bisa di load sebagai dictionary di Python	Wiktionary: ProyekWiki bahasa Indonesia [termasuk Lexicon]	WordNet Bahasa Indonesia: Bisa di load&nbsp;sebagai dictionary (atau NLTK*) di Python.	Daftar Kata Baku-Tidak Baku: Bisa di load sebagai dictionary di Python.	Spacy: Cepat/efisien, MIT License, tapi language model Indonesia masih terbatas.	UdPipe: Online request &amp; restricted license (support berbagai bahasa -&nbsp;pemrograman).<jupyter_code># Contoh Tokenisasi dalam bahasa Indonesia dengan Spacy
from spacy.lang.id import Indonesian
nlp_id = Indonesian()  # Language Model

teks = 'Sore itu, Hamzah melihat kupu-kupu di taman. Ibu membeli oleh-oleh di pasar'
tokenS_id = nlp_id(teks)
#T = []
#for token in tokenS_id:
#    T.append(token)
print([t for t in tokenS_id])
A = []
for i in range(7):
    A.append(i)
A
[i for i in range(7)] # list comprehension
# Jika menggunakan Language model English:
tokenS_en = nlp_en(teks)
print([token.text for token in tokenS_en])<jupyter_output>['Sore', 'itu', ',', 'Hamzah', 'melihat', 'kupu', '-', 'kupu', 'di', 'taman', '.', 'Ibu', 'membeli', 'oleh', '-', 'oleh', 'di', 'pasar']<jupyter_text>Word Case (Huruf BESAR/kecil):	Untuk menganalisa makna (semantic) dari suatu (frase) kata dan mencari informasi dalam proses textmining, seringnya (*) kita tidak membutuhkan informasi huruf besar/kecil dari kata&nbsp;tersebut.	Text case normaliation dapat dilakukan pada string secara efisien tanpa melalui tokenisasi (mengapa?).	Namun, bergantung pada analisa teks yang akan digunakan pengguna harus berhati-hati dengan urutan proses (pipelining) dalam preprocessing. Mengapa dan apa contohnya?(*) Coba temukan minimal 2 pengecualian dimana&nbsp; huruf kapital/kecil (case) mempengaruhi makna/pemrosesan teks.<jupyter_code># Ignore case (huruf besar/kecil)
T = "Hi there!, I am a student. Nice to meet you :)"
print(T.lower())
print(T.upper())
# Perintah ini sangat efisien karena hanya merubah satu bit di setiap (awal) bytes dari setiap karakter
# Sehingga tetap efisien jika ingin dilakukan sebelum tokenisasi<jupyter_output>hi there!, i am a student. nice to meet you :)
HI THERE!, I AM A STUDENT. NICE TO MEET YOU :)<jupyter_text>Morphological-Linguistic Normalization: Stemming &amp; Lemmatization(Canonical Representation)  Stemming dan Lemma		Stemmer&nbsp;akan menghasilkan sebuah bentuk kata yang disepakati oleh suatu sistem tanpa mengindahkan konteks kalimat. Syaratnya beberapa kata dengan makna serupa hanya perlu dipetakan secara konsisten ke sebuah kata baku.&nbsp;Banyak digunakan di IR &amp;&nbsp;komputasinya relatif sedikit. Biasanya dilakukan dengan menghilangkan imbuhan (suffix/prefix).			lemmatisation akan menghasilkan kata baku (dictionary word) dan bergantung konteks.			Lemma &amp; stemming bisa jadi sama-sama menghasilkan suatu akar kata (root word). Misal : Melompat ==&gt; lompat	 Mengapa melakukan Stemming &amp; Lemmatisasi?	Sering digunakan di IR (Information Retrieval) agar ketika seseorang mencari kata tertentu, maka seluruh kata yang terkait juga diikutsertakan.	Misal:&nbsp;organize,&nbsp;organizes, and&nbsp;organizing&nbsp;&nbsp;dan&nbsp;democracy,&nbsp;democratic, and&nbsp;democratization.	Di Text Mining Stemming dan Lemmatisasi akan mengurangi dimensi (mengurangi variasi morphologi), yang terkadang akan meningkatkan akurasi.	Tapi di IR efeknya malah berkebalikan: meningkatkan recall, tapi menurunkan akurasi&nbsp;[Link]. Contoh: kata&nbsp;operate, operating, operates, operation, operative, operatives, dan operational&nbsp;jika di stem menjadi operate, maka ketika seseorang mencari &quot;operating system&quot;, maka entry seperti&nbsp;operational and research dan&nbsp;operative and dentistry&nbsp;akan muncul sebagai entry dengan relevansi yang cukup tinggi. Stemming tidak perlu &quot;benar&quot;, hanya perlu konsisten. Sehingga memiliki berbagai variansi, (sebagian) contoh di NLTK:<jupyter_code># Contoh Stemming di NLTK
from nltk.stem.lancaster import LancasterStemmer
from nltk.stem.porter import PorterStemmer
from nltk.stem.snowball import SnowballStemmer

T = 'presumably I would like to MultiPly my provision, saying tHat without crYing'
print('Sentence: ',T)

StemmerS = [LancasterStemmer, PorterStemmer, SnowballStemmer] 
Names = ['Lancaster', 'Porter', 'SnowBall']

for stemmer_name,stem in zip(Names,StemmerS):
    if stemmer_name == 'SnowBall':
        st = stem('english')
    else:
        st = stem()
        
    print(stemmer_name,': ',' '.join(st.stem(t) for t in T.split()))
# perhatikan, kita tidak melakukan case normalization (lowercase) 
# Hasil stemming bisa tidak bermakna
# Contoh Lemmatizer di NLTK
from nltk.stem import WordNetLemmatizer

lemmatizer = WordNetLemmatizer()
T = "apples and oranges are similar. boots and hippos aren't, don't you think?"
print('Sentence: ', T)
print('Lemmatize: ',' '.join(lemmatizer.lemmatize(t) for t in T.split()))
# Lemma case sensitive. Dengan kata lain string harus diubah ke dalam bentuk huruf kecil (lower case)
# Lemmatizer menggunakan informasi pos. "pos" (part-of-speech) akan dibahas di segmen berikutnya
print(lemmatizer.lemmatize("better", pos="a")) # adjective
print(lemmatizer.lemmatize("better", pos="v")) # verb
# TextBlob Stemming & Lemmatizer
from textblob import Word
# Stemming
print(Word('running').stem()) # menggunakan NLTK Porter stemmer

# Lemmatizer
print(Word('went').lemmatize('v'))

# default Noun, plural akan menjadi singular dari akar katanya
# Juga case sensitive
# Spacy Lemmatizer English
E = "I am sure Apples and oranges are similar. Boots and hippos aren't, don't you think?"
en = nlp_en(E)
print( ' '.join( k.lemma_ for k in en ) )

# Perhatikan huruf besar/kecil
A = ['apa', 'kabar', 'hari', 'ini?']
print(A)
print(' '.join(A))
# Spacy Lemmatizer Indonesia
I = "perayaan itu mengurus dengan saat kita menonton ke Jogjakarta"
idn = nlp_id(I)
print( ' '.join( k.lemma_ for k in idn ) )
# Hati-hati huruf besar/kecil<jupyter_output>raya itu urus dengan saat kita tonton ke Jogjakarta<jupyter_text>Spacy "tidak" (bukan belum) support Stemming:[Image Source]<jupyter_code># Lemmatizer dengan Sastrawi
from Sastrawi.Stemmer.StemmerFactory import StemmerFactory
stemmer = StemmerFactory().create_stemmer()

I = "perayaan itu Berbarengan dengan saat kita bepergian ke Makassar"
print(stemmer.stem(I))
print(stemmer.stem("Perayaan Bepergian Menyuarakan"))
# Ada beberapa hal yang berbeda antara Sastrawi dan modul-modul diatas.
# Apa sajakah?<jupyter_output>raya itu bareng dengan saat kita pergi ke makassar
raya pergi suara<jupyter_text>Tips:	Secara umum &39;biasanya&39; di Text Mining yang kita butuhkan hanyalah Lemma.	&quot;Kecuali&quot; di aplikasi IR, spelling correction, variasi kata, clustering, atau terkadang klasifikasi. Pada aplikasi-aplikasi tersebut stemming terkadang lebih diinginkan.	Stemming jauh lebih cepat, tapi tidak selalu tersedia di modul NLP.	Beberapa algoritma tertentu membutuhkan tanda &quot;.&quot; dan &quot;,&quot; : contohnya untuk document summarization di textRank.	&quot;_&quot; juga biasa digunakan untuk menyatakan frase kata di representasi n-grams (misal &quot;buah_tangan&quot;).	Stemming juga digunakan pada Word Sense Disambiguation (WSD)Diskusi:	Untuk menghemat storage database, apakah sebaiknya kita menyimpan saja hasil preprocessed texts/documents?  Part-of-Speech (pos) di ilmu bahasa (Linguistik)[image source]<jupyter_code># POS tags in NLTK (English)
import nltk
T = 'I am currently learning NLP in English, but if possible I want to know NLP in Indonesian language too'

nltk_tokens = nltk.word_tokenize(T)
print(nltk.pos_tag(nltk_tokens))
# Tidak lagi hanya 9 macam tags seperti yang dibahas ahli bahasa (linguist)
Z = nltk.pos_tag(nltk_tokens)
Z[-1]
A = [2,3,9]
B = [2, 5, 3, 9, 7, 8, 1]

[x for x in B if x in A]
Z
# filtering berdasarkan "pos"
pos = ['NN','JJ']
hasil = []
for pt in Z:
    if pt[1] in pos:
        hasil.append(pt[0])
hasil
[h[0] for h in Z if h[1] in pos]
# Penggunaan di text mining jika suatu kata ingin dibedakan jika berbeda pos
hasil = []
for pt in Z:
    hasil.append(pt[0]+'_'+pt[1])
print(hasil)<jupyter_output>['I_PRP', 'am_VBP', 'currently_RB', 'learning_VBG', 'NLP_NNP', 'in_IN', 'English_NNP', ',_,', 'but_CC', 'if_IN', 'possible_JJ', 'I_PRP', 'want_VBP', 'to_TO', 'know_VB', 'NLP_NNP', 'in_IN', 'Indonesian_JJ', 'language_NN', 'too_RB']<jupyter_text>Daftar NLTK pos-tags:[image source]<jupyter_code># Pos tags in TextBlob (English)
for word, pos in TextBlob(T).tags:
    print(word, pos, end=', ')
# Pos Tag Spacy English
#from spacy.lang.en import English
#nlp_en = English()
import spacy
nlp_en = spacy.load('en_core_web_sm')

tokens = nlp_en(T)
for tok in tokens:
    print(tok, tok.tag_, end = ', ')
# Spacy tidak perlu tabel pos tag ...  bisa pakai perintah "explain"
spacy.explain('NNP')
# Daftar Lengkap: https://spacy.io/api/annotation#pos-tagging
# Pos Tags in Spacy - Bahasa Indonesia?

Ti = "Saat bepergian ke Jogjakarta jangan lupa membeli oleh-oleh"
Teks = nlp_id(Ti)
for token in Teks:
    print(token.lemma_, token.tag_)
# Fungsi pos-tags belum tersedia untuk bahasa indonesia .. :(
# Pos Tag Bahasa Indonesia lewat NLTK
# https://yudiwbs.wordpress.com/2018/02/20/pos-tagger-bahasa-indonesia-dengan-pytho/
from nltk.tag import CRFTagger
ct = CRFTagger()
ct.set_model_file('data/all_indo_man_tag_corpus_model.crf.tagger')

hasil = ct.tag_sents([['Saya','bekerja','di','Bandung']])
hasil = hasil[0]
print(hasil)
# Hati-hati dengan struktur data inputnya
hasil[0]
# pos tag Indonesia sederhana dari daftar kata
# Secara manual memuat kata dasar dan informasi pos-nya. 
# Catatan: tanpa "sense"/hierarchy/synonyms dan gagal untuk idioms (istilah)
import taudata as tau
kata_pos = tau.loadPos_id()

Teks = nlp_id(Ti)
for token in Teks:
    print(token.lemma_, end= ': ')
    try:
        print(kata_pos[token.lemma_], end= ', ')
    except:
        print('n', end= ', ') # default pos to noun seperti NLTK, Spacy, & TextBlob<jupyter_output>Saat: n, pergi: v, ke: pre, Jogjakarta: n, jangan: adv, lupa: v, beli: v, oleh-oleh: n,<jupyter_text>pip install --only-binary :all: mysqlclient<jupyter_code># Diskusi : kapan pakai pos tag: Topic Modelling, Summarization, Sentiment Analysis
# Contoh penggunaan pos-tag dengan hanya mengambil "Noun"
# Contoh penggunaan pos tag dengan menambahkan tag ke setiap kata<jupyter_output><empty_output><jupyter_text>Outline PreProcessing Data Text :	Review String di Python	Filtering (stopwords)	Replace slang/typos/singkatan    Spell Check	Machine translation	Reguler expression	Encodings    Latihan  Review Tipe Variabel di Python (string)<jupyter_code>a = 2.3 # Floating Point (tidak sama dengan bilangan Real)
b = 3.0   # Integer
c = True # T/F Boolean
d = 'python' # String
e = [a,b,c,d] # List
f = (a,b,c,d) # Tuple
g = set([a,b,c,d]) # Set
h = {'a':1, 'b':2, 7:'abc'} # Dictionary : keys, values, items
b = b/2
type(b)
# Tekan "d." lalu tekan tombol "tab"
#d.
# Sehingga kita bisa melakukan preprocessing dasar dengan string manipulation seperti berikut:
S = 'coba '
print(S)
print(S.strip())
print(S.replace("o","i"))
print(S.isalnum())
print(S.strip().isalnum()) # dsb
X = '764'
X.isdigit() 
help(X.isdecimal)
# String adalah Tuple, sehingga
S1 = 'apa '
S2 = 'kabar'
S1+S2
S2 = 'abcdefghijklmnopqrst'
S2[9:]
# String adalah Tuple sehingga bisa di akses seperti List
S = 'NLP dan TextMining di Python'
print('7 character pertama: ', S[:7])
print('7 character terakhir: ', S[-7:])
# Tapi hati-hati karena ia tuple maka:
try:
    S[5] = 'o'
except:
    print('Error, tuple tidak bisa dirubah nilainya (inplace)')
x = input('x = ')
try:
    print(1/int(x))
except:
    print('error')
print('sesuatu')<jupyter_output>x = 0
error
sesuatu<jupyter_text>Text Level Normalization: StopWordsDi Text Mining kata-kata yang sering muncul (dan jarang sekali muncul) memiliki sedikit sekali informasi (signifikansi) terhadap model (machine learning) yang digunakan. Hal ini di karenakan kata-kata tersebut muncul di semua kategori (di permasalahan klasifikasi) atau di semua cluster (di permasalahan pengelompokan/clustering). Kata-kata yang sering muncul ini biasa disebut &quot;StopWords&quot;. Stopwords berbeda-beda bergantung dari Bahasa dan Environment (aplikasi)-nya.Contoh:	Stopwords bahasa Inggris: am, is, are, do, the, of, etc.	Stopwords bahasa Indonesia: adalah, dengan, yang, di, ke, dsb	Stopwords twitter: RT, ...<jupyter_code># Loading Stopwords: Ada beberapa cara
import taudata as tau
from nltk.corpus import stopwords
from Sastrawi.StopWordRemover.StopWordRemoverFactory import StopWordRemoverFactory
factory = StopWordRemoverFactory()

NLTK_StopWords = stopwords.words('english')
Sastrawi_StopWords_id = factory.get_stop_words()
Personal_StopWords_en = [t.strip() for t in tau.LoadDocuments(file = 'data/stopwords_eng.txt')[0]]
Personal_StopWords_id = [t.strip() for t in tau.LoadDocuments(file = 'data/stopwords_id.txt')[0]]

print(NLTK_StopWords[:5])
print(Sastrawi_StopWords_id[:5])
print(Personal_StopWords_en[:5])
print(Personal_StopWords_id[:5])
print(len(Sastrawi_StopWords_id), len(Personal_StopWords_id), len(NLTK_StopWords), len(Personal_StopWords_en))<jupyter_output>['i', 'me', 'my', 'myself', 'we']
['yang', 'untuk', 'pada', 'ke', 'para']
['&gt', '&lt', '&nbsp', 'a', 'able']
['ada', 'adalah', 'adanya', 'adapun', 'agak']
126 755 179 2659<jupyter_text>Diskusi: Apakah sebaiknya kita menggunakan daftar stopwords bawaan modul atau custom milik kita sendiri?<jupyter_code># Tipe variabel memiliki aplikasi optimal yang berbeda-beda, misal
L = list(range(10**7))
S = set(range(10**7)) # selain unik dan tidak memiliki keterurutan, set memiliki fungsi lain.
%%timeit
9000000 in L
%%timeit
9000000 in S
# Tips: selalu rubah list stopwords ke bentuk set, karena di Python jauh lebih cepat untuk cek existence di set ketimbang list
NLTK_StopWords = set(NLTK_StopWords)
Sastrawi_StopWords_id = set(Sastrawi_StopWords_id)
Personal_StopWords_en = set(Personal_StopWords_en)
Personal_StopWords_id = set(Personal_StopWords_id)
St = ['ada', 'pesawat']
'Ada' in St
# Cara menggunakan stopwords
from textblob import TextBlob

T = "I am doing NLP at ITTC,... \
    adapun saya anu sedang belajar NLP di ITTC"
T = T.lower()
Personal_StopWords_id.add('anu')
Tokens = TextBlob(T).words # Tokenisasi 
T2 = [t for t in Tokens if t not in Personal_StopWords_id] # Sastrawi_StopWords_id Personal_StopWords_en Personal_StopWords_id
T2 = [t for t in T2 if t not in Personal_StopWords_en] # Sastrawi_StopWords_id Personal_StopWords_en Personal_StopWords_id
print(' '.join(T2))
# Catatan: Selalu lakukan Stopword filtering setelah tokenisasi (dan normalisasi).<jupyter_output>nlp ittc belajar nlp ittc<jupyter_text>[image source]  Menangani Slang atau Singkatan di Data Teks<jupyter_code># Sebuah contoh sederhana 
T = 'jangan ragu gan, langsung saja di order pajangannya.'
# Misal kita hendak mengganti setiap singkatan (slang) dengan bentuk penuhnya. 
# Dalam hal ini kita hendak mengganti 'gan' dengan 'juragan'
H = T.replace('gan','juragan')
print(H)
# Kita tidak bisa melakukan ini
D = {'yg':'yang', 'gan':'juragan'}
D['gan']
A = [2,5,1,3]

for i, a in enumerate(A):
    print(a, i)
# dengan tokenisasi
slangs = {'gan':'juragan', 'yg':'yang', 'dgn':'dengan'} #dictionary sederhana berisi daftar singkatan dan kepanjangannya

T = 'jangan ragu gan, langsung saja di order pajangan yg diatas.'
T = TextBlob(T).words
T
for i,t in enumerate(T):
    if t in slangs.keys():
        T[i] = slangs[t]
print(' '.join(T))
# Loading Slang dan Singkatan dari File
# Contoh memuat word fix melalui import file. 
slangS = tau.LoadDocuments(file = 'data/slang.dic')[0]
slangS 
slangS = [t.strip('\n').strip() for t in slangS]
print(slangS)
A = 'luv:love'
B = A.split(':')
B
A ='  apa  '
A.strip()
# pisahkan berdasarkan ':'
slangS = [t.split(":") for t in slangS]
slangS = [[k.strip(), v.strip()] for k,v in slangS]
print(slangS)
D = {} # dictionary kosong (inisialisasi)
for k,v in slangS:
    D[k]=v
D
s
# Test it!
tweet = 'I luv u say. serius gan!, tapi ndak tau kalau sesok.'
T = TextBlob(tweet).words

for i,t in enumerate(T):
    if t in slangS.keys():
        T[i] = slangS[t]
        
print(' '.join(T))<jupyter_output><empty_output><jupyter_text>Spell Check: Tujuan Spellcheck:		Cleaning Data		Word suggestions	OCR/hand writing (Image) recognition	Speech Recognition	Machine Translation<jupyter_code># aplikasi spell check di textBlob
from textblob import Word

w = Word('industri')
w.spellcheck()
w = Word('jaggan')
w.spellcheck()
# Kendalanya kalau Bahasa Indonesia ==> perlu pendekatan umum<jupyter_output><empty_output><jupyter_text>Norvig Spell Checker: Menggunakan Aturan Probabilitas Bayes&nbsp;<jupyter_code># http://norvig.com/spell-correct.html
# corpus = 'data/kata_dasar.txt'
print(tau.correction('industr1'))
print(tau.correction('jang4n'))
# prinsip yang sama kelak bisa diterapkan untuk n-grams dengan merubah karakter ==> kata<jupyter_output>industri
jangan<jupyter_text>Machine Language Detection and Translation[image Source]<jupyter_code>#Language Detection (TextBlob)
from textblob import TextBlob
T = "Aku ingin mengerti NLP dalam bahasa Inggris"
U = "opo iso mangan sa iki"
print(TextBlob(T).detect_language())
print(TextBlob(U).detect_language())
# Machine Translation (TextBlob)
# Butuh koneksi internet, limited calls. Error otherwise. Need "try" and "catch".
T = "Aku ingin mengerti NLP dalam bahasa Inggris. I love you"
print(TextBlob(T).translate(to='en'))
print(TextBlob(T).translate(to='ar-sa'))
print(TextBlob(T).translate(to='ja'))
# daftar kode bahasa : http://www.cardinalpath.com/resources/tools/google-analytics-language-codes/
# Perhatikan TextBlob secara automatis akan mendeteksi bahasa asal
# Kalau secara spesifik ingin translate dari suatu bahasa ke bahasa lain:
T = "Aku hanya ingin mengatakan : I Love you"
print(TextBlob(T).translate(from_lang ='id', to='en'))
print(TextBlob(T).translate(from_lang ='en', to='id'))<jupyter_output>I just want to say: I Love you
Aku hanya ingin mengatakan: I Love you<jupyter_text>Beberapa Reguler Expression yang sering digunakan di NLP/Text Mining	Menghilangkan/extract email	Menghilangkan/extract nomer telephone	Menghilangkan/extract URL di string.	Alpha Numeric filtering	Wild Card Search	Cleaning hashTags di Media Sosial<jupyter_code># Extracting atau replacing eMail.
import re
emailPattern = re.compile(r'[\w._%+-]+@[\w\.-]+\.[a-zA-Z]{2,4}')

txt = 'Contact kami di <EMAIL>, <EMAIL>, atau <EMAIL>'

print( re.sub(emailPattern, ' ', txt) )# clean email
eMailS = re.findall( emailPattern, txt )
print( 'email yang ditemukan: ', str(eMailS) )<jupyter_output>Contact kami di  ,  , atau  
email yang ditemukan:  ['<EMAIL>', '<EMAIL>', '<EMAIL>']<jupyter_text><jupyter_code># Pola telephone : \d penanda angka di reguler Expression, \s spasi, dan "|" adalah "atau"
# "?" menyatakan pilihan (optional): colou?r sesuai dengan colour atau color.

phonePattern = re.compile(r'(\d{3}[-\.\s]??\d{3}[-\.\s]??\d{4}|\(\d{3}\)\s*\d{3}[-\.\s]??\d{4}|\d{3}[-\.\s]??\d{4})')
txt = 'Contact kami di 021-7634562 atau 021-763-4562 atau 021 763 4562 atau 0822959020 atau +628199258688'
print(re.sub(phonePattern,'***',txt))# clean phone
    
noTelp = re.findall(phonePattern,txt)
print('Nomer telephone yang ditemukan: ',str(noTelp))
# Pola telephone 2: untuk setiap angka 8-14 digits dipisahkan oleh "spasi", "," atau "."
phonePattern = re.compile(r'\b\d{8,14}\b')
txt = 'Contact kami di 082295203040 atau +6282295203040'
print(re.sub(phonePattern,'***',txt))# clean phone
    
noTelp = re.findall(phonePattern,txt)

for no in noTelp:
    if no[0]!='0':
        print('+' + no)
    else:
        print(no)
#print('Nomer telephone yang ditemukan: ',str(noTelp))
# Website URLS http(s) .... untuk ftp trivial
urlPattern = re.compile(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+')

txt = 'website reguler expression & my site : https://www.regular-expressions.info/ & https://tau-data.id'
print(re.sub(urlPattern,' ',txt))# clean urls

URLs = re.findall(urlPattern,txt)# get URLs
print('URL yang ditemukan: ',str(URLs))
import time

time.sleep(5)
'Done'
# cleaning non alpha-numeric
txt = 'Hi! @Mukidi, apa kabar? #sapa_Pagi.'
print(re.sub(r'[^\w]',' ',txt))
# atau jika ingin exclude titik dan koma 
# re.sub(r'[^.,a-zA-Z0-9 \n\.]','',txt)
# alternative 2:
print(''.join([t for t in txt if t.isalnum() or t==' ']))
# ada perbedaan?<jupyter_output>Hi Mukidi apa kabar sapaPagi<jupyter_text><jupyter_code># Cleaning hashTags dalam posting media sosial
tweet = 'oh IoT, #AndaiSajaIaTahu #ApaYangAkuRasah... #AlayersTweet #d2d'

getHashtags = re.compile(r"#(\w+)")
print("Tags = {0}".format(re.findall(getHashtags, tweet)))
# temukan hanya tags ... perhatikan IoT bukan Tags walau ada huruf besar & kecil dalam satu kata
pisahtags = re.compile(r'[A-Z][^A-Z]*')

for tags in re.findall(getHashtags, tweet):
    print(re.findall(pisahtags, tags))
# Mengganti hashtags dengan kata dasar pembentuknya
tweet = 'oh IoT, #AndaiSajaIaTahu #ApaYangAkuRasah... #AlayersTweet'
tagS = re.findall(getHashtags, tweet)
for tag in tagS:
    proper_words = ' '.join(re.findall(pisahtags, tag))
    tweet = tweet.replace('#'+tag,proper_words)

print(tweet)
s = 'The25XYZ3abc'
re.split('(\d+)',s)<jupyter_output><empty_output><jupyter_text>Encoding-Decoding:	Hal berikutnya yang perlu diperhatikan dalam memproses data teks adalah encoding-decoding.	Contoh Encoding: ASCII, utf, latin, dsb.	saya membahas lebih jauh tetang encoding disini:&nbsp;	https://taufiksutanto.blogspot.co.id/2018/01/pereda-sakit-kepala-urgensi-memahami.html	Berikut adalah sebuah contoh sederhana tantangan proses encoding-decoding ketika kita hendak memproses data yang berasal dari internet atau media sosial.<jupyter_code># kita bisa menggunakan modul unidecode untuk mendapatkan representasi ASCII terdekat
from unidecode import unidecode

T = "ḊḕḀṙ ₲ØĐ, p̾l̾e̾a̾s̾e ḧḕḶṖ ṁḕ"
print(unidecode(T).lower())
# Bahasa Indonesia dan Inggris secara umum mampu direpresentasikan dalam encoding ASCII: 
# https://en.wikipedia.org/wiki/ASCII
# Kita juga bisa membersihkan posting media sosial/website dengan entitas html menggunakan fungsi "unescape" di modul "html"
from html import unescape

print(unescape('Satu &lt; Tiga&nbsp;&amp; &#169; adalah simbol Copyright'))
def pungsi(x,y):
    z=x**y
    return z

pungsi(2,3)<jupyter_output><empty_output><jupyter_text>Latihan 1:Diberikan&nbsp;tweet berikut:tweet&nbsp;=&nbsp; &quot;The OctopiPower is &amp;gt; Sharks! &amp;amp; they&39;re awsm! So happy to see them here http://www.octopusVSshark.com !&quot;preprocess tweet diatas sehingga didapatkan tweet seperti ini (Gunakan sembarang modul yang mendukung):tweet= &quot;the octopus power is &gt; shark ! &amp; they are awesome ! so happy to see them here !&quot;Petunjuk/Hints:	Buat satu atau lebih fungsi untuk memudahkan, misal fungsi fixTags dan cleanText.	fix kata &quot;they&39;re&quot; dan awsm dengan teknik sederhana dictionary fix.	Hati-hati terhadap urutan aksi di preprocessing karena akan mengakibatkan hasil yang berbeda.	Kelak di segmen berikutnya urutan aksi ini akan disebut sebagai &quot;Pipelining&quot;.	Code solusi latihan ini dengan dasar fikiran bahwa solusinya nanti akan bisa digunakan untuk sembarang preprocessing.	At this point, jangan hawatirkan dulu scalability/efisiensi.<jupyter_code>%time
# Coba jawaban Latihan [1] di cell ini: 
# Salah satu contoh jawaban latihan ini ada di cell paling bawah. 
# Namun coba untuk tidak melihat jawaban tersebut<jupyter_output><empty_output><jupyter_text>Latihan 2:Bagaimana caranya memfilter kata-kata (token) yang terdiri dari huruf dan angka (misal b29nf, _24x_,&nbsp;dsb)?<jupyter_code>%time
# Coba jawaban Latihan [2] di cell ini: 
# Salah satu contoh jawaban latihan ini ada di cell paling bawah. 
# Namun coba untuk tidak melihat jawaban tersebut
T = 'pesawat b29 dan mig276 adalah kepunyaan fhg347x dan _24x_'
# Harapan jawaban T = 'pesawat dan adalah kepunyaan dan'
# Petunjuk: gunakan property "isalpha" pada variabel string di Python.<jupyter_output><empty_output><jupyter_text>Outline Representasi Dokumen :* Loading documents (text data): pdf, json, csv, xls, url, doc, Datasets Modul* Representasi Sparse (VSM): Binary, tf &amp;-/ idf, Custom tf-idf, BM25* Frequency filtering, n-grams, vocabulary based* Representasi Dense:&nbsp;Word Embedding (Word2Vec dan FastText)* Tensor to Matrix representation untuk model Machine Learning di Text Mining  Loading Documents (Text Data)[Image Source] me-load file teks dapat dilakukan dengan berbagai cara, bergantung format dokumen. Misal:PDF(file).string  file pdf menggunakan modul patterndocx2txt.process(file)  file docx emnggunakan modul docx2txtopen(file,&quot;r&quot;,encoding=&quot;utf-8&quot;, errors=&39;replace&39;)  text file dengan Python &quot;open&quot;bz2(file, &quot;r&quot;)  untuk file text terkompresi menggunakan modul BZ2Catatan: encoder/parser diatas memiliki keterbatasan masing-masing.Berikut ini contoh import beberapa file dokumen sekaligus dari folder .&39;data&39;<jupyter_code># Gunakan Fungsi LoadDocuments untuk 
import taudata as tau

dPath = 'data/'
Docs, Files = tau.LoadDocuments(dPath,types=['txt','bz2','csv']) 
# csv is supported but imported as dataframe
print(Files)
# Contoh mengakses isi file
print(Docs[0])
# Fungsinya juga bisa digunakan untuk me-load satu dokumen saja
Doc = tau.LoadDocuments(file = 'data/Shakespeare_Hamlet.txt')[0]
print(Doc[-3:]) 
# Satu baris, satu elemen pada list.
# Menghitung distribusi frekuensi di dokumen hamlet
kata, frekuensi = tau.countWords(Doc) # frekuensi terurut descending
print('Total Token = {0}'.format(len(kata)))
print('contoh Token & frekuensinya:{0}'.format([(k,f) for k,f in zip(kata,frekuensi)][:5]))
# Plot Bar Chart frekuensi 100 Tokens pertama
tau.barChart(kata,frekuensi,N=100)<jupyter_output><empty_output><jupyter_text>Modul Python lain untuk Parsing Document: &quot;TextRact&quot;* https://textract.readthedocs.io/   Load data teks dari halaman website<jupyter_code>import urllib.request
from bs4 import BeautifulSoup as bs

URL = 'http://ittc.uad.ac.id'
Doc = urllib.request.urlopen(URL).read()
Doc = bs(Doc,'lxml').text
print(Doc)<jupyter_output>ITTC Universitas Ahmad Dahlan – Pelatihan IT untuk Kalangan Profesional dan Akademisi




			window._wpemojiSettings = {"baseUrl":"https:\/\/s.w.org\/images\/core\/emoji\/11\/72x72\/","ext":".png","svgUrl":"https:\/\/s.w.org\/images\/core\/emoji\/11\/svg\/","svgExt":".svg","source":{"concatemoji":"http:\/\/ittc.uad.ac.id\/wp-includes\/js\/wp-emoji-release.min.js?ver=5.0.3"}};
			!function(a,b,c){function d(a,b){var c=String.fromCharCode;l.clearRect(0,0,k.width,k.height),l.fillText(c.apply(this,a),0,0);var d=k.toDataURL();l.clearRect(0,0,k.width,k.height),l.fillText(c.apply(this,b),0,0);var e=k.toDataURL();return d===e}function e(a){var b;if(!l||!l.fillText)return!1;switch(l.textBaseline="top",l.font="600 32px Arial",a){case"flag":return!(b=d([55356,56826,55356,56819],[55356,56826,8203,55356,56819]))&&(b=d([55356,57332,56128,56423,56128,56418,56128,56421,56128,56430,56128,56423,56128,56447],[55356,57332,8203,56128,56423,8203,56128,56418,8203,56128,56421,8203,56128,56430,8203,5612[...]<jupyter_text>Json Files	Populer digunakan untuk data dari Media Sosial dan NoSQL	Portable: File Json memuat nama variabel dan nilainya (tidak seperti XML)	Plain Text	Schemaless: Setiap record tidak harus memiliki jumlah field yang tetap seperti csv	JSON isomorfis dengan &quot;Dictionary&quot; di Python	Contoh struktur file json:<jupyter_code># Contoh load JSON
import json

file = 'data/contoh.json'
f=open(file,encoding='utf-8', errors ='ignore', mode='r')
J=f.readlines()
f.close()
J
for i,t in enumerate(J):
    J[i] = json.loads(t.strip())
J[0]['nama']<jupyter_output><empty_output><jupyter_text>Loading Dataset dari Modulcontoh dataset dokumen yang cukup tenar: &quot;20 NewsGroup&quot;http://scikit-learn.org/stable/modules/generated/sklearn.datasets.fetch_20newsgroups.htmlsklearn.datasets.fetch_20newsgroupsCategories =&nbsp;[&39;alt.atheism&39;, &39;comp.graphics&39;, &39;comp.os.ms-windows.misc&39;, &39;comp.sys.ibm.pc.hardware&39;, &39;comp.sys.mac.hardware&39;, &39;comp.windows.x&39;, &39;misc.forsale&39;, &39;rec.autos&39;, &39;rec.motorcycles&39;, &39;rec.sport.baseball&39;, &39;rec.sport.hockey&39;, &39;sci.crypt&39;, &39;sci.electronics&39;, &39;sci.med&39;, &39;sci.space&39;, &39;soc.religion.christian&39;, &39;talk.politics.guns&39;, &39;talk.politics.mideast&39;, &39;talk.politics.misc&39;, &39;talk.religion.misc&39;]<jupyter_code># Warning: Butuh koneksi internet
from sklearn.datasets import fetch_20newsgroups

categories = ['sci.med', 'talk.politics.misc',  'rec.autos']
data = fetch_20newsgroups(subset='train', categories=categories,remove=('headers', 'footers', 'quotes'))
type(data)
# Ada baiknya data disimpan ke HardDisk, agar ketika kita perlu untuk me-load kembali
# Tidak perlu koneksi internet
import pickle

f = open('data/tdm2Apr.pckl', 'wb')
pickle.dump(data, f)
f.close()
'Done'
# Loading data dari "Pickle" dapat dilakukan dengan cara berikut
f = open('data/20newsgroups.pckl', 'rb')

data = pickle.load(f)
f.close()
'Done'
# Contoh cara mengakses datanya
print( type(data) )
print(dir(data))
print(data.data[0]) # Dokumen pertama
print(data.target_names[0]) # Dokumen pertama
print(data.DESCR)
# Rubah struktur data diatas ke dalam bentuk struktur data sederhana: "list of documents"
Y = data.target # List: 0 = class 1, 1 = class 2, ... dst
print('Contoh Label 3 dokumen pertama: ',Y[:3])
X = [doc for doc in data.data] # setiap elemen dalam list adalah dokumen<jupyter_output>Contoh Label 3 dokumen pertama:  [0 2 0]<jupyter_text>Vector Space Model - VSM 	Data yang biasanya kita ketahui berbentuk tabular (tabel/kolom-baris/matriks/array/larik), data seperti ini disebut data terstruktur (structured data).	Data terstruktur dapat disimpan dengan baik di&nbsp;spreadsheet&nbsp;(misal:&nbsp;Excel/CSV) atau basis data (database) relasional dan secara umum dapat digunakan langsung oleh berbagai model/tools&nbsp;statistik/data mining konvensional.	Sebagian data yang lain memiliki &ldquo;tags&rdquo; yang menjelaskan elemen semantik yang berbeda di dalamnya dan cenderung tidak memiliki skema (struktur) yang statis.	Data seperti ini disebut data&nbsp;semi-structured, contohnya data dalam bentuk &nbsp;XML.	Apa bedanya? Apa maksudnya tidak memiliki skema yang statis? Penjelasan mudahnya bayangkan sebuah data terstruktur (tabular), namun dalam setiap baris (record/instance)-nya tidak memiliki jumlah variabel (peubah) yang sama.	Tentu saja data seperti ini tidak sesuai jika disimpan dan diolah dengan&nbsp;tools/software&nbsp;yang mengasumsikan struktur yang statis pada setiap barisnya (misal: Excel dan SPSS). 	Data multimedia seperti teks, gambar atau video tidak dapat&nbsp;secara langsung&nbsp;dianalisa dengan model statistik/data mining.	Sebuah proses awal&nbsp;(pre-process)&nbsp;harus dilakukan terlebih dahulu untuk merubah data-data tidak (semi) terstruktur tersebut menjadi bentuk yang dapat digunakan oleh model statistik/data mining konvensional.	Terdapat berbagai macam cara mengubah data-data tidak terstruktur tersebut ke dalam bentuk yang lebih sederhana, dan ini adalah suatu bidang ilmu tersendiri yang cukup dalam. Sebagai contoh saja sebuah teks biasanya dirubah dalam bentuk vektor/topics&nbsp;terlebih dahulu sebelum diolah.	Vektor data teks sendiri bermacam-macam jenisnya: ada yang berdasarkan eksistensi (binary), frekuensi dokumen (tf), frekuensi dan invers jumlah dokumennya dalam corpus (tf-idf), tensor, dan sebagainya.	&nbsp;Proses perubahan ini sendiri biasanya tidak&nbsp;lossless, artinya terdapat cukup banyak informasi yang hilang. Maksudnya bagaimana? Sebagai contoh ketika teks direpresentasikan dalam vektor (sering disebut sebagai model bag-of-words) maka informasi urutan antar kata menghilang.&nbsp; Contoh bentuk umum representasi dokumen:Pada Model n-grams kolom bisa juga berupa frase. Document-Term Matrix : Vector Space Model - VSM   K = |d|<jupyter_code># Menggunakan modul SciKit untuk merubah data tidak terstruktur ke VSM
# Scikit implementation http://scikit-learn.org/stable/modules/feature_extraction.html

from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer

# http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html#sklearn.feature_extraction.text.CountVectorizer
# http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html#sklearn.feature_extraction.text.TfidfVectorizer
# VSM - "binari"
binary_vectorizer = CountVectorizer(binary = True, lowercase=True, stop_words='english')
binari = binary_vectorizer.fit_transform(X)
binari.shape # ukuran VSM
# Apakah "max_df" dan "min_df" ?
# MySQL menggunakan max_df = 0.5 (!!!)
# Sparse vectors/matrix
binari[0]
# Mengakses Datanya
print(binari[0].data)
print(binari[0].indices)
# Kolom dan term
print(str(binary_vectorizer.vocabulary_)[:93])
nama = ['udin', 'wati', 'budi']
umur = [12, 31, 22]

D = {n:u for n,u in zip(nama,umur)}
D['budi']
d = binary_vectorizer.vocabulary_
D = {k:v for v,k in d.items()}
# VSM term Frekuensi : "tf"
tf_vectorizer = CountVectorizer(binary = False, lowercase=True, stop_words='english')
tf = tf_vectorizer.fit_transform(X)

print(tf.shape) # Sama
print(tf[99].data) # Hanya data ini yg berubah
print(tf[0].indices) # Letak kolomnya tetap sama
d = tf_vectorizer.vocabulary_
d['car']
A = [2, 3, 7]
A.index(3)
sum(tf(:,4102))
# VSM term Frekuensi : "tf-idf"
tfidf_vectorizer = TfidfVectorizer(lowercase=True, stop_words='english')
tfidf = tfidf_vectorizer.fit_transform(X)

print(tfidf.shape) # Sama
print(tfidf[0].data) # Hanya data ini yg berubah
print(tfidf[0].indices) # Letak kolomnya berbeda, namun jumlah kolom dan elemennya tetap sama
# Making sure
print(tfidf_vectorizer.vocabulary_['car'])
print(tf_vectorizer.vocabulary_['car'])
# Yes, it's the same<jupyter_output><empty_output><jupyter_text>Hati-hati ... SciPy Vectorizer bisa menghasilkan Matriks dengan beberapa barisnya kosong.<jupyter_code># Pada contoh diatas:
baris_kosong = []
nBaris, nKolom = tfidf.shape
for i in range(nBaris):
    if sum(tfidf[i].data)==0:
        baris_kosong.append(i)
print('Jumlah baris kosong di VSM tfidf = ', len(baris_kosong))
print(baris_kosong)
# Mengapa ada baris kosong ini? ==> Diskusi<jupyter_output>Jumlah baris kosong di VSM tfidf =  61
[68, 71, 100, 144, 166, 168, 187, 192, 198, 239, 260, 265, 271, 276, 300, 407, 461, 483, 488, 489, 493, 529, 551, 583, 626, 661, 703, 743, 777, 786, 795, 807, 845, 870, 873, 875, 908, 911, 1017, 1025, 1062, 1098, 1105, 1129, 1135, 1140, 1158, 1203, 1217, 1277, 1287, 1369, 1463, 1467, 1473, 1506, 1512, 1526, 1552, 1570, 1645]<jupyter_text>Solusi?	Periksa terlebih dahulu baris-baris kosong tersebut. Penyebabnya bisa bermacam-macam: encoding, tokenizer (pattern), memang dokumennya kosong, dokumennya pendek dan hanya berisi stopwords, dsb.	Ignore: Exclude dokumen-dokumen tersebut dari analisis.	Separate analysis: Pisahkan terlebih dahulu dokumen-dokumen diatas, lalu analisa secara terpisah dengan parameter settings yang berbeda atau preprocessing yang berbeda.&nbsp;<jupyter_code># Contoh untuk di "ignore"
tfidf_nonZeroRows = tfidf[tfidf.getnnz(1)>0] # Remove Zero Rows
tfidf_nonZeroCols = tfidf[:,tfidf.getnnz(0)>0] # Remove Zero Columns. Becareful, it "might" change the VSM interpretation (word index)
tfidf_nonZeroRC = tfidf[tfidf.getnnz(1)>0][:,tfidf.getnnz(0)>0] # Remove Zero Rows and Columns
print(tfidf_nonZeroRows.shape, tfidf_nonZeroCols.shape, tfidf_nonZeroRC.shape)
# Jika jumlah kolom tidak berubah, maka interpretasi (index kata) VSM tidak berubah (aman :) ).
# Perintah ini sudah diimplementasikan di Fungsi ittc.IDF<jupyter_output>(1592, 22279) (1653, 22279) (1592, 22279)<jupyter_text>Custom tf-idf:* Menurut http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html* default formula tf-idf yang digunakan sk-learn adalah:* $tfidf = tf * log(\frac{N}{df+1})$ ==> Smooth IDF* namun kita merubahnya menjadi:* $tfidf = tf * log(\frac{N}{df})$ ==> Non Smooth IDF* $tfidf = tf * log(\frac{N}{df+1})$ ==> linear_tf, Smooth IDF* $tfidf = (1+log(tf)) * log(\frac{N}{df})$ ==> sublinear_tf, Non Smooth IDF<jupyter_code># VSM term Frekuensi : "tf-idf"
tfidf_vectorizer = TfidfVectorizer(smooth_idf= False, sublinear_tf=True, lowercase=True, stop_words='english')
tfidf = tfidf_vectorizer.fit_transform(X)
print(tfidf.shape) # Sama
print(tfidf[0].data) # Hanya data ini yg berubah
print(tfidf[0].indices) # Letak kolomnya = tfidf<jupyter_output>(1653, 22279)
[0.11389068 0.17884514 0.21429549 0.16488526 0.13190432 0.29976114
 0.1948156  0.10640536 0.16918467 0.14402551 0.39010977 0.15209175
 0.27505603 0.13095381 0.17736715 0.10115873 0.17304162 0.29976114
 0.29976114 0.29976114 0.23040512 0.11671129]
[21640  4102  2040 20134  9085 20943  3638  6919 11614  7992  2043 15805
 16413  6532 13231  9237  7433 17120  3984 14036 11933  7299]<jupyter_text>Best-Match Formula : BM25	di IR nilai b dan k yang optimal adalah :&nbsp; b = 0.75&nbsp; dan k = [1.2 - 2.0]&nbsp; &nbsp;	ref:&nbsp;<NAME>., <NAME>., &amp; <NAME>. &Uuml;. <NAME>. (2008). Introduction to information retrieval.&nbsp;An Introduction To Information Retrieval,&nbsp;151, 177.	Tapi kalau untuk TextMining (clustering) nilai k optimal adalah 20, nilai b = sembarang (boleh = 0.75)	ref:&nbsp;<NAME>., &amp; <NAME>. (2011). Improving document clustering using Okapi BM25 feature weighting.&nbsp;Information retrieval,&nbsp;14(5), 466-487.	avgDL adalah rata-rata panjang dokumen di seluruh dataset dan DL adalah panjang dokumen D.	hati-hati, ini berbeda dengan &nbsp;tf-idf MySQL diatas.<jupyter_code>bm25_ = tau.BM25(tf,tfidf)
bm25_[0].data<jupyter_output><empty_output><jupyter_text>Zipf&39;s Law: &quot;power law&quot; :	https://plus.maths.org/content/mystery-zipf	https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4176592/<jupyter_code># Frequency Filtering di VSM
tfidf_vectorizer = TfidfVectorizer()
tfidf_1 = tfidf_vectorizer.fit_transform(X)

tfidf_vectorizer = TfidfVectorizer(max_df=0.75, min_df=5)
tfidf_2 = tfidf_vectorizer.fit_transform(X)

print(tfidf_1.shape)
print(tfidf_2.shape)<jupyter_output>(1653, 22578)
(1653, 4709)<jupyter_text>Alasan melakukan filtering berdasarkan frekuensi:* Intuitively filter noise * Curse of Dimensionality (akan dibahas kemudian)* Computational Complexity* Improving accuracy<jupyter_code># Variasi pembentukan matriks VSM:
d1 = '@udin76, Minum kopi pagi-pagi sambil makan pisang goreng is the best'
d2 = 'Belajar NLP dan Text Mining ternyata seru banget sadiezz'
d3 =  'Sudah lumayan lama bingits tukang Bakso belum lewat'
d4 = 'Aduh ga banget makan Mie Ayam p4k4i kesyap, please deh'

D = [d1, d2, d3, d4]
# Jika kita menggunakan cara biasa: 
tfidf_vectorizer = TfidfVectorizer()
vsm = tfidf_vectorizer.fit_transform(D)
print(tfidf_vectorizer.vocabulary_)

# N-Grams VSM
# Bermanfaat untuk menangkap frase kata, misal: "ga banget", "pisang goreng", dsb
tfidf_vectorizer = TfidfVectorizer(ngram_range=(1, 2))
vsm = tfidf_vectorizer.fit_transform(D)
print(tfidf_vectorizer.vocabulary_)
# Vocabulary based VSM
# Bermanfaat untuk menghasilkan hasil analisa yang "bersih"
# variasi 2
d1 = '@udin76, Minum kopi pagi-pagi sambil makan pisang goreng is the best'
d2 = 'Belajar NLP dan Text Mining ternyata seru banget sadiezz'
d3 =  'Sudah lumayan lama bingits tukang Bakso belum lewat seru'
d4 = 'Aduh ga banget makan Mie Ayam p4k4i kesyap, please deh'
D = [d1,d2,d3,d4]
Vocab = {'seru banget':0, 'seru':1, 'the best':2, 'lama':3, 'text mining':4, 'nlp':5, 'ayam':6}
tf_vectorizer = CountVectorizer(binary = False, vocabulary=Vocab)
tf = tf_vectorizer.fit_transform(D)
print(tf.toarray())
tf_vectorizer.vocabulary_
Vocab = {'seru banget':0, 'the best':1, 'lama':2, 'text mining':3, 'nlp':4, 'ayam':5}
tfidf_vectorizer = TfidfVectorizer(max_df=1.0, min_df=1, lowercase=True, vocabulary=Vocab)
vsm = tfidf_vectorizer.fit_transform(D)
print(tfidf_vectorizer.vocabulary_)
# VSM terurut sesuai definisi dan terkesan lebih "bersih"
# Perusahaan besar biasanya memiliki menggunakan teknik ini dengan vocabulary yang comprehensif
# Sangat cocok untuk Sentiment Analysis<jupyter_output><empty_output><jupyter_text>Latihan: bentuk tfidf dan BM25 untuk (sembarang) 4 kategori lain dari data News20  Word Embeddings  Word2VecDikembangkan oleh <NAME> - Google :Goldberg, Yoav; Levy, Omer. &quot;word2vec Explained: Deriving Mikolov et al.&39;s Negative-Sampling Word-Embedding Method&quot;.&nbsp;arXiv:1402.3722<jupyter_code># Hati-hati. Gensim menerima input berupa "sentences of tokens"
# Misal: [['ibu', 'memasak', 'di', 'dapur'], ['ibu', 'bekerja', 'di','dapur'],['adik','membantu','ibu','di','dapur'],['bapak','di','garasi']]
# Kita akan menggunakan data News 20 lagi, namun bentuk datanya dirubah seperti contoh diatas
import pickle
from sklearn.datasets import fetch_20newsgroups

categories = ['sci.med', 'talk.politics.misc',  'rec.autos']
try:
    f = open('data/20newsgroups.pckl', 'rb')
    data = pickle.load(f)
    f.close()
except:
    data = fetch_20newsgroups(subset='train', categories=categories,remove=('headers', 'footers', 'quotes'))
    f = open('data/20newsgroups.pckl', 'wb')
    pickle.dump(data, f)
    f.close()
data = [doc for doc in data.data]
# PreProcess (clean) the data ==> Silahkan lihat Fungsi "cleanText" di TSutanto_lib.py
# Silahkan modifikasi jika diperlukan.
from tqdm import tqdm_notebook as tqdm

stops, lemmatizer = tau.LoadStopWords(lang='en')
for i,d in tqdm(enumerate(data)):
    data[i] = tau.cleanText(d, lemma = lemmatizer, stops = stops, symbols_remove = True, min_charLen = 2)
print(data[0])
# Rubah bentuk data seperti yang dibutuhkan genSim
# Bisa juga dilakukan dengan memodifikasi fungsi "cleanText" (agar lebih efisien)
from textblob import TextBlob

data_we = []
for doc in data:
    Tokens = [str(w) for w in TextBlob(doc).words]
    data_we.append(Tokens)
print(data_we[0])
# https://radimrehurek.com/gensim/models/word2vec.html
# train word2vec dengan data di atas
from gensim.models import Word2Vec

L = 300 # Jumlah neurons = ukuran vektor = jumlah kolom
model_wv = Word2Vec(data_we, min_count=5, size=L, window = 5, workers= -1)
# min_count adalah jumlah kata minimal yang muncul di corpus
# "size" adalah Dimensionality of the word vectors 
# (menurut beberapa literature untuk text disarankan 300-500)
# "window" adalah jarak maximum urutan kata yang di pertimbangkan
# workers = jumlah prosesor yang digunakan untuk menjalankan word2vec
print('Done!...')
# di data yang sebenarnya (i.e. besar) Gensim sering membutuhkan waktu cukup lama
# Untungnya kita bisa menyimpan dan me-load kembali hasil perhitungan model word2vec, misal
model_wv.save('data/model_w2v')
model_wv = Word2Vec.load('data/model_w2v')
print('Done!...')<jupyter_output>Done!...<jupyter_text>Hati-hati, Word2vec menggunakan Matriks DensePenggunaan memory oleh Gensim kurang lebih sebagai berikut:Jumlah kata x &quot;size&quot; x 12 bytesMisal terdapat 100 000 kata unik dan menggunakan 200 layers, maka penggunaan memory =&nbsp;100,000x200x12 bytes = ~229MBJika jumlah size semakin banyak, maka jumlah training data yang diperlukan juga semakin banyak, namun model akan semakin akurat.<jupyter_code># Melihat vector suatu kata
vektor = model_wv.wv.__getitem__(['car'])
print(len(vektor[0])) # Panjang vektor keseluruhan = jumlah neuron yang digunakan
print(vektor[0][:5]) # 5 elemen pertama dari vektornya
# Mencari kata terdekat menurut data training dan Word2Vec
model_wv.wv.most_similar('car')
# Melihat similarity antar kata
print(model_wv.wv.similarity('car', 'supra'))
print(model_wv.wv.similarity('car', 'alarm'))
print(model_wv.wv.similarity('car', 'car'))<jupyter_output>-0.03199897
-0.09292211
1.0<jupyter_text>Hati-hati Cosine adalah similarity bukan distanceHal ini akan mempengaruhi interpretasi<jupyter_code># error jika kata tidak ada di training data
# beckman bukan beckmans ==> hence di Word Embedding PreProcessing harus thourough

kata = 'cars'
try:
    print(model_wv.wv.most_similar(kata))
except:
    print('error! kata "',kata,'" tidak ada di training data')
# ini salah satu kelemahan Word2Vec<jupyter_output>error! kata " cars " tidak ada di training data<jupyter_text>Tips:Hati-hati GenSim tidak menggunakan seluruh kata di training data!.Perintah berikut akan menghasilkan kata-kata yang terdapat di vocabulary GenSim<jupyter_code>Vocabulary = model_wv.wv.vocab
print(str(Vocabulary.keys())[:130])
# Gunakan vocabulary ini (rubah ke "set") untuk membuat program menjadi lebih robust
# "predict" vector for new data without re-training from the beginning
d1 = ['new','generation','nvidia','gpu','is','rtx']
d2 = ['deep','learning','computation','mostly', 'on', 'gpu']
d3 = ['the','rtx','gpu','capable','super','sampling','ssdl']
D = [d1,d2,d3]
model_wv.train(D, total_examples=len(D), epochs=model_wv.epochs)
print(model_wv.predict_output_word('gpu'))
# Word2Vec ndak bisa "predict" kata yang ndak ada di vocabulary<jupyter_output>[('vacuum', 0.00023490722), ('hose', 0.00023490722), ('incentive', 0.00023490722), ('digest', 0.00023490722), ('recurrence', 0.00023490722), ('dizziness', 0.00023490722), ('cabin', 0.00023490722), ('pride', 0.00023490722), ('commander', 0.00023490722), ('translation', 0.00023490722)]<jupyter_text>Hati-hati menginterpretasikan hasil Word2Vec &nbsp;FastText (Facebook-2016)	Menggunakan Sub-words: app, ppl, ple - apple	Paper:&nbsp;https://arxiv.org/abs/1607.04606&nbsp;&nbsp;	Website:&nbsp;https://fasttext.cc/	Source:&nbsp;https://github.com/facebookresearch/fastText&nbsp;<jupyter_code>from gensim.models import FastText

L = 300 # Jumlah neurons = ukuran vektor = jumlah kolom
model_FT = FastText(data_we, size=L, window=4, min_count=1, workers=2)
'Done'
# Mencari kata terdekat menurut data training dan Word2Vec
model_FT.wv.most_similar('car')
# Melihat similarity antar kata
print(model_FT.wv.similarity('car', 'car'))
print(model_FT.wv.similarity('car', 'carpal'))
print(model_FT.wv.similarity('car', 'carter'))
# Tidak error jika kata tidak ada di training data

kata = 'beckmans'
try:
    print(model_FT.wv.most_similar(kata))
except:
    print('error! kata "',kata,'" tidak ada di training data')
# ini adalah kelebihan lain FastText
# Tapi hati-hati dengan hasil ini:
print(model_FT.wv.most_similar('beckman'))
# atau bahkan bisa seperti ini ...
try:
    print(model_wv.wv.most_similar('industri'))
except:
    print('Word2Vec error!')
    
try:
    print(model_FT.wv.most_similar('industri'))
except:
    print('FastText error!')<jupyter_output>Word2Vec error!
[('industrial', 0.9998847842216492), ('petri', 0.9998841881752014), ('hus', 0.999883770942688), ('bloat', 0.9998834133148193), ('idiom.berkeley.ca.us', 0.9998831748962402), ('tri', 0.9998831748962402), ('erlangen.de', 0.999882698059082), ('bus', 0.9998822212219238), ('versus', 0.999882161617279), ('kessner', 0.9998817443847656)]<jupyter_text>Diskusi:	Apakah kelebihan dan kekurangan WE secara umum?	Apakah kira-kira aplikasi WE?	Apakah bisa dijadikan representasi dokumen? Bagaimana caranya?	Bergantung pada apa sajakah performa model WE?* Preprocessing apa yang sebaiknya dilakukan pada model Word Embedding?* Apakah Pos Tag bermanfaat disini? Jika iya bagaimana menggunakannya? Text Analytics	Tidak seperti data terstruktur, data tidak terstruktur seperti teks termasuk salah satu data yang cukup sulit untuk divisualisasikan.		Namun terdapat Tools seperti Voyant yang dapat membantu dalam visualisasi sekaligus analisis.	 Voyant dapat digunakan dalam 2 cara:		Online:&nbsp;https://voyant-tools.org/	Kelebihan: Sederhana &amp; portable, tanpa harus install di komputer kita.	Kekurangan: butuh koneksi internet, tidak cocok untuk data teks yang besar, privacy.			Offline di komputer kita [Java Based]	 Instalasi Voyant:	Unduh Voyant dari &nbsp;https://github.com/sgsinclair/VoyantServer	Extract Voyant ke sembarang folder (disarankan C:\VoyantServer)	Unduh Java JDK dari &nbsp;http://www.oracle.com/technetwork/java/javase/downloads/index.html&amp;nbsp;	Install Java	Tambahkan variable Java Home ke &quot;System Variable&quot;	Jalankan VoyantServer.jar dari&nbsp;C:\VoyantServer	Tips: Jalankan Voyant Server sebelum Jupyter atau ganti &quot;port&quot; di VVoyant Server.<jupyter_code># Contoh
# [1]. Pertama-tama kita perlu menyimpan tweet sebagai file teks biasa
file = 'data/dataTweet_plain.txt'
with open(file, 'w') as f:
    for d in D:
        f.write(d+'\n')
'Done'<jupyter_output><empty_output><jupyter_text>[2]. Jalankan Voyant secara offline atau online di URL&nbsp;https://voyant-tools.org/[3]. Upload file yang baru saja kita simpan (dataTweet_plain.txt). Penggunaan Voyant 1: WordClouds	Upload teks yang akan di analisa: hasil cluster/ suatu kategori/ topics / raw text.	slider terms: mengkontrol banyaknya terms yang disertakan.	Summary (statistics)	Documents ==&gt; add more	Phrases (n-grams like)	Export Visualisasi (kanan atas - pertama)	Options (kanan atas ke-3): Font, size, stopwords, whitelist	&quot;?&quot; ==&gt; More Help&nbsp; Penggunaan Voyant 2: Bubbles	Upload teks yang akan di analisa: hasil cluster/ suatu kategori/ topics / raw text.	Atau file yang sudah terupload sebelumnya	&nbsp;Klik tanda 4-kotak kecil (kanan atas ke-3)	Pilih Visualization Tools ==&gt; Bubbles	Option: hanya stopwords	Export: Hanya PNG&nbsp; Penggunaan Voyant 3: Word Tree	Upload teks yang akan di analisa: hasil cluster/ suatu kategori/ topics / raw text.	Atau file yang sudah terupload sebelumnya	Klik branch untuk expand Penggunaan Voyant 4: Links	Upload teks yang akan di analisa: hasil cluster/ suatu kategori/ topics / raw text.	Atau file yang sudah terupload sebelumnya	Visualization Tools ==&gt; Links	Klik sembarang terms untuk expand Penggunaan Voyant 5: Trends	Upload teks yang akan di analisa: hasil cluster/ suatu kategori/ topics / raw text.	Atau file yang sudah terupload sebelumnya	Document Tools ==&gt; Trends	.. Butuh preprocessing ...&nbsp;	Data harus terurut waktu	Berikut contohnya<jupyter_code>Tweets[0]['created_at']
timeTeks = [(t['created_at'], d) for t,d in zip(Tweets,D)]
timeTeks[0]
# %a %b %d %l %m %M %z %Y https://www.foragoodstrftime.com/
# Rubah Teks ke DateTime Format 
from datetime import datetime
# %a %b %d %l %m %M %z %Y https://www.foragoodstrftime.com/
d1 = datetime.strptime('Jun 1 2005  1:33PM', '%b %d %Y %I:%M%p')
d2 = datetime.strptime('Jun 1 2004  1:33PM', '%b %d %Y %I:%M%p')
d1>d2
timeTeks = [((datetime.strptime(t,'%a %b %d %H:%M:%S %z %Y')),txt) for t,txt in timeTeks]
timeTeks[0]
Data = [(34,12),(67,20),(80,33)]
Data.sort(key=lambda t:t[1])
Data
timeTeks.sort(key=lambda tup: tup[0])  # sorts Text by Time
timeTeks[0]
plainTeks = [t for T,t in timeTeks]
plainTeks[0]
# Simpan ke File
namaFile = 'data/TeksUrutWaktu.txt'
with open(namaFile, 'w') as f:
        for tweet in plainTeks:
            f.write(tweet+'\n')
'Done!, silahkan upload file tsb ke Voyant'<jupyter_output><empty_output><jupyter_text>Latihan :&nbsp;	Crawl twitter dengan salah satu topik yang sedang trending saat ini di Indonesia.&nbsp;	Tentukan beberapa Important user-nya (centrality analysis)	Bentuk graph komunitasnya.	Analisa graph diatas di gephi.	Analisa graphnya di Voyant Tools. End of Module 07<jupyter_code>import re
from html import unescape
from nltk import word_tokenize as wt
from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()

def fixTags(T):
    getHashtags = re.compile(r"#(\w+)")
    pisahtags = re.compile(r'[A-Z][^A-Z]*')
    t = T
    tagS = re.findall(getHashtags, T)
    for tag in tagS:
        proper_words = ' '.join(re.findall(pisahtags, tag))
        t = t.replace('#'+tag,proper_words)
    return t

def cleanText(T, fix, patternS):
    t = T
    for pattern in patternS: #in case in the future we need more pattern cleaning
        t = re.sub(pattern,' ',t)
    t = unescape(t)
    t = fixTags(t)
    t = t.lower()
    for slang, formal in fix.items():
        t = t.replace(slang,formal)
    t = wt(t) # tokenize
    t = [lemmatizer.lemmatize(token) for token in t]
    return t
fix = {'awsm':'awesome', "they're":'they are'}
urlPattern = re.compile(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+')

patternS = [urlPattern]
%time
# Jawaban Latihan No 1
tweet = "The #OctopiPower is &gt; Sharks! &amp; they're awsm! So happy to see them here http://www.octopusVSshark.com !"
T = [tweet, 'status lain']

C = []
for t in T:
    C.append( cleanText(t, fix, patternS) )
print(' '.join(C[0]))
%time
# Contoh Jawaban Sederhana Latihan No 2
from nltk import word_tokenize as wt

T = 'pesawat b29 dan mig276 adalah kepunyaan fhg347x dan _24x_'
T_Clean = []
for t in wt(T):
    if sum(c.isalpha() for c in t)==len(t):
        T_Clean.append(t)
print(' '.join(T_Clean))<jupyter_output><empty_output>
StarcoderdataJupyterStructuredCleanDedup