[PYTHON] Versuchen Sie, inhaltsbasierte Filterung oder Dokumentempfehlungen zu implementieren

Fahren Sie mit dem vorherigen Artikel Implementieren der artikelbasierten Co-Filterung in Python unter Verwendung von MovieLens als Beispiel fort. Betrachten wir die inhaltsbasierte Filterung.

Informationen zur inhaltsbasierten Filterung

Es ist ein allgemeiner Begriff für ein System, das Artikel empfiehlt, indem der Geschmack der Benutzer mit den Eigenschaften der Artikel abgeglichen wird.

Wenn Sie sich die Funktionen des Inhalts ansehen, können Sie sagen, dass es sich um eine inhaltsbasierte Filterung handelt, sodass es keinen festen Algorithmus gibt. (Und ich verstehe)

Inhaltsbasierte Filtertechniken

Beispiel 1: Verwendung von Elementmetadaten

Im Fall eines Films kann die Feature-Menge des Elements beispielsweise {Schauspieler, Genre, Regisseur, Land} sein, und die Feature-Menge des Benutzers kann durch den Durchschnittswert der bevorzugten Elemente ausgedrückt werden.

Beispiel 2: Verwendung von Wörtern in Dokumenten

Wenn Sie Artikel auf Nachrichtenseiten empfehlen, können Sie Wörter verwenden, die im Dokument erscheinen. Beispielsweise wird die Merkmalsmenge eines Elements durch den TF / IDF-Wert eines Wortes ausgedrückt, und die Merkmalsmenge eines Benutzers wird durch den Durchschnittswert der bevorzugten Elemente (= Artikel) ausgedrückt.

Inhaltsbezogene Empfehlung von Dokumenten

Dieses Mal möchte ich unter der Annahme von Beispiel 2 eine Methode implementieren, um Dokumente auf Inhaltsbasis zu empfehlen.

Datenquelle

Verwenden Sie den Scikit-Learn-Datensatz Der 20 Newsgroups-Textdatensatz.

Enthält Daten für 20 Kategorien von Newsgroups wie "comp.graphics" und "rec.sport.baseball".

>>> from sklearn.datasets import fetch_20newsgroups
>>> newsgroups_train = fetch_20newsgroups(subset='train')
>>> newsgroups_train.data[0]
"From: [email protected] (where's my thing)\nSubject: WHAT car is this!?\nNntp-Posting-Host: rac3.wam.umd.edu\nOrganization: University of Maryland, College Park\nLines: 15\n\n I was wondering if anyone out there could enlighten me on this car I saw\nthe other day. It was a 2-door sports car, looked to be from the late 60s/\nearly 70s. It was called a Bricklin. The doors were really small. In addition,\nthe front bumper was separate from the rest of the body. This is \nall I know. If anyone can tellme a model name, engine specs, years\nof production, where this car is made, history, or whatever info you\nhave on this funky looking car, please e-mail.\n\nThanks,\n- IL\n   ---- brought to you by your neighborhood Lerxst ----\n\n\n\n\n"

Dokumentempfehlungssystem zu erstellen

Wir werden ein System aufbauen, das die Häufigkeit des Auftretens von Wörtern (Wortsack) eingibt und Dokumente mit hoher Ähnlichkeit zurückgibt (in diesem Fall das Posten in der Newsgroup).

1. Korpus bauen

from gensim import corpora, models, similarities
from sklearn.datasets import fetch_20newsgroups
from collections import defaultdict
import nltk
import re

def create_dictionary_and_corpus(documents):
    texts = [tokens(document) for document in documents]

    frequency = defaultdict(int)
    for text in texts:
        for token in text:
            frequency[token] += 1

    #Verwerfen Sie Token mit 1 Vorkommen in allen Dokumenten
    texts = [[token for token in text if frequency[token] > 1] for text in texts]

    dictionary = corpora.Dictionary(texts)
    corpus = [dictionary.doc2bow(text) for text in texts]
    
    return dictionary, corpus

def tokens(document):
    symbols = ["'", '"', '`', '.', ',', '-', '!', '?', ':', ';', '(', ')', '*', '--', '\\']
    stopwords = nltk.corpus.stopwords.words('english')

    #Verwerfen Sie Stoppwörter und Symbole
    tokens = [re.sub(r'[,\.]$', '', word) for word in document.lower().split() if word not in stopwords + symbols]
    
    return tokens

#Laden Sie Daten aus 20 Newsgroups herunter
newsgroups_train = fetch_20newsgroups(subset='train',remove=('headers', 'footers', 'quotes'))

#Erstellen Sie ein Wörterbuch und einen Korpus mit den ersten 100
dictionary, corpus = create_dictionary_and_corpus(newsgroups_train.data[0:100])

Informationen zum Umgang mit Diktaturen und Korpus finden Sie in gensim tutorial.

2. Erstellen Sie ein Modell

def create_model_and_index(corpus):
    tfidf = models.TfidfModel(corpus)
    index = similarities.MatrixSimilarity(tfidf[corpus])
    return tfidf, index

model, index = create_model_and_index(corpus)

Erstellen Sie ein Tfidf-Modell aus dem Korpus. Weitere Informationen finden Sie unter Themen und Transformationen.

3. Dokumente empfehlen

Versuchen Sie, die ersten Trainingsdaten (Index: 0) für die Eingabe zu verwenden. Wenn das Empfehlungssystem korrekt aufgebaut ist, sollten Sie als ähnliches Dokument empfohlen werden.

bow = dictionary.doc2bow(tokens(newsgroups_train.data[0]))
vec_tfidf = model[bow]
sims = index[vec_tfidf] 

sims = sorted(enumerate(sims), key=lambda item: item[1], reverse=True)

for i in range(3):
    doc_id     = sims[i][0]
    simirarity = round(sims[i][1] * 100, 0)
    print(doc_id, simirarity)

Wie erwartet wurde doc_id: 0 mit 100% Ähnlichkeit empfohlen.

0 100.0
17 12.0
84 11.0

Es sollte erwähnt werden, dass

sims = index[vec_tfidf] 

Die Ähnlichkeit wird in dem Teil von berechnet, aber Sie können das Tutorial Ähnlichkeitsabfragen für Details sehen.

Zusammenfassung

Dieses Mal haben wir Trainingsdaten als Eingabedaten verwendet. Wenn Sie jedoch das Lieblingsdokument des Benutzers in einer Wortsammlung ausdrücken und eingeben, wird es meiner Meinung nach ein personalisiertes Dokumentempfehlungssystem sein. (Obwohl es in der Praxis wahrscheinlich etwas Einfallsreichtum erfordern wird)

Ich werde auch den kombinierten Code einfügen.


from gensim import corpora, models, similarities
from sklearn.datasets import fetch_20newsgroups
from collections import defaultdict
import nltk
import re

def create_dictionary_and_corpus(documents):
    texts = [tokens(document) for document in documents]

    frequency = defaultdict(int)
    for text in texts:
        for token in text:
            frequency[token] += 1

    texts = [[token for token in text if frequency[token] > 1] for text in texts]

    dictionary = corpora.Dictionary(texts)
    corpus = [dictionary.doc2bow(text) for text in texts]
    
    return dictionary, corpus

def tokens(document):
    symbols = ["'", '"', '`', '.', ',', '-', '!', '?', ':', ';', '(', ')', '*', '--', '\\']
    stopwords = nltk.corpus.stopwords.words('english')
    tokens = [re.sub(r'[,\.]$', '', word) for word in document.lower().split() if word not in stopwords + symbols]
    
    return tokens

def create_model_and_index(corpus):
    tfidf = models.TfidfModel(corpus)
    index = similarities.MatrixSimilarity(tfidf[corpus])
    return tfidf, index

# Use 100 samples to build dictionary and corpus
newsgroups_train = fetch_20newsgroups(subset='train',remove=('headers', 'footers', 'quotes'))
dictionary, corpus = create_dictionary_and_corpus(newsgroups_train.data[0:100])

# Create TfIdf Model and its index
model, index = create_model_and_index(corpus)

# System Evaluation
bow = dictionary.doc2bow(tokens(newsgroups_train.data[0]))
vec_tfidf = model[bow]
sims = index[vec_tfidf] 

sims = sorted(enumerate(sims), key=lambda item: item[1], reverse=True)

for i in range(3):
    doc_id     = sims[i][0]
    simirarity = round(sims[i][1] * 100, 0)
    print(doc_id, simirarity)

Recommended Posts

Versuchen Sie, inhaltsbasierte Filterung oder Dokumentempfehlungen zu implementieren
[Empfehlung] Inhaltsbasierte Filterung und kooperative Filterung