2016-04-21 1 views
2

Ich möchte die Kosinusähnlichkeit für die aufeinander folgenden Artikelpaare in einer JSON-Datei berechnen. Bis jetzt schaffe ich es aber .... Ich merke nur, dass ich bei der Umwandlung der Tfidf jedes Artikels nicht die Begriffe aus allen in der Datei verfügbaren Artikeln verwende, sondern nur die aus jedem Paar. Hier ist der Code, den ich verwende, der den Cosinus-Ähnlichkeitskoeffizienten jedes aufeinander folgenden Paares von Artikeln bereitstellt.Kosinus-Ähnlichkeit zwischen aufeinanderfolgenden Paaren mit ganzen Artikeln in JSON-Datei

import json 
import nltk 
with open('SDM_2015.json') as f: 
    data = [json.loads(line) for line in f] 

## Loading the packages needed: 
import nltk, string 
from sklearn.feature_extraction.text import TfidfVectorizer 

## Defining our functions to filter the data 

# Short for stemming each word (common root) 
stemmer = nltk.stem.porter.PorterStemmer() 

# Short for removing puctuations etc 
remove_punctuation_map = dict((ord(char), None) for char in string.punctuation) 

## First function that creates the tokens 
def stem_tokens(tokens): 
    return [stemmer.stem(item) for item in tokens] 

## Function that incorporating the first function, converts all words into lower letters and removes puctuations maps (previously specified) 
def normalize(text): 
    return stem_tokens(nltk.word_tokenize(text.lower().translate(remove_punctuation_map))) 

## Lastly, a super function is created that contains all the previous ones plus stopwords removal 
vectorizer = TfidfVectorizer(tokenizer=normalize, stop_words='english') 

## Calculation one by one of the cosine similatrity 

def foo(x, y): 
    tfidf = vectorizer.fit_transform([x, y]) 
    return ((tfidf * tfidf.T).A)[0,1] 

my_funcs = {} 
for i in range(len(data) - 1): 
    x = data[i]['body'] 
    y = data[i+1]['body'] 
    foo.func_name = "cosine_sim%d" % i 
    my_funcs["cosine_sim%d" % i] = foo 
    print(foo(x,y)) 

Jede Idee, wie die Kosinus-Ähnlichkeit zu entwickeln, um die ganzen Bedingungen aller Artikel in der JSON-Datei und nicht nur diejenigen von jedem Paar mit?

Mit freundlichen Grüßen

Andres

+0

Wenn ich richtig verstehe, was Sie tun möchten, ist zunächst die TFIDF für jeden Begriff in jedem Artikel unabhängig zu berechnen. Die IDF ist über den gesamten Korpus verteilt. Dann berechnen Sie mit der TFIDF die Ähnlichkeit zwischen den Dokumenten. Ist das deine Frage? – flyingmeatball

+0

@flyingmeatball. Ja das stimmt, und tatsächlich gibt mir der Code schon die Kosinusähnlichkeit der aufeinander folgenden Paare. Da der Tfidf vom IDF gebildet wird, bin ich mir nicht sicher, was mein Korpus hier ist: ein Paar Artikel oder alle Artikel in meinem Dokument. –

+0

Ihr Korpus sind alle Artikel. Wenn ein gegebenes Wort in zwei aufeinander folgenden Artikeln unter allen Artikeln "selten" ist, sollte es sich dann im TFIDF-Wert für dieses Wort widerspiegeln, und die Artikel sollten aufgrund Ihrer Ähnlichkeitsmetrik näher zusammen erscheinen, da beide ein relativ seltenes Wort enthalten. – flyingmeatball

Antwort

1

Ich denke, auf der Grundlage unserer Diskussion über, müssen Sie unten die foo Funktion und alles ändern. Siehe den folgenden Code. Beachten Sie, dass ich dies nicht ausgeführt habe, da ich Ihre Daten nicht habe und keine Beispielzeilen zur Verfügung gestellt werden.

## Loading the packages needed: 
import nltk, string 
from sklearn.feature_extraction.text import TfidfVectorizer 
from sklearn.metrics import pairwise_distances 
from scipy.spatial.distance import cosine 
import json 
from sklearn.metrics.pairwise import cosine_similarity 

with open('SDM_2015.json') as f: 
    data = [json.loads(line) for line in f] 

## Defining our functions to filter the data 

# Short for stemming each word (common root) 
stemmer = nltk.stem.porter.PorterStemmer() 

# Short for removing puctuations etc 
remove_punctuation_map = dict((ord(char), None) for char in string.punctuation) 

## First function that creates the tokens 
def stem_tokens(tokens): 
    return [stemmer.stem(item) for item in tokens] 

## Function that incorporating the first function, converts all words into lower letters and removes puctuations maps (previously specified) 
def normalize(text): 
    return stem_tokens(nltk.word_tokenize(text.lower().translate(remove_punctuation_map))) 

## tfidf 
vectorizer = TfidfVectorizer(tokenizer=normalize, stop_words='english') 
tfidf_data = vectorizer.fit_transform(data) 

#cosine dists 
similarity matrix = cosine_similarity(tfidf_data) 
Verwandte Themen