Zadanieskuteczny sposób obliczyć odległość między kombinacjami kolumn ramowych pandy
Mam dataframe pandy gdzie:
- kolumny są nazwy dokumentu
- wiersze są słowa zawarte w tych dokumentach
- numery wewnątrz komórek ramki są miarą trafności słowa (liczba słów, jeśli chcesz zachować proste)
trzeba obliczyć nową macierz doc1-doc podobieństwa gdzie:
- wierszy i kolumn nazwy dokument
- komórki wewnątrz ramki są miarą podobieństwa (1 - cos odległości) pomiędzy dwa dokumenty:
Odległość cosinus jest wygodnie dostarczana przez script.spatial.distance.cosine.
Jestem obecnie to robi:
- użytku itertools stworzyć listę wszystkich 2-kombinacje nazw dokumentów (kolumny dataframe Names)
- pętla ponad nich i stworzyć aktualizację słownika {doc1 {zmienna doc2: podobieństwo}}
- po pętli, tworzenie nowej ramki przy użyciu pandas.DataFrame (dict)
problem
Ale to zajmuje bardzo dużo czasu. Poniżej pokazano aktualną prędkość MacBooka Pro 13 z 16GB pamięci RAM i 2,9 GHz i5cpu z najnowszym anakondy Pythona 3.5 ... czas kreślenia przeciwko kombinacjom dokumentów.
Widać, że 100.000 kombinacje trwa 1200 sekund. Ekstrapolacja tego do mojego korpusu dokumentów , która tworzy 3 1,549,596, zajęłaby 5 dni w celu obliczenia tej macierzy podobieństwa!
Jakieś pomysły?
- I previously dynamicznie tworzenie df.ix dataframe [doc1, zmienna doc2] = podobieństwa .. co było bardzo znacznie wolniej.
- Zastanawiam się nad numba @ git, ale zawiedzie się w strukturach danych pand.
- nie mogę znaleźć wbudowaną funkcję, która będzie wykonywać wszystkie prace wewnętrznie (w C?)
- Co muszę zrobić taktycznie jest losowo próbka dokumenty do stworzenia znacznie mniejszy zestaw do pracy z .. obecnie ułamek 0,02 prowadzi do około 20 minut obliczeń!
Oto kod (github)
docs_combinations = itertools.combinations(docs_sample, 2)
for doc1, doc2 in docs_combinations:
# scipy cosine similarity function includes normalising the vectors but is a distance .. so we need to take it from 1.0
doc_similarity_dict[doc2].update({doc1: 1.0 - scipy.spatial.distance.cosine(relevance_index[doc1],relevance_index[doc2])})
pass
#convert dict to pandas dataframe
doc_similarity_matrix = pandas.DataFrame(doc_similarity_dict)
Prosty przykład
@MaxU zadawane na przykład ilustracyjny.
związek macierzy (WordCount tutaj, żeby utrzymać proste)
... doc1 doc2 doc3
wheel 2. 3. 0.
seat 2. 2. 0.
lights 0. 1. 1.
cake 0. 0. 5.
obliczono macierz podobieństwa oparte na 2-kombinacjach (doc1, zmienna doc2), (zmienna doc2, doc3), (doc1, doc3)
... doc2 doc3
doc1 0.9449 0.
doc2 - 0.052
Take że wartość górnego lewego 0,889 .. ów iloczyn skalarny (2 * 3 * 2 + 2 + 0 + 0) = 10, ale znormalizowane o długości wektorów ... więc dzielenie przez sqrt (8) i sqrt (14) daje 0.9449. Widać, że nie ma podobieństwa między doc1 i doc3 .. iloczyn jest zerowy.
Skala ta z 3 dokumentów z 4 słów ... do dokumentów, który tworzy 3 kombinacje ...
Czy mógłbyś umieścić mały powtarzalny zestaw danych próbki (3-5 wierszy) i żądany zestaw danych (oba w formularzu __text__)? – MaxU
@MaxU Oto blog z uproszczonym przykładem obliczeń, które próbuję zrobić .. z dużą ilością diagramów [grupujących podobne dokumenty] (http://makeyourowntextminingtoolkit.blogspot.co.uk/2016/11/grouping -similar-documents-aka.html) –
@MYOTextMiningToolkit może możesz spróbować obliczyć podobieństwa za pomocą Hashingu lokalnego, powinno być znacznie bardziej wydajne. –