1. Web Scraping

library(tidyverse)
library(rvest)
library(stringr)

1.1 Data Mobil Bekas

url <- "https://www.carsome.id/beli-mobil-bekas"
card <- read_html(url) %>% html_elements('.mod-b-card')
other <- sapply(card,
                    function(card){
                      card %>% 
                        html_element('.mod-b-card__car-other') %>%
                        html_elements('span') %>%
                        html_text() %>%
                        paste(collapse = ',')
                    })
other
##  [1] "33.827 km,Automatic,Bekasi,"            
##  [2] "126.885 km,Automatic,Bekasi,"           
##  [3] "65.278 km,Automatic,Bekasi,"            
##  [4] "113.927 km,Manual,Bekasi,"              
##  [5] "114.899 km,Automatic,Bekasi,"           
##  [6] "30.404 km,Manual,Bekasi,"               
##  [7] "121.419 km,Automatic,Tangerang Selatan,"
##  [8] "75.380 km,Manual,Bekasi,"               
##  [9] "83.487 km,Automatic,Tangerang Selatan," 
## [10] "106.076 km,Manual,Bekasi,"              
## [11] "71.172 km,Automatic,Tangerang Selatan," 
## [12] "53.151 km,Automatic,Bekasi,"            
## [13] "82.137 km,Automatic,Bekasi,"            
## [14] "98.857 km,Automatic,Bekasi,"            
## [15] "46.182 km,Manual,Tangerang Selatan,"    
## [16] "45.376 km,Manual,Bekasi,"               
## [17] "61.937 km,Manual,Bekasi,"               
## [18] "47.085 km,Manual,Bekasi,"
url <- "https://www.carsome.id/beli-mobil-bekas"
card <- read_html(url) %>% html_elements('.mod-b-card')
tag.price <- sapply(card,
                    function(card){
                      card %>% 
                        html_element('.mod-card__price') %>%
                        html_elements('span') %>%
                        html_text() %>%
                        paste(collapse = ',')
                    })
tag.price
##  [1] "\n          Rp 12,12 jt/bln\n        ,"
##  [2] "\n          Rp 4,28 jt/bln\n        ," 
##  [3] "\n          Rp 3,93 jt/bln\n        ," 
##  [4] "\n          Rp 2,85 jt/bln\n        ," 
##  [5] "\n          Rp 4,00 jt/bln\n        ," 
##  [6] "\n          Rp 2,74 jt/bln\n        ," 
##  [7] "\n          Rp 3,48 jt/bln\n        ," 
##  [8] "\n          Rp 2,62 jt/bln\n        ," 
##  [9] "\n          Rp 4,94 jt/bln\n        ," 
## [10] "\n          Rp 4,14 jt/bln\n        ," 
## [11] "\n          Rp 3,24 jt/bln\n        ," 
## [12] "\n          Rp 2,83 jt/bln\n        ," 
## [13] "\n          Rp 3,40 jt/bln\n        ," 
## [14] "\n          Rp 3,04 jt/bln\n        ," 
## [15] "\n          Rp 2,83 jt/bln\n        ," 
## [16] "\n          Rp 3,61 jt/bln\n        ," 
## [17] "\n          Rp 2,58 jt/bln\n        ," 
## [18] "\n          Rp 2,55 jt/bln\n        ,"
spek <- sapply(other, function(other){
  seplit <- stringr::str_split(other,',')})

spesifikasi <- data.frame()

for (k in 1:length(spek)){
  spesifikasi = rbind(spesifikasi, cbind(spek[[k]][1],
                                         spek[[k]][2],
                                         spek[[k]][3]))
}

colnames(spesifikasi) <- c('Jarak', 'Tipe','Kota')
head(spesifikasi,10)
##         Jarak      Tipe              Kota
## 1   33.827 km Automatic            Bekasi
## 2  126.885 km Automatic            Bekasi
## 3   65.278 km Automatic            Bekasi
## 4  113.927 km    Manual            Bekasi
## 5  114.899 km Automatic            Bekasi
## 6   30.404 km    Manual            Bekasi
## 7  121.419 km Automatic Tangerang Selatan
## 8   75.380 km    Manual            Bekasi
## 9   83.487 km Automatic Tangerang Selatan
## 10 106.076 km    Manual            Bekasi

1.2 Data Wikipedia Film

url <- "https://en.wikipedia.org/wiki/List_of_action_films_of_the_2020s"
film <- read_html(url) %>% html_elements('.wikitable')
film <- sapply(film,
                    function(film){
                      film %>% 
                        html_elements('tr') %>%
                        html_elements('td') %>%
                        html_text() %>%
                        paste(collapse = ',')
                    })
spek <- sapply(film, function(film){
  seplit <- stringr::str_split(film,',')})

spesifikasi <- data.frame()

for (k in 1:length(spek)){
  spesifikasi = rbind(spesifikasi, cbind(spek[[k]][1],
                                         spek[[k]][2],
                                         spek[[k]][3],
                                         spek[[k]][4],
                                         spek[[k]][5]))
}

colnames(spesifikasi) <- c('Title', 'Directory','Cast',
                           'Country','Subgenre/notes')
head(spesifikasi,10)
##    Title        Directory                 Cast          Country
## 1   7500 Patrick Vollrath Joseph Gordon-Levitt      Aylin Tezel
## 2 2021\n         Aaraattu      B. Unnikrishnan         Mohanlal
## 3 2022\n          The 355        Simon Kinberg Jessica Chastain
## 4     65       Scott Beck          Bryan Woods      Adam Driver
## 5 2024\n          Argylle       Matthew Vaughn     Henry Cavill
##         Subgenre/notes
## 1              Germany
## 2                India
## 3       Lupita Nyong'o
## 4    Ariana Greenblatt
## 5  Bryce Dallas Howard

1.3 Data Berita Tempo

url <- "https://www.tempo.co/indeks/2023-10-09/nasional"
berita <- read_html(url) %>% html_elements('.text-card')
berita_data <- sapply(berita,
                    function(berita){
                      berita %>% 
                        html_elements('p') %>%
                        html_text() %>%
                        paste(collapse = ',')
                    })
judul_data <- berita %>% html_elements('.title') %>% html_text()
berita_tempo <- data.frame(Judul = judul_data, Isi = berita_data,
                           stringsAsFactors = FALSE)
head(berita_tempo)
##                                                                                              Judul
## 1                                   KTT AIS Forum 2023 Digelar Mulai Esok, Apa itu KTT AIS Forum? 
## 2                                Ketum PBNU Gus Yahya Serukan Hentikan Perang Palestina dan Israel
## 3                                   Koalisi Sipil Sebut UU ASN Berpeluang Bangkitkan Dwifungsi TNI
## 4 YLBHI Sebut Jokowi Legalkan Centengisasi soal Dugaan Polisi Dukung Perusahaan di Konflik Seruyan
## 5              Dari Kalangan NU, Pengamat Sebut Erick Thohir Potensial jadi Bakal Cawapres Prabowo
## 6                         Prabowo: Pemerintah Siapkan Rencana Evakuasi WNI di Palestina dan Israel
##                                                                                                                                                Isi
## 1                                        KTT AIS Forum 2023 akan berlangsung pada 10-11 Oktober mendatang, dan menampilkan puluhan negara peserta.
## 2    Ketua Umum PBNU Yahya Cholil Staquf atau Gus Yahya menyerukan untuk menghentikan kekerasan yang berujung perang antara Palestina dan Israel. 
## 3                                         Koalisi Sipil mengatakan revisi UU ASN berpeluang membangkitkan kembali dwifungsi militer era Orde Baru.
## 4                           Muhammad Isnur mengatakan Jokowi melegalkan praktik centengisasi dalam konflik di Bangkal, Seruyan, Kalimantan Tengah.
## 5 Pengamat sebut Erick Thohir potensial dampingi Prabowo Subianto, meski ada Khofifah Indar Parawansa. Erick Thohir juga berasal dari kalangan NU.
## 6 Menteri Pertahanan Prabowo Subianto mengatakan pemerintah mengupayakan evakuasi terhadap warga Indonesia yang bermukim di Palestina dan Israel.

2. Text Pre-Processing

Perintah di bawah ini dijalankan dalam environment bahasa pemrograman Python.

import pandas as pd
dummy_doc = pd.DataFrame({"text":["utk kamu yg disana, sdh makan belum?",
"Kepulauan Indonesia menjadi wilayah perdagangan penting sejak abad ke 7, yaitu sejak berdirinya Kerajaan Sriwijaya, sebuah kemaharajaan Hindu yang berpusat di Palembang.",
"Gue ga suka makan bakso, jangan dipaksaaa!!!",
"Woooy! mas aris lu gatau diri yaa! masih pura-pura lagi... padahal udah ketauan!",
"Kasus Covid-19 bertambah 40.618 pada Kamis (10/2), sehingga total kasus mencapai 4.667.554. Sebanyak 4.234.510 orang telah sembuh, dan 144.858 meninggal dunia."]})
dummy_doc
##                                                 text
## 0               utk kamu yg disana, sdh makan belum?
## 1  Kepulauan Indonesia menjadi wilayah perdaganga...
## 2       Gue ga suka makan bakso, jangan dipaksaaa!!!
## 3  Woooy! mas aris lu gatau diri yaa! masih pura-...
## 4  Kasus Covid-19 bertambah 40.618 pada Kamis (10...
def print_text_in_df(doc):
    for row in range(0,doc.shape[0]):
        print(doc.iloc[row,0])
print_text_in_df(dummy_doc)
## utk kamu yg disana, sdh makan belum?
## Kepulauan Indonesia menjadi wilayah perdagangan penting sejak abad ke 7, yaitu sejak berdirinya Kerajaan Sriwijaya, sebuah kemaharajaan Hindu yang berpusat di Palembang.
## Gue ga suka makan bakso, jangan dipaksaaa!!!
## Woooy! mas aris lu gatau diri yaa! masih pura-pura lagi... padahal udah ketauan!
## Kasus Covid-19 bertambah 40.618 pada Kamis (10/2), sehingga total kasus mencapai 4.667.554. Sebanyak 4.234.510 orang telah sembuh, dan 144.858 meninggal dunia.

Rekomendasi urutan untuk melakukan Basic Text Preprocessing dalam python:

  1. Noise Removal yang meliputi: case folding (huruf kapital/ bukan kapital), punctuation removal (menghilangkan tanda baca), menghapus/mentransformasi angka, whitespace removal (menghapus whitepace)

  2. Tokenization (memisahkan kalimat per kata)

  3. Text Normalization (mengubah tiap kata yang tidak baku menjadi kata baku)

  4. Stopwords Removal (menghapus kata yang tidak memiliki makna khusus)

  5. Stemming/Lemmatization (mengubah kata menjadi kata dasar tanpa imbuhan)

2.1 Noise Removal

import string
print(string.punctuation)
## !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
print(string.digits)
## 0123456789
def noise_remove(doc):
  doc1 = doc.lower()
  doc2 = doc1.translate(str.maketrans('', '', string.punctuation + string.digits))
  doc3 = doc2.strip()
  return doc3
print("Sebelum Preprocessing \n")
## Sebelum Preprocessing
print(dummy_doc.iloc[3,0],'\n')
## Woooy! mas aris lu gatau diri yaa! masih pura-pura lagi... padahal udah ketauan!
print("Sesudah Preprocessing \n")
## Sesudah Preprocessing
print(noise_remove(dummy_doc.iloc[3,0]))
## woooy mas aris lu gatau diri yaa masih purapura lagi padahal udah ketauan
dummy_doc2 = dummy_doc.apply(
  lambda doc: noise_remove(doc.iloc[0]),axis=1)
type(dummy_doc2)
## <class 'pandas.core.series.Series'>
dummy_doc2 = dummy_doc2.to_frame()
print_text_in_df(dummy_doc2)
## utk kamu yg disana sdh makan belum
## kepulauan indonesia menjadi wilayah perdagangan penting sejak abad ke  yaitu sejak berdirinya kerajaan sriwijaya sebuah kemaharajaan hindu yang berpusat di palembang
## gue ga suka makan bakso jangan dipaksaaa
## woooy mas aris lu gatau diri yaa masih purapura lagi padahal udah ketauan
## kasus covid bertambah  pada kamis  sehingga total kasus mencapai  sebanyak  orang telah sembuh dan  meninggal dunia

2.2 Tokenization

2.2.1 Fungsi Bawaan Python

Tokenisasi kata menggunakan fungsi bawaan Python.

# menggunakan fungsi bawaan dari python 
def tokenisasi_bawaan(doc):
  return doc.split()
tokenisasi_bawaan(dummy_doc2.iloc[2,0])
## ['gue', 'ga', 'suka', 'makan', 'bakso', 'jangan', 'dipaksaaa']
dummy_doc3 = dummy_doc2.apply(
  lambda doc : tokenisasi_bawaan(doc.iloc[0]), axis =1)

print(type(dummy_doc3))
## <class 'pandas.core.series.Series'>
dummy_doc3 = dummy_doc3.to_frame()
print_text_in_df(dummy_doc3)
## ['utk', 'kamu', 'yg', 'disana', 'sdh', 'makan', 'belum']
## ['kepulauan', 'indonesia', 'menjadi', 'wilayah', 'perdagangan', 'penting', 'sejak', 'abad', 'ke', 'yaitu', 'sejak', 'berdirinya', 'kerajaan', 'sriwijaya', 'sebuah', 'kemaharajaan', 'hindu', 'yang', 'berpusat', 'di', 'palembang']
## ['gue', 'ga', 'suka', 'makan', 'bakso', 'jangan', 'dipaksaaa']
## ['woooy', 'mas', 'aris', 'lu', 'gatau', 'diri', 'yaa', 'masih', 'purapura', 'lagi', 'padahal', 'udah', 'ketauan']
## ['kasus', 'covid', 'bertambah', 'pada', 'kamis', 'sehingga', 'total', 'kasus', 'mencapai', 'sebanyak', 'orang', 'telah', 'sembuh', 'dan', 'meninggal', 'dunia']

2.2.2 Package Spacy

Tokenisasi kata menggunakan Package Spacy.

# pip install spacy
# python -m spacy download id_core_news_sm

from spacy.lang.id import Indonesian
import spacy
nlp = Indonesian()
def tokenisasi_spacy(doc):
  doc1 = nlp(doc)
  token = [token.text for token in doc1]
  return token
dummy_doc4 = dummy_doc2.apply(
  lambda doc:tokenisasi_spacy(doc.iloc[0]),axis = 1)
  
dummy_doc4 = dummy_doc4.to_frame()
print_text_in_df(dummy_doc4)
## ['utk', 'kamu', 'yg', 'disana', 'sdh', 'makan', 'belum']
## ['kepulauan', 'indonesia', 'menjadi', 'wilayah', 'perdagangan', 'penting', 'sejak', 'abad', 'ke', ' ', 'yaitu', 'sejak', 'berdirinya', 'kerajaan', 'sriwijaya', 'sebuah', 'kemaharajaan', 'hindu', 'yang', 'berpusat', 'di', 'palembang']
## ['gue', 'ga', 'suka', 'makan', 'bakso', 'jangan', 'dipaksaaa']
## ['woooy', 'mas', 'aris', 'lu', 'gatau', 'diri', 'yaa', 'masih', 'purapura', 'lagi', 'padahal', 'udah', 'ketauan']
## ['kasus', 'covid', 'bertambah', ' ', 'pada', 'kamis', ' ', 'sehingga', 'total', 'kasus', 'mencapai', ' ', 'sebanyak', ' ', 'orang', 'telah', 'sembuh', 'dan', ' ', 'meninggal', 'dunia']
# untuk teks berbahasa inggris
eng_text = "You're such a good boy! I'll give you a gift, choose one!"
print(tokenisasi_bawaan(eng_text),'\n')
## ["You're", 'such', 'a', 'good', 'boy!', "I'll", 'give', 'you', 'a', 'gift,', 'choose', 'one!']
print(tokenisasi_spacy(eng_text))
## ["You're", 'such', 'a', 'good', 'boy', '!', "I'll", 'give', 'you', 'a', 'gift', ',', 'choose', 'one', '!']
# python -m spacy download en_core_web_sm
nlp_eng = spacy.load("en_core_web_sm")
def tokenisasi_spacy_eng(doc):
    doc1 = nlp_eng(doc)
    token = [token.text for token in doc1]
    return token
print(tokenisasi_spacy_eng(eng_text))
## ['You', "'re", 'such', 'a', 'good', 'boy', '!', 'I', "'ll", 'give', 'you', 'a', 'gift', ',', 'choose', 'one', '!']

2.2.3 Package NLTK

Tokenisasi kata menggunakan Package NLTK

import nltk
from nltk.tokenize import word_tokenize
# nltk.download('punkt')
print(word_tokenize(dummy_doc2.iloc[1,0]))
## ['kepulauan', 'indonesia', 'menjadi', 'wilayah', 'perdagangan', 'penting', 'sejak', 'abad', 'ke', 'yaitu', 'sejak', 'berdirinya', 'kerajaan', 'sriwijaya', 'sebuah', 'kemaharajaan', 'hindu', 'yang', 'berpusat', 'di', 'palembang']
print(word_tokenize(eng_text))
## ['You', "'re", 'such', 'a', 'good', 'boy', '!', 'I', "'ll", 'give', 'you', 'a', 'gift', ',', 'choose', 'one', '!']
dummy_doc5=dummy_doc2.apply(
  lambda doc: word_tokenize(doc.iloc[0]),axis=1)
dummy_doc5=dummy_doc5.to_frame()
print_text_in_df(dummy_doc5)
## ['utk', 'kamu', 'yg', 'disana', 'sdh', 'makan', 'belum']
## ['kepulauan', 'indonesia', 'menjadi', 'wilayah', 'perdagangan', 'penting', 'sejak', 'abad', 'ke', 'yaitu', 'sejak', 'berdirinya', 'kerajaan', 'sriwijaya', 'sebuah', 'kemaharajaan', 'hindu', 'yang', 'berpusat', 'di', 'palembang']
## ['gue', 'ga', 'suka', 'makan', 'bakso', 'jangan', 'dipaksaaa']
## ['woooy', 'mas', 'aris', 'lu', 'gatau', 'diri', 'yaa', 'masih', 'purapura', 'lagi', 'padahal', 'udah', 'ketauan']
## ['kasus', 'covid', 'bertambah', 'pada', 'kamis', 'sehingga', 'total', 'kasus', 'mencapai', 'sebanyak', 'orang', 'telah', 'sembuh', 'dan', 'meninggal', 'dunia']

2.3 Normalization

Untuk menormalisasi teks dapat menggunakan daftar kata-kata tidak baku dan baku. Berikut beberapa daftar yang bisa digunakan.

indo_slang_word = pd.read_csv("https://raw.githubusercontent.com/nasalsabila/kamus-alay/master/colloquial-indonesian-lexicon.csv")
indo_slang_word.head()
##      slang    formal  In-dictionary  ...  category1 category2 category3
## 0     woww       wow              1  ...   elongasi         0         0
## 1    aminn      amin              1  ...   elongasi         0         0
## 2      met   selamat              1  ...  abreviasi         0         0
## 3   netaas   menetas              1  ...   afiksasi  elongasi         0
## 4  keberpa  keberapa              0  ...  abreviasi         0         0
## 
## [5 rows x 7 columns]
indo_slang2=pd.read_csv("https://raw.githubusercontent.com/okkyibrohim/id-multi-label-hate-speech-and-abusive-language-detection/master/new_kamusalay.csv",
encoding = "cp1252",header=None, names=['slang','formal'])
indo_slang2.head()
##                  slang                    formal
## 0  anakjakartaasikasik  anak jakarta asyik asyik
## 1         pakcikdahtua         pak cik sudah tua
## 2       pakcikmudalagi         pak cik muda lagi
## 3          t3tapjokowi              tetap jokowi
## 4                   3x                 tiga kali
indo_slang3=pd.read_csv("https://raw.githubusercontent.com/ramaprakoso/analisis-sentimen/master/kamus/kbba.txt",sep='\t', header=None, names=['slang','formal'])
indo_slang3.tail()
##            slang   formal
## 1314       istaa    nista
## 1315  benarjujur    benar
## 1316  benarjujur    jujur
## 1317       sayan   sayang
## 1318       mgkin  mungkin
indo_slang_word.query("slang == 'met'")
##       slang   formal  In-dictionary  ...  category1 category2 category3
## 2       met  selamat              1  ...  abreviasi         0         0
## 36      met  selamat              1  ...  abreviasi         0         0
## 2231    met  selamat              1  ...  abreviasi         0         0
## 14009   met  selamat              1  ...  abreviasi         0         0
## 14010   met  selamat              1  ...  abreviasi         0         0
## 
## [5 rows x 7 columns]
#mendefinisikan fungsi untuk mengubah kata tidak baku menjadi kata baku
def replace_slang_word(doc,slang_word):
    for index in range(len(doc)):
        index_slang = slang_word.slang==doc[index]
        formal = list(set(slang_word[index_slang].formal))
        if len(formal)==1:
            doc[index]=formal[0]
    return doc
print("Sebelum Preprocessing \n")
## Sebelum Preprocessing
print(dummy_doc3.iloc[3,0])
## ['woooy', 'mas', 'aris', 'lu', 'gatau', 'diri', 'yaa', 'masih', 'purapura', 'lagi', 'padahal', 'udah', 'ketauan']
print("\nSesudah Preprocessing \n")
## 
## Sesudah Preprocessing
print(replace_slang_word(tokenisasi_spacy(dummy_doc2.iloc[3,0]),indo_slang_word))
## ['woooy', 'mas', 'aris', 'lu', 'enggak tau', 'diri', 'ya', 'masih', 'purapura', 'lagi', 'padahal', 'sudah', 'ketahuan']
print("Sebelum Preprocessing \n")
## Sebelum Preprocessing
print(dummy_doc3.iloc[3,0])
## ['woooy', 'mas', 'aris', 'lu', 'gatau', 'diri', 'yaa', 'masih', 'purapura', 'lagi', 'padahal', 'udah', 'ketauan']
print("\nSesudah Preprocessing \n")
## 
## Sesudah Preprocessing
print(replace_slang_word(tokenisasi_spacy(dummy_doc2.iloc[3,0]),indo_slang2))
## ['woooy', 'mas', 'aris', 'kamu', 'tak tau', 'diri', 'ya', 'masih', 'purapura', 'lagi', 'padahal', 'sudah', 'ketahuan']
print("Sebelum Preprocessing \n")
## Sebelum Preprocessing
print(dummy_doc3.iloc[3,0])
## ['woooy', 'mas', 'aris', 'lu', 'gatau', 'diri', 'yaa', 'masih', 'purapura', 'lagi', 'padahal', 'udah', 'ketauan']
print("\nSesudah Preprocessing \n")
## 
## Sesudah Preprocessing
print(replace_slang_word(tokenisasi_spacy(dummy_doc2.iloc[3,0]),indo_slang3))
## ['woooy', 'mas', 'aris', 'kamu', 'tidak tahu', 'diri', 'yaa', 'masih', 'purapura', 'lagi', 'padahal', 'sudah', 'ketahuan']
dummy_doc6=dummy_doc2.apply(
  lambda doc: replace_slang_word(
    tokenisasi_spacy(doc.iloc[0]),indo_slang3),axis=1)
dummy_doc6=dummy_doc6.to_frame()
print_text_in_df(dummy_doc6)
## ['untuk', 'kamu', 'yang', 'disana', 'sudah', 'makan', 'belum']
## ['kepulauan', 'indonesia', 'menjadi', 'wilayah', 'perdagangan', 'penting', 'sejak', 'abad', 'ke', ' ', 'yaitu', 'sejak', 'berdirinya', 'kerajaan', 'sriwijaya', 'sebuah', 'kemaharajaan', 'hindu', 'yang', 'berpusat', 'di', 'palembang']
## ['saya', 'tidak', 'suka', 'makan', 'bakso', 'jangan', 'dipaksaaa']
## ['woooy', 'mas', 'aris', 'kamu', 'tidak tahu', 'diri', 'yaa', 'masih', 'purapura', 'lagi', 'padahal', 'sudah', 'ketahuan']
## ['kasus', 'covid', 'bertambah', ' ', 'pada', 'kamis', ' ', 'sehingga', 'total', 'kasus', 'mencapai', ' ', 'sebanyak', ' ', 'orang', 'telah', 'sembuh', 'dan', ' ', 'meninggal', 'dunia']

2.4 Stopword Removal

#fungsi menghapus stopword
def stopwords_removal(words,stopword):
    return [word for word in words if word not in stopword]

2.4.1 Package Spacy

Menghapus Stopword menggunakan Spacy

from spacy.lang.id.stop_words import STOP_WORDS
print(list(STOP_WORDS)[:10])
## ['ucapnya', 'ibaratkan', 'mengira', 'dimulainya', 'mengucapkan', 'mempersoalkan', 'jadi', 'agak', 'pantas', 'mungkin']
len(STOP_WORDS)
## 757
print("Sebelum Preprocessing \n")
## Sebelum Preprocessing
print(dummy_doc.iloc[3,0])
## Woooy! mas aris lu gatau diri yaa! masih pura-pura lagi... padahal udah ketauan!
print("Sesudah Preprocessing \n")
## Sesudah Preprocessing
print(stopwords_removal(dummy_doc6.iloc[3,0],STOP_WORDS))
## ['woooy', 'mas', 'aris', 'tidak tahu', 'yaa', 'purapura', 'ketahuan']
dummy_doc7=dummy_doc6.apply(
  lambda doc: stopwords_removal(
    doc.iloc[0],STOP_WORDS),axis=1)
    
dummy_doc7=dummy_doc7.to_frame()
print_text_in_df(dummy_doc7)
## ['disana', 'makan']
## ['kepulauan', 'indonesia', 'wilayah', 'perdagangan', 'abad', ' ', 'berdirinya', 'kerajaan', 'sriwijaya', 'kemaharajaan', 'hindu', 'berpusat', 'palembang']
## ['suka', 'makan', 'bakso', 'dipaksaaa']
## ['woooy', 'mas', 'aris', 'tidak tahu', 'yaa', 'purapura', 'ketahuan']
## ['covid', 'bertambah', ' ', 'kamis', ' ', 'total', 'mencapai', ' ', ' ', 'orang', 'sembuh', ' ', 'meninggal', 'dunia']
def find_word(word,doc):
    return list(filter(lambda x: word in x, doc))
find_word("sudah",list(STOP_WORDS))
## ['sesudah', 'sudah', 'sesudahnya', 'sudahkah', 'sudahlah']
kata_bukan_stopword=['tidak','sudah','kamu','aku','saya','belum','jangan']
STOP_WORDS2=[s for s in list(STOP_WORDS) if s not in kata_bukan_stopword]
find_word("sudah",STOP_WORDS2)
## ['sesudah', 'sesudahnya', 'sudahkah', 'sudahlah']
dummy_doc8=dummy_doc6.apply(
  lambda doc: stopwords_removal(
    doc.iloc[0],STOP_WORDS2),axis=1)
    
dummy_doc8=dummy_doc8.to_frame()
print_text_in_df(dummy_doc8)
## ['kamu', 'disana', 'sudah', 'makan', 'belum']
## ['kepulauan', 'indonesia', 'wilayah', 'perdagangan', 'abad', ' ', 'berdirinya', 'kerajaan', 'sriwijaya', 'kemaharajaan', 'hindu', 'berpusat', 'palembang']
## ['saya', 'tidak', 'suka', 'makan', 'bakso', 'jangan', 'dipaksaaa']
## ['woooy', 'mas', 'aris', 'kamu', 'tidak tahu', 'yaa', 'purapura', 'sudah', 'ketahuan']
## ['covid', 'bertambah', ' ', 'kamis', ' ', 'total', 'mencapai', ' ', ' ', 'orang', 'sembuh', ' ', 'meninggal', 'dunia']

2.4.2 NLTK

Menghapus Stopword menggunakan NLTK

from nltk.corpus import stopwords
# mendapatkan stopword bahasa indonesia
# nltk.download('stopwords')
indo_stopwords = stopwords.words('indonesian')
print(type(indo_stopwords))
## <class 'list'>
len(indo_stopwords)
## 758
print(indo_stopwords[0:10])
## ['ada', 'adalah', 'adanya', 'adapun', 'agak', 'agaknya', 'agar', 'akan', 'akankah', 'akhir']
find_word("sudah",indo_stopwords)
## ['sesudah', 'sesudahnya', 'sudah', 'sudahkah', 'sudahlah']
dummy_doc9=dummy_doc6.apply(
  lambda doc: stopwords_removal(
    doc.iloc[0],indo_stopwords),axis=1)
    
dummy_doc9=dummy_doc9.to_frame()
print_text_in_df(dummy_doc9)
## ['disana', 'makan']
## ['kepulauan', 'indonesia', 'wilayah', 'perdagangan', 'abad', ' ', 'berdirinya', 'kerajaan', 'sriwijaya', 'kemaharajaan', 'hindu', 'berpusat', 'palembang']
## ['suka', 'makan', 'bakso', 'dipaksaaa']
## ['woooy', 'mas', 'aris', 'tidak tahu', 'yaa', 'purapura', 'ketahuan']
## ['covid', 'bertambah', ' ', 'kamis', ' ', 'total', 'mencapai', ' ', ' ', 'orang', 'sembuh', ' ', 'meninggal', 'dunia']

2.5 Stemming

# !pip install Pysastrawi
from Sastrawi.Stemmer.StemmerFactory import StemmerFactory
# create stemmer
factory = StemmerFactory()
stemmer = factory.create_stemmer()
def lemma_indo(doc):
    return [stemmer.stem(word) for word in doc]
dummy_doc10 = dummy_doc8.apply(
  lambda doc: lemma_indo(doc.iloc[0]),axis=1)
  
dummy_doc10=dummy_doc10.to_frame()
print_text_in_df(dummy_doc10)
## ['kamu', 'sana', 'sudah', 'makan', 'belum']
## ['pulau', 'indonesia', 'wilayah', 'dagang', 'abad', '', 'diri', 'raja', 'sriwijaya', 'maharaja', 'hindu', 'pusat', 'palembang']
## ['saya', 'tidak', 'suka', 'makan', 'bakso', 'jangan', 'dipaksaaa']
## ['woooy', 'mas', 'aris', 'kamu', 'tidak tahu', 'yaa', 'purapura', 'sudah', 'tahu']
## ['covid', 'tambah', '', 'kamis', '', 'total', 'capai', '', '', 'orang', 'sembuh', '', 'tinggal', 'dunia']
#menggabungkan proses pre-processing teks menjadi suatu fungsi
import re
def my_tokenizer(doc):
    #menghapus url
    doc1 = re.sub(r"https\S+", "",doc)
    # punctuation removal+menghapus angka
    doc2 = doc1.translate(str.maketrans('', '', string.punctuation + string.digits))
    # whitespace removal
    doc3 = doc2.strip()
    # word tokenization
    doc4 = nlp(doc3)
    doc_token1 = [token.text for token in doc4]
    # Text Normalization/Noise Removal]
    for index in  range(len(doc_token1)):
        index_slang = indo_slang3.slang==doc_token1[index]
        formal = list(set(indo_slang3[index_slang].formal))
        if len(formal)==1:
            doc_token1[index]=formal[0] 
    #Stopwords Removal
    doc_token2 = [word for word in doc_token1 if word not in STOP_WORDS2]
    #Stemming/Lemmatization
    factory = StemmerFactory()
    stemmer = factory.create_stemmer()
    doc_token3 = [stemmer.stem(word) for word in doc_token2]
    # menghapus spasi pada list
    doc_token4 = list(filter(lambda word: word != "", doc_token3))
    return doc_token4
dummy_doc10=dummy_doc.apply(
  lambda doc: my_tokenizer(doc.iloc[0]),axis=1)
print_text_in_df(dummy_doc10.to_frame())
## ['kamu', 'sana', 'sudah', 'makan', 'belum']
## ['pulau', 'indonesia', 'wilayah', 'dagang', 'abad', 'diri', 'raja', 'sriwijaya', 'maharaja', 'hindu', 'pusat', 'palembang']
## ['gue', 'tidak', 'suka', 'makan', 'bakso', 'jangan', 'dipaksaaa']
## ['woooy', 'mas', 'aris', 'kamu', 'tidak tahu', 'yaa', 'purapura', 'sudah', 'tahu']
## ['kasus', 'covid', 'tambah', 'kamis', 'total', 'capai', 'banyak', 'orang', 'sembuh', 'tinggal', 'dunia']
dummy_doc10
## 0                    [kamu, sana, sudah, makan, belum]
## 1    [pulau, indonesia, wilayah, dagang, abad, diri...
## 2    [gue, tidak, suka, makan, bakso, jangan, dipak...
## 3    [woooy, mas, aris, kamu, tidak tahu, yaa, pura...
## 4    [kasus, covid, tambah, kamis, total, capai, ba...
## dtype: object
#convert token to text
def list_to_text(token):
    text = " "
    return text.join(token)
doc_final=dummy_doc10.apply(list_to_text)
print_text_in_df(doc_final.to_frame())
## kamu sana sudah makan belum
## pulau indonesia wilayah dagang abad diri raja sriwijaya maharaja hindu pusat palembang
## gue tidak suka makan bakso jangan dipaksaaa
## woooy mas aris kamu tidak tahu yaa purapura sudah tahu
## kasus covid tambah kamis total capai banyak orang sembuh tinggal dunia

2.6 Bag of Word

2.6.1 Binary Vectorizer

from sklearn.feature_extraction.text import CountVectorizer
import warnings
warnings.filterwarnings("ignore")
cv = CountVectorizer(tokenizer=my_tokenizer,lowercase=True,binary=True)
cv_matrix = cv.fit_transform(doc_final)
print(cv.vocabulary_)
## {'kamu': 13, 'sudah': 26, 'makan': 15, 'belum': 3, 'pulau': 19, 'indonesia': 10, 'wilayah': 31, 'dagang': 6, 'abad': 0, 'raja': 22, 'sriwijaya': 25, 'maharaja': 14, 'hindu': 9, 'pusat': 21, 'palembang': 18, 'saya': 23, 'tidak': 28, 'suka': 27, 'bakso': 2, 'jangan': 11, 'dipaksaaa': 7, 'woooy': 32, 'mas': 16, 'aris': 1, 'yaa': 33, 'purapura': 20, 'covid': 5, 'kamis': 12, 'total': 30, 'capai': 4, 'orang': 17, 'sembuh': 24, 'tinggal': 29, 'dunia': 8}
cv_matrix2 = cv_matrix.toarray()
print(cv_matrix2)
## [[0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
##  [1 0 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 0 1 1 0 1 1 0 0 1 0 0 0 0 0 1 0 0]
##  [0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0]
##  [0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 1]
##  [0 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0]]
print("Banyaknya document x banyaknya vocabulary: ",cv_matrix2.shape)
## Banyaknya document x banyaknya vocabulary:  (5, 34)
# jalankan perintah pip install --upgrade scikit-learn di cmd sebagai administator terlebih dahulu
# from sklearn.feature_extraction.text import CountVectorizer

# get all unique words in the corpus
vocab = cv.get_feature_names()
# show document feature vectors
pd.DataFrame(cv_matrix2, columns=vocab)
##    abad  aris  bakso  belum  capai  ...  tinggal  total  wilayah  woooy  yaa
## 0     0     0      0      1      0  ...        0      0        0      0    0
## 1     1     0      0      0      0  ...        0      0        1      0    0
## 2     0     0      1      0      0  ...        0      0        0      0    0
## 3     0     1      0      0      0  ...        0      0        0      1    1
## 4     0     0      0      0      1  ...        1      1        0      0    0
## 
## [5 rows x 34 columns]
import plotly
pd.options.plotting.backend = "plotly"
def doc_plot(bow,vectorizer,n=10,desc=True):
    feature_names = vectorizer.get_feature_names_out()
    bow_result_df = pd.DataFrame(bow.toarray())
    bow_result_df = bow_result_df.sum(axis=0).T.to_frame(name="BoW")
    bow_result_df["feature_names"] = feature_names
    if(desc):
        fig1 = bow_result_df.nlargest(n,"BoW").plot.barh(y="feature_names",x="BoW",text="BoW",text_auto=True)
    else:
        fig1 = bow_result_df.nsmallest(n,"BoW").plot.barh(y="feature_names",x="BoW",text="BoW",text_auto=True)
    fig1.update_traces(marker_color='darkblue')
    fig1.update_layout(yaxis={'categoryorder':'total ascending'})
    fig1.show()
doc_plot(cv_matrix,cv,n=10)

2.6.2 Frequency Vectorizer

cv_2= CountVectorizer(tokenizer=my_tokenizer,lowercase=True)
cv_matrix_2 = cv_2.fit_transform(doc_final)
print(cv_2.vocabulary_)
## {'kamu': 13, 'sudah': 26, 'makan': 15, 'belum': 3, 'pulau': 19, 'indonesia': 10, 'wilayah': 31, 'dagang': 6, 'abad': 0, 'raja': 22, 'sriwijaya': 25, 'maharaja': 14, 'hindu': 9, 'pusat': 21, 'palembang': 18, 'saya': 23, 'tidak': 28, 'suka': 27, 'bakso': 2, 'jangan': 11, 'dipaksaaa': 7, 'woooy': 32, 'mas': 16, 'aris': 1, 'yaa': 33, 'purapura': 20, 'covid': 5, 'kamis': 12, 'total': 30, 'capai': 4, 'orang': 17, 'sembuh': 24, 'tinggal': 29, 'dunia': 8}
cv_matrix_22 = cv_matrix_2.toarray()
print(cv_matrix_22)
## [[0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0]
##  [1 0 0 0 0 0 1 0 0 1 1 0 0 0 1 0 0 0 1 1 0 1 1 0 0 1 0 0 0 0 0 1 0 0]
##  [0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0]
##  [0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 1]
##  [0 0 0 0 1 1 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0]]
cv_3 = CountVectorizer(tokenizer = my_tokenizer, lowercase = True)
cv_matrix_3 = cv_3.fit_transform(["Data sains menjadi populer belakangan ini, sehingga banyak pelatihan data sains", "Kamu suka sekali makan mie dan makan coklat", "Peserta pelatihan data sains adalah mahasiswa semester 5 juga semester 7"])
print(cv_matrix_3.toarray())
## [[0 2 0 1 0 0 0 1 2 0 0 0]
##  [1 0 1 0 0 2 1 0 0 0 0 1]
##  [0 1 0 1 1 0 0 0 1 2 1 0]]
print(cv_3.vocabulary_)
## {'data': 1, 'sains': 8, 'populer': 7, 'latih': 3, 'kamu': 2, 'suka': 11, 'makan': 5, 'mie': 6, 'coklat': 0, 'serta': 10, 'mahasiswa': 4, 'semester': 9}
doc_plot(cv_matrix_3, cv_3, n = 10)

2.7 TF-IDF

Term Frequency - Inverse Document Frequency

from sklearn.feature_extraction.text import TfidfVectorizer
tf_idf= TfidfVectorizer(tokenizer=my_tokenizer,lowercase=True)
tf_idf_matrix= tf_idf.fit_transform(doc_final)
print(tf_idf.vocabulary_)
## {'kamu': 13, 'sudah': 26, 'makan': 15, 'belum': 3, 'pulau': 19, 'indonesia': 10, 'wilayah': 31, 'dagang': 6, 'abad': 0, 'raja': 22, 'sriwijaya': 25, 'maharaja': 14, 'hindu': 9, 'pusat': 21, 'palembang': 18, 'saya': 23, 'tidak': 28, 'suka': 27, 'bakso': 2, 'jangan': 11, 'dipaksaaa': 7, 'woooy': 32, 'mas': 16, 'aris': 1, 'yaa': 33, 'purapura': 20, 'covid': 5, 'kamis': 12, 'total': 30, 'capai': 4, 'orang': 17, 'sembuh': 24, 'tinggal': 29, 'dunia': 8}
print(tf_idf_matrix.toarray())
## [[0.         0.         0.         0.5819515  0.         0.
##   0.         0.         0.         0.         0.         0.
##   0.         0.4695148  0.         0.4695148  0.         0.
##   0.         0.         0.         0.         0.         0.
##   0.         0.         0.4695148  0.         0.         0.
##   0.         0.         0.         0.        ]
##  [0.30151134 0.         0.         0.         0.         0.
##   0.30151134 0.         0.         0.30151134 0.30151134 0.
##   0.         0.         0.30151134 0.         0.         0.
##   0.30151134 0.30151134 0.         0.30151134 0.30151134 0.
##   0.         0.30151134 0.         0.         0.         0.
##   0.         0.30151134 0.         0.        ]
##  [0.         0.         0.39835162 0.         0.         0.
##   0.         0.39835162 0.         0.         0.         0.39835162
##   0.         0.         0.         0.32138758 0.         0.
##   0.         0.         0.         0.         0.         0.39835162
##   0.         0.         0.         0.39835162 0.32138758 0.
##   0.         0.         0.         0.        ]
##  [0.         0.37924665 0.         0.         0.         0.
##   0.         0.         0.         0.         0.         0.
##   0.         0.30597381 0.         0.         0.37924665 0.
##   0.         0.         0.37924665 0.         0.         0.
##   0.         0.         0.30597381 0.         0.30597381 0.
##   0.         0.         0.37924665 0.37924665]
##  [0.         0.         0.         0.         0.35355339 0.35355339
##   0.         0.         0.35355339 0.         0.         0.
##   0.35355339 0.         0.         0.         0.         0.35355339
##   0.         0.         0.         0.         0.         0.
##   0.35355339 0.         0.         0.         0.         0.35355339
##   0.35355339 0.         0.         0.        ]]
doc_plot(tf_idf_matrix,tf_idf,n=10)

3. Analisis Sentimen

import base64
import requests
import pandas as pd
import re
import emoji
import string
import warnings
warnings.filterwarnings("ignore")
neg= "https://raw.githubusercontent.com/ramaprakoso/analisis-sentimen/master/kamus/negative_keyword.txt"
neg_word = requests.get(neg).text
pos='https://raw.githubusercontent.com/ramaprakoso/analisis-sentimen/master/kamus/positif_ta2.txt'
pos_word = requests.get(pos).text
type(neg_word)
## <class 'str'>
neg_word_list=neg_word.split('\r\n')
pos_word_list=pos_word.split('\r\n')
print(neg_word_list[:10])
## ['acak-acakan', 'adu', 'adu domba', 'aib', 'akal bulus', 'alasan saja', 'alibi', 'aliran', 'amatir', 'ambisi']
def sentimen_prediksi(word):
    word = str(word)
    count_p = 0
    count_n = 0
    for kata_pos in pos_word_list:
        if kata_pos in word:
            count_p += 1
    for kata_neg in neg_word_list:
        if kata_neg in word:
            count_n += 1
    if count_p>count_n:
        return ('positif')
    elif count_p<count_n:
        return ('negatif')
    else:
        return ('netral')
Teks = "permainan itu sangat membosankan"
sentimen_prediksi(Teks)
## 'negatif'
Teks2 = "makanan dari tempat ini enak dan murah"
sentimen_prediksi(Teks2)
## 'positif'
Teks3 = "ibu memasak"
sentimen_prediksi(Teks3)
## 'netral'
def find_word(word,doc):
    return list(filter(lambda x: word in x, doc))
find_word("sudah",pos_word_list)
## ['sudah berupaya', 'sudah berusaha', 'sudah dilakukan']
find_word("jangan",neg_word_list)
## ['jangan asal', 'jangan diganggu', 'jangan sampai', 'jangan sekarang', 'jangan tanya', 'jangan-jangan', 'jangankan', 'penelanjangan']
df1 = pd.read_csv('7. Indonesian Sentiment Tweet Dataset Unlabeled.csv',
                  delimiter=',', header = None,names=['tweet'])
df1.head()
##                                                tweet
## 0  lagu bosan apa yang aku save ni huhuhuhuhuhuhu...
## 1  kita lanjutkan saja diam ini hingga kau dan ak...
## 2  Doa rezeki tak putus Inna haa zaa larizquna ma...
## 3  Makasih loh ntar kita bagi hasil aku 99 9 sisa...
## 4  Aku tak faham betul jenis orang malaysia yang ...
df1.shape
## (453390, 1)
df1.drop_duplicates(inplace=True)
df1.shape
## (444860, 1)
df1=df1.iloc[:5000,]
df1.shape
## (5000, 1)
def print_text_in_df(doc):
    for row in range(0,doc.shape[0]):
        print(doc.iloc[row,0])
print_text_in_df(df1.head())
## lagu bosan apa yang aku save ni huhuhuhuhuhuhuhuhuhuuuuuuuuuuuuuu
## kita lanjutkan saja diam ini hingga kau dan aku mengerti tidak semua kebersamaan harus melibatkan hati 
## Doa rezeki tak putus Inna haa zaa larizquna maa lahu min na fadesungguhnya ini ialah pemberian kami kepada kamu p 
## Makasih loh ntar kita bagi hasil aku 99 9 sisanya buat kamu
## Aku tak faham betul jenis orang malaysia yang tak reti nak sangkut balik hose tu Aku geli bodoh nak pegang
#cek apakah ada teks yang memuat link http
df1.tweet[df1.tweet.str.contains("http")]
## 293     nctea selama ini aku cuma tau fotonya jisung a...
## 1028    Aku suka orang cakap macam ni even tak rasa be...
## 1185    Berkenan betul aku dgn concept design IKEA ni ...
## 1257    Admin tau kalo hoseok bisa nyetir TAPI KENAPA ...
## 1539    Chemotherapy GDP Cycle 2 Day 1 Orang lain sibu...
## 3225    Weh korang mak aku ada buat hand sock dengan i...
## 3753    Kas jogathon ni benda paling bodoh time sekola...
## 4310                             Say rumah aku sepi http 
## Name: tweet, dtype: object
#cek apakah ada teks yang memuat @
df1.tweet[df1.tweet.str.contains("@")]
## Series([], Name: tweet, dtype: object)
def clean_tweet(tweet):
    tweet = re.sub("@[A-Za-z0-9]+","",tweet) #Remove @ sign
    tweet = re.sub(r"(?:\@|http?\://|https?\://|www)\S+", "", tweet) #Remove http links
    tweet = " ".join(tweet.split())
    emoji_pattern = re.compile("["
                           u"\U0001F600-\U0001F64F"  # emoticons
                           u"\U0001F300-\U0001F5FF"  # symbols & pictographs
                           u"\U0001F680-\U0001F6FF"  # transport & map symbols
                           u"\U0001F1E0-\U0001F1FF"  # flags (iOS)
                           u"\U00002702-\U000027B0"
                           u"\U000024C2-\U0001F251"
                           "]+", flags=re.UNICODE)
    tweet = emoji_pattern.sub(r'', tweet) #Remove Emojis
    tweet = tweet.replace("#", "").replace("_", " ") #Remove hashtag sign but keep the text

    return tweet
df_clean=df1.copy()
df_clean.tweet = df_clean.tweet.apply(clean_tweet)
df_clean.tweet = df_clean.tweet.apply(lambda x: re.sub("RT USER|USER","",x))
print_text_in_df(df_clean.head())
## lagu bosan apa yang aku save ni huhuhuhuhuhuhuhuhuhuuuuuuuuuuuuuu
## kita lanjutkan saja diam ini hingga kau dan aku mengerti tidak semua kebersamaan harus melibatkan hati
## Doa rezeki tak putus Inna haa zaa larizquna maa lahu min na fadesungguhnya ini ialah pemberian kami kepada kamu p
## Makasih loh ntar kita bagi hasil aku 99 9 sisanya buat kamu
## Aku tak faham betul jenis orang malaysia yang tak reti nak sangkut balik hose tu Aku geli bodoh nak pegang
def noise_remove(doc):
    doc1 = doc.lower()
    doc2 = doc1.translate(str.maketrans('', '', string.punctuation + string.digits))
    doc3 = doc2.strip()
    return doc3
df_clean_2=df_clean.apply(lambda doc: noise_remove(doc.iloc[0]),axis=1)
df_clean_2=df_clean_2.to_frame()
print_text_in_df(df_clean_2.head())
## lagu bosan apa yang aku save ni huhuhuhuhuhuhuhuhuhuuuuuuuuuuuuuu
## kita lanjutkan saja diam ini hingga kau dan aku mengerti tidak semua kebersamaan harus melibatkan hati
## doa rezeki tak putus inna haa zaa larizquna maa lahu min na fadesungguhnya ini ialah pemberian kami kepada kamu p
## makasih loh ntar kita bagi hasil aku   sisanya buat kamu
## aku tak faham betul jenis orang malaysia yang tak reti nak sangkut balik hose tu aku geli bodoh nak pegang
from spacy.lang.id import Indonesian
import spacy
nlp = Indonesian()
def tokenisasi_spacy(doc):
    doc1 = nlp(doc)
    token = [token.text for token in doc1]
    return token
df_clean_3=df_clean_2.apply(lambda doc: tokenisasi_spacy(doc.iloc[0]),axis=1)
df_clean_3=df_clean_3.to_frame()
print_text_in_df(df_clean_3.head())
## ['lagu', 'bosan', 'apa', 'yang', 'aku', 'save', 'ni', 'huhuhuhuhuhuhuhuhuhuuuuuuuuuuuuuu']
## ['kita', 'lanjutkan', 'saja', 'diam', 'ini', 'hingga', 'kau', 'dan', 'aku', 'mengerti', 'tidak', 'semua', 'kebersamaan', 'harus', 'melibatkan', 'hati']
## ['doa', 'rezeki', 'tak', 'putus', 'inna', 'haa', 'zaa', 'larizquna', 'maa', 'lahu', 'min', 'na', 'fadesungguhnya', 'ini', 'ialah', 'pemberian', 'kami', 'kepada', 'kamu', 'p']
## ['makasih', 'loh', 'ntar', 'kita', 'bagi', 'hasil', 'aku', '  ', 'sisanya', 'buat', 'kamu']
## ['aku', 'tak', 'faham', 'betul', 'jenis', 'orang', 'malaysia', 'yang', 'tak', 'reti', 'nak', 'sangkut', 'balik', 'hose', 'tu', 'aku', 'geli', 'bodoh', 'nak', 'pegang']
indo_slang3=pd.read_csv("https://raw.githubusercontent.com/ramaprakoso/analisis-sentimen/master/kamus/kbba.txt",sep='\t',
                       header=None, names=['slang','formal'])
#mendefinisikan fungsi untuk mengubah kata tidak baku menjadi kata baku
def replace_slang_word(doc,slang_word):
    for index in range(len(doc)):
        index_slang = slang_word.slang==doc[index]
        formal = list(set(slang_word[index_slang].formal))
        if len(formal)==1:
            doc[index]=formal[0]
    return doc
df_clean_4=df_clean_3.apply(lambda doc: replace_slang_word(doc.iloc[0],indo_slang3),axis=1)
df_clean_4=df_clean_4.to_frame()
print_text_in_df(df_clean_4.head())
## ['lagu', 'bosan', 'apa', 'yang', 'aku', 'save', 'ini', 'huhuhuhuhuhuhuhuhuhuuuuuuuuuuuuuu']
## ['kita', 'lanjutkan', 'saja', 'diam', 'ini', 'hingga', 'kamu', 'dan', 'aku', 'mengerti', 'tidak', 'semua', 'kebersamaan', 'harus', 'melibatkan', 'hati']
## ['doa', 'rezeki', 'tidak', 'putus', 'inna', 'haa', 'zaa', 'larizquna', 'maa', 'lahu', 'min', 'na', 'fadesungguhnya', 'ini', 'ialah', 'pemberian', 'kami', 'kepada', 'kamu', 'p']
## ['terima kasih', 'loh', 'ntar', 'kita', 'bagi', 'hasil', 'aku', '  ', 'sisanya', 'buat', 'kamu']
## ['aku', 'tidak', 'faham', 'betul', 'jenis', 'orang', 'malaysia', 'yang', 'tidak', 'reti', 'nak', 'sangkut', 'balik', 'hose', 'tu', 'aku', 'geli', 'bodoh', 'nak', 'pegang']
#fungsi menghapus stopword
def stopwords_removal(words,stopword):
    return [word for word in words if word not in stopword]
from spacy.lang.id.stop_words import STOP_WORDS
kata_bukan_stopword=['tidak','sudah','belum','jangan']
STOP_WORDS2=[s for s in list(STOP_WORDS) if s not in kata_bukan_stopword]
df_clean_5=df_clean_4.apply(lambda doc: stopwords_removal(doc.iloc[0],STOP_WORDS2),axis=1)
print_text_in_df(df_clean_5.to_frame().head())
## ['lagu', 'bosan', 'save', 'huhuhuhuhuhuhuhuhuhuuuuuuuuuuuuuu']
## ['lanjutkan', 'diam', 'mengerti', 'tidak', 'kebersamaan', 'melibatkan', 'hati']
## ['doa', 'rezeki', 'tidak', 'putus', 'inna', 'haa', 'zaa', 'larizquna', 'maa', 'lahu', 'min', 'na', 'fadesungguhnya', 'pemberian', 'p']
## ['terima kasih', 'loh', 'ntar', 'hasil', '  ', 'sisanya']
## ['tidak', 'faham', 'jenis', 'orang', 'malaysia', 'tidak', 'reti', 'nak', 'sangkut', 'hose', 'tu', 'geli', 'bodoh', 'nak', 'pegang']
#convert token to text
def list_to_text(token):
    text = " "
    return text.join(token)
doc_final=df_clean_5.apply(list_to_text)
print_text_in_df(doc_final.to_frame().head())
## lagu bosan save huhuhuhuhuhuhuhuhuhuuuuuuuuuuuuuu
## lanjutkan diam mengerti tidak kebersamaan melibatkan hati
## doa rezeki tidak putus inna haa zaa larizquna maa lahu min na fadesungguhnya pemberian p
## terima kasih loh ntar hasil    sisanya
## tidak faham jenis orang malaysia tidak reti nak sangkut hose tu geli bodoh nak pegang
type(doc_final)
## <class 'pandas.core.series.Series'>
from wordcloud import WordCloud
import matplotlib.pyplot as plt
teks_string = doc_final.to_string()
#wordcloud = WordCloud(background_color="white")
#wordcloud.generate(teks_string)
# Display the generated image:
#plt.imshow(wordcloud, interpolation='bilinear')
#plt.axis("off")
#plt.show()
def remove_certain_word(words,text):
    return [word for word in words if word not in text]
df_clean_6 = df_clean_5.apply(lambda x: remove_certain_word(x,["sudah","iya","deh","nak",                                                          "kat","nya",'tu','je','eh',                                                          'kak','kali','ku','g','t','sih']))
df_clean_7 = df_clean_6.apply(list_to_text)
print_text_in_df(df_clean_7.to_frame().head())
## lagu bosan save huhuhuhuhuhuhuhuhuhuuuuuuuuuuuuuu
## lanjutkan diam mengerti tidak kebersamaan melibatkan hati
## doa rezeki tidak putus inna haa zaa larizquna maa lahu min na fadesungguhnya pemberian p
## terima kasih loh ntar hasil    sisanya
## tidak faham jenis orang malaysia tidak reti sangkut hose geli bodoh pegang
#wordcloud = WordCloud(background_color="white")
#wordcloud.generate(df_clean_7.to_string())
#plt.imshow(wordcloud, interpolation='bilinear')
#plt.axis("off")
#plt.show()
fin_df=df_clean_7.to_frame()
fin_df.columns=['tweet']
fin_df['sentimen']=fin_df.apply(lambda doc: sentimen_prediksi(doc.iloc[0]),axis=1)
fin_df.head()
##                                                tweet sentimen
## 0  lagu bosan save huhuhuhuhuhuhuhuhuhuuuuuuuuuuuuuu  negatif
## 1  lanjutkan diam mengerti tidak kebersamaan meli...  positif
## 2  doa rezeki tidak putus inna haa zaa larizquna ...  positif
## 3             terima kasih loh ntar hasil    sisanya  positif
## 4  tidak faham jenis orang malaysia tidak reti sa...  negatif
import seaborn as sns
import matplotlib.pyplot as plt
sns.countplot(y='sentimen', data=fin_df)
plt.show()

from sklearn.feature_extraction.text import TfidfVectorizer
tf_idf_vectorizer = TfidfVectorizer()
tf_idf_result = tf_idf_vectorizer.fit_transform(fin_df.tweet)
tf_idf_result_df = pd.DataFrame(tf_idf_result.toarray(),columns=tf_idf_vectorizer.get_feature_names_out())
tf_idf_result_df.sum(axis=0).T.sort_values(ascending=False)
## tidak         177.997306
## orang          73.753019
## tertawa        42.826361
## suka           41.371937
## jangan         40.771063
##                  ...    
## aangen          0.193439
## vitachimin      0.193439
## kaaa            0.193439
## yukur           0.190408
## lauk            0.190408
## Length: 11888, dtype: float64
tf_idf_result_df_2=tf_idf_result_df.copy()
tf_idf_result_df_2['sentimen']=fin_df.sentimen
tf_idf_result_df_2.head()
##     aa  aaa  aaaa  aaaaa  aah  ...   zr  zri  zyal  zzz  sentimen
## 0  0.0  0.0   0.0    0.0  0.0  ...  0.0  0.0   0.0  0.0   negatif
## 1  0.0  0.0   0.0    0.0  0.0  ...  0.0  0.0   0.0  0.0   positif
## 2  0.0  0.0   0.0    0.0  0.0  ...  0.0  0.0   0.0  0.0   positif
## 3  0.0  0.0   0.0    0.0  0.0  ...  0.0  0.0   0.0  0.0   positif
## 4  0.0  0.0   0.0    0.0  0.0  ...  0.0  0.0   0.0  0.0   negatif
## 
## [5 rows x 11889 columns]
import numpy as np

sentimen=['negatif','netral','positif']
for i,sent in enumerate(sentimen):
    cluster_df = tf_idf_result_df_2.groupby("sentimen").sum().T.sort_values(ascending=False,by=sent).head(10)[sent].to_frame().reset_index()
    cluster_df.columns = ["words","TF_IDF"]
    sns.barplot(x="TF_IDF",y="words",data=cluster_df).set_title('Cluster '+str(sent))
    plt.show()

from sklearn.cluster import MiniBatchKMeans
kmeans = MiniBatchKMeans()
from yellowbrick.cluster import KElbowVisualizer

# Silhouette
kmeans_vis_sil = KElbowVisualizer(kmeans, k=(2,12),metric="silhouette")

kmeans_vis_sil.fit(tf_idf_result)        # Fit the data to the visualizer
## KElbowVisualizer(ax=<AxesSubplot:>, estimator=MiniBatchKMeans(n_clusters=11),
##                  k=(2, 12), metric='silhouette')
kmeans_vis_sil.show()        # Finalize and render the figure

kmeans = MiniBatchKMeans(n_clusters=3)
kmeans.fit(tf_idf_result)
## MiniBatchKMeans(n_clusters=3)
# extract cluster's label
cluster_label = pd.DataFrame(kmeans.predict(tf_idf_result),columns=["cluster"])
tf_idf_df_lab = pd.concat([tf_idf_result_df,cluster_label],axis=1)
import numpy as np

for i in range(3):
    cluster_df = tf_idf_df_lab.groupby("cluster").sum().T.sort_values(ascending=False,by=i).head(10)[i].to_frame().reset_index()
    cluster_df.columns = ["words","TF_IDF"]
    sns.barplot(x="TF_IDF",y="words",data=cluster_df).set_title('Cluster '+str(i))
    plt.show()