Gensim - Szybki przewodnik

Ten rozdział pomoże ci zrozumieć historię i funkcje Gensim, a także jego zastosowania i zalety.

Co to jest Gensim?

Gensim = “Generate Similar”to popularna biblioteka open source do przetwarzania języka naturalnego (NLP) używana do modelowania tematów bez nadzoru. Wykorzystuje najlepsze modele akademickie i nowoczesne statystyczne uczenie maszynowe do wykonywania różnych złożonych zadań, takich jak -

  • Tworzenie dokumentów lub wektorów słów
  • Corpora
  • Wykonywanie identyfikacji tematu
  • Wykonywanie porównania dokumentów (pobieranie semantycznie podobnych dokumentów)
  • Analiza dokumentów tekstowych pod kątem struktury semantycznej

Oprócz wykonywania wyżej wymienionych złożonych zadań, Gensim, zaimplementowany w Pythonie i Cythonie, jest przeznaczony do obsługi dużych zbiorów tekstów przy użyciu strumieniowania danych, a także przyrostowych algorytmów online. To sprawia, że ​​różni się od tych pakietów oprogramowania do uczenia maszynowego, które są przeznaczone tylko do przetwarzania w pamięci.

Historia

W 2008 roku Gensim zaczął jako zbiór różnych skryptów Pythona dla czeskiej matematyki cyfrowej. Służyło tam do wygenerowania krótkiej listy artykułów najbardziej podobnych do danego artykułu. Ale w 2009 roku RARE Technologies Ltd. wydało swoją pierwszą wersję. Następnie, w lipcu 2019 roku, otrzymaliśmy jego stabilną wersję (3.8.0).

Różne funkcje

Oto niektóre funkcje i możliwości oferowane przez Gensim -

Skalowalność

Gensim może z łatwością przetwarzać duże korporacje na skalę internetową, używając swoich algorytmów przyrostowego szkolenia online. Z natury jest skalowalny, ponieważ nie ma potrzeby, aby cały korpus wejściowy znajdował się w całości w pamięci o dostępie swobodnym (RAM) w dowolnym momencie. Innymi słowy, wszystkie jego algorytmy są niezależne od pamięci w odniesieniu do rozmiaru korpusu.

Krzepki

Gensim ma solidny charakter i jest używany w różnych systemach przez różne osoby i organizacje od ponad 4 lat. Możemy łatwo podłączyć własny korpus wejściowy lub strumień danych. Jest również bardzo łatwy do rozszerzenia o inne algorytmy przestrzeni wektorowej.

Platforma Agnostic

Jak wiemy, Python jest bardzo wszechstronnym językiem, ponieważ będąc czystym Pythonem, Gensim działa na wszystkich platformach (takich jak Windows, Mac OS, Linux), które obsługują Python i Numpy.

Wydajne implementacje wielordzeniowe

Aby przyspieszyć przetwarzanie i pobieranie w klastrach maszyn, Gensim zapewnia wydajne implementacje wielordzeniowe różnych popularnych algorytmów, takich jak Latent Semantic Analysis (LSA), Latent Dirichlet Allocation (LDA), Random Projections (RP), Hierarchical Dirichlet Process (HDP).

Open Source i obfitość wsparcia społeczności

Gensim jest objęty licencją na podstawie zatwierdzonej przez OSI licencji GNU LGPL, która pozwala na bezpłatne korzystanie z niego zarówno do użytku osobistego, jak i komercyjnego. Wszelkie modyfikacje wprowadzone w Gensim są z kolei oparte na otwartych źródłach i mają również duże wsparcie społeczności.

Zastosowania Gensim

Gensim był używany i cytowany w ponad tysiącach zastosowań komercyjnych i akademickich. Jest również cytowany w różnych pracach naukowych i pracach studenckich. Obejmuje strumieniowe zrównoleglone implementacje następujących elementów -

fastText

fastText, wykorzystuje sieć neuronową do osadzania słów, jest biblioteką do nauki osadzania słów i klasyfikacji tekstu. Jest tworzony przez laboratorium AI Research (FAIR) Facebooka. Ten model w zasadzie pozwala nam stworzyć nadzorowany lub nienadzorowany algorytm do uzyskiwania reprezentacji wektorowych dla słów.

Word2vec

Word2vec, używany do tworzenia osadzania słów, to grupa płytkich i dwuwarstwowych modeli sieci neuronowych. Modele są w zasadzie przeszkolone w zakresie rekonstrukcji językowych kontekstów słów.

LSA (ukryta analiza semantyczna)

Jest to technika stosowana w NLP (przetwarzanie języka naturalnego), która pozwala nam analizować relacje między zbiorem dokumentów a zawierającymi je terminami. Odbywa się to poprzez stworzenie zestawu pojęć związanych z dokumentami i terminami.

LDA (Latent Dirichlet Allocation)

Jest to technika w NLP, która pozwala na wyjaśnianie zestawów obserwacji przez nieobserwowane grupy. Te niezauważone grupy wyjaśniają, dlaczego niektóre części danych są podobne. Dlatego jest to generatywny model statystyczny.

tf-idf (termin odwrotna częstotliwość dokumentu)

tf-idf, statystyka numeryczna w wyszukiwaniu informacji, odzwierciedla, jak ważne jest słowo dla dokumentu w korpusie. Jest często używany przez wyszukiwarki do oceny i rankingu trafności dokumentu na podstawie zapytania użytkownika. Może być również używany do filtrowania słów pomijanych w podsumowaniu tekstu i klasyfikacji.

Wszystkie z nich zostaną szczegółowo wyjaśnione w następnych rozdziałach.

Zalety

Gensim to pakiet NLP, który zajmuje się modelowaniem tematycznym. Ważne zalety Gensim są następujące -

  • Możemy uzyskać udogodnienia modelowania tematów i osadzania słów w innych pakietach, takich jak ‘scikit-learn’ i ‘R’, ale udogodnienia oferowane przez Gensim do tworzenia modeli tematycznych i osadzania słów są niezrównane. Zapewnia również wygodniejsze narzędzia do przetwarzania tekstu.

  • Kolejną najważniejszą zaletą Gensima jest to, że pozwala nam obsługiwać duże pliki tekstowe nawet bez ładowania całego pliku do pamięci.

  • Gensim nie wymaga kosztownych adnotacji ani ręcznego tagowania dokumentów, ponieważ wykorzystuje modele bez nadzoru.

Rozdział wyjaśnia wymagania wstępne instalacji Gensim, jego podstawowe zależności oraz informacje o jego aktualnej wersji.

Wymagania wstępne

Aby zainstalować Gensim, musimy mieć zainstalowany Python na naszych komputerach. Możesz przejść do łącza www.python.org/downloads/ i wybrać najnowszą wersję dla swojego systemu operacyjnego, tj. Windows i Linux / Unix. Możesz skorzystać z łącza www.tutorialspoint.com/python3/index.htm, aby zapoznać się z podstawowym samouczkiem dotyczącym języka Python. Gensim jest obsługiwany w systemach Linux, Windows i Mac OS X.

Zależności kodu

Gensim powinien działać na dowolnej platformie obsługującej Python 2.7 or 3.5+ i NumPy. W rzeczywistości zależy to od następującego oprogramowania -

Pyton

Gensim jest testowany z wersjami Pythona 2.7, 3.5, 3.6 i 3.7.

Odrętwiały

Jak wiemy, NumPy to pakiet do obliczeń naukowych w Pythonie. Może być również używany jako wydajny wielowymiarowy kontener danych ogólnych. Gensim zależy od pakietu NumPy do przetwarzania liczb. Aby zapoznać się z podstawowym samouczkiem dotyczącym języka Python, możesz skorzystać z łącza www.tutorialspoint.com/numpy/index.htm .

smart_open

smart_open, biblioteka Python 2 i Python 3, służy do wydajnego przesyłania strumieniowego bardzo dużych plików. Obsługuje przesyłanie strumieniowe z / do magazynów, takich jak S3, HDFS, WebHDFS, HTTP, HTTPS, SFTP lub lokalne systemy plików. Gensim zależy odsmart_open Biblioteka Pythona do przezroczystego otwierania plików na zdalnym magazynie, a także plików skompresowanych.

Obecna wersja

Aktualna wersja Gensim to 3.8.0 który został wydany w lipcu 2019 r.

Instalacja za pomocą terminala

Jednym z najprostszych sposobów zainstalowania Gensima jest uruchomienie następującego polecenia w terminalu -

pip install --upgrade gensim

Instalowanie przy użyciu środowiska Conda

Alternatywnym sposobem pobrania Gensima jest użycie condaśrodowisko. Uruchom następujące polecenie w swoimconda terminal -

conda install –c conda-forge gensim

Instalowanie za pomocą pakietu źródłowego

Załóżmy, że jeśli pobrałeś i rozpakowałeś pakiet źródłowy, musisz uruchomić następujące polecenia -

python setup.py test
python setup.py install

Tutaj dowiemy się o podstawowych koncepcjach Gensim, ze szczególnym uwzględnieniem dokumentów i korpusu.

Podstawowe pojęcia Gensim

Poniżej przedstawiono podstawowe pojęcia i terminy potrzebne do zrozumienia i używania Gensim -

  • Document - Z To odnosi się do jakiegoś tekstu.

  • Corpus - Odnosi się do zbioru dokumentów.

  • Vector - Matematyczna reprezentacja dokumentu nazywana jest wektorem.

  • Model - Odnosi się do algorytmu używanego do przekształcania wektorów z jednej reprezentacji do drugiej.

Co to jest dokument?

Jak omówiono, odnosi się do jakiegoś tekstu. Jeśli przejdziemy bardziej szczegółowo, jest to obiekt typu sekwencji tekstu, który jest znany jako‘str’ w Pythonie 3. Na przykład w Gensim dokumentem może być wszystko, na przykład -

  • Krótki tweet zawierający 140 znaków
  • Pojedynczy akapit, czyli streszczenie artykułu lub pracy naukowej
  • Artykuł informacyjny
  • Book
  • Novel
  • Theses

Sekwencja tekstu

Typ sekwencji tekstu jest powszechnie znany jako ‘str’ w Pythonie 3. Jak wiemy, w Pythonie dane tekstowe są obsługiwane za pomocą łańcuchów lub bardziej szczegółowo ‘str’obiekty. Ciągi znaków są w zasadzie niezmiennymi sekwencjami punktów kodowych Unicode i można je zapisać w następujący sposób -

  • Single quotes - Na przykład ‘Hi! How are you?’. Pozwala nam również osadzać podwójne cudzysłowy. Na przykład,‘Hi! “How” are you?’

  • Double quotes - Na przykład "Hi! How are you?". Pozwala nam również osadzać pojedyncze cudzysłowy. Na przykład,"Hi! 'How' are you?"

  • Triple quotes - Może mieć trzy pojedyncze cudzysłowy, takie jak, '''Hi! How are you?'''. lub trzy podwójne cudzysłowy, takie jak,"""Hi! 'How' are you?"""

Wszystkie spacje zostaną uwzględnione w literale ciągu.

Przykład

Poniżej znajduje się przykład dokumentu w Gensim -

Document = “Tutorialspoint.com is the biggest online tutorials library and it’s all free also”

Co to jest Corpus?

Korpus można zdefiniować jako duży i zorganizowany zbiór tekstów do odczytu maszynowego, tworzonych w naturalnym środowisku komunikacyjnym. W Gensim zbiór obiektów dokumentu nazywany jest korpusem. Liczba mnoga korpusu tocorpora.

Rola Corpus w Gensim

Korpus w Gensim spełnia następujące dwie role -

Służy jako dane wejściowe do szkolenia modelu

Pierwszą i najważniejszą rolą, jaką odgrywa korpus w Gensim, jest wprowadzenie do treningu modelu. Aby zainicjować wewnętrzne parametry modelu, podczas szkolenia model szuka pewnych wspólnych tematów i tematów z korpusu szkoleniowego. Jak wspomniano powyżej, Gensim koncentruje się na modelach bez nadzoru, dlatego nie wymaga żadnej interwencji człowieka.

Służy jako ekstraktor tematów

Po przeszkoleniu modelu można go użyć do wyodrębnienia tematów z nowych dokumentów. Tutaj nowe dokumenty to te, które nie są wykorzystywane w fazie szkolenia.

Przykład

Korpus może zawierać wszystkie tweety danej osoby, listę wszystkich artykułów z gazety lub wszystkie artykuły naukowe na określony temat itp.

Zbieranie Corpus

Poniżej znajduje się przykład małego korpusu, który zawiera 5 dokumentów. Tutaj każdy dokument jest łańcuchem składającym się z jednego zdania.

t_corpus = [
   "A survey of user opinion of computer system response time",
   "Relation of user perceived response time to error measurement",
   "The generation of random binary unordered trees",
   "The intersection graph of paths in trees",
   "Graph minors IV Widths of trees and well quasi ordering",
]

Przetwarzanie wstępne Zbieranie korpusu

Po zebraniu korpusu należy wykonać kilka kroków wstępnego przetwarzania, aby zachować prostotę korpusu. Możemy po prostu usunąć niektóre powszechnie używane angielskie słowa, takie jak „the”. Możemy również usunąć słowa, które występują tylko raz w korpusie.

Na przykład następujący skrypt w języku Python jest używany do małych liter w każdym dokumencie, dzielenia go na białe znaki i odfiltrowywania słów ignorowanych -

Przykład

import pprint
t_corpus = [
   "A survey of user opinion of computer system response time", 
   "Relation of user perceived response time to error measurement", 
   "The generation of random binary unordered trees", 
   "The intersection graph of paths in trees", 
   "Graph minors IV Widths of trees and well quasi ordering",
]
stoplist = set('for a of the and to in'.split(' '))
processed_corpus = [[word for word in document.lower().split() if word not in stoplist]
   for document in t_corpus]
	
pprint.pprint(processed_corpus)
]

Wynik

[['survey', 'user', 'opinion', 'computer', 'system', 'response', 'time'],
['relation', 'user', 'perceived', 'response', 'time', 'error', 'measurement'],
['generation', 'random', 'binary', 'unordered', 'trees'],
['intersection', 'graph', 'paths', 'trees'],
['graph', 'minors', 'iv', 'widths', 'trees', 'well', 'quasi', 'ordering']]

Efektywne przetwarzanie wstępne

Gensim zapewnia również funkcję bardziej efektywnego przetwarzania wstępnego korpusu. W takim przetwarzaniu wstępnym możemy przekształcić dokument w listę tokenów składających się z małych liter. Możemy również zignorować tokeny, które są za krótkie lub za długie. Taka jest funkcjagensim.utils.simple_preprocess(doc, deacc=False, min_len=2, max_len=15).

gensim.utils.simple_preprocess() fucntion

Gensim udostępnia tę funkcję, aby przekształcić dokument w listę tokenów zapisanych małymi literami, a także do ignorowania tokenów, które są zbyt krótkie lub zbyt długie. Ma następujące parametry -

doc (str)

Odnosi się do dokumentu wejściowego, na którym należy zastosować przetwarzanie wstępne.

deacc (bool, opcjonalnie)

Ten parametr służy do usuwania znaków akcentu z tokenów. To używadeaccent() zrobić to.

min_len (int, opcjonalnie)

Za pomocą tego parametru możemy ustawić minimalną długość tokena. Żetony krótsze niż określona długość zostaną odrzucone.

max_len (int, opcjonalnie)

Za pomocą tego parametru możemy ustawić maksymalną długość tokena. Tokeny dłuższe niż określona długość zostaną odrzucone.

Wynikiem tej funkcji byłyby tokeny wyodrębnione z dokumentu wejściowego.

Tutaj dowiemy się o podstawowych koncepcjach Gensim, ze szczególnym uwzględnieniem wektora i modelu.

Co to jest wektor?

A jeśli chcemy wywnioskować ukrytą strukturę w naszym korpusie? W tym celu musimy przedstawić dokumenty w taki sposób, abyśmy mogli manipulować nimi matematycznie. Jednym z popularnych rodzajów reprezentacji jest przedstawienie każdego dokumentu korpusu jako wektora cech. Dlatego możemy powiedzieć, że wektor jest matematycznie wygodną reprezentacją dokumentu.

Aby dać przykład, przedstawmy pojedynczą funkcję z naszego powyżej używanego korpusu jako parę do kontroli jakości -

Q - Ile razy to słowo Hello pojawia się w dokumencie?

A - Zero (0).

Q - Ile akapitów zawiera dokument?

A - Dwa (2)

Pytanie jest generalnie reprezentowane przez jego całkowity id, stąd reprezentacja tego dokumentu to seria par, takich jak (1, 0,0), (2, 2,0). Taka reprezentacja wektora jest znana jakodensewektor. Czemudense, ponieważ zawiera jednoznaczną odpowiedź na wszystkie powyższe pytania.

Reprezentacja może być prosta, jak (0, 2), jeśli znamy wszystkie pytania z góry. Taka kolejność odpowiedzi (oczywiście jeśli pytania są znane z góry) tovector dla naszego dokumentu.

Innym popularnym rodzajem reprezentacji jest bag-of-word (BoW)Model. W tym podejściu każdy dokument jest zasadniczo reprezentowany przez wektor zawierający liczbę częstotliwości każdego słowa w słowniku.

Aby dać ci przykład, załóżmy, że mamy słownik zawierający słowa [„Hello”, „How”, „are”, „you”]. Dokument składający się z ciągu „How are you how” byłby wówczas reprezentowany przez wektor [0, 2, 1, 1]. Tutaj wpisy wektora są w kolejności wystąpienia „Hello”, „How”, „are” i „you”.

Dokument wektorowy a dokument

Z powyższego wyjaśnienia wektora, można prawie zrozumieć różnicę między dokumentem a wektorem. Ale żeby było jaśniej,document to tekst i vectorjest matematycznie wygodną reprezentacją tego tekstu. Niestety, czasami wiele osób używa tych terminów zamiennie.

Na przykład, załóżmy, że mamy jakiś arbitralny dokument A, a następnie zamiast mówić „wektor odpowiadający dokumentowi A”, zwykli mawiać, „wektor A” lub „dokument A”. Prowadzi to do wielkiej niejednoznaczności. Jeszcze jedną ważną rzeczą, na którą należy zwrócić uwagę, jest to, że dwa różne dokumenty mogą mieć tę samą reprezentację wektorową.

Konwersja korpusu do listy wektorów

Zanim weźmiemy przykład implementacji konwersji korpusu na listę wektorów, musimy skojarzyć każde słowo w korpusie z unikalnym identyfikatorem całkowitym. W tym celu rozszerzymy przykład z powyższego rozdziału.

Przykład

from gensim import corpora
dictionary = corpora.Dictionary(processed_corpus)
print(dictionary)

Wynik

Dictionary(25 unique tokens: ['computer', 'opinion', 'response', 'survey', 'system']...)

Pokazuje, że w naszym korpusie jest w tym 25 różnych tokenów gensim.corpora.Dictionary.

Przykład implementacji

Możemy użyć słownika, aby zamienić tokenizowane dokumenty na te 5-wymiarowe wektory w następujący sposób -

pprint.pprint(dictionary.token2id)

Wynik

{
   'binary': 11,
   'computer': 0,
   'error': 7,
   'generation': 12,
   'graph': 16,
   'intersection': 17,
   'iv': 19,
   'measurement': 8,
   'minors': 20,
   'opinion': 1,
   'ordering': 21,
   'paths': 18,
   'perceived': 9,
   'quasi': 22,
   'random': 13,
   'relation': 10,
   'response': 2,
   'survey': 3,
   'system': 4,
   'time': 5,
   'trees': 14,
   'unordered': 15,
   'user': 6,
   'well': 23,
   'widths': 24
}

I podobnie, możemy utworzyć reprezentację worka słów dla dokumentu w następujący sposób -

BoW_corpus = [dictionary.doc2bow(text) for text in processed_corpus]
pprint.pprint(BoW_corpus)

Wynik

[
   [(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1)],
   [(2, 1), (5, 1), (6, 1), (7, 1), (8, 1), (9, 1), (10, 1)],
   [(11, 1), (12, 1), (13, 1), (14, 1), (15, 1)],
   [(14, 1), (16, 1), (17, 1), (18, 1)],
   [(14, 1), (16, 1), (19, 1), (20, 1), (21, 1), (22, 1), (23, 1), (24, 1)]
]

Co to jest model?

Po wektoryzacji korpusu, co dalej? Teraz możemy to przekształcić za pomocą modeli. Model można odnieść do algorytmu używanego do przekształcania reprezentacji jednego dokumentu w inny.

Jak już omówiliśmy, dokumenty w Gensim są reprezentowane jako wektory, dlatego możemy, chociaż modelować jako transformację między dwiema przestrzeniami wektorowymi. Zawsze istnieje faza szkoleniowa, w której modele uczą się szczegółów takich przekształceń. Model odczytuje korpus treningowy podczas fazy treningu.

Inicjowanie modelu

Zróbmy inicjalizację tf-idfModel. Model ten przekształca wektory z reprezentacji BoW (Bag of Words) do innej przestrzeni wektorowej, w której liczniki częstotliwości są ważone zgodnie ze względną rzadkością każdego słowa w korpusie.

Przykład implementacji

W poniższym przykładzie mamy zamiar zainicjować tf-idfModel. Będziemy trenować go na naszym korpusie, a następnie przekształcić ciąg „wykres drzew”.

Przykład

from gensim import models
tfidf = models.TfidfModel(BoW_corpus)
words = "trees graph".lower().split()
print(tfidf[dictionary.doc2bow(words)])

Wynik

[(3, 0.4869354917707381), (4, 0.8734379353188121)]

Teraz, po utworzeniu modelu, możemy przekształcić cały korpus za pomocą tfidf i zindeksować go, a także zapytać o podobieństwo naszego dokumentu zapytania (podajemy dokument zapytania „system drzew”) w odniesieniu do każdego dokumentu w korpusie -

Przykład

from gensim import similarities
index = similarities.SparseMatrixSimilarity(tfidf[BoW_corpus],num_features=5)
query_document = 'trees system'.split()
query_bow = dictionary.doc2bow(query_document)
simils = index[tfidf[query_bow]]
print(list(enumerate(simils)))

Wynik

[(0, 0.0), (1, 0.0), (2, 1.0), (3, 0.4869355), (4, 0.4869355)]

Z powyższego wynika, że ​​dokument 4 i dokument 5 mają wynik podobieństwa wynoszący około 49%.

Co więcej, możemy również posortować te dane wyjściowe dla większej czytelności w następujący sposób -

Przykład

for doc_number, score in sorted(enumerate(sims), key=lambda x: x[1], reverse=True):
   print(doc_number, score)

Wynik

2 1.0
3 0.4869355
4 0.4869355
0 0.0
1 0.0

W ostatnim rozdziale, w którym omawialiśmy wektor i model, masz pomysł na temat słownika. Tutaj będziemy omawiaćDictionary bardziej szczegółowo.

Co to jest słownik?

Zanim zagłębimy się w pojęcie słownika, przyjrzyjmy się kilku prostym koncepcjom NLP -

  • Token - Token oznacza „słowo”.

  • Document - Dokument odnosi się do zdania lub akapitu.

  • Corpus - Odnosi się do zbioru dokumentów jako worka słów (BoW).

W przypadku wszystkich dokumentów korpus zawsze zawiera identyfikator tokenu każdego słowa wraz z liczbą częstotliwości w dokumencie.

Przejdźmy do pojęcia słownika w Gensim. Do pracy z dokumentami tekstowymi Gensim wymaga również, aby słowa, czyli tokeny zostały przekonwertowane na ich unikalne identyfikatory. Aby to osiągnąć, daje nam możliwośćDictionary object, który odwzorowuje każde słowo na ich unikalny identyfikator całkowity. Robi to, konwertując tekst wejściowy na listę słów, a następnie przekazując go do plikucorpora.Dictionary() obiekt.

Potrzeba słownika

Teraz pojawia się pytanie, po co właściwie obiekt słownikowy i gdzie można go użyć? W Gensim obiekt słownika jest używany do tworzenia korpusu zbioru słów (BoW), który jest następnie używany jako dane wejściowe do modelowania tematów i innych modeli.

Formy wprowadzania tekstu

Istnieją trzy różne formy wprowadzania tekstu, które możemy dostarczyć firmie Gensim -

  • Ponieważ zdania przechowywane w natywnym obiekcie listy Pythona (znanym jako str w Pythonie 3)

  • Jako jeden plik tekstowy (może być mały lub duży)

  • Wiele plików tekstowych

Tworzenie słownika za pomocą Gensim

Jak już wspomniano, w Gensimie słownik zawiera mapowanie wszystkich słów, czyli tokenów, na ich unikalny identyfikator całkowity. Możemy stworzyć słownik z listy zdań, z jednego lub więcej niż jednego pliku tekstowego (plik tekstowy zawierający wiele linii tekstu). Zacznijmy więc od stworzenia słownika przy użyciu listy zdań.

Z listy zdań

W poniższym przykładzie utworzymy słownik z listy zdań. Kiedy mamy listę zdań lub możesz powiedzieć wiele zdań, musimy przekonwertować każde zdanie na listę słów, a rozumienie jest jednym z bardzo powszechnych sposobów, aby to zrobić.

Przykład implementacji

Najpierw zaimportuj wymagane i niezbędne pakiety w następujący sposób -

import gensim
from gensim import corpora
from pprint import pprint

Następnie z listy zdań / dokumentu utwórz listę zrozumienia, aby z niej skorzystać tworząc słownik -

doc = [
   "CNTK formerly known as Computational Network Toolkit",
   "is a free easy-to-use open-source commercial-grade toolkit",
   "that enable us to train deep learning algorithms to learn like the human brain."
]

Następnie musimy podzielić zdania na słowa. Nazywa się to tokenizacją.

text_tokens = [[text for text in doc.split()] for doc in doc]

Teraz za pomocą następującego skryptu możemy stworzyć słownik -

dict_LoS = corpora.Dictionary(text_tokens)

Teraz zdobądźmy więcej informacji, takich jak liczba tokenów w słowniku -

print(dict_LoS)

Wynik

Dictionary(27 unique tokens: ['CNTK', 'Computational', 'Network', 'Toolkit', 'as']...)

Możemy również zobaczyć mapowanie słowa na unikalne liczby całkowite w następujący sposób -

print(dict_LoS.token2id)

Wynik

{
   'CNTK': 0, 'Computational': 1, 'Network': 2, 'Toolkit': 3, 'as': 4, 
   'formerly': 5, 'known': 6, 'a': 7, 'commercial-grade': 8, 'easy-to-use': 9,
   'free': 10, 'is': 11, 'open-source': 12, 'toolkit': 13, 'algorithms': 14,
   'brain.': 15, 'deep': 16, 'enable': 17, 'human': 18, 'learn': 19, 'learning': 20,
   'like': 21, 'that': 22, 'the': 23, 'to': 24, 'train': 25, 'us': 26
}

Pełny przykład implementacji

import gensim
from gensim import corpora
from pprint import pprint
doc = [
   "CNTK formerly known as Computational Network Toolkit",
   "is a free easy-to-use open-source commercial-grade toolkit",
   "that enable us to train deep learning algorithms to learn like the human brain."
]
text_tokens = [[text for text in doc.split()] for doc in doc]
dict_LoS = corpora.Dictionary(text_tokens)
print(dict_LoS.token2id)

Z pojedynczego pliku tekstowego

W poniższym przykładzie będziemy tworzyć słownik z pojedynczego pliku tekstowego. W podobny sposób możemy również utworzyć słownik z więcej niż jednego pliku tekstowego (tj. Katalogu plików).

W tym celu zapisaliśmy dokument użyty w poprzednim przykładzie w pliku tekstowym o nazwie doc.txt. Gensim będzie czytać plik wiersz po wierszu i przetwarzać wiersz po wierszu przy użyciusimple_preprocess. W ten sposób nie musi ładować od razu całego pliku z pamięci.

Przykład implementacji

Najpierw zaimportuj wymagane i niezbędne pakiety w następujący sposób -

import gensim
from gensim import corpora
from pprint import pprint
from gensim.utils import simple_preprocess
from smart_open import smart_open
import os

Następna linia kodów utworzy słownik gensim za pomocą pojedynczego pliku tekstowego o nazwie doc.txt -

dict_STF = corpora.Dictionary(
   simple_preprocess(line, deacc =True) for line in open(‘doc.txt’, encoding=’utf-8’)
)

Teraz zdobądźmy więcej informacji, takich jak liczba tokenów w słowniku -

print(dict_STF)

Wynik

Dictionary(27 unique tokens: ['CNTK', 'Computational', 'Network', 'Toolkit', 'as']...)

Możemy również zobaczyć mapowanie słowa na unikalne liczby całkowite w następujący sposób -

print(dict_STF.token2id)

Wynik

{
   'CNTK': 0, 'Computational': 1, 'Network': 2, 'Toolkit': 3, 'as': 4, 
   'formerly': 5, 'known': 6, 'a': 7, 'commercial-grade': 8, 'easy-to-use': 9, 
   'free': 10, 'is': 11, 'open-source': 12, 'toolkit': 13, 'algorithms': 14, 
   'brain.': 15, 'deep': 16, 'enable': 17, 'human': 18, 'learn': 19, 
   'learning': 20, 'like': 21, 'that': 22, 'the': 23, 'to': 24, 'train': 25, 'us': 26
}

Pełny przykład implementacji

import gensim
from gensim import corpora
from pprint import pprint
from gensim.utils import simple_preprocess
from smart_open import smart_open
import os
dict_STF = corpora.Dictionary(
   simple_preprocess(line, deacc =True) for line in open(‘doc.txt’, encoding=’utf-8’)
)
dict_STF = corpora.Dictionary(text_tokens)
print(dict_STF.token2id)

Z wielu plików tekstowych

Teraz stwórzmy słownik z wielu plików, czyli więcej niż jednego pliku tekstowego zapisanego w tym samym katalogu. W tym przykładzie utworzyliśmy trzy różne pliki tekstowe, a mianowiciefirst.txt, second.txt i third.txtzawierający trzy linie z pliku tekstowego (doc.txt), którego użyliśmy w poprzednim przykładzie. Wszystkie te trzy pliki tekstowe są zapisywane w katalogu o nazwieABC.

Przykład implementacji

Aby to zaimplementować, musimy zdefiniować klasę za pomocą metody, która może iterować przez wszystkie trzy pliki tekstowe (pierwszy, drugi i trzeci.txt) w katalogu (ABC) i uzyskać przetworzoną listę tokenów słów.

Zdefiniujmy klasę o nazwie Read_files posiadanie metody o nazwie __iteration__ () w następujący sposób -

class Read_files(object):
   def __init__(self, directoryname):
      elf.directoryname = directoryname
   def __iter__(self):
      for fname in os.listdir(self.directoryname):
         for line in open(os.path.join(self.directoryname, fname), encoding='latin'):
   yield simple_preprocess(line)

Następnie musimy podać ścieżkę do katalogu w następujący sposób -

path = "ABC"

#provide the path as per your computer system where you saved the directory.

Kolejne kroki są podobne, jak w poprzednich przykładach. Następna linia kodów utworzy katalog Gensim przy użyciu katalogu zawierającego trzy pliki tekstowe -

dict_MUL = corpora.Dictionary(Read_files(path))

Wynik

Dictionary(27 unique tokens: ['CNTK', 'Computational', 'Network', 'Toolkit', 'as']...)

Teraz możemy również zobaczyć mapowanie słowa na unikalne liczby całkowite w następujący sposób -

print(dict_MUL.token2id)

Wynik

{
   'CNTK': 0, 'Computational': 1, 'Network': 2, 'Toolkit': 3, 'as': 4, 
   'formerly': 5, 'known': 6, 'a': 7, 'commercial-grade': 8, 'easy-to-use': 9, 
   'free': 10, 'is': 11, 'open-source': 12, 'toolkit': 13, 'algorithms': 14, 
   'brain.': 15, 'deep': 16, 'enable': 17, 'human': 18, 'learn': 19, 
   'learning': 20, 'like': 21, 'that': 22, 'the': 23, 'to': 24, 'train': 25, 'us': 26
}

Zapisywanie i ładowanie słownika Gensim

Gensim wspiera swoich tubylców save() metoda zapisywania słownika na dysku i load() metoda ładowania z powrotem słownika z dysku.

Na przykład możemy zapisać słownik za pomocą następującego skryptu -

Gensim.corpora.dictionary.save(filename)

#provide the path where you want to save the dictionary.

Podobnie możemy załadować zapisany słownik za pomocą metody load (). Następujący skrypt może to zrobić -

Gensim.corpora.dictionary.load(filename)

#provide the path where you have saved the dictionary.

Zrozumieliśmy, jak stworzyć słownik z listy dokumentów iz plików tekstowych (z jednego, jak iz więcej niż jednego). Teraz w tej sekcji utworzymy korpus worka słów (BoW). Aby pracować z Gensimem, jest to jeden z najważniejszych obiektów, z którymi musimy się zapoznać. Zasadniczo jest to korpus zawierający słowo id i jego częstotliwość w każdym dokumencie.

Tworzenie korpusu BoW

Jak omówiono w Gensim, korpus zawiera słowo id i jego częstotliwość w każdym dokumencie. Możemy stworzyć korpus BoW z prostej listy dokumentów oraz z plików tekstowych. To, co musimy zrobić, to przekazać tokenizowaną listę słów do nazwanego obiektuDictionary.doc2bow(). Więc najpierw zacznijmy od stworzenia korpusu BoW przy użyciu prostej listy dokumentów.

Z prostej listy zdań

W poniższym przykładzie utworzymy korpus BoW z prostej listy zawierającej trzy zdania.

Najpierw musimy zaimportować wszystkie niezbędne pakiety w następujący sposób -

import gensim
import pprint
from gensim import corpora
from gensim.utils import simple_preprocess

Teraz podaj listę zawierającą zdania. Na naszej liście mamy trzy zdania -

doc_list = [
   "Hello, how are you?", "How do you do?", 
   "Hey what are you doing? yes you What are you doing?"
]

Następnie wykonaj tokenizację zdań w następujący sposób -

doc_tokenized = [simple_preprocess(doc) for doc in doc_list]

Utwórz obiekt corpora.Dictionary() w następujący sposób -

dictionary = corpora.Dictionary()

Teraz przekaż te tokenizowane zdania do dictionary.doc2bow() objectw następujący sposób -

BoW_corpus = [dictionary.doc2bow(doc, allow_update=True) for doc in doc_tokenized]

W końcu możemy wydrukować Worek korpusu słów -

print(BoW_corpus)

Wynik

[
   [(0, 1), (1, 1), (2, 1), (3, 1)], 
   [(2, 1), (3, 1), (4, 2)], [(0, 2), (3, 3), (5, 2), (6, 1), (7, 2), (8, 1)]
]

Powyższe dane wyjściowe pokazują, że słowo o id = 0 pojawia się raz w pierwszym dokumencie (ponieważ w wyniku mamy (0,1)) i tak dalej.

Powyższy wynik jest w jakiś sposób niemożliwy do odczytania przez ludzi. Możemy również przekonwertować te identyfikatory na słowa, ale w tym celu potrzebujemy naszego słownika, aby dokonać konwersji w następujący sposób -

id_words = [[(dictionary[id], count) for id, count in line] for line in BoW_corpus]
print(id_words)

Wynik

[
   [('are', 1), ('hello', 1), ('how', 1), ('you', 1)], 
   [('how', 1), ('you', 1), ('do', 2)], 
   [('are', 2), ('you', 3), ('doing', 2), ('hey', 1), ('what', 2), ('yes', 1)]
]

Teraz powyższe dane wyjściowe są w jakiś sposób czytelne dla człowieka.

Pełny przykład implementacji

import gensim
import pprint
from gensim import corpora
from gensim.utils import simple_preprocess
doc_list = [
   "Hello, how are you?", "How do you do?", 
   "Hey what are you doing? yes you What are you doing?"
]
doc_tokenized = [simple_preprocess(doc) for doc in doc_list]
dictionary = corpora.Dictionary()
BoW_corpus = [dictionary.doc2bow(doc, allow_update=True) for doc in doc_tokenized]
print(BoW_corpus)
id_words = [[(dictionary[id], count) for id, count in line] for line in BoW_corpus]
print(id_words)

Z pliku tekstowego

W poniższym przykładzie utworzymy korpus BoW z pliku tekstowego. W tym celu zapisaliśmy dokument użyty w poprzednim przykładzie w pliku tekstowym o nazwiedoc.txt..

Gensim będzie czytać plik wiersz po wierszu i przetwarzać wiersz po wierszu przy użyciu simple_preprocess. W ten sposób nie musi ładować od razu całego pliku z pamięci.

Przykład implementacji

Najpierw zaimportuj wymagane i niezbędne pakiety w następujący sposób -

import gensim
from gensim import corpora
from pprint import pprint
from gensim.utils import simple_preprocess
from smart_open import smart_open
import os

Następnie następująca linia kodów spowoduje odczytanie dokumentów z doc.txt i tokenizację -

doc_tokenized = [
   simple_preprocess(line, deacc =True) for line in open(‘doc.txt’, encoding=’utf-8’)
]
dictionary = corpora.Dictionary()

Teraz musimy przekazać te tokenizowane słowa do dictionary.doc2bow() obiekt (tak jak w poprzednim przykładzie)

BoW_corpus = [
   dictionary.doc2bow(doc, allow_update=True) for doc in doc_tokenized
]
print(BoW_corpus)

Wynik

[
   [(9, 1), (10, 1), (11, 1), (12, 1), (13, 1), (14, 1), (15, 1)], 
   [
      (15, 1), (16, 1), (17, 1), (18, 1), (19, 1), (20, 1), (21, 1), 
      (22, 1), (23, 1), (24, 1)
   ], 
   [
      (23, 2), (25, 1), (26, 1), (27, 1), (28, 1), (29, 1), 
      (30, 1), (31, 1), (32, 1), (33, 1), (34, 1), (35, 1), (36, 1)
   ], 
   [(3, 1), (18, 1), (37, 1), (38, 1), (39, 1), (40, 1), (41, 1), (42, 1), (43, 1)], 
   [
      (18, 1), (27, 1), (31, 2), (32, 1), (38, 1), (41, 1), (43, 1), 
      (44, 1), (45, 1), (46, 1), (47, 1), (48, 1), (49, 1), (50, 1), (51, 1), (52, 1)
   ]
]

Plik doc.txt plik ma następującą zawartość -

CNTK, wcześniej znany jako Computational Network Toolkit, to darmowy, łatwy w użyciu, komercyjny zestaw narzędzi o otwartym kodzie źródłowym, który pozwala nam trenować algorytmy głębokiego uczenia, aby uczyć się jak ludzki mózg.

Możesz znaleźć jego darmowy samouczek na tutorialspoint.com, który zawiera również najlepsze samouczki techniczne dotyczące technologii, takich jak uczenie maszynowe AI Deep Learning.

Pełny przykład implementacji

import gensim
from gensim import corpora
from pprint import pprint
from gensim.utils import simple_preprocess
from smart_open import smart_open
import os
doc_tokenized = [
   simple_preprocess(line, deacc =True) for line in open(‘doc.txt’, encoding=’utf-8’)
]
dictionary = corpora.Dictionary()
BoW_corpus = [dictionary.doc2bow(doc, allow_update=True) for doc in doc_tokenized]
print(BoW_corpus)

Zapisywanie i ładowanie korpusu Gensim

Korpus możemy uratować za pomocą następującego skryptu -

corpora.MmCorpus.serialize(‘/Users/Desktop/BoW_corpus.mm’, bow_corpus)

#provide the path and the name of the corpus. The name of corpus is BoW_corpus and we saved it in Matrix Market format.

Podobnie możemy załadować zapisany korpus za pomocą następującego skryptu -

corpus_load = corpora.MmCorpus(‘/Users/Desktop/BoW_corpus.mm’)
for line in corpus_load:
print(line)

Ten rozdział pomoże ci dowiedzieć się o różnych przemianach w Gensim. Zacznijmy od zrozumienia przekształcających się dokumentów.

Przekształcanie dokumentów

Przekształcanie dokumentów oznacza przedstawienie dokumentu w taki sposób, aby można było nim manipulować matematycznie. Oprócz wydedukowania ukrytej struktury korpusu przekształcanie dokumentów będzie służyć również następującym celom -

  • Odkrywa związek między słowami.

  • Wydobywa ukrytą strukturę w korpusie.

  • Opisuje dokumenty w nowy i bardziej semantyczny sposób.

  • Sprawia, że ​​przedstawienie dokumentów jest bardziej zwarte.

  • Poprawia wydajność, ponieważ nowa reprezentacja zużywa mniej zasobów.

  • Poprawia skuteczność, ponieważ w nowej reprezentacji marginalne trendy danych są ignorowane.

  • Szum jest również redukowany w nowej reprezentacji dokumentu.

Zobaczmy kroki implementacji przekształcania dokumentów z jednej reprezentacji przestrzeni wektorowej na inną.

Etapy wdrażania

Aby przekształcić dokumenty, musimy wykonać następujące kroki -

Krok 1: Tworzenie korpusu

Pierwszym i podstawowym krokiem jest utworzenie korpusu z dokumentów. Stworzyliśmy już korpus w poprzednich przykładach. Stwórzmy kolejny z kilkoma ulepszeniami (usunięcie popularnych słów i słów, które pojawiają się tylko raz) -

import gensim
import pprint
from collections import defaultdict
from gensim import corpora

Teraz podaj dokumenty do stworzenia korpusu -

t_corpus = ["CNTK dawniej znany jako Computational Network Toolkit", "to darmowy, łatwy w użyciu, komercyjny zestaw narzędzi o otwartym kodzie źródłowym", "który pozwala nam trenować algorytmy głębokiego uczenia, aby uczyć się jak ludzki mózg.", " Możesz znaleźć darmowy samouczek na tutorialspoint.com "," Tutorialspoint.com zapewnia również najlepsze samouczki techniczne na temat technologii takich jak uczenie maszynowe AI deep learning "]

Następnie musimy zrobić tokenizację, a wraz z nią usuniemy również popularne słowa -

stoplist = set('for a of the and to in'.split(' '))
processed_corpus = [
   [
      word for word in document.lower().split() if word not in stoplist
   ]
	for document in t_corpus
]

Poniższy skrypt usunie te słowa, które pojawiają się tylko -

frequency = defaultdict(int)
for text in processed_corpus:
   for token in text:
      frequency[token] += 1
   processed_corpus = [
      [token for token in text if frequency[token] > 1] 
      for text in processed_corpus
   ]
pprint.pprint(processed_corpus)

Wynik

[
   ['toolkit'],
   ['free', 'toolkit'],
   ['deep', 'learning', 'like'],
   ['free', 'on', 'tutorialspoint.com'],
   ['tutorialspoint.com', 'on', 'like', 'deep', 'learning', 'learning', 'free']
]

Teraz przekaż to do corpora.dictionary() obiekt, aby uzyskać unikalne obiekty w naszym korpusie -

dictionary = corpora.Dictionary(processed_corpus)
print(dictionary)

Wynik

Dictionary(7 unique tokens: ['toolkit', 'free', 'deep', 'learning', 'like']...)

Następnie poniższy wiersz kodów utworzy model Bag of Word dla naszego korpusu -

BoW_corpus = [dictionary.doc2bow(text) for text in processed_corpus]
pprint.pprint(BoW_corpus)

Wynik

[
   [(0, 1)],
   [(0, 1), (1, 1)],
   [(2, 1), (3, 1), (4, 1)],
   [(1, 1), (5, 1), (6, 1)],
   [(1, 1), (2, 1), (3, 2), (4, 1), (5, 1), (6, 1)]
]

Krok 2: Tworzenie transformacji

Przekształcenia to niektóre standardowe obiekty Pythona. Możemy zainicjować te transformacje, czyli obiekty Pythona, używając wytrenowanego korpusu. Tutaj będziemy używaćtf-idf model do stworzenia transformacji naszego wyszkolonego korpusu tj BoW_corpus.

Najpierw musimy zaimportować pakiet modeli z gensim.

from gensim import models

Teraz musimy zainicjalizować model w następujący sposób -

tfidf = models.TfidfModel(BoW_corpus)

Krok 3: Przekształcanie wektorów

Teraz, w ostatnim kroku, wektory zostaną przekonwertowane ze starej reprezentacji do nowej reprezentacji. Ponieważ zainicjowaliśmy model tfidf w powyższym kroku, tfidf będzie teraz traktowany jako obiekt tylko do odczytu. Tutaj, używając tego obiektu tfidf, przekonwertujemy nasz wektor z zestawu reprezentacji słów (stara reprezentacja) na wagi o wartościach rzeczywistych Tfidf (nowa reprezentacja).

doc_BoW = [(1,1),(3,1)]
print(tfidf[doc_BoW]

Wynik

[(1, 0.4869354917707381), (3, 0.8734379353188121)]

Zastosowaliśmy transformację na dwóch wartościach korpusu, ale możemy również zastosować ją do całego korpusu w następujący sposób -

corpus_tfidf = tfidf[BoW_corpus]
for doc in corpus_tfidf:
   print(doc)

Wynik

[(0, 1.0)]
[(0, 0.8734379353188121), (1, 0.4869354917707381)]
[(2, 0.5773502691896257), (3, 0.5773502691896257), (4, 0.5773502691896257)]
[(1, 0.3667400603126873), (5, 0.657838022678017), (6, 0.657838022678017)]
[
   (1, 0.19338287240886842), (2, 0.34687949360312714), (3, 0.6937589872062543), 
   (4, 0.34687949360312714), (5, 0.34687949360312714), (6, 0.34687949360312714)
]

Pełny przykład implementacji

import gensim
import pprint
from collections import defaultdict
from gensim import corpora
t_corpus = [
   "CNTK formerly known as Computational Network Toolkit", 
   "is a free easy-to-use open-source commercial-grade toolkit", 
   "that enable us to train deep learning algorithms to learn like the human brain.", 
   "You can find its free tutorial on tutorialspoint.com", 
   "Tutorialspoint.com also provide best technical tutorials on 
   technologies like AI deep learning machine learning for free"
]
stoplist = set('for a of the and to in'.split(' '))
processed_corpus = [
   [word for word in document.lower().split() if word not in stoplist]
   for document in t_corpus
]
frequency = defaultdict(int)
for text in processed_corpus:
   for token in text:
      frequency[token] += 1
   processed_corpus = [
      [token for token in text if frequency[token] > 1] 
      for text in processed_corpus
   ]
pprint.pprint(processed_corpus)
dictionary = corpora.Dictionary(processed_corpus)
print(dictionary)
BoW_corpus = [dictionary.doc2bow(text) for text in processed_corpus]
pprint.pprint(BoW_corpus)
   from gensim import models
   tfidf = models.TfidfModel(BoW_corpus)
   doc_BoW = [(1,1),(3,1)]
   print(tfidf[doc_BoW])
   corpus_tfidf = tfidf[BoW_corpus]
   for doc in corpus_tfidf:
print(doc)

Różne przemiany w Gensim

Korzystając z Gensima możemy zaimplementować różne popularne transformacje, np. Algorytmy Vector Space Model. Niektóre z nich są następujące -

Tf-Idf (termin odwrotna częstotliwość dokumentu)

Podczas inicjalizacji ten algorytm modelu tf-idf oczekuje, że korpus szkoleniowy ma wartości całkowite (takie jak model Bag-of-Words). Następnie, w czasie transformacji, przyjmuje reprezentację wektorową i zwraca inną reprezentację wektorową.

Wektor wyjściowy będzie miał taką samą wymiarowość, ale wartość rzadkich cech (w czasie uczenia) zostanie zwiększona. Zasadniczo konwertuje wektory o wartościach całkowitych na wektory o wartościach rzeczywistych. Poniżej znajduje się składnia transformacji Tf-idf -

Model=models.TfidfModel(corpus, normalize=True)

LSI (ukryte indeksowanie semantyczne)

Algorytm modelu LSI może przekształcić dokument z modelu wektorowego o wartościach całkowitych (takiego jak model Bag-of-Words) lub z przestrzeni ważonej Tf-Idf w przestrzeń utajoną. Wektor wyjściowy będzie miał mniejszą wymiarowość. Poniżej znajduje się składnia transformacji LSI -

Model=models.LsiModel(tfidf_corpus, id2word=dictionary, num_topics=300)

LDA (Latent Dirichlet Allocation)

Algorytm modelu LDA to kolejny algorytm, który przekształca dokument z przestrzeni modelu Bag-of-Words w przestrzeń tematyczną. Wektor wyjściowy będzie miał mniejszą wymiarowość. Poniżej znajduje się składnia transformacji LSI -

Model=models.LdaModel(corpus, id2word=dictionary, num_topics=100)

Losowe prognozy (RP)

RP, bardzo wydajne podejście, ma na celu zmniejszenie wymiarowości przestrzeni wektorowej. To podejście jest w zasadzie przybliżeniem odległości Tf-Idf między dokumentami. Robi to, rzucając trochę przypadkowości.

Model=models.RpModel(tfidf_corpus, num_topics=500)

Hierarchiczny proces Dirichleta (HDP)

HDP to nieparametryczna metoda bayesowska, która jest nowym dodatkiem do Gensim. Powinniśmy zachować ostrożność podczas korzystania z niego.

Model=models.HdpModel(corpus, id2word=dictionary

Tutaj dowiemy się o tworzeniu macierzy częstotliwości dokumentów odwrotnej częstotliwości terminów (TF-IDF) z pomocą Gensim.

Co to jest TF-IDF?

Jest to model częstotliwości dokumentów z odwróconą częstotliwością terminów, który jest również modelem worka słów. Różni się od zwykłego korpusu, ponieważ obciąża tokeny, tj. Słowa często pojawiające się w dokumentach. Podczas inicjalizacji ten algorytm modelu tf-idf oczekuje, że korpus szkoleniowy ma wartości całkowite (takie jak model Bag-of-Words).

Następnie w momencie transformacji przyjmuje reprezentację wektorową i zwraca inną reprezentację wektorową. Wektor wyjściowy będzie miał taką samą wymiarowość, ale wartość rzadkich cech (w czasie uczenia) zostanie zwiększona. Zasadniczo konwertuje wektory o wartościach całkowitych na wektory o wartościach rzeczywistych.

Jak to jest obliczane?

Model TF-IDF oblicza tfidf za pomocą dwóch prostych kroków -

Krok 1: Mnożenie składnika lokalnego i globalnego

Na tym pierwszym etapie model pomnoży składnik lokalny, taki jak TF (Częstotliwość terminów), ze składnikiem globalnym, takim jak IDF (Odwrotna częstotliwość dokumentów).

Krok 2: Normalizuj wynik

Po zakończeniu mnożenia w kolejnym kroku model TFIDF znormalizuje wynik do długości jednostki.

W wyniku tych dwóch kroków, często występujące słowa w dokumentach zostaną zmniejszone.

Jak zdobyć wagi TF-IDF?

Tutaj zaimplementujemy przykład, aby zobaczyć, jak możemy uzyskać wagi TF-IDF. Zasadniczo, aby uzyskać wagi TF-IDF, najpierw musimy wytrenować korpus, a następnie zastosować ten korpus w modelu tfidf.

Trenuj Corpus

Jak wspomniano powyżej, aby uzyskać TF-IDF, najpierw musimy wyszkolić nasz korpus. Najpierw musimy zaimportować wszystkie niezbędne pakiety w następujący sposób -

import gensim
import pprint
from gensim import corpora
from gensim.utils import simple_preprocess

Teraz podaj listę zawierającą zdania. Na naszej liście mamy trzy zdania -

doc_list = [
   "Hello, how are you?", "How do you do?", 
   "Hey what are you doing? yes you What are you doing?"
]

Następnie wykonaj tokenizację zdań w następujący sposób -

doc_tokenized = [simple_preprocess(doc) for doc in doc_list]

Utwórz obiekt corpora.Dictionary() w następujący sposób -

dictionary = corpora.Dictionary()

Teraz przekaż te tokenizowane zdania do dictionary.doc2bow() obiekt w następujący sposób -

BoW_corpus = [dictionary.doc2bow(doc, allow_update=True) for doc in doc_tokenized]

Następnie otrzymamy identyfikatory słów i ich częstotliwości w naszych dokumentach.

for doc in BoW_corpus:
   print([[dictionary[id], freq] for id, freq in doc])

Wynik

[['are', 1], ['hello', 1], ['how', 1], ['you', 1]]
[['how', 1], ['you', 1], ['do', 2]]
[['are', 2], ['you', 3], ['doing', 2], ['hey', 1], ['what', 2], ['yes', 1]]

W ten sposób wyszkoliliśmy nasz korpus (korpus Bag-of-Word).

Następnie musimy zastosować ten wyuczony korpus w modelu tfidf models.TfidfModel().

Najpierw zaimportuj pakiet numpay -

import numpy as np

Teraz stosujemy nasz wyszkolony korpus (BoW_corpus) w nawiasach kwadratowych models.TfidfModel()

tfidf = models.TfidfModel(BoW_corpus, smartirs='ntc')

Następnie otrzymamy identyfikatory słów i ich częstotliwości w naszym korpusie modelowanym przez tfidf -

for doc in tfidf[BoW_corpus]:
   print([[dictionary[id], np.around(freq,decomal=2)] for id, freq in doc])

Wynik

[['are', 0.33], ['hello', 0.89], ['how', 0.33]]
[['how', 0.18], ['do', 0.98]]
[['are', 0.23], ['doing', 0.62], ['hey', 0.31], ['what', 0.62], ['yes', 0.31]]

[['are', 1], ['hello', 1], ['how', 1], ['you', 1]]
[['how', 1], ['you', 1], ['do', 2]]
[['are', 2], ['you', 3], ['doing', 2], ['hey', 1], ['what', 2], ['yes', 1]]

[['are', 0.33], ['hello', 0.89], ['how', 0.33]]
[['how', 0.18], ['do', 0.98]]
[['are', 0.23], ['doing', 0.62], ['hey', 0.31], ['what', 0.62], ['yes', 0.31]]

Na podstawie powyższych danych wyjściowych widzimy różnicę w częstotliwościach słów w naszych dokumentach.

Pełny przykład implementacji

import gensim
import pprint
from gensim import corpora
from gensim.utils import simple_preprocess
doc_list = [
   "Hello, how are you?", "How do you do?", 
   "Hey what are you doing? yes you What are you doing?"
]
doc_tokenized = [simple_preprocess(doc) for doc in doc_list]
dictionary = corpora.Dictionary()
BoW_corpus = [dictionary.doc2bow(doc, allow_update=True) for doc in doc_tokenized]
for doc in BoW_corpus:
   print([[dictionary[id], freq] for id, freq in doc])
import numpy as np
tfidf = models.TfidfModel(BoW_corpus, smartirs='ntc')
for doc in tfidf[BoW_corpus]:
   print([[dictionary[id], np.around(freq,decomal=2)] for id, freq in doc])

Różnica w wadze słów

Jak omówiono powyżej, słowa, które będą występować częściej w dokumencie, otrzymają mniejsze wagi. Rozumiemy różnicę w wagach słów z dwóch powyższych wyników. Słowo‘are’występuje w dwóch dokumentach i zostały obciążone. Podobnie słowo‘you’ pojawiające się we wszystkich dokumentach i całkowicie usunięte.

W tym rozdziale omówiono modelowanie tematyczne w odniesieniu do Gensim.

Aby opisać nasze dane i zrozumieć strukturę zdań, jedną z najlepszych metod jest użycie obliczeniowych algorytmów lingwistycznych. Bez wątpienia za pomocą tych obliczeniowych algorytmów lingwistycznych możemy zrozumieć drobne szczegóły dotyczące naszych danych, ale

  • Czy możemy wiedzieć, jakie słowa pojawiają się częściej niż inne w naszym korpusie?

  • Czy możemy grupować nasze dane?

  • Czy możemy bazować na motywach w naszych danych?

Bylibyśmy w stanie to wszystko osiągnąć za pomocą modelowania tematycznego. Zagłębmy się więc w koncepcję modeli tematycznych.

Jakie są modele tematyczne?

Model tematyczny można zdefiniować jako model probabilistyczny zawierający informacje o tematach w naszym tekście. Ale tutaj pojawiają się dwa ważne pytania, które są następujące -

Pierwszy, what exactly a topic is?

Temat, jak sama nazwa wskazuje, to leżące u podstaw idee lub tematy przedstawione w naszym tekście. Aby dać ci przykład, korpus zawierającynewspaper articles miałby tematy związane finance, weather, politics, sports, various states news i tak dalej.

Druga, what is the importance of topic models in text processing?

Jak wiemy, aby zidentyfikować podobieństwo w tekście, możemy zastosować techniki wyszukiwania informacji i wyszukiwania przy użyciu słów. Ale za pomocą modeli tematycznych możemy teraz wyszukiwać i porządkować nasze pliki tekstowe przy użyciu tematów, a nie słów.

W tym sensie możemy powiedzieć, że tematy są probabilistycznym rozkładem słów. Dlatego korzystając z modeli tematycznych, możemy opisać nasze dokumenty jako probabilistyczne rozkłady tematów.

Cele modeli tematycznych

Jak wspomniano powyżej, modelowanie tematyczne koncentruje się na podstawowych ideach i tematach. Jego główne cele są następujące -

  • Modele tematyczne mogą być użyte do podsumowania tekstu.

  • Mogą służyć do porządkowania dokumentów. Na przykład, możemy użyć modelowania tematów, aby zgrupować artykuły z wiadomościami w zorganizowaną / połączoną sekcję, taką jak organizowanie wszystkich artykułów związanych zcricket.

  • Mogą poprawić wyniki wyszukiwania. W jaki sposób? W przypadku zapytania wyszukiwania możemy użyć modeli tematycznych, aby ujawnić dokument zawierający kombinację różnych słów kluczowych, ale dotyczą tego samego pomysłu.

  • Pojęcie rekomendacji jest bardzo przydatne w marketingu. Jest używany przez różne sklepy internetowe, serwisy informacyjne i wiele innych. Modele tematyczne pomagają w formułowaniu rekomendacji dotyczących tego, co kupić, co przeczytać dalej itp. Robią to poprzez znajdowanie na liście materiałów o wspólnym temacie.

Topic Modeling Algorithms in Gensim

Niewątpliwie Gensim jest najpopularniejszym zestawem narzędzi do modelowania tematycznego. Jego bezpłatna dostępność i bycie w Pythonie sprawiają, że jest bardziej popularny. W tej sekcji omówimy niektóre najpopularniejsze algorytmy modelowania tematycznego. Tutaj skupimy się raczej na „co” niż „jak”, ponieważ Gensim bardzo dobrze je streszcza.

Ukryty przydział Dirichleta (LDA)

Utajona alokacja Dirichleta (LDA) jest najbardziej powszechną i popularną obecnie techniką modelowania tematycznego. Jest to ten, który badacze Facebooka wykorzystali w swoim artykule badawczym opublikowanym w 2013 roku. Po raz pierwszy zaproponowali go David Blei, Andrew Ng i Michael Jordan w 2003 roku. Zaproponowali LDA w swoim artykule zatytułowanym po prostuLatent Dirichlet allocation.

Charakterystyka LDA

Dowiedzmy się więcej o tej wspaniałej technice dzięki jej cechom -

Probabilistic topic modeling technique

LDA to probabilistyczna technika modelowania tematycznego. Jak omówiliśmy powyżej, w modelowaniu tematycznym zakładamy, że w każdym zbiorze powiązanych ze sobą dokumentów (mogą to być artykuły naukowe, artykuły prasowe, posty na Facebooku, tweety, e-maile itp.), W każdym dokumencie znajduje się kilka kombinacji tematów .

Głównym celem probabilistycznego modelowania tematycznego jest odkrycie ukrytej struktury tematycznej dla gromadzenia powiązanych ze sobą dokumentów. Struktura tematów obejmuje zazwyczaj trzy rzeczy:

  • Topics

  • Statystyczny rozkład tematów w dokumentach

  • Słowa w dokumencie zawierającym temat

Work in an unsupervised way

LDA działa bez nadzoru. Dzieje się tak, ponieważ LDA używa prawdopodobieństw warunkowych, aby odkryć ukrytą strukturę tematu. Zakłada, że ​​tematy są nierównomiernie rozłożone w zbiorze powiązanych ze sobą dokumentów.

Very easy to create it in Gensim

W Gensim bardzo łatwo jest stworzyć model LDA. musimy tylko określić korpus, mapowanie słownika i liczbę tematów, których chcielibyśmy użyć w naszym modelu.

Model=models.LdaModel(corpus, id2word=dictionary, num_topics=100)

May face computationally intractable problem

Obliczenie prawdopodobieństwa każdej możliwej struktury tematu jest wyzwaniem obliczeniowym, przed którym stoi LDA. Jest to trudne, ponieważ musi obliczyć prawdopodobieństwo każdego zaobserwowanego słowa w każdej możliwej strukturze tematu. Jeśli mamy dużą liczbę tematów i słów, LDA może napotkać trudny obliczeniowo problem.

Ukryte indeksowanie semantyczne (LSI)

Algorytmy modelowania tematu, które zostały po raz pierwszy zaimplementowane w Gensim z Latent Dirichlet Allocation (LDA) jest Latent Semantic Indexing (LSI). Nazywa się to równieżLatent Semantic Analysis (LSA).

Został opatentowany w 1988 roku przez Scotta Deerwestera, Susan Dumais, George'a Furnasa, Richarda Harshmana, Thomasa Landaura, Karen Lochbaum i Lynn Streeter. W tej sekcji mamy zamiar skonfigurować nasz model LSI. Można to zrobić w ten sam sposób, jak konfigurując model LDA. musimy zaimportować model LSI zgensim.models.

Rola LSI

W rzeczywistości LSI jest techniką NLP, zwłaszcza w semantyce dystrybucyjnej. Analizuje związek między zbiorem dokumentów a terminami, które te dokumenty zawierają. Jeśli mówimy o jego działaniu, konstruuje on macierz zawierającą liczbę słów w dokumencie z dużego fragmentu tekstu.

Po skonstruowaniu, w celu zmniejszenia liczby wierszy, model LSI wykorzystuje technikę matematyczną zwaną dekompozycją wartości osobliwej (SVD). Wraz ze zmniejszeniem liczby wierszy zachowuje również strukturę podobieństwa między kolumnami. W macierzy wiersze reprezentują unikalne słowa, a kolumny reprezentują każdy dokument. Działa w oparciu o hipotezę dystrybucyjną, tzn. Zakłada, że ​​słowa bliskie znaczenia pojawią się w tym samym rodzaju tekstu.

Model=models.LsiModel(corpus, id2word=dictionary, num_topics=100)

Hierarchiczny proces Dirichleta (HDP)

Modele tematyczne, takie jak LDA i LSI, pomagają w podsumowywaniu i organizowaniu dużych archiwów tekstów, których nie można przeanalizować ręcznie. Oprócz LDA i LSI, innym potężnym modelem tematycznym w Gensim jest HDP (Hierarchical Dirichlet Process). Jest to w zasadzie model członkostwa mieszanego do nienadzorowanej analizy zgrupowanych danych. W przeciwieństwie do LDA (jej skończony odpowiednik), HDP wnioskuje liczbę tematów na podstawie danych.

Model=models.HdpModel(corpus, id2word=dictionary

Ten rozdział pomoże Ci dowiedzieć się, jak utworzyć model tematyczny alokacji Latent Dirichlet (LDA) w Gensim.

Automatyczne wyodrębnianie informacji na tematy z dużej ilości tekstów w jednej z podstawowych aplikacji NLP (przetwarzanie języka naturalnego). Duża ilość tekstów może pochodzić z recenzji hoteli, tweetów, postów na Facebooku, kanałów z innych kanałów mediów społecznościowych, recenzji filmów, wiadomości, opinii użytkowników, e-maili itp.

W erze cyfrowej wiedza o tym, o czym mówią ludzie / klienci, zrozumienie ich opinii i problemów, może być bardzo cenna dla firm, kampanii politycznych i administratorów. Ale czy możliwe jest ręczne przeczytanie tak dużych ilości tekstu, a następnie wydobycie informacji z tematów?

Nie, nie jest. Wymaga automatycznego algorytmu, który może czytać te duże ilości dokumentów tekstowych i automatycznie wyodrębniać z nich wymagane informacje / omawiane tematy.

Rola LDA

Podejście LDA do modelowania tematu polega na klasyfikowaniu tekstu w dokumencie do określonego tematu. Modelowane jako dystrybucje Dirichleta, LDA buduje -

  • Temat na model dokumentu i
  • Słowa według modelu tematu

Po dostarczeniu algorytmu modelu tematu LDA, w celu uzyskania dobrej kompozycji rozkładu temat-słowo kluczowe, zmienia on -

  • Dystrybucje tematów w dokumencie i
  • Rozkład słów kluczowych w ramach tematów

Podczas przetwarzania niektóre z założeń przyjętych przez LDA to:

  • Każdy dokument jest modelowany jako wielomianowe rozkłady tematów.
  • Każdy temat jest modelowany jako wielomianowe rozkłady słów.
  • Powinniśmy musieć wybrać odpowiedni korpus danych, ponieważ LDA zakłada, że ​​każdy fragment tekstu zawiera powiązane słowa.
  • LDA zakłada również, że dokumenty są tworzone z wielu różnych tematów.

Wdrożenie z Gensim

Tutaj użyjemy LDA (Latent Dirichlet Allocation) do wyodrębnienia naturalnie omawianych tematów ze zbioru danych.

Ładowanie zestawu danych

Zbiór danych, którego będziemy używać, to zbiór danych ’20 Newsgroups’posiadanie tysięcy artykułów z różnych sekcji raportu prasowego. Jest dostępny w ramachSklearnzbiory danych. Możemy łatwo pobrać za pomocą następującego skryptu Pythona -

from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train')

Przyjrzyjmy się niektórym przykładowym wiadomościom za pomocą następującego skryptu -

newsgroups_train.data[:4]
["From: [email protected] (where's my thing)\nSubject: 
WHAT car is this!?\nNntp-Posting-Host: rac3.wam.umd.edu\nOrganization: 
University of Maryland, College Park\nLines: 
15\n\n I was wondering if anyone out there could enlighten me on this car 
I saw\nthe other day. It was a 2-door sports car, looked to be from the 
late 60s/\nearly 70s. It was called a Bricklin. The doors were really small. 
In addition,\nthe front bumper was separate from the rest of the body. 
This is \nall I know. If anyone can tellme a model name, 
engine specs, years\nof production, where this car is made, history, or 
whatever info you\nhave on this funky looking car, please e-mail.\n\nThanks,
\n- IL\n ---- brought to you by your neighborhood Lerxst ----\n\n\n\n\n",

"From: [email protected] (Guy Kuo)\nSubject: SI Clock Poll - Final 
Call\nSummary: Final call for SI clock reports\nKeywords: 
SI,acceleration,clock,upgrade\nArticle-I.D.: shelley.1qvfo9INNc3s\nOrganization: 
University of Washington\nLines: 11\nNNTP-Posting-Host: carson.u.washington.edu\n\nA 
fair number of brave souls who upgraded their SI clock oscillator have\nshared their 
experiences for this poll. Please send a brief message detailing\nyour experiences with 
the procedure. Top speed attained, CPU rated speed,\nadd on cards and adapters, heat 
sinks, hour of usage per day, floppy disk\nfunctionality with 800 and 1.4 m floppies 
are especially requested.\n\nI will be summarizing in the next two days, so please add 
to the network\nknowledge base if you have done the clock upgrade and haven't answered 
this\npoll. Thanks.\n\nGuy Kuo <;[email protected]>\n",

'From: [email protected] (Thomas E Willis)\nSubject: 
PB questions...\nOrganization: Purdue University Engineering 
Computer Network\nDistribution: usa\nLines: 36\n\nwell folks, 
my mac plus finally gave up the ghost this weekend after\nstarting 
life as a 512k way back in 1985. sooo, i\'m in the market for 
a\nnew machine a bit sooner than i intended to be...\n\ni\'m looking 
into picking up a powerbook 160 or maybe 180 and have a bunch\nof 
questions that (hopefully) somebody can answer:\n\n* does anybody 
know any dirt on when the next round of powerbook\nintroductions 
are expected? i\'d heard the 185c was supposed to make an\nappearence 
"this summer" but haven\'t heard anymore on it - and since i\ndon\'t 
have access to macleak, i was wondering if anybody out there had\nmore 
info...\n\n* has anybody heard rumors about price drops to the powerbook 
line like the\nones the duo\'s just went through recently?\n\n* what\'s 
the impression of the display on the 180? i could probably swing\na 180 
if i got the 80Mb disk rather than the 120, but i don\'t really have\na 
feel for how much "better" the display is (yea, it looks great in the\nstore, 
but is that all "wow" or is it really that good?). could i solicit\nsome 
opinions of people who use the 160 and 180 day-to-day on if its
worth\ntaking the disk size and money hit to get the active display? 
(i realize\nthis is a real subjective question, but i\'ve only played around 
with the\nmachines in a computer store breifly and figured the opinions 
of somebody\nwho actually uses the machine daily might prove helpful).\n\n* 
how well does hellcats perform? ;)\n\nthanks a bunch in advance for any info - 
if you could email, i\'ll post a\nsummary (news reading time is at a premium 
with finals just around the\ncorner... :
( )\n--\nTom Willis \\ [email protected] \\ Purdue Electrical 
Engineering\n---------------------------------------------------------------------------\
n"Convictions are more dangerous enemies of truth than lies." - F. W.\nNietzsche\n',

'From: jgreen@amber (Joe Green)\nSubject: Re: Weitek P9000 ?\nOrganization: 
Harris Computer Systems Division\nLines: 14\nDistribution: world\nNNTP-Posting-Host: 
amber.ssd.csd.harris.com\nX-Newsreader: TIN [version 1.1 PL9]\n\nRobert 
J.C. Kyanko ([email protected]) wrote:\n >[email protected] writes in article 
<[email protected] >:\n> > Anyone know about the 
Weitek P9000 graphics chip?\n > As far as the low-level stuff goes, it looks 
pretty nice. It\'s got this\n> quadrilateral fill command that requires just 
the four points.\n\nDo you have Weitek\'s address/phone number? I\'d like to get 
some information\nabout this chip.\n\n--\nJoe Green\t\t\t\tHarris 
Corporation\[email protected]\t\t\tComputer Systems Division\n"The only 
thing that really scares me is a person with no sense of humor.
"\n\t\t\t\t\t\t-- Jonathan Winters\n']

Warunek wstępny

Potrzebujemy stopwords z NLTK i modelu angielskiego ze Scapy. Oba można pobrać w następujący sposób -

import nltk;
nltk.download('stopwords')
nlp = spacy.load('en_core_web_md', disable=['parser', 'ner'])

Importowanie niezbędnych pakietów

W celu zbudowania modelu LDA musimy zaimportować odpowiedni pakiet -

import re
import numpy as np
import pandas as pd
from pprint import pprint
import gensim
import gensim.corpora as corpora
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel
import spacy
import pyLDAvis
import pyLDAvis.gensim
import matplotlib.pyplot as plt

Przygotowywanie odrzucanych słów

Teraz musimy zaimportować stopwords i użyć ich -

from nltk.corpus import stopwords
stop_words = stopwords.words('english')
stop_words.extend(['from', 'subject', 're', 'edu', 'use'])

Oczyść tekst

Teraz z pomocą Gensima simple_preprocess()musimy ująć każde zdanie w listę słów. Powinniśmy również usunąć znaki interpunkcyjne i niepotrzebne znaki. W tym celu stworzymy funkcję o nazwiesent_to_words() -

def sent_to_words(sentences):
   for sentence in sentences:
      yield(gensim.utils.simple_preprocess(str(sentence), deacc=True))
data_words = list(sent_to_words(data))

Budowanie modeli Bigram i Trigram

Jak wiemy, bigramy to dwa słowa, które często występują razem w dokumencie, a trygram to trzy słowa, które często występują razem w dokumencie. Z pomocą GensimaPhrases model, możemy to zrobić -

bigram = gensim.models.Phrases(data_words, min_count=5, threshold=100)
trigram = gensim.models.Phrases(bigram[data_words], threshold=100)
bigram_mod = gensim.models.phrases.Phraser(bigram)
trigram_mod = gensim.models.phrases.Phraser(trigram)

Odfiltruj odrzucane słowa

Następnie musimy odfiltrować odrzucane słowa. Oprócz tego stworzymy również funkcje do tworzenia bigramów, trygramów i do lematyzacji -

def remove_stopwords(texts):
   return [[word for word in simple_preprocess(str(doc))
if word not in stop_words] for doc in texts]
def make_bigrams(texts):
   return [bigram_mod[doc] for doc in texts]
def make_trigrams(texts):
   return [trigram_mod[bigram_mod[doc]] for doc in texts]
def lemmatization(texts, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']):
   texts_out = []
   for sent in texts:
     doc = nlp(" ".join(sent))
     texts_out.append([token.lemma_ for token in doc if token.pos_ in allowed_postags])
   return texts_out

Tworzenie słownika i korpusu dla modelu tematycznego

Teraz musimy zbudować słownik i korpus. Zrobiliśmy to również w poprzednich przykładach -

id2word = corpora.Dictionary(data_lemmatized)
texts = data_lemmatized
corpus = [id2word.doc2bow(text) for text in texts]

Tworzenie modelu tematycznego LDA

Wdrożyliśmy już wszystko, co jest potrzebne do trenowania modelu LDA. Teraz nadszedł czas, aby zbudować model tematyczny LDA. W naszym przykładzie implementacji można to zrobić za pomocą następującego wiersza kodów -

lda_model = gensim.models.ldamodel.LdaModel(
   corpus=corpus, id2word=id2word, num_topics=20, random_state=100, 
   update_every=1, chunksize=100, passes=10, alpha='auto', per_word_topics=True
)

Przykład implementacji

Zobaczmy pełny przykład implementacji, aby zbudować model tematu LDA -

import re
import numpy as np
import pandas as pd
from pprint import pprint
import gensim
import gensim.corpora as corpora
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel
import spacy
import pyLDAvis
import pyLDAvis.gensim
import matplotlib.pyplot as plt
from nltk.corpus import stopwords
stop_words = stopwords.words('english')
stop_words.extend(['from', 'subject', 're', 'edu', 'use'])
from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train')
data = newsgroups_train.data
data = [re.sub('\S*@\S*\s?', '', sent) for sent in data]
data = [re.sub('\s+', ' ', sent) for sent in data]
data = [re.sub("\'", "", sent) for sent in data]
print(data_words[:4]) #it will print the data after prepared for stopwords
bigram = gensim.models.Phrases(data_words, min_count=5, threshold=100)
trigram = gensim.models.Phrases(bigram[data_words], threshold=100)
bigram_mod = gensim.models.phrases.Phraser(bigram)
trigram_mod = gensim.models.phrases.Phraser(trigram)
def remove_stopwords(texts):
   return [[word for word in simple_preprocess(str(doc)) 
   if word not in stop_words] for doc in texts]
def make_bigrams(texts):
   return [bigram_mod[doc] for doc in texts]
def make_trigrams(texts):
   [trigram_mod[bigram_mod[doc]] for doc in texts]
def lemmatization(texts, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']):
   texts_out = []
   for sent in texts:
      doc = nlp(" ".join(sent))
      texts_out.append([token.lemma_ for token in doc if token.pos_ in allowed_postags])
   return texts_out
data_words_nostops = remove_stopwords(data_words)
data_words_bigrams = make_bigrams(data_words_nostops)
nlp = spacy.load('en_core_web_md', disable=['parser', 'ner'])
data_lemmatized = lemmatization(data_words_bigrams, allowed_postags=[
   'NOUN', 'ADJ', 'VERB', 'ADV'
])
print(data_lemmatized[:4]) #it will print the lemmatized data.
id2word = corpora.Dictionary(data_lemmatized)
texts = data_lemmatized
corpus = [id2word.doc2bow(text) for text in texts]
print(corpus[:4]) #it will print the corpus we created above.
[[(id2word[id], freq) for id, freq in cp] for cp in corpus[:4]] 
#it will print the words with their frequencies.
lda_model = gensim.models.ldamodel.LdaModel(
   corpus=corpus, id2word=id2word, num_topics=20, random_state=100, 
   update_every=1, chunksize=100, passes=10, alpha='auto', per_word_topics=True
)

Możemy teraz użyć utworzonego powyżej modelu LDA, aby uzyskać tematy i obliczyć zagadnienie modelu.

W tym rozdziale zrozumiemy, jak używać modelu tematycznego Latent Dirichlet Allocation (LDA).

Przeglądanie tematów w modelu LDA

Stworzony powyżej model LDA (lda_model) można wykorzystać do przeglądania tematów z dokumentów. Można to zrobić za pomocą następującego skryptu -

pprint(lda_model.print_topics())
doc_lda = lda_model[corpus]

Wynik

[
   (0, 
   '0.036*"go" + 0.027*"get" + 0.021*"time" + 0.017*"back" + 0.015*"good" + '
   '0.014*"much" + 0.014*"be" + 0.013*"car" + 0.013*"well" + 0.013*"year"'),
   (1,
   '0.078*"screen" + 0.067*"video" + 0.052*"character" + 0.046*"normal" + '
   '0.045*"mouse" + 0.034*"manager" + 0.034*"disease" + 0.031*"processor" + '
   '0.028*"excuse" + 0.028*"choice"'),
   (2,
   '0.776*"ax" + 0.079*"_" + 0.011*"boy" + 0.008*"ticket" + 0.006*"red" + '
   '0.004*"conservative" + 0.004*"cult" + 0.004*"amazing" + 0.003*"runner" + '
   '0.003*"roughly"'),
   (3,
   '0.086*"season" + 0.078*"fan" + 0.072*"reality" + 0.065*"trade" + '
   '0.045*"concept" + 0.040*"pen" + 0.028*"blow" + 0.025*"improve" + '
   '0.025*"cap" + 0.021*"penguin"'),
   (4,
   '0.027*"group" + 0.023*"issue" + 0.016*"case" + 0.016*"cause" + '
   '0.014*"state" + 0.012*"whole" + 0.012*"support" + 0.011*"government" + '
   '0.010*"year" + 0.010*"rate"'),
   (5,
   '0.133*"evidence" + 0.047*"believe" + 0.044*"religion" + 0.042*"belief" + '
   '0.041*"sense" + 0.041*"discussion" + 0.034*"atheist" + 0.030*"conclusion" +
   '
   '0.029*"explain" + 0.029*"claim"'),
   (6,
   '0.083*"space" + 0.059*"science" + 0.031*"launch" + 0.030*"earth" + '
   '0.026*"route" + 0.024*"orbit" + 0.024*"scientific" + 0.021*"mission" + '
   '0.018*"plane" + 0.017*"satellite"'),
   (7,
   '0.065*"file" + 0.064*"program" + 0.048*"card" + 0.041*"window" + '
   '0.038*"driver" + 0.037*"software" + 0.034*"run" + 0.029*"machine" + '
   '0.029*"entry" + 0.028*"version"'),
   (8,
   '0.078*"publish" + 0.059*"mount" + 0.050*"turkish" + 0.043*"armenian" + '
   '0.027*"western" + 0.026*"russian" + 0.025*"locate" + 0.024*"proceed" + '
   '0.024*"electrical" + 0.022*"terrorism"'),
   (9,
   '0.023*"people" + 0.023*"child" + 0.021*"kill" + 0.020*"man" + 0.019*"death" '
   '+ 0.015*"die" + 0.015*"live" + 0.014*"attack" + 0.013*"age" + '
   '0.011*"church"'),
   (10,
   '0.092*"cpu" + 0.085*"black" + 0.071*"controller" + 0.039*"white" + '
   '0.028*"water" + 0.027*"cold" + 0.025*"solid" + 0.024*"cool" + 0.024*"heat" '
   '+ 0.023*"nuclear"'),
   (11,
   '0.071*"monitor" + 0.044*"box" + 0.042*"option" + 0.041*"generate" + '
   '0.038*"vote" + 0.032*"battery" + 0.029*"wave" + 0.026*"tradition" + '
   '0.026*"fairly" + 0.025*"task"'),
   (12,
   '0.048*"send" + 0.045*"mail" + 0.036*"list" + 0.033*"include" + '
   '0.032*"price" + 0.031*"address" + 0.027*"email" + 0.026*"receive" + '
   '0.024*"book" + 0.024*"sell"'),
   (13,
   '0.515*"drive" + 0.052*"laboratory" + 0.042*"blind" + 0.020*"investment" + '
   '0.011*"creature" + 0.010*"loop" + 0.005*"dialog" + 0.000*"slave" + '
   '0.000*"jumper" + 0.000*"sector"'),
   (14,
   '0.153*"patient" + 0.066*"treatment" + 0.062*"printer" + 0.059*"doctor" + '

   '0.036*"medical" + 0.031*"energy" + 0.029*"study" + 0.029*"probe" + '
   '0.024*"mph" + 0.020*"physician"'),
   (15,
   '0.068*"law" + 0.055*"gun" + 0.039*"government" + 0.036*"right" + '
   '0.029*"state" + 0.026*"drug" + 0.022*"crime" + 0.019*"person" + '
   '0.019*"citizen" + 0.019*"weapon"'),
   (16,
   '0.107*"team" + 0.102*"game" + 0.078*"play" + 0.055*"win" + 0.052*"player" + '
   '0.051*"year" + 0.030*"score" + 0.025*"goal" + 0.023*"wing" + 0.023*"run"'),
   (17,
   '0.031*"say" + 0.026*"think" + 0.022*"people" + 0.020*"make" + 0.017*"see" + '
   '0.016*"know" + 0.013*"come" + 0.013*"even" + 0.013*"thing" + 0.013*"give"'),
   (18,
   '0.039*"system" + 0.034*"use" + 0.023*"key" + 0.016*"bit" + 0.016*"also" + '
   '0.015*"information" + 0.014*"source" + 0.013*"chip" + 0.013*"available" + '
   '0.010*"provide"'),
   (19,
   '0.085*"line" + 0.073*"write" + 0.053*"article" + 0.046*"organization" + '
   '0.034*"host" + 0.023*"be" + 0.023*"know" + 0.017*"thank" + 0.016*"want" + '
   '0.014*"help"')
]

Obliczanie złożoności modelu

Model LDA (lda_model), który stworzyliśmy powyżej, może być użyty do obliczenia złożoności modelu, tj. Jak dobry jest model. Im niższy wynik, tym lepszy będzie model. Można to zrobić za pomocą następującego skryptu -

print('\nPerplexity: ', lda_model.log_perplexity(corpus))

Wynik

Perplexity: -12.338664984332151

Obliczanie wyniku koherencji

Model LDA (lda_model)utworzonym powyżej można wykorzystać do obliczenia wyniku koherencji modelu, tj. średniej / mediany wyników podobieństwa słów w parach słów w temacie. Można to zrobić za pomocą następującego skryptu -

coherence_model_lda = CoherenceModel(
   model=lda_model, texts=data_lemmatized, dictionary=id2word, coherence='c_v'
)
coherence_lda = coherence_model_lda.get_coherence()
print('\nCoherence Score: ', coherence_lda)

Wynik

Coherence Score: 0.510264381411751

Wizualizacja tematów-słów kluczowych

Model LDA (lda_model), które stworzyliśmy powyżej, można wykorzystać do zbadania stworzonych tematów i powiązanych słów kluczowych. Można to zwizualizować za pomocąpyLDAvispakiet w następujący sposób -

pyLDAvis.enable_notebook()
vis = pyLDAvis.gensim.prepare(lda_model, corpus, id2word)
vis

Wynik

Na podstawie powyższego wyniku bąbelki po lewej stronie reprezentują temat, a im większy bąbelek, tym bardziej rozpowszechniony jest ten temat. Model tematyczny będzie dobry, jeśli model tematu zawiera duże, nie nakładające się bąbelki rozrzucone po całym wykresie.

W tym rozdziale wyjaśniono, czym jest model młotka utajonego alokacji Dirichleta (LDA) i jak go stworzyć w Gensim.

W poprzedniej sekcji zaimplementowaliśmy model LDA i pobraliśmy tematy z dokumentów ze zbioru danych 20Newsgroup. To była wbudowana wersja algorytmu LDA firmy Gensim. Istnieje również wersja Mallet Gensim, która zapewnia lepszą jakość tematów. Tutaj zastosujemy LDA Malleta na poprzednim przykładzie, który już zaimplementowaliśmy.

Co to jest model młotka LDA?

Mallet, zestaw narzędzi open source, został napisany przez Andrew McCulluma. Jest to w zasadzie pakiet oparty na Javie, który jest używany do NLP, klasyfikacji dokumentów, klastrowania, modelowania tematów i wielu innych aplikacji do uczenia maszynowego do tekstu. Udostępnia nam zestaw narzędzi Mallet Topic Modeling, który zawiera wydajne, oparte na próbkowaniu implementacje LDA oraz Hierarchical LDA.

Mallet2.0 to aktualne wydanie MALLET, zestawu narzędzi do modelowania tematów w języku Java. Zanim zaczniemy używać go z Gensim dla LDA, musimy pobrać pakiet mallet-2.0.8.zip w naszym systemie i rozpakować go. Po zainstalowaniu i rozpakowaniu, ustaw zmienną środowiskową% MALLET_HOME% tak, aby wskazywała na katalog MALLET ręcznie lub za pomocą kodu, który będziemy dostarczać, podczas wdrażania LDA z Malletem.

Gensim Wrapper

Python zapewnia opakowanie Gensim dla Latent Dirichlet Allocation (LDA). Składnia tego opakowania togensim.models.wrappers.LdaMallet. Moduł ten, zwinięty próbkowanie Gibbsa z MALLET, umożliwia oszacowanie modelu LDA na podstawie korpusu szkoleniowego i wnioskowanie o rozkładzie tematów na nowych, niewidocznych dokumentach.

Przykład implementacji

Będziemy używać LDA Mallet na wcześniej zbudowanym modelu LDA i sprawdzimy różnicę w wydajności, obliczając wynik koherencji.

Zapewnienie ścieżki do pliku Mallet

Przed zastosowaniem modelu Mallet LDA w naszym korpusie zbudowanym w poprzednim przykładzie, musimy zaktualizować zmienne środowiskowe i podać ścieżkę do pliku Mallet. Można to zrobić za pomocą następującego kodu -

import os
from gensim.models.wrappers import LdaMallet
os.environ.update({'MALLET_HOME':r'C:/mallet-2.0.8/'}) 
#You should update this path as per the path of Mallet directory on your system.
mallet_path = r'C:/mallet-2.0.8/bin/mallet' 
#You should update this path as per the path of Mallet directory on your system.

Gdy już podaliśmy ścieżkę do pliku Malleta, możemy go teraz użyć w korpusie. Można to zrobić za pomocąldamallet.show_topics() działają w następujący sposób -

ldamallet = gensim.models.wrappers.LdaMallet(
   mallet_path, corpus=corpus, num_topics=20, id2word=id2word
)
pprint(ldamallet.show_topics(formatted=False))

Wynik

[
   (4,
   [('gun', 0.024546225966016102),
   ('law', 0.02181426826996709),
   ('state', 0.017633545129043606),
   ('people', 0.017612848479831116),
   ('case', 0.011341763768445888),
   ('crime', 0.010596684396796159),
   ('weapon', 0.00985160502514643),
   ('person', 0.008671896020034356),
   ('firearm', 0.00838214293105946),
   ('police', 0.008257963035784506)]),
   (9,
   [('make', 0.02147966482730431),
   ('people', 0.021377478029838543),
   ('work', 0.018557122419783363),
   ('money', 0.016676885346413244),
   ('year', 0.015982015123646026),
   ('job', 0.012221540976905783),
   ('pay', 0.010239117106069897),
   ('time', 0.008910688739014919),
   ('school', 0.0079092581238504),
   ('support', 0.007357449417535254)]),
   (14,
   [('power', 0.018428398507941996),
   ('line', 0.013784244460364121),
   ('high', 0.01183271164249895),
   ('work', 0.011560979224821522),
   ('ground', 0.010770484918850819),
   ('current', 0.010745781971789235),
   ('wire', 0.008399002000938712),
   ('low', 0.008053160742076529),
   ('water', 0.006966231071366814),
   ('run', 0.006892122230182061)]),
   (0,
   [('people', 0.025218349201353372),
   ('kill', 0.01500904870564167),
   ('child', 0.013612400660948935),
   ('armenian', 0.010307655991816822),
   ('woman', 0.010287984892595798),
   ('start', 0.01003226060272248),
   ('day', 0.00967818081674404),
   ('happen', 0.009383114328428673),
   ('leave', 0.009383114328428673),
   ('fire', 0.009009363443229208)]),
   (1,
   [('file', 0.030686386604212003),
   ('program', 0.02227713642901929),
   ('window', 0.01945561169918489),
   ('set', 0.015914874783314277),
   ('line', 0.013831003577619592),
   ('display', 0.013794120901412606),
   ('application', 0.012576992586582082),
   ('entry', 0.009275993066056873),
   ('change', 0.00872275292295209),
   ('color', 0.008612104894331132)]),
   (12,
   [('line', 0.07153810971508515),
   ('buy', 0.02975597944523662),
   ('organization', 0.026877236406682988),
   ('host', 0.025451316957679788),
   ('price', 0.025182275552207485),
   ('sell', 0.02461728860071565),
   ('mail', 0.02192687454599263),
   ('good', 0.018967419085797303),
   ('sale', 0.017998870026097017),
   ('send', 0.013694207538540181)]),
   (11,
   [('thing', 0.04901329901329901),
   ('good', 0.0376018876018876),
   ('make', 0.03393393393393394),
   ('time', 0.03326898326898327),
   ('bad', 0.02664092664092664),
   ('happen', 0.017696267696267698),
   ('hear', 0.015615615615615615),
   ('problem', 0.015465465465465466),
   ('back', 0.015143715143715144),
   ('lot', 0.01495066495066495)]),
   (18,
   [('space', 0.020626317374284855),
   ('launch', 0.00965716006366413),
   ('system', 0.008560244332602057),
   ('project', 0.008173097603991913),
   ('time', 0.008108573149223556),
   ('cost', 0.007764442723792318),
   ('year', 0.0076784101174345075),
   ('earth', 0.007484836753129436),
   ('base', 0.0067535595990880545),
   ('large', 0.006689035144319697)]),
   (5,
   [('government', 0.01918437232469453),
   ('people', 0.01461203206475212),
   ('state', 0.011207097828624796),
   ('country', 0.010214802708381975),
   ('israeli', 0.010039691804809714),
   ('war', 0.009436532025838587),
   ('force', 0.00858043427504086),
   ('attack', 0.008424780138532182),
   ('land', 0.0076659662230523775),
   ('world', 0.0075103120865437)]),
   (2,
   [('car', 0.041091194044470564),
   ('bike', 0.015598981291017729),
   ('ride', 0.011019688510138114),
   ('drive', 0.010627877363110981),
   ('engine', 0.009403467528651191),
   ('speed', 0.008081104907434616),
   ('turn', 0.007738270153785875),
   ('back', 0.007738270153785875),
   ('front', 0.007468899990204721),
   ('big', 0.007370947203447938)])
]

Ocena wydajności

Teraz możemy również ocenić jego wydajność, obliczając wynik koherencji w następujący sposób -

ldamallet = gensim.models.wrappers.LdaMallet(
   mallet_path, corpus=corpus, num_topics=20, id2word=id2word
)
pprint(ldamallet.show_topics(formatted=False))

Wynik

Coherence Score: 0.5842762900901401

W tym rozdziale omówiono dokumenty i model LDA w Gensim.

Znajdowanie optymalnej liczby tematów dla LDA

Optymalną liczbę tematów do LDA możemy znaleźć, tworząc wiele modeli LDA z różnymi wartościami tematów. Spośród tych LDA możemy wybrać taką, która ma najwyższą wartość spójności.

Następująca funkcja o nazwie coherence_values_computation()będzie trenować wiele modeli LDA. Zapewni także modele, a także odpowiadający im wynik spójności -

def coherence_values_computation(dictionary, corpus, texts, limit, start=2, step=3):
   coherence_values = []
   model_list = []
   for num_topics in range(start, limit, step):
      model = gensim.models.wrappers.LdaMallet(
         mallet_path, corpus=corpus, num_topics=num_topics, id2word=id2word
      )
      model_list.append(model)
   coherencemodel = CoherenceModel(
      model=model, texts=texts, dictionary=dictionary, coherence='c_v'
   )
   coherence_values.append(coherencemodel.get_coherence())
return model_list, coherence_values

Teraz za pomocą poniższego kodu możemy uzyskać optymalną liczbę tematów, które możemy pokazać również za pomocą wykresu -

model_list, coherence_values = coherence_values_computation (
   dictionary=id2word, corpus=corpus, texts=data_lemmatized, 
   start=1, limit=50, step=8
)
limit=50; start=1; step=8;
x = range(start, limit, step)
plt.plot(x, coherence_values)
plt.xlabel("Num Topics")
plt.ylabel("Coherence score")
plt.legend(("coherence_values"), loc='best')
plt.show()

Wynik

Następnie możemy również wydrukować wartości spójności dla różnych tematów w następujący sposób -

for m, cv in zip(x, coherence_values):
   print("Num Topics =", m, " is having Coherence Value of", round(cv, 4))

Wynik

Num Topics = 1 is having Coherence Value of 0.4866
Num Topics = 9 is having Coherence Value of 0.5083
Num Topics = 17 is having Coherence Value of 0.5584
Num Topics = 25 is having Coherence Value of 0.5793
Num Topics = 33 is having Coherence Value of 0.587
Num Topics = 41 is having Coherence Value of 0.5842
Num Topics = 49 is having Coherence Value of 0.5735

Teraz pojawia się pytanie, który model wybrać teraz? Jedną z dobrych praktyk jest wybranie modelu, czyli nadanie najwyższej wartości koherencji przed schlebieniem. Dlatego wybierzemy model z 25 tematami, który jest pod numerem 4 na powyższej liście.

optimal_model = model_list[3]
model_topics = optimal_model.show_topics(formatted=False)
pprint(optimal_model.print_topics(num_words=10))

[
   (0,
   '0.018*"power" + 0.011*"high" + 0.010*"ground" + 0.009*"current" + '
   '0.008*"low" + 0.008*"wire" + 0.007*"water" + 0.007*"work" + 0.007*"design" '
   '+ 0.007*"light"'),
   (1,
   '0.036*"game" + 0.029*"team" + 0.029*"year" + 0.028*"play" + 0.020*"player" '
   '+ 0.019*"win" + 0.018*"good" + 0.013*"season" + 0.012*"run" + 0.011*"hit"'),
   (2,
   '0.020*"image" + 0.019*"information" + 0.017*"include" + 0.017*"mail" + '
   '0.016*"send" + 0.015*"list" + 0.013*"post" + 0.012*"address" + '
   '0.012*"internet" + 0.012*"system"'),
   (3,
   '0.986*"ax" + 0.002*"_" + 0.001*"tm" + 0.000*"part" + 0.000*"biz" + '
   '0.000*"mb" + 0.000*"mbs" + 0.000*"pne" + 0.000*"end" + 0.000*"di"'),
   (4,
   '0.020*"make" + 0.014*"work" + 0.013*"money" + 0.013*"year" + 0.012*"people" '
   '+ 0.011*"job" + 0.010*"group" + 0.009*"government" + 0.008*"support" + '
   '0.008*"question"'),
   (5,
   '0.011*"study" + 0.011*"drug" + 0.009*"science" + 0.008*"food" + '
   '0.008*"problem" + 0.008*"result" + 0.008*"effect" + 0.007*"doctor" + '
   '0.007*"research" + 0.007*"patient"'),
   (6,
   '0.024*"gun" + 0.024*"law" + 0.019*"state" + 0.015*"case" + 0.013*"people" + '
   '0.010*"crime" + 0.010*"weapon" + 0.010*"person" + 0.008*"firearm" + '
   '0.008*"police"'),
   (7,
   '0.012*"word" + 0.011*"question" + 0.011*"exist" + 0.011*"true" + '
   '0.010*"religion" + 0.010*"claim" + 0.008*"argument" + 0.008*"truth" + '
   '0.008*"life" + 0.008*"faith"'),
   (8,
   '0.077*"time" + 0.029*"day" + 0.029*"call" + 0.025*"back" + 0.021*"work" + '
   '0.019*"long" + 0.015*"end" + 0.015*"give" + 0.014*"year" + 0.014*"week"'),
   (9,
   '0.048*"thing" + 0.041*"make" + 0.038*"good" + 0.037*"people" + '
   '0.028*"write" + 0.019*"bad" + 0.019*"point" + 0.018*"read" + 0.018*"post" + '
   '0.016*"idea"'),
   (10,
   '0.022*"book" + 0.020*"_" + 0.013*"man" + 0.012*"people" + 0.011*"write" + '
   '0.011*"find" + 0.010*"history" + 0.010*"armenian" + 0.009*"turkish" + '
   '0.009*"number"'),
   (11,
   '0.064*"line" + 0.030*"buy" + 0.028*"organization" + 0.025*"price" + '
   '0.025*"sell" + 0.023*"good" + 0.021*"host" + 0.018*"sale" + 0.017*"mail" + '
   '0.016*"cost"'),
   (12,
   '0.041*"car" + 0.015*"bike" + 0.011*"ride" + 0.010*"engine" + 0.009*"drive" '
   '+ 0.008*"side" + 0.008*"article" + 0.007*"turn" + 0.007*"front" + '
   '0.007*"speed"'),
   (13,
   '0.018*"people" + 0.011*"attack" + 0.011*"state" + 0.011*"israeli" + '
   '0.010*"war" + 0.010*"country" + 0.010*"government" + 0.009*"live" + '
   '0.009*"give" + 0.009*"land"'),
   (14,
   '0.037*"file" + 0.026*"line" + 0.021*"read" + 0.019*"follow" + '
   '0.018*"number" + 0.015*"program" + 0.014*"write" + 0.012*"entry" + '
   '0.012*"give" + 0.011*"check"'),
   (15,
   '0.196*"write" + 0.172*"line" + 0.165*"article" + 0.117*"organization" + '
   '0.086*"host" + 0.030*"reply" + 0.010*"university" + 0.008*"hear" + '
   '0.007*"post" + 0.007*"news"'),
   (16,
   '0.021*"people" + 0.014*"happen" + 0.014*"child" + 0.012*"kill" + '
   '0.011*"start" + 0.011*"live" + 0.010*"fire" + 0.010*"leave" + 0.009*"hear" '
   '+ 0.009*"home"'),
   (17,
   '0.038*"key" + 0.018*"system" + 0.015*"space" + 0.015*"technology" + '
   '0.014*"encryption" + 0.010*"chip" + 0.010*"bit" + 0.009*"launch" + '
   '0.009*"public" + 0.009*"government"'),
   (18,
   '0.035*"drive" + 0.031*"system" + 0.027*"problem" + 0.027*"card" + '
   '0.020*"driver" + 0.017*"bit" + 0.017*"work" + 0.016*"disk" + '
   '0.014*"monitor" + 0.014*"machine"'),
   (19,
   '0.031*"window" + 0.020*"run" + 0.018*"color" + 0.018*"program" + '
   '0.017*"application" + 0.016*"display" + 0.015*"set" + 0.015*"version" + '
   '0.012*"screen" + 0.012*"problem"')
]

Znajdowanie dominujących tematów w zdaniach

Znajdowanie dominujących tematów w zdaniach jest jednym z najbardziej przydatnych praktycznych zastosowań modelowania tematów. Określa, jakiego tematu dotyczy dany dokument. Tutaj znajdziemy numer tematu, który ma największy udział procentowy w tym konkretnym dokumencie. Aby zagregować informacje w tabeli, utworzymy funkcję o nazwiedominant_topics() -

def dominant_topics(ldamodel=lda_model, corpus=corpus, texts=data):
   sent_topics_df = pd.DataFrame()

Następnie uzyskamy główne tematy w każdym dokumencie -

for i, row in enumerate(ldamodel[corpus]):
   row = sorted(row, key=lambda x: (x[1]), reverse=True)

Następnie otrzymamy temat dominujący, udział procentowy i słowa kluczowe dla każdego dokumentu -

for j, (topic_num, prop_topic) in enumerate(row):
   if j == 0: # => dominant topic
      wp = ldamodel.show_topic(topic_num)
      topic_keywords = ", ".join([word for word, prop in wp])
sent_topics_df = sent_topics_df.append(
   pd.Series([int(topic_num), round(prop_topic,4), topic_keywords]), ignore_index=True
)
   else:
      break
sent_topics_df.columns = ['Dominant_Topic', 'Perc_Contribution', 'Topic_Keywords']

Za pomocą poniższego kodu dodamy oryginalny tekst na końcu wyjścia -

contents = pd.Series(texts)
   sent_topics_df = pd.concat([sent_topics_df, contents], axis=1)
   return(sent_topics_df)
df_topic_sents_keywords = dominant_topics(
   ldamodel=optimal_model, corpus=corpus, texts=data
)

Teraz sformatuj tematy w zdaniach w następujący sposób -

df_dominant_topic = df_topic_sents_keywords.reset_index()
df_dominant_topic.columns = [
   'Document_No', 'Dominant_Topic', 'Topic_Perc_Contrib', 'Keywords', 'Text'
]

Na koniec możemy przedstawić dominujące tematy w następujący sposób -

df_dominant_topic.head(15)

Znalezienie najbardziej reprezentatywnego dokumentu

Aby lepiej zrozumieć temat, możemy również znaleźć dokumenty, w których dany temat ma największy udział. Możemy wywnioskować ten temat, czytając ten konkretny dokument (y).

sent_topics_sorteddf_mallet = pd.DataFrame()
sent_topics_outdf_grpd = df_topic_sents_keywords.groupby('Dominant_Topic')
for i, grp in sent_topics_outdf_grpd:
   sent_topics_sorteddf_mallet = pd.concat([sent_topics_sorteddf_mallet,
grp.sort_values(['Perc_Contribution'], ascending=[0]).head(1)], axis=0)
sent_topics_sorteddf_mallet.reset_index(drop=True, inplace=True)
sent_topics_sorteddf_mallet.columns = [
   'Topic_Number', "Contribution_Perc", "Keywords", "Text"
]
sent_topics_sorteddf_mallet.head()

Wynik

Tom i dystrybucja tematów

Czasami chcemy również ocenić, jak szeroko temat jest omawiany w dokumentach. W tym celu musimy zrozumieć ilość i dystrybucję tematów w dokumentach.

Najpierw oblicz liczbę dokumentów dla każdego tematu w następujący sposób -

topic_counts = df_topic_sents_keywords['Dominant_Topic'].value_counts()

Następnie oblicz procent dokumentów dla każdego tematu w następujący sposób -;

topic_contribution = round(topic_counts/topic_counts.sum(), 4)

Teraz znajdź temat Liczba i słowa kluczowe w następujący sposób -

topic_num_keywords = df_topic_sents_keywords[['Dominant_Topic', 'Topic_Keywords']]

Teraz połącz, a następnie kolumny w następujący sposób -

df_dominant_topics = pd.concat(
   [topic_num_keywords, topic_counts, topic_contribution], axis=1
)

Następnie zmienimy nazwy kolumn w następujący sposób -

df_dominant_topics.columns = [
   'Dominant-Topic', 'Topic-Keywords', 'Num_Documents', 'Perc_Documents'
]
df_dominant_topics

Wynik

Ten rozdział dotyczy tworzenia modelu tematycznego utajonego indeksowania semantycznego (LSI) i hierarchicznego procesu Dirichleta (HDP) w odniesieniu do Gensim.

Algorytmy modelowania tematu, które zostały po raz pierwszy zaimplementowane w Gensim z Latent Dirichlet Allocation (LDA) to Latent Semantic Indexing (LSI). Nazywa się to równieżLatent Semantic Analysis (LSA). Został opatentowany w 1988 roku przez Scotta Deerwestera, Susan Dumais, George'a Furnasa, Richarda Harshmana, Thomasa Landaura, Karen Lochbaum i Lynn Streeter.

W tej sekcji mamy zamiar skonfigurować nasz model LSI. Można to zrobić w ten sam sposób, jak konfigurując model LDA. Musimy zaimportować model LSI zgensim.models.

Rola LSI

W rzeczywistości LSI jest techniką NLP, zwłaszcza w semantyce dystrybucyjnej. Analizuje związek między zbiorem dokumentów a terminami, które te dokumenty zawierają. Jeśli mówimy o jego działaniu, konstruuje on macierz zawierającą liczbę słów w dokumencie z dużego fragmentu tekstu.

Po skonstruowaniu, w celu zmniejszenia liczby wierszy, model LSI wykorzystuje technikę matematyczną zwaną dekompozycją wartości osobliwej (SVD). Wraz ze zmniejszeniem liczby wierszy zachowuje również strukturę podobieństwa między kolumnami.

W macierzy wiersze reprezentują unikalne słowa, a kolumny reprezentują każdy dokument. Działa w oparciu o hipotezę dystrybucyjną, tj. Zakłada, że ​​słowa bliskie znaczeniom będą występować w tym samym rodzaju tekstu.

Wdrożenie z Gensim

Tutaj użyjemy LSI (Latent Semantic Indexing) do wyodrębnienia naturalnie omawianych tematów ze zbioru danych.

Ładowanie zestawu danych

Zbiór danych, którego będziemy używać, to zbiór danych ’20 Newsgroups’posiadanie tysięcy artykułów z różnych sekcji raportu prasowego. Jest dostępny w ramachSklearnzbiory danych. Możemy łatwo pobrać za pomocą następującego skryptu Pythona -

from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train')

Przyjrzyjmy się niektórym przykładowym wiadomościom za pomocą następującego skryptu -

newsgroups_train.data[:4]
["From: [email protected] (where's my thing)\nSubject: 
WHAT car is this!?\nNntp-Posting-Host: rac3.wam.umd.edu\nOrganization: 
University of Maryland, College Park\nLines: 15\n\n 
I was wondering if anyone out there could enlighten me on this car 
I saw\nthe other day. It was a 2-door sports car,
looked to be from the late 60s/\nearly 70s. It was called a Bricklin. 
The doors were really small. In addition,\nthe front bumper was separate from 
the rest of the body. This is \nall I know. If anyone can tellme a model name, 
engine specs, years\nof production, where this car is made, history, or 
whatever info you\nhave on this funky looking car, 
please e-mail.\n\nThanks,\n- IL\n ---- brought to you by your neighborhood 
Lerxst ----\n\n\n\n\n",

"From: [email protected] (Guy Kuo)\nSubject: 
SI Clock Poll - Final Call\nSummary: Final call for SI clock reports\nKeywords: 
SI,acceleration,clock,upgrade\nArticle-I.D.: shelley.1qvfo9INNc3s\nOrganization: 
University of Washington\nLines: 11\nNNTP-Posting-Host: carson.u.washington.edu\n\nA 
fair number of brave souls who upgraded their SI clock oscillator have\nshared their 
experiences for this poll. Please send a brief message detailing\nyour experiences with 
the procedure. Top speed attained, CPU rated speed,\nadd on cards and adapters, heat 
sinks, hour of usage per day, floppy disk\nfunctionality with 800 and 1.4 m floppies 
are especially requested.\n\nI will be summarizing in the next two days, so please add 
to the network\nknowledge base if you have done the clock upgrade and haven't answered 
this\npoll. Thanks.\n\nGuy Kuo <[email protected]>\n",

'From: [email protected] (Thomas E Willis)\nSubject: 
PB questions...\nOrganization: Purdue University Engineering Computer 
Network\nDistribution: usa\nLines: 36\n\nwell folks, my mac plus finally gave up the 
ghost this weekend after\nstarting life as a 512k way back in 1985. sooo, i\'m in the 
market for a\nnew machine a bit sooner than i intended to be...\n\ni\'m looking into 
picking up a powerbook 160 or maybe 180 and have a bunch\nof questions that (hopefully) 
somebody can answer:\n\n* does anybody know any dirt on when the next round of 
powerbook\nintroductions are expected? i\'d heard the 185c was supposed to make 
an\nappearence "this summer" but haven\'t heard anymore on it - and since i\ndon\'t 
have access to macleak, i was wondering if anybody out there had\nmore info...\n\n* has 
anybody heard rumors about price drops to the powerbook line like the\nones the duo\'s 
just went through recently?\n\n* what\'s the impression of the display on the 180? i 
could probably swing\na 180 if i got the 80Mb disk rather than the 120, but i don\'t 
really have\na feel for how much "better" the display is (yea, it looks great in 
the\nstore, but is that all "wow" or is it really that good?). could i solicit\nsome 
opinions of people who use the 160 and 180 day-to-day on if its worth\ntaking the disk 
size and money hit to get the active display? (i realize\nthis is a real subjective 
question, but i\'ve only played around with the\nmachines in a computer store breifly 
and figured the opinions of somebody\nwho actually uses the machine daily might prove 
helpful).\n\n* how well does hellcats perform? ;)\n\nthanks a bunch in advance for any 
info - if you could email, i\'ll post a\nsummary (news reading time is at a premium 
with finals just around the\ncorner... :( )\n--\nTom Willis \\ [email protected] 
\\ Purdue Electrical 
Engineering\n---------------------------------------------------------------------------\
n"Convictions are more dangerous enemies of truth than lies." - F. W.\nNietzsche\n',

'From: jgreen@amber (Joe Green)\nSubject: Re: Weitek P9000 ?\nOrganization: Harris 
Computer Systems Division\nLines: 14\nDistribution: world\nNNTP-Posting-Host: 
amber.ssd.csd.harris.com\nX-Newsreader: TIN [version 1.1 PL9]\n\nRobert J.C. Kyanko 
([email protected]) wrote:\n > [email protected] writes in article <
[email protected]>:\n> > Anyone know about the Weitek P9000 
graphics chip?\n > As far as the low-level stuff goes, it looks pretty nice. It\'s 
got this\n > quadrilateral fill command that requires just the four
points.\n\nDo you have Weitek\'s address/phone number? I\'d like to get some 
information\nabout this chip.\n\n--\nJoe Green\t\t\t\tHarris 
Corporation\[email protected]\t\t\tComputer Systems Division\n"The only thing that 
really scares me is a person with no sense of humor."\n\t\t\t\t\t\t-- Jonathan 
Winters\n']

Warunek wstępny

Potrzebujemy stopwords z NLTK i modelu angielskiego ze Scapy. Oba można pobrać w następujący sposób -

import nltk;
nltk.download('stopwords')
nlp = spacy.load('en_core_web_md', disable=['parser', 'ner'])

Importowanie niezbędnych pakietów

Aby zbudować model LSI musimy zaimportować następujący pakiet -

import re
import numpy as np
import pandas as pd
from pprint import pprint
import gensim
import gensim.corpora as corpora
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel
import spacy
import matplotlib.pyplot as plt

Przygotowywanie odrzucanych słów

Teraz musimy zaimportować stopwords i użyć ich -

from nltk.corpus import stopwords
stop_words = stopwords.words('english')
stop_words.extend(['from', 'subject', 're', 'edu', 'use'])

Oczyść tekst

Teraz z pomocą Gensima simple_preprocess()musimy ująć każde zdanie w listę słów. Powinniśmy również usunąć znaki interpunkcyjne i niepotrzebne znaki. W tym celu stworzymy funkcję o nazwiesent_to_words() -

def sent_to_words(sentences):
   for sentence in sentences:
      yield(gensim.utils.simple_preprocess(str(sentence), deacc=True))
data_words = list(sent_to_words(data))

Budowanie modeli Bigram i Trigram

Jak wiemy, bigramy to dwa słowa, które często występują razem w dokumencie, a trygram to trzy słowa, które często występują razem w dokumencie. Za pomocą modelu Gensim's Phrases możemy to zrobić -

bigram = gensim.models.Phrases(data_words, min_count=5, threshold=100)
trigram = gensim.models.Phrases(bigram[data_words], threshold=100)
bigram_mod = gensim.models.phrases.Phraser(bigram)
trigram_mod = gensim.models.phrases.Phraser(trigram)

Odfiltruj odrzucane słowa

Następnie musimy odfiltrować odrzucane słowa. Oprócz tego stworzymy również funkcje do tworzenia bigramów, trygramów i do lematyzacji -

def remove_stopwords(texts):
   return [[word for word in simple_preprocess(str(doc)) 
   if word not in stop_words] for doc in texts]
def make_bigrams(texts):
   return [bigram_mod[doc] for doc in texts]
def make_trigrams(texts):
   return [trigram_mod[bigram_mod[doc]] for doc in texts]
def lemmatization(texts, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']):
   texts_out = []
   for sent in texts:
      doc = nlp(" ".join(sent))
      texts_out.append([token.lemma_ for token in doc if token.pos_ in allowed_postags])
   return texts_out

Tworzenie słownika i korpusu dla modelu tematycznego

Teraz musimy zbudować słownik i korpus. Zrobiliśmy to również w poprzednich przykładach -

id2word = corpora.Dictionary(data_lemmatized)
texts = data_lemmatized
corpus = [id2word.doc2bow(text) for text in texts]

Budowanie modelu tematycznego LSI

Wdrożyliśmy już wszystko, co jest wymagane do trenowania modelu LSI. Nadszedł czas, aby zbudować model tematyczny LSI. W naszym przykładzie implementacji można to zrobić za pomocą następującego wiersza kodów -

lsi_model = gensim.models.lsimodel.LsiModel(
   corpus=corpus, id2word=id2word, num_topics=20,chunksize=100
)

Przykład implementacji

Zobaczmy pełny przykład implementacji, aby zbudować model tematu LDA -

import re
import numpy as np
import pandas as pd
from pprint import pprint
import gensim
import gensim.corpora as corpora
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel
import spacy
import matplotlib.pyplot as plt
from nltk.corpus import stopwords
stop_words = stopwords.words('english')
stop_words.extend(['from', 'subject', 're', 'edu', 'use'])
from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train')
data = newsgroups_train.data
data = [re.sub('\S*@\S*\s?', '', sent) for sent in data]
data = [re.sub('\s+', ' ', sent) for sent in data]
data = [re.sub("\'", "", sent) for sent in data]
print(data_words[:4]) #it will print the data after prepared for stopwords
bigram = gensim.models.Phrases(data_words, min_count=5, threshold=100)
trigram = gensim.models.Phrases(bigram[data_words], threshold=100)
bigram_mod = gensim.models.phrases.Phraser(bigram)
trigram_mod = gensim.models.phrases.Phraser(trigram)
def remove_stopwords(texts):
   return [[word for word in simple_preprocess(str(doc)) 
   if word not in stop_words] for doc in texts]
def make_bigrams(texts):
   return [bigram_mod[doc] for doc in texts]
def make_trigrams(texts):
   return [trigram_mod[bigram_mod[doc]] for doc in texts]
def lemmatization(texts, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']):
   texts_out = []
   for sent in texts:
      doc = nlp(" ".join(sent))
      texts_out.append([token.lemma_ for token in doc if token.pos_ in allowed_postags])
return texts_out
data_words_nostops = remove_stopwords(data_words)
data_words_bigrams = make_bigrams(data_words_nostops)
nlp = spacy.load('en_core_web_md', disable=['parser', 'ner'])
data_lemmatized = lemmatization(
   data_words_bigrams, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']
)
print(data_lemmatized[:4]) #it will print the lemmatized data.
id2word = corpora.Dictionary(data_lemmatized)
texts = data_lemmatized
corpus = [id2word.doc2bow(text) for text in texts]
print(corpus[:4]) #it will print the corpus we created above.
[[(id2word[id], freq) for id, freq in cp] for cp in corpus[:4]] 
#it will print the words with their frequencies.
lsi_model = gensim.models.lsimodel.LsiModel(
   corpus=corpus, id2word=id2word, num_topics=20,chunksize=100
)

Możemy teraz użyć utworzonego powyżej modelu LSI, aby uzyskać tematy.

Przeglądanie tematów w modelu LSI

Model LSI (lsi_model)stworzone powyżej mogą służyć do przeglądania tematów z dokumentów. Można to zrobić za pomocą następującego skryptu -

pprint(lsi_model.print_topics())
doc_lsi = lsi_model[corpus]

Wynik

[
   (0,
   '1.000*"ax" + 0.001*"_" + 0.000*"tm" + 0.000*"part" +    0.000*"pne" + '
   '0.000*"biz" + 0.000*"mbs" + 0.000*"end" + 0.000*"fax" + 0.000*"mb"'),
   (1,
   '0.239*"say" + 0.222*"file" + 0.189*"go" + 0.171*"know" + 0.169*"people" + '
   '0.147*"make" + 0.140*"use" + 0.135*"also" + 0.133*"see" + 0.123*"think"')
]

Hierarchiczny proces Dirichleta (HPD)

Modele tematyczne, takie jak LDA i LSI, pomagają w podsumowywaniu i organizowaniu dużych archiwów tekstów, których nie można przeanalizować ręcznie. Oprócz LDA i LSI, innym potężnym modelem tematycznym w Gensim jest HDP (Hierarchical Dirichlet Process). Jest to w zasadzie model członkostwa mieszanego do nienadzorowanej analizy zgrupowanych danych. W przeciwieństwie do LDA (jej skończony odpowiednik), HDP wnioskuje liczbę tematów na podstawie danych.

Wdrożenie z Gensim

Aby zaimplementować HDP w Gensim, musimy wyszkolić korpus i słownik (tak jak w powyższych przykładach podczas implementacji modeli tematycznych LDA i LSI) Model tematu HDP, który możemy zaimportować z gensim.models.HdpModel. Tutaj również zaimplementujemy model tematu HDP na danych 20Newsgroup i kroki również są takie same.

Dla naszego korpusu i słownika (utworzonego w powyższych przykładach dla modelu LSI i LDA) możemy zaimportować HdpModel w następujący sposób -

Hdp_model = gensim.models.hdpmodel.HdpModel(corpus=corpus, id2word=id2word)

Przeglądanie tematów w modelu LSI

Model HDP (Hdp_model)można użyć do przeglądania tematów z dokumentów. Można to zrobić za pomocą następującego skryptu -

pprint(Hdp_model.print_topics())

Wynik

[
   (0,
   '0.009*line + 0.009*write + 0.006*say + 0.006*article + 0.006*know + '
   '0.006*people + 0.005*make + 0.005*go + 0.005*think + 0.005*be'),
   (1,
   '0.016*line + 0.011*write + 0.008*article + 0.008*organization + 0.006*know '
   '+ 0.006*host + 0.006*be + 0.005*get + 0.005*use + 0.005*say'),
   (2,
   '0.810*ax + 0.001*_ + 0.000*tm + 0.000*part + 0.000*mb + 0.000*pne + '
   '0.000*biz + 0.000*end + 0.000*wwiz + 0.000*fax'),
   (3,
   '0.015*line + 0.008*write + 0.007*organization + 0.006*host + 0.006*know + '
   '0.006*article + 0.005*use + 0.005*thank + 0.004*get + 0.004*problem'),
   (4,
   '0.004*line + 0.003*write + 0.002*believe + 0.002*think + 0.002*article + '
   '0.002*belief + 0.002*say + 0.002*see + 0.002*look + 0.002*organization'),
   (5,
   '0.005*line + 0.003*write + 0.003*organization + 0.002*article + 0.002*time '
   '+ 0.002*host + 0.002*get + 0.002*look + 0.002*say + 0.001*number'),
   (6,
   '0.003*line + 0.002*say + 0.002*write + 0.002*go + 0.002*gun + 0.002*get + '
   '0.002*organization + 0.002*bill + 0.002*article + 0.002*state'),
   (7,
   '0.003*line + 0.002*write + 0.002*article + 0.002*organization + 0.001*none '
   '+ 0.001*know + 0.001*say + 0.001*people + 0.001*host + 0.001*new'),
   (8,
   '0.004*line + 0.002*write + 0.002*get + 0.002*team + 0.002*organization + '
   '0.002*go + 0.002*think + 0.002*know + 0.002*article + 0.001*well'),
   (9,
   '0.004*line + 0.002*organization + 0.002*write + 0.001*be + 0.001*host + '
   '0.001*article + 0.001*thank + 0.001*use + 0.001*work + 0.001*run'),
   (10,
   '0.002*line + 0.001*game + 0.001*write + 0.001*get + 0.001*know + '
   '0.001*thing + 0.001*think + 0.001*article + 0.001*help + 0.001*turn'),
   (11,
   '0.002*line + 0.001*write + 0.001*game + 0.001*organization + 0.001*say + '
   '0.001*host + 0.001*give + 0.001*run + 0.001*article + 0.001*get'),
   (12,
   '0.002*line + 0.001*write + 0.001*know + 0.001*time + 0.001*article + '
   '0.001*get + 0.001*think + 0.001*organization + 0.001*scope + 0.001*make'),
   (13,
   '0.002*line + 0.002*write + 0.001*article + 0.001*organization + 0.001*make '
   '+ 0.001*know + 0.001*see + 0.001*get + 0.001*host + 0.001*really'),
   (14,
   '0.002*write + 0.002*line + 0.002*know + 0.001*think + 0.001*say + '
   '0.001*article + 0.001*argument + 0.001*even + 0.001*card + 0.001*be'),
   (15,
   '0.001*article + 0.001*line + 0.001*make + 0.001*write + 0.001*know + '
   '0.001*say + 0.001*exist + 0.001*get + 0.001*purpose + 0.001*organization'),
   (16,
   '0.002*line + 0.001*write + 0.001*article + 0.001*insurance + 0.001*go + '
   '0.001*be + 0.001*host + 0.001*say + 0.001*organization + 0.001*part'),
   (17,
   '0.001*line + 0.001*get + 0.001*hit + 0.001*go + 0.001*write + 0.001*say + '
   '0.001*know + 0.001*drug + 0.001*see + 0.001*need'),
   (18,
   '0.002*option + 0.001*line + 0.001*flight + 0.001*power + 0.001*software + '
   '0.001*write + 0.001*add + 0.001*people + 0.001*organization + 0.001*module'),
   (19,
   '0.001*shuttle + 0.001*line + 0.001*roll + 0.001*attitude + 0.001*maneuver + '
   '0.001*mission + 0.001*also + 0.001*orbit + 0.001*produce + 0.001*frequency')
]

Ten rozdział pomoże nam zrozumieć osadzanie słów rozwijających się w Gensim.

Osadzanie słów, podejście do reprezentowania słów i dokumentów, to gęsta reprezentacja wektorowa tekstu, w której słowa o tym samym znaczeniu mają podobną reprezentację. Poniżej przedstawiono niektóre cechy osadzania słów -

  • Jest to klasa techniki, która przedstawia poszczególne słowa jako wektory o wartościach rzeczywistych w określonej przestrzeni wektorowej.

  • Technika ta jest często umieszczana w polu DL (głębokiego uczenia się), ponieważ każde słowo jest mapowane na jeden wektor, a wartości wektorów są uczone w taki sam sposób, jak NN (sieci neuronowe).

  • Kluczowym podejściem do techniki osadzania słów jest gęsto rozmieszczona reprezentacja każdego słowa.

Różne metody / algorytmy osadzania słów

Jak omówiono powyżej, metody / algorytmy osadzania słów uczą się reprezentacji wektorowej o wartościach rzeczywistych z korpusu tekstu. Ten proces uczenia się może być używany z modelem NN w zadaniach, takich jak klasyfikacja dokumentów, lub jest procesem nienadzorowanym, takim jak statystyki dokumentów. Tutaj omówimy dwie metody / algorytmy, których można użyć do nauki osadzania słowa z tekstu -

Word2Vec firmy Google

Word2Vec, opracowany przez Tomasa Mikolova i in. glin. w Google w 2013 r. jest metodą statystyczną do efektywnego uczenia się osadzania słów z korpusu tekstu. W rzeczywistości został opracowany w odpowiedzi na zwiększenie wydajności uczenia osadzania słów w oparciu o NN. Stało się de facto standardem osadzania słów.

Osadzanie słów przez Word2Vec obejmuje analizę wyuczonych wektorów, a także eksplorację matematyki wektorowej na reprezentacji słów. Poniżej znajdują się dwie różne metody uczenia się, które można wykorzystać jako część metody Word2Vec -

  • Model CBoW (ciągły zbiór słów)
  • Ciągły model Skip-Gram

GloVe firmy Standford

GloVe (Global vectors for Word Representation) to rozszerzenie metody Word2Vec. Został opracowany przez Penningtona i wsp. w Stanford. Algorytm GloVe jest połączeniem obu -

  • Globalne statystyki technik faktoryzacji macierzy, takich jak LSA (Latent Semantic Analysis)
  • Lokalne uczenie się oparte na kontekście w Word2Vec.

Jeśli mówimy o jego działaniu, zamiast używać okna do definiowania lokalnego kontekstu, GloVe konstruuje jawną macierz współwystępowania słów, używając statystyk w całym korpusie tekstu.

Tworzenie osadzania Word2Vec

Tutaj będziemy rozwijać osadzanie Word2Vec przy użyciu Gensim. Aby pracować z modelem Word2Vec, Gensim zapewnia namWord2Vec klasa, z której można importować models.word2vec. Do swojej implementacji word2vec wymaga dużej ilości tekstu, np. Całego korpusu recenzji Amazon. Ale tutaj zastosujemy tę zasadę do tekstu o małej pamięci.

Przykład implementacji

Najpierw musimy zaimportować klasę Word2Vec z gensim.models w następujący sposób -

from gensim.models import Word2Vec

Następnie musimy zdefiniować dane treningowe. Zamiast brać duży plik tekstowy, używamy kilku zdań, aby zaimplementować tę zasadę.

sentences = [
   ['this', 'is', 'gensim', 'tutorial', 'for', 'free'],
   ['this', 'is', 'the', 'tutorials' 'point', 'website'],
   ['you', 'can', 'read', 'technical','tutorials', 'for','free'],
   ['we', 'are', 'implementing','word2vec'],
   ['learn', 'full', 'gensim', 'tutorial']
]

Po dostarczeniu danych szkoleniowych musimy wytrenować model. można to zrobić w następujący sposób -

model = Word2Vec(sentences, min_count=1)

Możemy podsumować model w następujący sposób -;

print(model)

Możemy podsumować słownictwo w następujący sposób -

words = list(model.wv.vocab)
print(words)

Następnie przejdźmy do wektora dla jednego słowa. Robimy to dla słowa „tutorial”.

print(model['tutorial'])

Następnie musimy zapisać model -

model.save('model.bin')

Następnie musimy załadować model -

new_model = Word2Vec.load('model.bin')

Na koniec wydrukuj zapisany model w następujący sposób -

print(new_model)

Pełny przykład implementacji

from gensim.models import Word2Vec
sentences = [
   ['this', 'is', 'gensim', 'tutorial', 'for', 'free'],
   ['this', 'is', 'the', 'tutorials' 'point', 'website'],
   ['you', 'can', 'read', 'technical','tutorials', 'for','free'],
   ['we', 'are', 'implementing','word2vec'],
   ['learn', 'full', 'gensim', 'tutorial']
]
model = Word2Vec(sentences, min_count=1)
print(model)
words = list(model.wv.vocab)
print(words)
print(model['tutorial'])
model.save('model.bin')
new_model = Word2Vec.load('model.bin')
print(new_model)

Wynik

Word2Vec(vocab=20, size=100, alpha=0.025)
[
   'this', 'is', 'gensim', 'tutorial', 'for', 'free', 'the', 'tutorialspoint', 
   'website', 'you', 'can', 'read', 'technical', 'tutorials', 'we', 'are', 
   'implementing', 'word2vec', 'learn', 'full'
]
[
   -2.5256255e-03 -4.5352755e-03 3.9024993e-03 -4.9509313e-03
   -1.4255195e-03 -4.0217536e-03 4.9407515e-03 -3.5925603e-03
   -1.1933431e-03 -4.6682903e-03 1.5440651e-03 -1.4101702e-03
   3.5070938e-03 1.0914479e-03 2.3334436e-03 2.4452661e-03
   -2.5336299e-04 -3.9676363e-03 -8.5054158e-04 1.6443320e-03
   -4.9968651e-03 1.0974540e-03 -1.1123562e-03 1.5393364e-03
   9.8941079e-04 -1.2656028e-03 -4.4471184e-03 1.8309267e-03
   4.9302122e-03 -1.0032534e-03 4.6892050e-03 2.9563988e-03
   1.8730218e-03 1.5343715e-03 -1.2685956e-03 8.3664013e-04
   4.1721235e-03 1.9445885e-03 2.4097660e-03 3.7517555e-03
   4.9687522e-03 -1.3598346e-03 7.1032363e-04 -3.6595813e-03
   6.0000515e-04 3.0872561e-03 -3.2115565e-03 3.2270295e-03
   -2.6354722e-03 -3.4988276e-04 1.8574356e-04 -3.5757164e-03
   7.5391348e-04 -3.5205986e-03 -1.9795434e-03 -2.8321696e-03
   4.7155009e-03 -4.3349937e-04 -1.5320212e-03 2.7013756e-03
   -3.7055744e-03 -4.1658725e-03 4.8034848e-03 4.8594419e-03
   3.7129463e-03 4.2385766e-03 2.4612297e-03 5.4920948e-04
   -3.8912550e-03 -4.8226118e-03 -2.2763973e-04 4.5571579e-03
   -3.4609400e-03 2.7903817e-03 -3.2709218e-03 -1.1036445e-03
   2.1492650e-03 -3.0384419e-04 1.7709908e-03 1.8429896e-03
   -3.4038599e-03 -2.4872608e-03 2.7693063e-03 -1.6352943e-03
   1.9182395e-03 3.7772327e-03 2.2769428e-03 -4.4629495e-03
   3.3151123e-03 4.6509290e-03 -4.8521687e-03 6.7615538e-04
   3.1034781e-03 2.6369948e-05 4.1454583e-03 -3.6932561e-03
   -1.8769916e-03 -2.1958587e-04 6.3395966e-04 -2.4969708e-03
]
Word2Vec(vocab=20, size=100, alpha=0.025)

Wizualizacja osadzania słów

Możemy również zbadać osadzanie słów za pomocą wizualizacji. Można to zrobić za pomocą klasycznej metody rzutowania (takiej jak PCA), aby zredukować wielowymiarowe wektory słów do wykresów 2-D. Po zmniejszeniu możemy przedstawić je na wykresie.

Wykreślanie wektorów słownych za pomocą PCA

Najpierw musimy pobrać wszystkie wektory z wytrenowanego modelu w następujący sposób -

Z = model[model.wv.vocab]

Następnie musimy utworzyć model 2-D PCA wektorów słów przy użyciu klasy PCA w następujący sposób -

pca = PCA(n_components=2)
result = pca.fit_transform(Z)

Teraz możemy wykreślić wynikową projekcję za pomocą matplotlib w następujący sposób -

Pyplot.scatter(result[:,0],result[:,1])

Możemy również opisać punkty na wykresie za pomocą samych słów. Wykreśl wynikowy rzut za pomocą matplotlib w następujący sposób -

words = list(model.wv.vocab)
for i, word in enumerate(words):
   pyplot.annotate(word, xy=(result[i, 0], result[i, 1]))

Pełny przykład implementacji

from gensim.models import Word2Vec
from sklearn.decomposition import PCA
from matplotlib import pyplot
sentences = [
   ['this', 'is', 'gensim', 'tutorial', 'for', 'free'],
	['this', 'is', 'the', 'tutorials' 'point', 'website'],
	['you', 'can', 'read', 'technical','tutorials', 'for','free'],
	['we', 'are', 'implementing','word2vec'],
	['learn', 'full', 'gensim', 'tutorial']
]
model = Word2Vec(sentences, min_count=1)
X = model[model.wv.vocab]
pca = PCA(n_components=2)
result = pca.fit_transform(X)
pyplot.scatter(result[:, 0], result[:, 1])
words = list(model.wv.vocab)
for i, word in enumerate(words):
   pyplot.annotate(word, xy=(result[i, 0], result[i, 1]))
pyplot.show()

Wynik

Model Doc2Vec, w przeciwieństwie do modelu Word2Vec, służy do tworzenia zwektoryzowanej reprezentacji grupy słów traktowanych zbiorczo jako pojedyncza jednostka. Nie tylko podaje prostą średnią słów w zdaniu.

Tworzenie wektorów dokumentów za pomocą Doc2Vec

Tutaj, aby utworzyć wektory dokumentów za pomocą Doc2Vec, będziemy używać zestawu danych text8, który można pobrać z gensim.downloader.

Pobieranie zestawu danych

Możemy pobrać zestaw danych text8 za pomocą następujących poleceń -

import gensim
import gensim.downloader as api
dataset = api.load("text8")
data = [d for d in dataset]

Pobranie zestawu danych text8 zajmie trochę czasu.

Wytrenuj Doc2Vec

Aby wytrenować model, potrzebujemy otagowanego dokumentu, który można utworzyć za pomocą models.doc2vec.TaggedDcument() w następujący sposób -

def tagged_document(list_of_list_of_words):
   for i, list_of_words in enumerate(list_of_list_of_words):
      yield gensim.models.doc2vec.TaggedDocument(list_of_words, [i])
data_for_training = list(tagged_document(data))

Możemy wydrukować wytrenowany zestaw danych w następujący sposób -

print(data_for_training [:1])

Wynik

[TaggedDocument(words=['anarchism', 'originated', 'as', 'a', 'term', 'of',
'abuse', 'first', 'used', 'against', 'early', 'working', 'class', 'radicals',
'including', 'the', 'diggers', 'of', 'the', 'english', 'revolution', 
'and', 'the', 'sans', 'culottes', 'of', 'the', 'french', 'revolution',
'whilst', 'the', 'term', 'is', 'still', 'used', 'in', 'a', 'pejorative',
'way', 'to', 'describe', 'any', 'act', 'that', 'used', 'violent', 
'means', 'to', 'destroy',
'the', 'organization', 'of', 'society', 'it', 'has', 'also', 'been'
, 'taken', 'up', 'as', 'a', 'positive', 'label', 'by', 'self', 'defined',
'anarchists', 'the', 'word', 'anarchism', 'is', 'derived', 'from', 'the',
'greek', 'without', 'archons', 'ruler', 'chief', 'king', 'anarchism', 
'as', 'a', 'political', 'philosophy', 'is', 'the', 'belief', 'that', 
'rulers', 'are', 'unnecessary', 'and', 'should', 'be', 'abolished',
'although', 'there', 'are', 'differing', 'interpretations', 'of', 
'what', 'this', 'means', 'anarchism', 'also', 'refers', 'to', 
'related', 'social', 'movements', 'that', 'advocate', 'the', 
'elimination', 'of', 'authoritarian', 'institutions', 'particularly',
'the', 'state', 'the', 'word', 'anarchy', 'as', 'most', 'anarchists', 
'use', 'it', 'does', 'not', 'imply', 'chaos', 'nihilism', 'or', 'anomie',
'but', 'rather', 'a', 'harmonious', 'anti', 'authoritarian', 'society', 
'in', 'place', 'of', 'what', 'are', 'regarded', 'as', 'authoritarian',
'political', 'structures', 'and', 'coercive', 'economic', 'institutions', 
'anarchists', 'advocate', 'social', 'relations', 'based', 'upon', 'voluntary',
'association', 'of', 'autonomous', 'individuals', 'mutual', 'aid', 'and', 
'self', 'governance', 'while', 'anarchism', 'is', 'most', 'easily', 'defined',
'by', 'what', 'it', 'is', 'against', 'anarchists', 'also', 'offer', 
'positive', 'visions', 'of', 'what', 'they', 'believe', 'to', 'be', 'a',
'truly', 'free', 'society', 'however', 'ideas', 'about', 'how', 'an', 'anarchist',
'society', 'might', 'work', 'vary', 'considerably', 'especially', 'with',
'respect', 'to', 'economics', 'there', 'is', 'also', 'disagreement', 'about', 
'how', 'a', 'free', 'society', 'might', 'be', 'brought', 'about', 'origins', 
'and', 'predecessors', 'kropotkin', 'and', 'others', 'argue', 'that', 'before',
'recorded', 'history', 'human', 'society', 'was', 'organized', 'on', 'anarchist', 
'principles', 'most', 'anthropologists', 'follow', 'kropotkin', 'and', 'engels', 
'in', 'believing', 'that', 'hunter', 'gatherer', 'bands', 'were', 'egalitarian',
'and', 'lacked', 'division', 'of', 'labour', 'accumulated', 'wealth', 'or', 'decreed',
'law', 'and', 'had', 'equal', 'access', 'to', 'resources', 'william', 'godwin', 
'anarchists', 'including', 'the', 'the', 'anarchy', 'organisation', 'and', 'rothbard',
'find', 'anarchist', 'attitudes', 'in', 'taoism', 'from', 'ancient', 'china', 
'kropotkin', 'found', 'similar', 'ideas', 'in', 'stoic', 'zeno', 'of', 'citium', 
'according', 'to', 'kropotkin', 'zeno', 'repudiated', 'the', 'omnipotence', 'of',
'the', 'state', 'its', 'intervention', 'and', 'regimentation', 'and', 'proclaimed',
'the', 'sovereignty', 'of', 'the', 'moral', 'law', 'of', 'the', 'individual', 'the',
'anabaptists', 'of', 'one', 'six', 'th', 'century', 'europe', 'are', 'sometimes',
'considered', 'to', 'be', 'religious', 'forerunners', 'of', 'modern', 'anarchism',
'bertrand', 'russell', 'in', 'his', 'history', 'of', 'western', 'philosophy', 
'writes', 'that', 'the', 'anabaptists', 'repudiated', 'all', 'law', 'since', 
'they', 'held', 'that', 'the', 'good', 'man', 'will', 'be', 'guided', 'at', 
'every', 'moment', 'by', 'the', 'holy', 'spirit', 'from', 'this', 'premise',
'they', 'arrive', 'at', 'communism', 'the', 'diggers', 'or', 'true', 'levellers', 
'were', 'an', 'early', 'communistic', 'movement',
(truncated…)

Zainicjuj model

Po przeszkoleniu musimy teraz zainicjować model. można to zrobić w następujący sposób -

model = gensim.models.doc2vec.Doc2Vec(vector_size=40, min_count=2, epochs=30)

Teraz zbuduj słownictwo w następujący sposób -

model.build_vocab(data_for_training)

Teraz wytrenujmy model Doc2Vec w następujący sposób -

model.train(data_for_training, total_examples=model.corpus_count, epochs=model.epochs)

Analiza wyników

Na koniec możemy przeanalizować dane wyjściowe za pomocą model.infer_vector () w następujący sposób -

print(model.infer_vector(['violent', 'means', 'to', 'destroy', 'the','organization']))

Pełny przykład implementacji

import gensim
import gensim.downloader as api
dataset = api.load("text8")
data = [d for d in dataset]
def tagged_document(list_of_list_of_words):
   for i, list_of_words in enumerate(list_of_list_of_words):
      yield gensim.models.doc2vec.TaggedDocument(list_of_words, [i])
data_for_training = list(tagged_document(data))
print(data_for_training[:1])
model = gensim.models.doc2vec.Doc2Vec(vector_size=40, min_count=2, epochs=30)
model.build_vocab(data_training)
model.train(data_training, total_examples=model.corpus_count, epochs=model.epochs)
print(model.infer_vector(['violent', 'means', 'to', 'destroy', 'the','organization']))

Wynik

[
   -0.2556166 0.4829361 0.17081228 0.10879577 0.12525807 0.10077011
   -0.21383236 0.19294572 0.11864349 -0.03227958 -0.02207291 -0.7108424
   0.07165232 0.24221905 -0.2924459 -0.03543589 0.21840079 -0.1274817
   0.05455418 -0.28968817 -0.29146606 0.32885507 0.14689675 -0.06913587
   -0.35173815 0.09340707 -0.3803535 -0.04030455 -0.10004586 0.22192696
   0.2384828 -0.29779273 0.19236489 -0.25727913 0.09140676 0.01265439
   0.08077634 -0.06902497 -0.07175519 -0.22583418 -0.21653089 0.00347822
   -0.34096122 -0.06176808 0.22885063 -0.37295452 -0.08222228 -0.03148199
   -0.06487323 0.11387568
]