Në këtë postim do të hyjmë në botën e NLP ( përpunimi i gjuhës natyrore ) që studion ndërveprimet midis kompjuterëve dhe gjuhës njerëzore.

Analiza e tekstit është një fushë e madhe aplikimi për algoritmet e mësimit të makinerive.

Ne do të shpjegojmë se si të analizojmë tekstin e marrë nga rishikimet e produkteve të Amazon, ne do ta quajmë këtë analizë ndjenjash.

Në rishikimet e Amazon, klientët vendosin yje në komentin e tyre (1 deri në 5), në këtë rast ne marrim parasysh vetëm vlerësimet e mira (4,5) ose të këqija (1,2), jo neutrale.

Pastaj aplikoni një model parashikimi dhe vlerësoni performancën e tij. Ne do ta bëjmë atë në 2 pjesë:

pjesa 1) Ne do të pastrojmë tekstin tonë duke hequr gjithçka që nuk është e dobishme për ta analizuar atë. Ne do të përdorim NLTK për të hequr fjalët e ndalimit dhe për t'i përmbledhur fjalët tona. Ne do të krijojmë një vektorizer që na lejon të krijojmë një matricë me përsëritjen e fjalëve tona.

pjesa 2) Ne do të aplikojmë një model të quajtur Random Forest në kornizën tonë të të dhënave të marrë në pjesën 1. Më pas do të vlerësojmë performancën e tij me metrika të ndryshme dhe do të testojmë konfigurime të ndryshme të modelit duke përdorur GridSearchCV

Ok, shumë për të shpjeguar !!, ju rekomandoj që ndërsa lexoni çdo koncept që do të shpjegoj me kodin e tij, mbani jupyterin tuaj të hapur me fletoren kushtuar këtij postimi dhe provoni vetë.

Importoni bibliotekat

import pandas as pd
import nltk
import re
import string

nga nltk do të na duhen: ndalesa dhe PorterStemmer, por për çfarë janë ato?

Fjalë ndalese

përmban një grup fjalësh të pakuptimta si artikuj, përemra, parafjalë etj. që filtrohen para ose pas përpunimit. P.sh.: 'i', 'unë', 'i'ja', 'vetja ime', 'ne', 'jonë', 'tona', 'vetvetja', 'ju', 'ju jeni',...

Rrjedhimi dhe Lematizimi

PorterStemmer është një lloj Stemming: “ Rrjedha (rrënja) është pjesa e fjalës së cilës i shtoni ndajshtesa lakore (ndryshuese/rrjedhuese) si(-ed,-ize, -s ,-de,-ing). Pra, rrjedhja e një fjale ose fjalie mund të rezultojë në fjalë që nuk janë fjalë aktuale. Rrjedhat krijohen duke hequr prapashtesat ose parashtesat e përdorura me një fjalë. “ (datacamp.com)

Anjë teknikë tjetër e ngjashme është Lemmatizimi: “ Lemmatizimi, ndryshe nga Stemming, redukton fjalët e lakuara siç duhet duke siguruar që fjala rrënjë i përket gjuhës. Në lematizim, fjala rrënjë quhetLemma. Një lemë (lema ose lema në shumës) është forma kanonike, forma e fjalorit ose forma e citimit të një grupi fjalësh." (datacamp.com)

Pra, Stemming dhe Lemmatization të dyja gjenerojnë formën rrënjësore të fjalëve të lakuara. Dallimi është se rrjedha mund të mos jetë një fjalë aktuale ndërsa, lema është një fjalë e vërtetë gjuhësore. Të dyja janë teknika të mira të përdorura gjerësisht në Tekst Mining.

# nltk libraries
nltk.download('stopwords')
from nltk.corpus import stopwords
from nltk import PorterStemmer
stopwords = stopwords.words('english')
ps = PorterStemmer()

Merrni të dhënat

Ne i marrim të dhënat nga kaggle (Amazon Reviews for Sentiment Analysis). Të dhënat janë në skedarë txt të kompaktuar me bz2 me formatin e mëposhtëm:

__label__ Teksti i komentit, ku etiketa mund të jetë __label__1 (koment i keq) ose __label__2 (vlerësim i mirë)

import bz2 #unzip and load
train_file = bz2.BZ2File('train.ft.txt.bz2')
test_file = bz2.BZ2File('test.ft.txt.bz2')
train_lines = train_file.readlines()
test_lines = test_file.readlines()
print('Train line: {}'.format(train_lines[11]))

Linja e trenit: b'__label__2 Libër i mrekullueshëm: Ky ishte një libër i mrekullueshëm, thjesht nuk mund ta lija poshtë dhe munda…

Ka 3600000 linja treni, 400000 linja testimi !!

kështu, dhe për shkak të kohës së përpunimit, ne do të marrim vetëm një pjesë të vogël të atyre të dhënave

train_part = train_lines[:10000]
test_part = test_lines[:2000]
# Put all together
amz_rev_part = train_part + test_part

Përgatitni të dhënat

Tani do të marrim vlerat tona të X (rishikimi) dhe y (etiketa), me disa detyra pastrimi dhe transformimi në X

# Get label text and return 0 (__label__1=bad review) and 1 (__label__1=good_review)
def reviewToY(review): 
    return 0 if review.split(' ')[0] == '__label__1' else 1
# Get review string feature
# delete the last char (\n) and transform to lower
def reviewToX(review):
    review = review.split(' ', 1)[1][:-1].lower()
    return review
def splitReviewsLabels(lines): 
    reviews = []
    labels = []
    for review in tqdm(lines):
        rev = reviewToX(review)
        label = reviewToY(review)
        # only get the first 512 chars for review
        reviews.append(rev[:512])
        labels.append(label)
    return reviews, labels
X_amz_rev_part, y_amz_rev_part = splitReviewsLabels(amz_rev_part)

Më pas krijoni një metodë që shënon vlerësimet tona (merrni një listë fjalësh), hiqni fjalët e ndalimit dhe vendosni rrënjët e fjalëve:

# Tokenize sentence, then delete stopwords and stemming
def remove_stopword_and_stem(text):
    tokens = re.split('\W+', text)
    text = [ps.stem(word) for word in tokens if word not in stopwords]
 return text

Krijo çantën e fjalëve me CountVetorizer

Çfarë është një qese me fjalë?

BoW e kthen tekstin në vektorë me gjatësi fikse duke numëruar numrin e herëve që një fjalë shfaqet në një dokument.

Në Scikit Learn ka disa vektorizues që gjenerojnë një BoW, ku më të përdorurit janë CountVetorizer dhe TfidfVectorizer.

Për informacion të detajuar mbi këtë temë, lexoni "Nxjerrja e veçorive të tekstit" në "sklearn-feature-extraction"

# create vectorizer
count_vect = CountVectorizer(analyzer=remove_stopword_and_stem)
# train the vectorizer
vec = count_vect.fit(X_amz_rev_part)
# create my bag of words (X_cv) with transform()
X_cv = vec.transform(X_amz_rev_part)
# view BoW
print(X_cv.shape)
print(count_vect.get_feature_names()[3000:3010])

(12000, 31803)

['bock', 'bode', 'bodi', 'bodic', 'bodo', 'bodybuild', 'bodyfin', 'bodyroom', 'bodyguard', 'bodyment']

Dhe ky është lloji dhe forma e BoW-së sime:

‹12000x31803 matricë e rrallë e tipit '‹class 'numpy.int64'›' me 351918 elementë të ruajtur në formatin e ngjeshur të rreshtit të rrallë›

Tani ne krijojmë një kornizë të re të të dhënave me informacionin tim BoW:

# build dataframe with the sparse matrix 
X_features_df = pd.DataFrame(X_cv.toarray())
# Rename columns with the word
X_features_df.columns = count_vect.get_feature_names()
X_features_df

Tani që kemi kornizën tonë të të dhënave nga ku mund të marrim X (veçoritë), mund të shtojmë kolona të reja bazuar në të dhënat që kemi tashmë, si p.sh. një veçori që ka numrin e shkronjave që ka çdo rishikim.

Pra, ne marrim df-në tonë origjinale (X_amz_rev_part) dhe numërojmë letrat e rishikimit, më pas krijojmë veçorinë e re (review_len) në df-në e re (X_features_df ):

# Adding new features , For ex. = len(review) 
X_amz_df = pd.DataFrame(X_amz_rev_part, columns = ['Review'])
X_features_df['review_len'] = X_amz_df['Review'].apply(lambda x: len(x) - x.count(" "))
X_features_df['review_len']

ok, shumë numra, matricë dhe vektorë, po sikur të përfytyrojmë diçka më të kuptueshme për njeriun? :)

Për shembull, dhjetë fjalët kryesore të zakonshme në BoW tim:

# Sum words of my Bag of Words, and get an ordered freq. of that
sum_words = X_cv.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)
# get the top 10 common words
common_words = words_freq[:10]
# create df with top words and count
df = pd.DataFrame(common_words, columns = ['ReviewText' , 'count'])
# build a bar graph and plot
import matplotlib.pyplot as plt
fig = plt.gcf()
fig.set_size_inches( 20, 8)
ax = df.plot.bar(x='ReviewText', y='count', rot=0)

Ok njerëz, kjo është pjesa e parë e analizës sonë të ndjenjave në rishikimet e amazon. Ne i kemi marrë të dhënat tona në formën numerike të kërkuar nga një algoritëm i mësimit të makinës.

pjesën 2 ne do të aplikojmë për këto të dhëna një klasifikues ML të quajtur Pyll i rastësishëm, i cili shpresojmë se mund të parashikojë me saktësinë më të madhe nëse një rishikim është i mirë / i keq.

Si gjithmonë, lidhja e github me "analizën e ndjenjave jupyter nb" të plotë është bashkangjitur në mënyrë që të verifikoni vetë kodin. Më ndiqni gjithashtu në blogun tim të shkencës së të dhënave EmpowereDataScience

Komentet dhe/ose pëlqimet tuaja vlerësohen ;)