Zephyrnet-logo

Sentimentanalyse met LSTM

Datum:

Dit artikel is gepubliceerd als onderdeel van het Data Science-blogathon.

Introductie

Sentimentanalyse is een NLP-toepassing die de emotionele of sentimentele toon of mening van een tekstcorpus identificeert. Gewoonlijk kunnen emoties of houdingen ten opzichte van een onderwerp positief, negatief of neutraal zijn. Dit maakt sentimentanalyse tot een tekstclassificatietaak. Voorbeelden van positieve, negatieve en neutrale uitdrukkingen zijn:

“Ik heb genoten van de film!” – Positief

"Ik weet niet zeker of ik de film leuk vond." – Neutraal

"Het was de meest verschrikkelijke film die ik ooit heb gezien." – Negatief

Sentimentanalyse is een krachtig hulpmiddel met uiteenlopende toepassingen in verschillende sectoren. Het is nuttig voor sociale media en merkmonitoring, klantenondersteuning en feedbackanalyse, marktonderzoek, enz. De doelgroep of demografie van een nieuw product kan worden geïdentificeerd door sentimentanalyse uit te voeren op de eerste ontvangen feedback van klanten, en het kan helpen bij het evalueren van het succes van een marketing campagne. Naarmate sentimentanalyse in de branche steeds nuttiger wordt, wordt het essentieel voor ons om te leren hoe deze uit te voeren. In dit artikel wordt uitgelegd hoe u sentimentanalyses kunt uitvoeren op filmrecensies met behulp van LSTM's.

 

Wat is LSTM? 

Terugkerende neurale netwerken (RNN's) zijn een vorm van kunstmatige neurale netwerken die reeksen invoerpatronen van willekeurige lengte kunnen onthouden door verbindingen tussen opeenvolgende gegevenstypen vast te leggen. Vanwege het falen van stochastische gradiënten zijn RNN's echter niet in staat om langdurige afhankelijkheden in lange reeksen te detecteren. Verschillende nieuwe RNN-modellen, met name LSTM, werden voorgesteld om dit probleem aan te pakken. LSTM-netwerken zijn RNN-extensies die zijn ontworpen om sequentiële (tijdelijke) gegevens en hun langetermijnverbindingen nauwkeuriger te leren dan standaard RNN's. Ze worden vaak gebruikt in deep learning-toepassingen zoals voorraadprognoses, spraakherkenning, natuurlijke taalverwerking, enz.

 

De gegevensset laden 

We zullen sentimentanalyse uitvoeren op 50 IMDB-filmrecensies en de dataset wordt in evenwicht gehouden met 25 positieve en 25 negatieve filmrecensies. U kunt de dataset downloaden van hier. We beginnen met het importeren van benodigde pakketten voor tekstmanipulatie en modelbouw.

importeer panda's opnieuw als pd importeer numpy als np van sklearn.preprocessing importeer LabelEncoder van sklearn.model_selection importeer train_test_split van keras.preprocessing.text importeer Tokenizer van keras.preprocessing.sequence importeer pad_sequences importeer kera's van sklearn.metrics van sklearn.metrics nauwkeurigheid importeren_score wiskunde importeren nltk

We laden de dataset in een panda's dataframe met behulp van de volgende code:

data = pd.read_csv('IMDB Dataset.csv') data

De gegevens zien er als volgt uit:

Sentimentanalyse met LSTM

Bron: Screenshot van mijn Jupyter Notebook

 

Data Preprocessing

Eerst moeten we HTML-tags, URL's en niet-alfanumerieke tekens uit de recensies verwijderen. We doen dat met behulp van de remove_tags-functie, en Regex-functies worden gebruikt voor eenvoudige manipulatie van strings.

def remove_tags(string): removelist = "" result = re.sub('','',string) #verwijder HTML-tags result = re.sub('https://.*','',result) #remove URL's result = re.sub(r'[^w'+removelist+']', ' ',result) #remove niet-alfanumerieke karakters result = result.lower() return resultaat data['review']=data['review '].apply(lambda cw: remove_tags(cw))

We moeten ook stopwoorden uit het corpus verwijderen. Stopwoorden zijn veelgebruikte woorden zoals 'and', 'the', 'at' die geen speciale betekenis of betekenis aan een zin toevoegen. Een lijst met stopwoorden is beschikbaar met nltk, en ze kunnen uit het corpus worden verwijderd met de volgende code:

nltk.download('stopwords') van nltk.corpus import stopwords stop_words = set(stopwords.words('english')) data['review'] = data['review'].apply(lambda x: ' '.join ([woord voor woord in x.split() indien woord niet in (stop_words)]))

We voeren nu lemmatisering uit op de tekst. Lemmatisatie is een nuttige techniek in NLP om de wortelvorm van woorden te verkrijgen, ook wel lemma's genoemd. Het lemma van de woorden lezen, lezen, lezen wordt bijvoorbeeld gelezen. Dit helpt onnodige rekenkundige overhead te besparen bij het proberen om hele woorden te ontcijferen, omdat de betekenissen van de meeste woorden goed worden uitgedrukt door hun afzonderlijke lemma's. We voeren lemmatisering uit met behulp van de WordNetLemmatizer() van nltk. De tekst wordt eerst opgedeeld in afzonderlijke woorden met behulp van de WhitespaceTokenizer() van nltk. We schrijven een functie lemmatize_text om lemmatisatie uit te voeren op de individuele tokens.

w_tokenizer = nltk.tokenize.WhitespaceTokenizer() lemmatizer = nltk.stem.WordNetLemmatizer() def lemmatize_text(text): st = "" voor w in w_tokenizer.tokenize(text): st = st + lemmatizer.lemmatize(w) + " " return st data['review'] = data.review.apply(lemmatize_text) data

De verwerkte gegevens zien er als volgt uit:

Sentimentanalyse met LSTM
Bron: Screenshot van mijn Jupyter Notebook

Vervolgens printen we enkele basisstatistieken over de dataset en controleren of de dataset in evenwicht is of niet (gelijk aantal van alle labels). Idealiter zou de dataset in evenwicht moeten zijn, omdat een ernstig onevenwichtige dataset een uitdaging kan zijn om te modelleren en gespecialiseerde technieken vereist.

s = 0.0 voor i in data ['review']: word_list = i.split() s = s + len(word_list) print("Gemiddelde lengte van elke recensie: ",s/data.shape[0]) pos = 0 voor i in range(data.shape[0]): if data.iloc[i]['sentiment'] == 'positive': pos = pos + 1 neg = data.shape[0]-pos print(" Percentage reviews met een positief sentiment is "+str(pos/data.shape[0]*100)+"%") print("Percentage reviews met een negatief sentiment is "+str(neg/data.shape[0]*) 100)+"%") >>Gemiddelde lengte van elke beoordeling: 119.57112 >>Percentage beoordelingen met een positief sentiment is 50.0% >>Percentage beoordelingen met een negatief sentiment is 50.0%

Labels coderen en trein-testsplitsingen maken

We gebruiken de LabelEncoder() van sklearn.preprocessing om de labels ('positief', 'negatief') om te zetten in respectievelijk enen en nullen.

reviews = data['review'].values ​​labels = data['sentiment'].values ​​encoder = LabelEncoder() encoded_labels = encoder.fit_transform(labels)

Ten slotte splitsen we de dataset op in trein- en testonderdelen met behulp van train_test_split van sklearn.model_selection. We gebruiken 80% van de dataset voor training en 20% voor testen.

train_sentences, test_sentences, train_labels, test_labels = train_test_split (reviews, encoded_labels, stratify = encoded_labels)

Voordat ze in het LSTM-model worden ingevoerd, moeten de gegevens worden opgevuld en getokeniseerd:

  • Tokeniseren: De ingebouwde tokenizer-API van Keras past in de dataset, die de zinnen in woorden splitst en een woordenboek creëert van alle unieke gevonden woorden en hun uniek toegewezen gehele getallen. Elke zin wordt omgezet in een reeks gehele getallen die alle afzonderlijke woorden vertegenwoordigen die erin voorkomen.
  • Volgorde vulling: De array die elke zin in de dataset vertegenwoordigt, is gevuld met nullen aan de linkerkant om de grootte van de array tien te maken en alle collecties even lang te maken.
# Hyperparameters van het model vocab_size = 3000 # kies op basis van statistieken oov_tok = '' embedding_dim = 100 max_length = 200 # kies op basis van statistieken, bijvoorbeeld 150 tot 200 padding_type='post' trunc_type='post' # tokenize zinnen tokenizer = Tokenizer (num_words = vocab_size, oov_token=oov_tok) tokenizer.fit_on_texts(train_sentences) word_index = tokenizer.word_index # converteer treindataset naar sequentie en padsequenties train_sequences = tokenizer.texts_to_sequences(train_sentences'maxpadding=paddings_sequences) =max_length) # converteer testgegevensset naar reeks en padreeksen test_sequences = tokenizer.texts_to_sequences(test_sentences) test_padded = pad_sequences(test_sequences, padding='post', maxlen=max_length)

Het model bouwen

Er wordt een Keras sequentieel model gebouwd. Het is een lineaire stapel van de volgende lagen:

  •  Een inbeddingslaag met dimensie 100 zet elk woord in de zin om in een dichte vector met vaste lengte van 100. De invoerdimensie wordt ingesteld als de woordenschatgrootte en de uitvoerdimensie is 100. Elk woord in de invoer wordt daarom weergegeven door een vector van grootte 100.
  • Een bidirectionele LSTM-laag van 64 eenheden.
  • Een dichte (volledig verbonden) laag van 24 eenheden met relu-activering.
  • Een dichte laag van 1 eenheid en sigmoïde activering geeft de kans op de beoordeling positief, dwz als het label 1 is.

De code voor het bouwen van het model:

# model initialisatie model = keras.Sequential([keras.layers.Embedding(vocab_size, embedding_dim, input_length=max_length), keras.layers.Bidirectioneel(keras.layers.LSTM(64)), keras.layers.Dense(24, activatie ='relu'), keras.layers.Dense(1, activatie='sigmoid') ]) # compileer model model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # modeloverzicht model.summary()

Het model is gecompileerd met binair kruis-entropieverlies en adam-optimizer. Omdat we een binair classificatieprobleem hebben, wordt binair kruis-entropieverlies gebruikt. De Adam-optimizer gebruikt stochastische gradiëntafdaling om deep learning-modellen te trainen en vergelijkt elk van de voorspelde kansen met het werkelijke klasselabel (0 of 1). Nauwkeurigheid wordt gebruikt als de primaire prestatiemaatstaf. Het modeloverzicht is hieronder te zien:

Het model bouwen

Bron: Screenshot van mijn Jupyter Notebook

 

Modeltraining en evaluatie

Het model is getraind voor vijf tijdperken.

num_epochs = 5 history = model.fit(train_padded, train_labels, epochs=num_epochs, verbose=1, validation_split=0.1)

Het model wordt geëvalueerd door de nauwkeurigheid ervan te berekenen. De nauwkeurigheid van de classificatie wordt berekend door het aantal juiste voorspellingen te delen door het totale aantal voorspellingen.

voorspelling = model.predict(test_padded) # Haal labels op gebaseerd op kans 1 if p>= 0.5 else 0 pred_labels = [] for i in voorspelling: if i >= 0.5: pred_labels.append(1) else: pred_labels.append(0 ) print("Nauwkeurigheid van voorspelling op testset : ", accuratesse_score(test_labels,pred_labels))

De nauwkeurigheid van de voorspelling op de testset komt uit op 87.27%! U kunt de nauwkeurigheid verder verbeteren door te spelen met de modelhyperparameters, de modelarchitectuur verder af te stemmen of de trein-test-splitverhouding te wijzigen. Je zou het model ook moeten trainen voor een groter aantal tijdperken, en we stopten bij vijf tijdperken vanwege de rekentijd. In het ideale geval zou het helpen het model voor te bereiden totdat de trein- en testverliezen convergeren.

 

Het model gebruiken om het sentiment van ongeziene filmrecensies te bepalen

We kunnen ons getrainde model gebruiken om het sentiment te bepalen van nieuwe ongeziene filmrecensies die niet in de dataset aanwezig zijn. Elke nieuwe tekst moet worden getokeniseerd en opgevuld voordat deze als invoer in het model wordt ingevoerd. De functie model.predict() retourneert de waarschijnlijkheid van de positieve beoordeling. Als de kans groter is dan 0.5, beschouwen we het onderzoek als positief, anders negatief.

# recensies waarop we moeten voorspellen zin = ["De film was erg ontroerend en hartverscheurend", "Ik heb nog nooit zo'n vreselijke film gezien", "de filmplot is verschrikkelijk, maar er werd goed geacteerd"] # converteren naar a sequence sequences = tokenizer.texts_to_sequences(zin) # pad the sequence padding = pad_sequences(sequences, padding='post', maxlen=max_length) # Haal labels op gebaseerd op kans 1 als p>= 0.5 else 0 voorspelling = model.predict( opgevuld) pred_labels = [] for i in voorspelling: if i >= 0.5: pred_labels.append(1) else: pred_labels.append(0) for i in range(len(zin)): print(zin[i]) if pred_labels[i] == 1: s = 'Positief' else: s = 'Negatief' print("Voorspelde sentiment: ",s)

De output ziet er veelbelovend uit!

Bron: Screenshot van mijn Jupyter Notebook

 

Conclusie

Sentimentanalyse kan, net als elke andere classificatietaak, worden uitgevoerd met veel verschillende modellen voor machine learning en deep learning, zoals Naive Bayes, KNN, SVM of CNN, ANN, enz. Nu u de basis kent, kunt u doorgaan en andere modellen verkennen om sentimentanalyse uitvoeren.

Bedankt voor het lezen.

Jij kunt lezen hier over het gebruik van CNN's voor tekstclassificatie!

Voel je vrij om contact met mij op te nemen via e-mail: [e-mail beveiligd]

De in dit artikel getoonde media zijn geen eigendom van Analytics Vidhya en worden naar goeddunken van de auteur gebruikt. 

Bron: https://www.analyticsvidhya.com/blog/2022/01/sentiment-analysis-with-lstm/

spot_img

Laatste intelligentie

spot_img

Chat met ons

Hallo daar! Hoe kan ik u helpen?