Studi ini melihat lebih dalam pesan teks historis dengan menerapkan berbagai teknik pembelajaran mesin. Tujuan dari penelitian ini adalah untuk menerapkan teknik Natural Language Processing (NLP) untuk mengidentifikasi tren komunikasi, mengevaluasi efektivitas proses yang ada, dan untuk memberikan wawasan dari data historis.

Metodologi

Untuk analisis data, saya menggunakan Python sebagai bahasa pemrograman bersama dengan berbagai perpustakaan perangkat lunak seperti pandas, math, numpy, sklearn, matplotlib dan lain-lain. Selain itu, saya telah menggunakan Natural Language Processing (NLP) yang merupakan pembelajaran mesin (ML) teknik yang membantu memahami, menafsirkan, dan memanipulasi bahasa manusia menggunakan kecerdasan buatan.

Eksplorasi Data

Fokusnya di sini adalah untuk mengeksplorasi kumpulan besar data tidak terstruktur dan mengungkap pola awal, karakteristik, dan hal menarik. Langkah ini tidak diharapkan untuk mengungkapkan seluruh informasi yang terdapat dalam kumpulan data, melainkan untuk membantu menciptakan gambaran luas tentang tren penting dan poin-poin utama untuk dipelajari secara lebih rinci.

Menemukan tren Pesan Masuk dan Keluar untuk Musim Semi dan Musim Panas

Kumpulan data saat ini berisi sejumlah kolom terbatas. Untuk mendapatkan jumlah pesan berdasarkan bulan, kita perlu mengekstrak tahun dan bulan dari kolom waktu.

df_text=pd.read_csv('../Data/clean_text.csv')
df_text.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 62513 entries, 0 to 62512
Data columns (total 7 columns):
message_type    62513 non-null object
text            62513 non-null object
time            62513 non-null object
ID              62513 non-null object
group_list      62513 non-null object
term            62513 non-null object
sent_by         62513 non-null object
dtypes: object(7)
memory usage: 3.3+ MB
#Extracting year and month from 'time' column and append the dataframe with new columns.
df_text['year'] = pd.DatetimeIndex(df_text['time']).year
df_text['month'] = pd.DatetimeIndex(df_text['time']).month
df_text.head()

Sekarang kita dapat menghitung jumlah pesan masuk dan keluar berdasarkan bulan.

# Getting the message count by message type and month
# reset_index() gives a column for counting, after groupby uses year and category
df_cnt = (df_text.reset_index()
          .groupby(['month','message_type'], as_index=False)
          .count()
          # rename isn't strictly necessary here, it's just for readability
          .rename(columns={'index':'count'})
       )
#sorting the values by month
df_cnt.sort_values(by = 'month', ascending = True)

Sekarang saatnya menggunakan matplotlibuntuk menyajikan data.

import matplotlib.pyplot as plt
df_all_cnt =df_cnt
#adding month name for better presentation
df_all_cnt['month_t'] = df_all_cnt['month'].apply(lambda x: calendar.month_abbr[x])
fig, ax = plt.subplots(figsize=(5, 3), dpi=150)
# key gives the group name (i.e. category), data gives the actual values
for key, data in df_all_cnt.groupby('message_type'):
    data.plot(x='month_t', y='count', ax=ax, label=key)
    
# Hide the right and top spines
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
#draw the grid
ax.grid( linestyle='-', linewidth=0.2)     
ax.legend()
ax.set_xlabel('Month')
ax.set_ylabel('Nu. Of Messages')
ax.set_title('In and Out Messages By Month - Both Programs')

Dengan cara yang sama, kita dapat menggunakan kolom lain dalam kumpulan data sebagai sumbu x dan y untuk mengisi berbagai jenis grafik guna memperlihatkan berbagai aspek dari kumpulan data yang sama.

Analisis Teks dengan NLP

NLP adalah metode yang sangat baik untuk menganalisis dan menafsirkan data tekstual seperti respon siswa. Ini adalah teknik ML yang digunakan mesin untuk memahami bahasa manusia seperti teks, ucapan, emoji, dan banyak digunakan di industri saat ini (yaitu Siri dan Alexa).

Membersihkan, menghilangkan stopword dan stemming

Penting untuk membersihkan data Anda dengan menghapus semua kata, simbol, dan teks yang tidak perlu yang tidak akan membantu Anda melakukan analisis yang berarti. Fungsi di bawah ini akan membantu kita membersihkan, menghapus stopwords tetapi kita juga memerlukan beberapa perpustakaan untuk membantu hal itu.

from nltk.corpus import stopwords
nltk.download('stopwords')
nltk.download('punkt')
from gensim.parsing.preprocessing import STOPWORDS
from gensim.parsing.preprocessing import remove_stopwords
set(stopwords.words('english'))
from nltk.tokenize import word_tokenize
from contractions import contractions_dict
import unicodedata
def remove_punctuation(text):
    text = ''.join([i for i in text if not i.isdigit()])
    return re.sub("[!@#$+%*:()/|,;:'-]", ' ', text)
def removebrackets(text):
    return re.sub('[\(\[].*?[\)\]]', ' ', text)
def remove_accented_chars(text):
    return unicodedata.normalize('NFKD', text).encode('ascii', 'ignore').decode('utf-8', 'ignore')
def remove_special_chars(text, remove_digits=False):
    pattern = r'[^a-zA-Z0-9\s]' if not remove_digits else r'[^a-zA-Z\s]'
    return re.sub(pattern, '', text)
def remove_stopwords(text):
   # text_tokens = word_tokenize(text)
   # text = remove_stopwords(text)
      
    from gensim.parsing.preprocessing import STOPWORDS
all_stopwords_gensim = STOPWORDS.union(set(['thank', 'need', 'yes', 'okay']))
text_tokens = word_tokenize(text)
    tokens_without_sw = ' '.join([word for word in text_tokens if not word in all_stopwords_gensim])
    
    return tokens_without_sw
def stemming (text):
    
   ps = nltk.porter.PorterStemmer()
   return ' '.join([ps.stem(word) for word in text.split()])
    
  stopword_list = stopwords.words('english')
  tokens = nltk.word_tokenize(text)
  tokens = [token.strip() for token in tokens]
  return ' '.join([token for token in tokens if token not in stopword_list])
def lemmatize(text):
    text = nlp(text)
    return ' '.join([word.lemma_ if word.lemma_ != '-PRON-' else word.text for word in text])
def expand_contractions(text, contraction_mapping=contractions_dict):
    
    contractions_pattern = re.compile('({})'.format('|'.join(contraction_mapping.keys())), 
                                      flags=re.IGNORECASE|re.DOTALL)
    def expand_match(contraction):
        match = contraction.group(0)
        first_char = match[0]
        expanded_contraction = contraction_mapping.get(match)\
                                if contraction_mapping.get(match)\
                                else contraction_mapping.get(match.lower())                       
        expanded_contraction = first_char+expanded_contraction[1:]
        return expanded_contraction
        
    expanded_text = contractions_pattern.sub(expand_match, text)
    return re.sub("'", "", expanded_text)

Setelah membersihkan data, kami dapat mengisi kata cloud untuk analisis kami. Word Cloud adalah salah satu cara paling efektif untuk merepresentasikan data ini, yang menunjukkan pentingnya teks berdasarkan ukuran, kedalaman warna, dan ketebalan kata.

from wordcloud import WordCloud, STOPWORDS, ImageColorGenerator
wc = WordCloud(stopwords=STOPWORDS,max_font_size=200, max_words=1000000, background_color="white", width=1000, height=1000).generate(' '.join(df_filtered['text_clean']))
plt.figure(figsize=(20,20))
plt.imshow(wc)
plt.axis("off")
plt.show()

Setelah mengisi kata cloud, Anda dapat mengidentifikasi teks lain yang tidak diperlukan untuk analisis Anda. Anda cukup memperluas perpustakaan stopwords saat ini dengan menambahkan kata-kata yang teridentifikasi sebagai berikut.

def clean_text_again(text):
from gensim.parsing.preprocessing import STOPWORDS
all_stopwords_gensim = STOPWORDS.union(set(['thank', 'need', 'yes', 'okay','ok','thanks','morning','hello','sure','hi', 'know', 'got','yesterday']))
text_tokens = word_tokenize(text)
    tokens_without_sw = [word for word in text_tokens if not word in all_stopwords_gensim]
return ' '.join([word for word in text_tokens if not word in all_stopwords_gensim])

Word Cloud diperluas — Eksplorasi Ngram

Ngram hanyalah rangkaian kata n yang bersebelahan. Melihat n-gram yang paling sering dapat memberi kita pemahaman yang lebih baik tentang konteksnya.

Fungsi di bawah ini menyajikan kata-kata non-stop yang paling sering muncul dalam diagram batang.

import seaborn as sns
def plot_top_non_stopwords_barchart(text):
     
    new= text.str.split()
    new=new.values.tolist()
    corpus=[word for i in new for word in i]
counter=Counter(corpus)
    most=counter.most_common()
    x, y=[], []
    for word,count in most[:40]:
        if (word not in stop):
            x.append(word)
            y.append(count)
      
    plt.figure(figsize=(15,8))
    sns.barplot(x=y,y=x,palette="colorblind")

Namun, untuk memahami konteks kata-kata non-stop dan hubungannya; kita perlu mengisi grafik dengan kata-kata yang cenderung segera mengikutinya. Saya mengubah fungsi di atas menggunakan 3 kata langsung untuk menggambar Trigramsebagai berikut.

def plot_top_ngrams_barchart(text, n=3): #n is the number of immediate words you need.
      
    new= text.str.split()
    new=new.values.tolist()
    corpus=[word for i in new for word in i]
def _get_top_ngram(corpus, n=None):
        vec = CountVectorizer(ngram_range=(n, n)).fit(corpus)
        bag_of_words = vec.transform(corpus)
        sum_words = bag_of_words.sum(axis=0) 
        words_freq = [(word, sum_words[0, idx]) 
                      for word, idx in vec.vocabulary_.items()]
        words_freq =sorted(words_freq, key = lambda x: x[1], reverse=True)
        return words_freq[:10]
top_n_bigrams=_get_top_ngram(text,n)[:10]
    x,y=map(list,zip(*top_n_bigrams))
    sns.barplot(x=y,y=x)

Analisis Sentimen

Analisis sentimen adalah alat yang banyak digunakan dengan perangkat NLP yang mengklasifikasikan sentimen data tekstual seperti respons siswa dengan cara otomatis. Pertama, kita dapat mengetahui distribusi sentimen menggunakan histogram polaritas. Polaritas adalah bilangan floating-point yang terletak pada rentang -1 sampai 1 dimana 1 berarti pernyataan positif dan -1 berarti pernyataan negatif.

from textblob import TextBlob
    
def plot_polarity_histogram(text):
    
    def polarity(text):
        return TextBlob(text).sentiment.polarity
    
    df_x = pd.DataFrame() 
    polarity_score =text.apply(lambda x : polarity(x))
    df_filtered['polarity_score']=df_filtered['text'].\
       apply(lambda x : polarity(x))
    polarity_score.hist()

Sentimen tersebut dapat kita analisa lebih lanjut untuk melihat sebaran sentimen positif, negatif, dan netral. Fungsi di bawah ini mengkategorikan sentimen dan menyajikan plot batang.

from textblob import TextBlob
import matplotlib.pyplot as plt
from nltk.sentiment.vader import SentimentIntensityAnalyzer
import nltk
def sentiment_vader(text, sid):
    ss = sid.polarity_scores(text)
    ss.pop('compound')
    return max(ss, key=ss.get)
def sentiment_textblob(text):
        x = TextBlob(text).sentiment.polarity
        
        if x<0:
            return 'Negative'
        elif x==0:
            return 'Neutral'
        else:
            return 'Positive'
        
def sentiment_x(x):
    if x<0:
        return 'Negative'
    elif x==0:
        return 'Neutral'
    else:
        return 'Positive' 
        
def plot_sentiment_barchart(text, method):
    if method == 'TextBlob':
        sentiment = text.map(lambda x: sentiment_textblob(x))
    elif method == 'Vader':
        nltk.download('vader_lexicon')
        sid = SentimentIntensityAnalyzer()
        sentiment = text.map(lambda x: sentiment_vader(x, sid=sid))
    else:
        raise ValueError('Textblob or Vader')
    
    df_filtered['polarity']=df_filtered['polarity_score'].\
       apply(lambda x : sentiment_x(x))
  
    plt.figure(figsize=(5, 2), dpi=100)
    plt.bar(sentiment.value_counts().index,
            sentiment.value_counts())

Teknologi analisis sentimen masih dalam tahap awal. Oleh karena itu, prediksi harus dievaluasi sesuai dan dengan campur tangan manusia. Namun dengan sejumlah besar data yang bersih dan diberi label, jaringan saraf yang cukup besar akan semakin akurat dan akan menjadi alat yang hebat dalam jangka panjang.