Mam częściowo działający system, który rozwiązuje ten problem, oparty na otwartym kodzie źródłowym za pomocą scikit-learn, z serią postów na blogu opisujących to, co robię. Problem, z którym się zmagam, to ujednoznacznienie w sensie słów (wybranie jednej z wielu opcji sensu słów ), co nie jest tym samym, co Rozpoznawanie nazwanych jednostek. Moje podstawowe podejście jest nieco konkurencyjne w stosunku do istniejących rozwiązań i (co najważniejsze) można je dostosowywać.
Istnieje kilka istniejących komercyjnych narzędzi NER (OpenCalais, DBPedia Spotlight i AlchemyAPI), które mogą dać wystarczająco dobry wynik komercyjny - wypróbuj je najpierw!
Część z nich wykorzystałem do projektu klienta (konsultuję się przy użyciu NLP / ML w Londynie), ale nie byłem zadowolony z ich wycofania ( precyzja i przywołanie ). Zasadniczo mogą być precyzyjne (kiedy mówią „To jest Apple Inc”, zazwyczaj są poprawne), ale z niską pamięcią (rzadko mówią „To jest Apple Inc”, chociaż dla człowieka tweet dotyczy oczywiście Apple Inc). Pomyślałem, że zbudowanie wersji open source dostosowanej do tweetów byłoby interesującym intelektualnie ćwiczeniem. Oto aktualny kod:
https://github.com/ianozsvald/social_media_brand_disambiguator
Zauważę - nie próbuję rozwiązywać uogólnionego problemu ujednoznaczniania sensu słów za pomocą tego podejścia, tylko ujednoznacznienie marki (firmy, ludzie itp.), Kiedy już masz ich nazwę. Dlatego uważam, że to proste podejście zadziała.
Zacząłem to sześć tygodni temu i jest napisane w Pythonie 2.7 przy użyciu scikit-learn. Wykorzystuje bardzo podstawowe podejście. Wektoryzuję za pomocą binarnego wektoryzatora liczenia (liczę tylko, czy pojawi się słowo, a nie ile razy) z 1-3 n-gramami . Nie skaluję z TF-IDF (TF-IDF jest dobry, gdy masz zmienną długość dokumentu; dla mnie tweety to tylko jedno lub dwa zdania, a moje wyniki testów nie wykazały poprawy z TF-IDF).
Używam podstawowego tokenizera, który jest bardzo prosty, ale zaskakująco przydatny. Ignoruje @ # (więc tracisz kontekst) i oczywiście nie rozwija adresu URL. Następnie trenuję przy użyciu regresji logistycznej i wydaje się, że ten problem jest nieco liniowy (wiele terminów dla jednej klasy nie istnieje dla drugiej). Obecnie unikam wszelkiego wyprowadzania / czyszczenia (próbuję najprostszej możliwej rzeczy, która może zadziałać).
Kod ma pełne README i powinieneś być w stanie stosunkowo łatwo przyswoić swoje tweety, a następnie postępować zgodnie z moimi sugestiami dotyczącymi testowania.
Działa to w przypadku Apple, ponieważ ludzie nie jedzą ani nie piją komputerów Apple, ani nie piszemy ani nie bawimy się owocami, więc słowa można łatwo podzielić na jedną lub drugą kategorię. Ten warunek może nie obowiązywać, gdy rozważa się coś w rodzaju #definance dla programu telewizyjnego (gdzie ludzie używają również #definance w odniesieniu do Arabskiej Wiosny, meczów krykieta, powtórzenia egzaminów i zespołu muzycznego). W tym przypadku może być wymagane podejście Cleverer.
Mam serię postów na blogu opisujących ten projekt, w tym godzinną prezentację, którą wygłosiłem na grupie użytkowników BrightonPython (która zamieniła się w krótszą prezentację dla 140 osób w DataScienceLondon).
Jeśli używasz czegoś takiego jak Regresja Logistyczna (gdzie uzyskujesz prawdopodobieństwo dla każdej klasyfikacji), możesz wybrać tylko pewne klasyfikacje iw ten sposób możesz wymusić wysoką precyzję, handlując przeciwko wycofaniu (dzięki czemu uzyskasz prawidłowe wyniki, ale ich mniej). Będziesz musiał dostroić to do swojego systemu.
Oto możliwe podejście algorytmiczne wykorzystujące scikit-learn:
- Użyj Binary CountVectorizer (nie sądzę, aby liczba terminów w krótkich wiadomościach dodawała dużo informacji, ponieważ większość słów występuje tylko raz)
- Zacznij od klasyfikatora drzewa decyzyjnego. Będzie miał możliwą do wyjaśnienia wydajność (zobacz przykład nadmiernego dopasowania za pomocą drzewa decyzyjnego ).
- Przejdź do regresji logistycznej
- Zbadaj błędy generowane przez klasyfikatory (przeczytaj wyeksportowane dane wyjściowe DecisionTree lub spójrz na współczynniki w LogisticRegression, przeprowadź błędnie sklasyfikowane tweety z powrotem przez Vectorizer, aby zobaczyć, jak wygląda podstawowa reprezentacja Bag of Words - będzie tam mniej tokenów niż zacząłeś w surowym tweecie - czy wystarczy na klasyfikację?)
- Spójrz na mój przykładowy kod w https://github.com/ianozsvald/social_media_brand_disambiguator/blob/master/learn1.py, aby uzyskać działającą wersję tego podejścia
Rzeczy do rozważenia:
- Potrzebujesz większego zbioru danych. Używam 2000 oznaczonych tweetów (zajęło mi to pięć godzin) i jako minimum chcesz zbalansowanego zestawu z> 100 na klasę (patrz uwaga o przeuczeniu poniżej)
- Ulepsz tokeniser (bardzo łatwy dzięki scikit-learn), aby zachować # @ w tokenach i być może dodaj detektor marki z wielką literą (jako notatki user @ user2425429)
- Rozważ nieliniowy klasyfikator (jak sugestia @ oiez powyżej), gdy sprawy stają się trudniejsze. Osobiście uważam, że LinearSVC radzi sobie gorzej niż regresja logistyczna (ale może to wynikać z wielowymiarowej przestrzeni funkcji, której jeszcze nie zmniejszyłem).
- Specyficzna dla tweeta część taggera mowy (moim skromnym zdaniem nie Standforda, jak sugeruje @Neil - z mojego doświadczenia wynika, że słabo działa na słabej gramatyce na Twitterze)
- Gdy będziesz mieć dużo tokenów, prawdopodobnie zechcesz zmniejszyć wymiarowość (jeszcze tego nie próbowałem - zobacz mój wpis na blogu na temat kary LogisticRegression l1 l2)
Re. przeładowanie. W moim zbiorze danych zawierającym 2000 pozycji mam 10-minutową migawkę z Twittera tweetów „Apple”. Około 2/3 tweetów jest dla Apple Inc, 1/3 dla innych zastosowań Apple. Wyciągam zrównoważony podzbiór (myślę, że około 584 wierszy) z każdej klasy i przeprowadzam pięciokrotną weryfikację krzyżową na potrzeby treningu.
Ponieważ mam tylko 10-minutowe okno czasowe, mam wiele tweetów na ten sam temat i prawdopodobnie dlatego mój klasyfikator radzi sobie tak dobrze w porównaniu z istniejącymi narzędziami - będzie zbyt dobrze dopasowany do funkcji szkoleniowych bez dobrego uogólniania (podczas gdy istniejący komercyjny narzędzia działają gorzej w tym sklepie snapshop, ale bardziej niezawodnie w szerszym zestawie danych). Rozszerzę moje okno czasowe, aby przetestować to jako kolejną część pracy.