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.
Në 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 ;)