Jak pogrupować ciągi według wspólnych tematów?

10

Próbuję grupować, na przykład, ciągi o programowaniu z innymi ciągami o programowaniu, ciągi o fizyce z innymi ciągami o fizyce itp., Dla szerokiego zakresu tematów. Pomimo rażącego teoretycznego aspektu językowego problemu, zamierzam to zrobić za pomocą programowania / oprogramowania.

Podsumowanie: Biorąc pod uwagę dużą liczbę ciągów, jak miałbym pogrupować je według tematyki semantycznej?

Konkretna aplikacja: mam ~ 200 000 ciekawostek, które chciałbym podzielić na wspólne grupy (samochody, komputery, polityka, Kanada, jedzenie, Barack Obama itp.).

Co sprawdziłem: Wikipedia ma listę zestawów narzędzi do przetwarzania języka naturalnego (zakładając, że to, co próbuję zrobić, nazywa się NLP), więc spojrzałem na kilka, ale żadne nie wydaje się robić czegoś podobnego do moich potrzeb.

Uwagi: Zwrócono uwagę, że robienie tego wymaga dodatkowej wiedzy (np. Porsche jest samochodem, C ++ jest językiem programowania). Zakładam, że dane treningowe są potrzebne, ale jeśli mam tylko listę pytań i odpowiedzi, jak mogę wygenerować dane treningowe? A potem, jak korzystać z danych treningowych?

Więcej notatek: Jeśli bieżące formatowanie mojej pomocy w pytaniach i odpowiedziach (choć wygląda jak JSON, jest to w zasadzie nieprzetworzony plik tekstowy):

// row 1: is metadata
// row 2: is a very specific kind of "category"
// row 3: is the question
// row 4: is the answer
{
  15343
  A MUSICAL PASTICHE
  Of classical music's "three B's", he was the one born in Hamburg in 1833
  Johannes Brahms
}

Zanim jednak ktoś zauważy, że istnieje już kategoria, zwróć uwagę, że istnieje ~ 200 000 takich pytań i odpowiedzi oraz w zasadzie tyle „kategorii”. Próbuję pogrupować je w szersze grupy, takie jak te wymienione powyżej. Również to formatowanie można bardzo łatwo zmienić na wszystkie pytania, robię to programowo.

I więcej notatek: tak naprawdę nie wiem, ile kategorii potrzebuję (co najmniej 10-20), ponieważ sam nie przeczytałem wszystkich pytań. Po części spodziewałem się, że jakaś liczba skończona zostanie jakoś określona podczas kategoryzacji. W każdym razie zawsze mogę ręcznie utworzyć wiele kategorii.

Whymarrh
źródło
Jak używałeś marchewki? Z mojej krótkiej lektury na ten temat wydaje się, że powinien z łatwością obsłużyć 200 000 rekordów.
Zajęło mi to dużo więcej czasu, niż się spodziewałem, i zmusiło mnie do zwiększenia początkowego przydziału pamięci JVM do 1024 m, a maksymalnej pamięci do 2048 m. Nie było tak źle, jak mogłem wydać ten dźwięk.
Potrzebujesz tylko wystarczających danych treningowych, a następnie powinieneś być w stanie podzielić pytania na te kategorie. W pełni automatyczne podejście najprawdopodobniej skończy je grupując w inny sposób, np. Pytania zawierające słowo „samochód”. Nie możesz nauczyć się synonimów w tym samym czasie, co tworzenie grupy.
Ma ZAKOŃCZENIE - Anony-Mousse
Ech, zajmujesz się przetwarzaniem zbiorczym; podawanie JVM nie jest tak naprawdę problemem. Jak długo to zajęło? Skąd ładowałeś dokumenty? Niestandardowe źródło?
Zajęło mi to może 10 minut, ale zgadzam się, że przetwarzanie zbiorcze jest z definicji czasochłonne i wymaga dużej ilości pamięci. Chociaż całe to zamieszanie nie było problemem, a raczej notatką dodatkową.

Odpowiedzi:

4

Jest to dość standardowy problem w NLP, a magiczne słowa Google, których szukasz, to „modelowanie tematów”. Chociaż twoje łańcuchy są dość krótkie, możesz odnieść pewien sukces dzięki Latent Dirichlet Allocation lub podobnej metodzie. Jest ładny blogu Edwin Chen tutaj , określającej ogólną ideę algorytmu. Szczegóły implementacji zostały omówione w tej notatce przez Yi Wanga.

Jeśli szukasz gotowego rozwiązania, polecam wypróbowanie topicmodelspakietu dla R, ponieważ zapewnia on całkiem przyjemny interfejs zarówno dla LDA, jak i bardziej wyrafinowanego skorelowanego modelu tematycznego. Jest też dobra lista wdrożeń prowadzonych przez Davida Mimno tutaj .

Martin O'Leary
źródło
Dziękuję, post na blogu Chena wydaje się być na miejscu, co próbuję zrobić. Czy jest jakaś szansa, że ​​wykorzystałeś coś, co wcześniej wymieniłeś / zrobiłeś? Jestem tutaj na zupełnie nowych podstawach i byłbym wdzięczny za opis tego, co powinienem zrobić (używając jednego z gotowych rozwiązań). Jak sformatować moje „dokumenty”? Czy powinienem stosować identyfikatory do każdego pytania i odpowiedzi, aby umożliwić mi zidentyfikowanie dokumentu, w której grupie? Jak korzystać z danych wyjściowych? Tak jak powiedziałem, nie rozumiem wielu szczegółów.
Whymarrh
Dość często korzystałem z pakietu modułów tematycznych R. Z pewnością poleciłbym to zamiast zrolowania własnego kodu - jest trochę dokumentacji z działającym przykładem na cran.r-project.org/web/packages/topicmodels/vignettes/… . Specyficzne formatowanie każdego dokumentu nie ma tak naprawdę znaczenia, ponieważ wszystko i tak zostanie sprowadzone do reprezentacji „worka słów”. Po prostu rzuć cały powiązany tekst w jeden ciąg.
Martin O'Leary
4

Próbujesz tutaj rozwiązać dwa problemy.

Problem 1: Kategoryzuj ciągi pytań w odpowiedniej kategorii.

Problem 2: Utwórz odpowiednie kategorie.

Pierwszy problem można rozwiązać za pomocą tak zwanych algorytmów nadzorowanych, wiele klasyfikatorów może dać bardzo dobrą dokładność i wydajność. Jednak problem 2, tworzenie kategorii z powietrza (tony danych), jest znacznie trudniejszy. Jest to problem bez nadzoru, biorąc pod uwagę dużą ilość danych, komputer samodzielnie decyduje o kategoriach, biorąc pod uwagę pewne kryteria. Idealnie te kryteria i algorytm powinny starannie uporządkować dane w klastry. Można je następnie oznaczyć. Ponieważ jest to jednak znacznie trudniejsze zadanie, powiedziałbym, że nie ma tutaj akceptowalnego rozwiązania, które dałoby dobry wynik bez dużego wysiłku tuningowego, który najprawdopodobniej wymagałby ekspertów.

Obawiam się, że nie ma tu jeszcze magicznego przycisku. Możesz jednak nieco pomóc maszynie. Na przykład możesz zdecydować o zestawie kategorii. Po wybraniu kategorii możesz utworzyć dane treningowe. W tym ustawieniu dane treningowe to tylko pytanie i poprawne pary kategorii.

Im więcej danych treningowych, tym lepiej. Ponieważ jednak zadanie wciąż polega na czymś automatycznym, nie ma sensu na początku robić rzeczy ręcznie. Dlaczego chcesz mieć dane treningowe? Ocena dokładności. Jeśli chcesz uzyskać dobre wyniki, ważne jest, abyś mógł dokonać oceny tego, jak dobrze działa konfiguracja. Jedynym sposobem, aby to zrobić dość systematycznie, jest ręczne samodzielne etykietowanie niektórych zadań. W przeciwnym razie jesteś w ciemno.

Potem pojawiają się nowe pytania. Po pierwsze: ile danych treningowych potrzebuję? "To zależy". Bez obejrzenia twoich danych lub kategorii nie jestem pewien, czy nawet zgadłbym; ale mogę zrobić „szacunkową ocenę” i powiedzieć około 500 pytań. Zauważ, że mógłbym być wyłączony o rząd wielkości.

Czy to naprawdę oznacza, że ​​musisz ręcznie oznaczyć 500 pytań? Tak i nie. Możliwe jest wykorzystanie wyników pośrednich i sprytności do klasyfikatorów „bootstrap”. Wciąż jest to jednak praca ręczna, a kiedy się nad tym zastanowić, 500 pytań nie potrwa tak długo. Bycie sprytnym tutaj może szybko dać gorsze wyniki niż bycie pracowitym.

Kiedy masz wystarczającą ilość danych treningowych, weź 75% i stwórz klasyfikator za pomocą swojego ulubionego narzędzia (np. Tych wymienionych tutaj lub czegokolwiek innego). Teraz pozwól, aby klasyfikator spróbował oznaczyć wstrzymane 25% danych i zmierzyć wynikową dokładność. Jeśli wynik jest dobry, to pop szampana. Jeśli nie, zrób więcej danych treningowych lub wypróbuj inny klasyfikator.

TL; DR

Podsumowując, oto jak bym to zrobił.

0) Use a supervised learner.
1) Create a category set yourself. 
2) Label manually about 500 questions
3) Use 75% of those to train a classifier.
4) Check performance.
5) If good then cheers else goto 2.

źródło
Jedno małe pytanie: mówisz „około 500 pytań” dla danych treningowych i ręcznie je otagowujesz, ale także „Mogę być o rząd wielkości”, więc gdybym zamiast tego użył pytań 5k lub 50k, nadal bym ręcznie otagować tyle?
Rzecz w tym; nie widząc danych ani nie mając jasnego pojęcia o najdrobniejszych szczegółach w twoim projekcie, trudno jest dobrze oszacować. Należy jednak pamiętać, że jeśli 500 będzie o wiele za niskie, wysiłek tagowania nie zostanie zmarnowany. Nadal potrzebujesz ręcznie oznakowanych pytań do oceny. Im więcej danych do oceny, tym lepsze oceny.
Przez jeden rząd wielkości miałem na myśli 50-500-5000. Nie sądzę, że będziesz musiał sklasyfikować 50 tys. To 1/4 całego twojego ciała! Jeśli 500 pytań będzie o wiele za mało, możliwe jest uruchomienie klasyfikatorów. Chodzi o to, że trenujesz klasyfikator na małym początkowym korpusie (np. 500), a następnie otagujesz resztę. Teraz możesz użyć niektórych przypadków, w których klasyfikator był bardzo pewny, że przekwalifikowuje nowy, większy klasyfikator.
Kolejna ważna rzecz, o której należy pamiętać; wydajność wielu klasyfikatorów nie jest liniowa pod względem ilości danych treningowych, ale zazwyczaj będzie to krzywa sigmoidalna. Oznacza to, że 500 dodatkowych otagowanych pytań może być prawie tak samo dobrą korzyścią jak 5000. Moja rada to praca w małych krokach.
Jakie szczegóły zapewniłyby dodatkowy wgląd w mój projekt? Mogę podzielić się przykładowymi pytaniami, aby pokazać moje formatowanie, ale jestem gotów dostosować format moich pytań i odpowiedzi, aby pasował do procesu kategoryzacji. Doceniam pomoc.