Miałem nadzieję na burzę mózgów na temat przechowywania danych n- gram. W moim projekcie próbuję rozwiązać problemy językowe, w których znam wszystkie elementy danych ( n -1) i chcę statystycznie odgadnąć moje n za pomocą interpolacji liniowej dla wszystkich odpowiednich n- gramów. (Tak, istnieje tagger, który przypisuje tagi do znanych słów zgodnie z jego leksykonem i drzewem sufiksów, które próbują odgadnąć rodzaj słowa dla nieznanych słów; omawiany tutaj komponent n -gram będzie miał zadanie rozwiązać ambugułę).
Moje początkowe podejście polegałoby po prostu na przechowywaniu wszystkich zaobserwowanych n- gramów (dla n = 1..3, tj. Monogramu, bigrama, trigramu) w odpowiednich bazach danych SQL i nazywanie go dniem. Ale wymagania mojego projektu mogą ulec zmianie i obejmować inne długości wektorów ( n ), i chciałbym, aby moja aplikacja dostosowała się do 4 gramów bez większego nakładu pracy (aktualizacja schematu, aktualizacja kodu aplikacji itp.); idealnie, po prostu powiedziałbym mojej aplikacji, aby teraz pracowała z 4-gramami, bez konieczności zmiany kodu (lub wcale) i trenowania danych z danego źródła danych.
Podsumowując wszystkie wymagania:
- Możliwość przechowywania danych n- gram (początkowo dla n = {1, 2, 3}
- Możliwość zmiany, jakiego rodzaju n- gramów należy użyć (między uruchomieniami aplikacji)
- Możliwość (ponownego) trenowania danych n- gramowych (między uruchomieniami aplikacji)
Możliwość zapytania do magazynu danych (np. Jeśli zaobserwowałem A, B, C, chciałbym poznać najczęściej obserwowany element, co może nastąpić przy użyciu wyszkolonych zestawów danych 4-, 3-, 2-, 1-gramowych )
Aplikacja najprawdopodobniej będzie obciążona odczytem, najprawdopodobniej zestawy danych nie będą tak często ponownie szkolone
- Rozwiązanie wykorzystuje platformę .NET Framework (do 4.0)
Jaki projekt byłby lepiej dopasowany do takiego zadania?
- Stała tabela zarządzana przez serwer SQL (MSSQL, MySQL, ...) dla każdego n (np. Dedykowane tabele dla bi-gramów, tri-gramów itp.)
- Lub rozwiązanie bazy danych dokumentów NoSQL, które przechowuje pierwsze n -1 jako klucz dokumentu, a sam dokument zawiera n-tą wartość i obserwowane częstotliwości?
- A może coś innego?
źródło
Odpowiedzi:
Biorąc pod uwagę, że nie poznasz optymalnego zakresu N, zdecydowanie chcesz móc go zmienić. Na przykład, jeśli twoja aplikacja przewiduje prawdopodobieństwo, że określony tekst jest angielski, prawdopodobnie będziesz chciał użyć N-gramów znaków dla N 3..5. (Właśnie to znaleźliśmy eksperymentalnie.)
Nie udostępniłeś szczegółowych informacji o swojej aplikacji, ale problem jest wystarczająco jasny. Chcesz reprezentować dane w gramach w relacyjnej bazie danych (lub rozwiązaniu opartym na dokumentach NoSQL). Zanim zaproponuję własne rozwiązanie, możesz rzucić okiem na następujące podejścia:
Teraz, nie czytając żadnego z powyższych łączy, sugeruję proste, relacyjne podejście do bazy danych przy użyciu wielu tabel, po jednej dla każdego rozmiaru N-gramów. Możesz umieścić wszystkie dane w jednej tabeli z maksymalną niezbędną liczbą kolumn (tj. Przechowywać bigramy i trygramy w ngram_4, pozostawiając końcowe kolumny puste), ale zalecam partycjonowanie danych. W zależności od silnika bazy danych pojedyncza tabela z dużą liczbą wierszy może mieć negatywny wpływ na wydajność.
Następnie dam ci zapytanie, które zwróci najbardziej prawdopodobne następne słowo, biorąc pod uwagę wszystkie tabele ngram. Ale po pierwsze, oto kilka przykładowych danych, które powinieneś wstawić do powyższych tabel:
Aby wyszukać najbardziej prawdopodobne następne słowo, użyj takiego zapytania.
Jeśli dodasz więcej tabel ngram, będziesz musiał dodać kolejną klauzulę UNION do powyższego zapytania. Możesz zauważyć, że w pierwszym zapytaniu użyłem słowa1 = @ słowo3. A w drugim zapytaniu słowo1 = @ słowo2 ORAZ słowo2 = @ słowo3. Jest tak, ponieważ musimy wyrównać trzy słowa w zapytaniu dotyczącym danych ngram. Jeśli chcemy najbardziej prawdopodobnego następnego słowa dla ciągu trzech słów, będziemy musieli sprawdzić pierwsze słowo w danych bigram z ostatnim słowem słów w sekwencji.
Możesz dostosować parametry wagi, jak chcesz. W tym przykładzie założyłem, że wyższe porządkowe „n” gramy będą bardziej niezawodne.
PS Skonfiguruję kod programu, aby obsługiwał dowolną liczbę tabel ngram_N poprzez konfigurację. Można deklaratywnie zmienić program, aby używał zakresu N-gramów N (1..6) po utworzeniu tabel ngram_5 i ngram_6.
źródło
ngram_2
frazabuilding with
ma częstotliwość = 0,5. To samo pytanie@bigramWeight
, co to jest ?. Myślę, że freq to pole będzie aktualizowane przy każdej aktualizacji bazy danych. Czyli jeśli użytkownik wprowadzi więcej ciągu, częstotliwość tego ciągu zostanie ponownie obliczona? 0,5 to 0,5 procent łącznej liczby wykorzystanych czasów lub częstotliwości pojawiania się każdej frazy?W przeciwieństwie do tego, co sugerują inni, sugerowałbym unikanie struktur bardziej złożonych niż tablica skrótów lub magazyn wartości kluczowych.
Pamiętaj o swoich wymaganiach dotyczących dostępu do danych: a) 99% żądań - zapytaj ngram „aaa-bbb-ccc” i pobierz wartość (lub 0) b) 1% żądań - wstawianie / aktualizowanie liczby określonych ngram c) nie ma (do).
Najbardziej skutecznym sposobem jest odzyskanie go za pomocą jednego wyszukiwania. Możesz użyć separatora spoza zakresu (lub klawisza zmiany znaczenia), aby połączyć pełny n-gram w jednym ciągu (np. „Alpha | beta | gamma” dla 3gram, „alpha” dla unigram itp.) I po prostu pobrać ten ( hash tego). Tak robi to całkiem sporo oprogramowania NLP.
Jeśli twoje dane ngram są małe (powiedzmy, <1 gb) i mieszczą się w pamięci, sugerowałbym użycie wydajnej struktury pamięci w programie (mapy skrótów, drzewa, próby itp.), Aby uniknąć narzutu; i po prostu serializuj / deserializuj do płaskich plików. Jeśli twoje dane ngram to terabajty lub więcej, możesz wybrać magazyny klucz-wartość NoSQL podzielone na wiele węzłów.
Aby uzyskać dodatkową wydajność, możesz zastąpić wszystkie słowa wszędzie identyfikatorami całkowitymi, aby Twój algorytm podstawowy nie widział żadnych (wolnych) ciągów; to nieco inaczej wdraża ten sam pomysł.
źródło
Nie najbardziej wydajny, ale prosty i dopasowany do bazy danych, jak chcesz:
wordpos powinny mieć indeksy w dokumencie i poz.
bigramy to:
Następnie możesz policzyć () i pogrupować drogę do częstotliwości i innych rzeczy.
Aby przejść na trygramy, łatwo jest wygenerować ten ciąg znaków, aby zawierał słowo 3.
Zrobiłem to już wcześniej (nawet jeśli SQL tam jest prawdopodobnie trochę zardzewiały). Zdecydowałem się na zestaw płaskich plików, które można łatwo wyszukać, a następnie przesłać strumieniowo z dysku. Rodzaj zależy od twojego sprzętu, jak to zrobić lepiej.
źródło
Próbując ulepszyć proste wyszukiwania moich aplikacji do bigramów i trygramów z unigramów, w zasadzie widziałem twoje pytanie.
Jeśli jednym z wymagań jest możliwość wysłania zapytania do rozproszonego systemu plików lub bazy danych, może to również być interesujące dla Ciebie: papier Pibiri i Venturini 2018 „Skuteczne przetwarzanie ogromnych zestawów danych N-Gram” opisuje skuteczny sposób przechowywania danych w gramach N warunki środowiska wykonawczego i przestrzeni. Zaproponowali wdrożenie na stronie https://github.com/jermp/tongrams
Każde „n” n-gramów jest przechowywane w osobnej tabeli, do której dostęp ma minimalna idealna funkcja skrótu z bardzo szybkimi możliwościami wyboru i zapytania. Tabele są statyczne i zbudowane przez główny kod przy użyciu danych wejściowych w formacie plików tekstowych Google n-gram.
Nie korzystałem jeszcze z tego kodu, ale istnieje wiele sposobów na spełnienie otwartych wymagań dotyczących źródła zapytań.
Jeden sposób: jeśli odpowiednik serwletu .NET jest używany z bazą danych lub magazynem danych i jeśli chcesz zaoszczędzić miejsce w pamięci, to przechowywanie każdej tabeli ngram w formie binarnej w bazie danych / magazynie danych jako jedna opcja (jedna baza danych / tabela danych dla wynikowego pliku statycznego wydajnego kodu ngram dla wszystkich 1-gramów, inny dla wszystkich 2-gramów itp.). Zapytania byłyby uruchamiane przez wywołanie wydajnego kodu n-gram (zapakowanego, aby był dostępny dla twojego serwletu). Obejściem problemu jest utworzenie rozproszonej bazy danych, która używa wydajnego kodu n-gram do uzyskiwania dostępu do plików w rozproszonym systemie plików. Zauważ, że w tabelach binarnych baz danych / magazynów danych obowiązują ograniczenia rozmiaru pliku systemu plików.
źródło