sobota, 3 lutego 2024

Analiza sentymentów danych giełdowych - witaj Machine Learning

Ten post jest kontynuacją: https://kamilkondrat.blogspot.com/2024/01/analiza-sentymentow-danych-giedowych.html

Ta praca odzwierciedla zainteresowanie autora analizą finansową i wykorzystaniem narzędzi informatycznych w jej realizacji. Niniejszy blog nie ma na celu dostarczania porad finansowych, lecz stanowi konstruktywne podejście autora do dzielenia się wiedzą. Autor widzi w tym sposobność do rozwijania swoich umiejętności i zachęcania do wzajemnej dyskusji. Należy pamiętać, że wnioski wynikające z analiz prezentowanych na tym blogu nie powinny być bezpośrednio stosowane do podejmowania decyzji finansowych. Nawet jeśli analizy są dokładne, stanowią one tylko fragment potrzebnych informacji do podjęcia w pełni świadomej decyzji. Brak szerszego kontekstu, w którym znajduje się potencjalny inwestor lub decydent, może prowadzić do niepełnych wniosków.

Nasz projekt będzie zawierał w sobie budowę modelu NLP opartego o głębokie uczenie maszynowe i TensorFlow. Z importujmy wszystkie istotne elementy dla naszej pracy:

import tensorflow as tf
from tensorflow.keras.layers import Bidirectional, Conv1D, Dense, 
	Dropout, Embedding, Flatten, Input, LSTM, MaxPool1D
from tensorflow.keras.models import Model, Sequential
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.preprocessing.text import one_hot, Tokenizer
from tensorflow.keras.utils import to_categorical

 "tf" - to alias dla tensorflow. Takie zabiegi skracają i upraszczają kod, czyniąc go prostszym i czytelniejszym.

"layers" - oznacza warstwy w modelu sieci neuronowej. Po słowie kluczowym import znajdują się wymienione te wszystkie warstwy, które pozwolą nam stworzyć działający model.

"'Bidirectional" - w sieci neuronowej pozwala na dwukierunkową analizę tekstu. Przy przetwarzaniu zdania, bada słowa zarówno od lewej do prawej strony, jak i od prawej do lewej strony zdania jednocześnie. Warstwa "Bidirectional" łączy informacje z obu kierunków, tworząc pełny kontekst analizowanego tekstu.

"Conv1D" -  wykrywa wzorce w danych jednowymiarowych. Wykonuje operację konwolucji, która sprawia, że filtrowane dane tekstowe wykrywają określone wzorce, wedle wstępnych, skonfigurowanych, założeń.

Dense - jest to warstwa służąca do budowania głębokich sieci neuronowych. Naurony warstwy Dense są warstwą, która jest połączona z warstwą poprzedzającą, w taki sposób, że każdy neuron warstwy poprzedzającej (dowolnego rodzaju) łączy się z warstwą następującą (w tym przypadku Dense - na tej się teraz skupiamy) i jest połączony z każdym neuronem tej warstwy. A więc jeśli mamy załóżmy 5 poprzedzających neuronów, które przekazują informacje do warstwy Dense mającą 3 neurony, to każdy z tych 5 neuronów będzie połączony z każdym z tych 3 neuronów warstwy Dense. 

Mamy wtedy 3 * 5 = 15 połączeń i jest to 15 okazji do przyjęcia i później przekazania dalej unikalnych "paczek" informacji. Te unikalności w tej całej złożoności odkrywają szczególne sieci połączeń istotne dla rozwiązania danego problemu stając się też podstawą do bardziej zaawansowanych zadań w uczeniu maszynowym.

Dropout - ta warstwa umożliwia losowe wyłączanie pewnego odsetku neuronów (np. 15%) w celu uniknięcia przetrenowania modelu. 

Przetrenowany model to taki, który jest wrażliwy głównie albo tylko na dane treningowe. Na przykład jeśli będziemy uczyć go rozpoznawać zdjęcia pomarańczy korzystając z naszej własnej raczej mało wymyślnej kolekcji pomarańczy (załóżmy że tak jest), to gdy wytrenujemy model, zdjęcie pomarańczy naszego znajomego, który chciał się nam pochwalić fotką z wakacji robiąc zdjęcie pomarańczy w słonecznej Catanii może okazać się, że według naszego modelu nie mamy do czynienia z pomarańczą. 

W wyniku naturalnego słonecznego oświetlenia i innej naturalnej barwy świeżego pomarańcza obraz ten wymknie się naszemu modelowi i jasność i barwa itp. sprawią, że pomarańcz nie zostanie zidentyfikowany jako pomarańcz. 

Podobna sytuacja może być ze zdeformowaną pomarańczą, choć dla naszego oka po skórze owocu i kolorze wyraźnie będziemy widzieć, że to pomarańcz, jednak nasz przetrenowany model odrzuci to zdjęcie jako to które miałoby przedstawiać pomarańczę. 

Model musi trochę "stracić na ostrości," spojrzeć nieco z "przymrużeniem oka", by być w stanie uogólnić, co to znaczy dla niego "pomarańcz." To w ten sposób za kategoryzuje jako pomarańcze też te pomarańcze, które odbiegają od standardowego wyglądu pomarańczy. Żeby to było możliwe, wykorzystujemy do tego właśnie takie narzędzia jak Dropout.

Innym sposobem w jaki może zareagować przetrenowany model będzie zakwalifikowanie obiektu niebędącego pomarańczem, wtedy gdy ukażą się znaki szczególne dla pomarańczy na przykład w przypadku, gdy podamy mu rysunek pomarańczy. Przetrenowany model da się oszukać. Bierze się to z tego, że brak "przymrużenia oka", zdystansowania się i rozmycia sprawił, że model stał się wyjątkowo wrażliwy na znaki szczególne, jeśli by choć trochę stracił w tym rozeznanie, to na pewno odrzuciłby rysunek pomarańcza jako zdjęcie właściwego obiektu pomarańcza zrobionego gdzieś w trójwymiarowej przestrzeni, nie pokwapiłby się na znaki szczególne dla standardowej pomarańczy wyróżnione na rysunku.

Zdjęcia akurat nie mają związku z analizą sentymentów względem zawirowań giełdowych, jednak uważam, że przykłady z analizą obrazów są dobre dla ukazania ogólnej zasady. 

Jednak zaadaptujmy to sobie do analizy sentymentów. Jeśli przetrenowalibyśmy model dając mu zbyt wiele określonych danych, na przykład byłyby to jedynie pozytywne opinie i to jeszcze wyrażane przez ludzi w wąski podobny sposób, to moglibyśmy mieć problem z tym, że opinie negatywne i neutralne również mogłyby być zinterpretowane jako pozytywne, gdyż pewne elementy kategorii "pozytywne", zostały by odnalezione w opiniach obiektywnie negatywnych i neutralnych, które następnie zostałyby zakwalifikowane jako pozytywne przez model. Taka sytuacja analogicznie odpowiadałby sytuacji z rysunkiem pomarańczy, który omyłkowo byłby zakwalifikowany jako pomarańcz.

Jest też inna opcja, analogiczna do sytuacji, w której prawdziwa pomarańcza przez przeuczenie modelu została odrzucona jako nieprawdziwa pomarańcza, gdyż odstawała od standardowej wizji pomarańczy wytrenowanej na mało zróżnicowanych danych służących do wytrenowania modelu. 

W przypadku analizy sentymentów może to wyglądać tak, że z racji tego rodzaju przeuczenia modelu, faktycznie pozytywny sentyment (pozytywna opinia) zostanie odrzucony jako pozytywny i zakwalifikowany jako neutralny lub negatywny, gdyż nie będzie odpowiadał zakwalifikowaniu go do pozytywnego sentymentu, co wyniknie nie z tego, że nie będzie to pozytywna opinia z naszego ludzkiego punktu widzenia, a z tego że przetrenowany modelu będzie oczekiwał "wyidealizowanej" wersji pozytywnego sentymentu, bo tylko takie "wyidealizowane" wersje pozytywnie wyrażanych sentymentów nauczył się rozpoznawać jako pozytywne.

Uniknięciem przeuczenia byłoby wtedy zapobieżeniu temu na przykład przy pomocy omawianej warstwy "Dropout" i zyskaniu "mniejszej ostrości", aby ten mniej "wyidealizowany" pozytywny komentarz lub opinia i zarazem wyraz sentymentu był, mówiąc kolokwialnie, słusznie podciągnięty pod sentyment pozytywny, a bardziej fachowo, zostałby zgeneralizowany jako pozytywny sentyment.

Na zakończenie tego wpisy chcę tylko zaznaczyć, że należy pamiętać iż machine learning obfituje w swojej złożoności rozmaitością scenariuszy tego jakimi drogami potoczy się proces trenowania modelu i jak będzie on zachowywał się w przyszłości wykonując dla nas pracę. Tak samo rozmaite sposoby i techniki zapanowania nad całym proces i kierowania nim są różnorodne, na każdym etapie projektowania modelu uczenia maszynowego można stosować mnogość różnych technik, które chroniłyby by nas przed przetrenowaniem modelu lub innymi rzeczami związanymi z trenowaniem modelu, o tym i o innych rzeczach będę się uczył tak jak Wy i tutaj pisał.

Brak komentarzy:

Prześlij komentarz

Analiza sentymentów - wpisy na mediach społecznościowych (podział danych)

Ten wpis zaczniemy od stworzenia DataFrame z danymi treningowymi train_df = pd.read_csv('train.csv', encoding='ISO-8859-1')....