Po pierwsze, jeśli chcesz wyodrębnić funkcje zliczania i zastosować normalizację TF-IDF i normalizację euklidesową w wierszach, możesz to zrobić w jednej operacji za pomocą TfidfVectorizer
:
>>> from sklearn.feature_extraction.text import TfidfVectorizer
>>> from sklearn.datasets import fetch_20newsgroups
>>> twenty = fetch_20newsgroups()
>>> tfidf = TfidfVectorizer().fit_transform(twenty.data)
>>> tfidf
<11314x130088 sparse matrix of type '<type 'numpy.float64'>'
with 1787553 stored elements in Compressed Sparse Row format>
Teraz, aby znaleźć odległości cosinusowe jednego dokumentu (np. Pierwszego w zbiorze danych) i wszystkich pozostałych, wystarczy obliczyć iloczyn skalarny pierwszego wektora z wszystkimi pozostałymi, ponieważ wektory tfidf są już znormalizowane wierszowo.
Jak wyjaśnił Chris Clark w komentarzach i tutaj Cosinus Podobieństwo nie bierze pod uwagę wielkości wektorów. Wartość znormalizowana wierszami ma wielkość 1, więc liniowe jądro jest wystarczające do obliczenia wartości podobieństwa.
Scipy Sparse Matrix API jest trochę dziwne (nie tak elastyczne jak gęste N-wymiarowe tablice numpy). Aby otrzymać pierwszy wektor, musisz przeciąć macierz wierszami, aby uzyskać podmacierz z jednym wierszem:
>>> tfidf[0:1]
<1x130088 sparse matrix of type '<type 'numpy.float64'>'
with 89 stored elements in Compressed Sparse Row format>
scikit-learn już zapewnia metryki parami (zwane także jądrem w języku uczenia maszynowego), które działają zarówno dla gęstych, jak i rzadkich reprezentacji kolekcji wektorów. W tym przypadku potrzebujemy iloczynu skalarnego, znanego również jako jądro liniowe:
>>> from sklearn.metrics.pairwise import linear_kernel
>>> cosine_similarities = linear_kernel(tfidf[0:1], tfidf).flatten()
>>> cosine_similarities
array([ 1. , 0.04405952, 0.11016969, ..., 0.04433602,
0.04457106, 0.03293218])
W związku z tym, aby znaleźć 5 najważniejszych powiązanych dokumentów, możemy użyć argsort
i niektórych ujemnych wycinków tablicowych (większość powiązanych dokumentów ma najwyższe wartości podobieństwa cosinusowego, stąd na końcu tablicy posortowanych indeksów):
>>> related_docs_indices = cosine_similarities.argsort()[:-5:-1]
>>> related_docs_indices
array([ 0, 958, 10576, 3277])
>>> cosine_similarities[related_docs_indices]
array([ 1. , 0.54967926, 0.32902194, 0.2825788 ])
Pierwszym wynikiem jest sprawdzenie poprawności: dokument zapytania jest najbardziej podobny z wynikiem podobieństwa cosinusowego równym 1 i ma następujący tekst:
>>> print twenty.data[0]
From: lerxst@wam.umd.edu (where's my thing)
Subject: WHAT car is this!?
Nntp-Posting-Host: rac3.wam.umd.edu
Organization: University of Maryland, College Park
Lines: 15
I was wondering if anyone out there could enlighten me on this car I saw
the other day. It was a 2-door sports car, looked to be from the late 60s/
early 70s. It was called a Bricklin. The doors were really small. In addition,
the front bumper was separate from the rest of the body. This is
all I know. If anyone can tellme a model name, engine specs, years
of production, where this car is made, history, or whatever info you
have on this funky looking car, please e-mail.
Thanks,
- IL
---- brought to you by your neighborhood Lerxst ----
Drugim najbardziej podobnym dokumentem jest odpowiedź, która cytuje oryginalną wiadomość, dlatego zawiera wiele popularnych słów:
>>> print twenty.data[958]
From: rseymour@reed.edu (Robert Seymour)
Subject: Re: WHAT car is this!?
Article-I.D.: reed.1993Apr21.032905.29286
Reply-To: rseymour@reed.edu
Organization: Reed College, Portland, OR
Lines: 26
In article <1993Apr20.174246.14375@wam.umd.edu> lerxst@wam.umd.edu (where's my
thing) writes:
>
> I was wondering if anyone out there could enlighten me on this car I saw
> the other day. It was a 2-door sports car, looked to be from the late 60s/
> early 70s. It was called a Bricklin. The doors were really small. In
addition,
> the front bumper was separate from the rest of the body. This is
> all I know. If anyone can tellme a model name, engine specs, years
> of production, where this car is made, history, or whatever info you
> have on this funky looking car, please e-mail.
Bricklins were manufactured in the 70s with engines from Ford. They are rather
odd looking with the encased front bumper. There aren't a lot of them around,
but Hemmings (Motor News) ususally has ten or so listed. Basically, they are a
performance Ford with new styling slapped on top.
> ---- brought to you by your neighborhood Lerxst ----
Rush fan?
--
Robert Seymour rseymour@reed.edu
Physics and Philosophy, Reed College (NeXTmail accepted)
Artificial Life Project Reed College
Reed Solar Energy Project (SolTrain) Portland, OR