Einfaches Empfehlungssystem in Python

Einfaches Empfehlungssystem in Python

Eine mittlerweile weit verbreitete Anwendung von künstlicher Intelligenz bzw. Machine Learning sind Empfehlungssysteme. Diese haben sich vor allem in der Welt der Online-Plattformen und digitalen Dienste etabliert. Sie analysieren Präferenzen und Verhalten der Nutzer:innen, um neue Produkte oder Dienstleistungen vorzuschlagen, die interessant sein könnten. Ein Beispiel dafür ist die Online-Kursplattform Udemy. Wenn man dort einen Kurs z.B. zum Thema „Teamwork“ abschließt, schlägt das System weitere Kurse in diesem Bereich vor, vielleicht zu den Themen „Effektive Meetings“ oder „Tools für Zusammenarbeit im Team“. In diesem Post zeige ich ein einfaches Empfehlungssystem in Python.

Unser Anwendungsfall ist angelehnt an Udemy: eine fiktive Kursplattform. Ziel soll es sein, ein System zu erstellen, das basierend auf bisher abgeschlossenen Kursen ähnliche Kurse findet und empfiehlt. Der Ansatz ist inhaltsbasiert: Es werden Merkmale der verschiedenen Kurse verglichen. Eine Alternative wäre kollaborativ, bei dem auf andere User geschaut wird. Genauer gesagt: Welche Kurse haben User noch gekauft, die zum User ähnlich sind, für den ich eine Empfehlung generieren möchte?

Im Folgenden werden wir durch den Python-Code gehen, um dieses Empfehlungssystem Schritt für Schritt zu erstellen.

Einfaches Empfehlungssystem in Python

Bibliotheken

Zuerst kurz die Bibliotheken, die wir verwenden werden:

  • Scikit-Learn: Beinhaltet den ML-Algorithmus für Nearest Neighbors und Funktionen fürs Preprocessing
  • Pandas: Wird genutzt, um Data Frames (Tabellen) verwenden zu können
  • Numpy: Beinhaltet diverse Funktionen, um Array-Datenstrukturen zu manipulieren
import pandas as pd
import numpy as np
from sklearn.preprocessing import OneHotEncoder, MultiLabelBinarizer
from sklearn.neighbors import NearestNeighbors

Datengrundlage

Als erstes erstellen wir unseren synthetischen Datensatz, welcher die Kurse auf der fiktiven Plattform repräsentiert. Jeder Kurs hat dabei drei Eigenschaften:

  • Name („z.B. „Robotik und Automatisierung“)
  • Kategorie (z.B. „Datenanalyse“)
  • Tags (z.B. „Python“ oder „Grundlagen“)
# Liste mit Kursnamen erstellen
courses = [
    "Python für Anfänger",
    "Data Science mit Python",
    "Webentwicklung mit Django",
    "Machine Learning mit TensorFlow",
    "Java für Anfänger",
    "Webdesign mit HTML und CSS",
    "SQL-Datenbanken",
    "Einführung in die Informatik",
    "Mathematik für Informatiker",
    "Algorithmen und Datenstrukturen",
    "Künstliche Intelligenz",
    "Deep Learning",
    "Neuronale Netze",
    "Robotik und Automatisierung",
    "Netzwerktechnik",
    "IT-Sicherheit",
    "Datenanalyse mit Excel",
    "UI/UX-Design",
    "Blockchain-Technologie",
    "Cloud Computing",
    "Mobile App-Entwicklung",
    "Spieleentwicklung",
    "Digitale Bildbearbeitung",
    "Audio- und Videobearbeitung",
    "3D-Modellierung",
]

# Kategorien der Kurse
categories = [
    "Programmierung",
    "Datenanalyse",
    "Webentwicklung",
    "Datenanalyse",
    "Programmierung",
    "Webentwicklung",
    "IT Allgemein",
    "IT Allgemein",
    "IT Allgemein",
    "IT Allgemein",
    "Datenanalyse",
    "Datenanalyse",
    "Datenanalyse",
    "IT Allgemein",
    "IT Allgemein",
    "IT Allgemein",
    "Datenanalyse",
    "Kreative Medien",
    "IT Allgemein",
    "IT Allgemein",
    "Webentwicklung",
    "Kreative Medien",
    "Kreative Medien",
    "Kreative Medien",
    "Kreative Medien",
]

# Tags der Kurse
tags = [
    ["Python", "Programmierung", "Anfänger"],
    ["Python", "Data Science", "Datenanalyse"],
    ["Django", "Webentwicklung", "Python"],
    ["TensorFlow", "Machine Learning", "Datenanalyse"],
    ["Java", "Programmierung", "Anfänger"],
    ["HTML", "CSS", "Webdesign"],
    ["SQL", "Datenbanken", "Abfragen"],
    ["Informatik", "Grundlagen", "Computersysteme"],
    ["Mathematik", "Informatik", "Logik"],
    ["Algorithmen", "Datenstrukturen", "Optimierung"],
    ["Künstliche Intelligenz", "Machine Learning", "Neuronale Netze"],
    ["Deep Learning", "Künstliche Intelligenz", "Datenanalyse"],
    ["Neuronale Netze", "Künstliche Intelligenz", "Deep Learning"],
    ["Robotik", "Automatisierung", "Mechatronik"],
    ["Netzwerktechnik", "Kommunikation", "Infrastruktur"],
    ["IT-Sicherheit", "Cybersecurity", "Verschlüsselung"],
    ["Excel", "Datenanalyse", "Tabellenkalkulation"],
    ["UI/UX", "Design", "Webdesign"],
    ["Blockchain", "Kryptowährungen", "Technologie"],
    ["Cloud Computing", "Speicher", "Infrastruktur"],
    ["Mobile App", "Entwicklung", "iOS"],
    ["Spieleentwicklung", "Game Design", "Programmierung"],
    ["Bildbearbeitung", "Grafikdesign", "Photoshop"],
    ["Multimedia", "Produktion", "Videobearbeitung"],
    ["3D-Modellierung", "Animation", "Design"],
]

# Daten in Pandas DataFrame speichern
df = pd.DataFrame({"Name": courses, "Category": categories, "Tags": tags})

Um diese Daten für das Nearest Neighbors-Modell nutzbar zu machen, verwenden wir One-Hot-Encoding und MultiLabelBinarizer. Diese Techniken wandeln kategorische Daten in eine numerische Form um, die von ML-Algorithmen verarbeitet werden kann. Dabei erzeugen sie eine Matrix, in der jede Zeile einen Kurs und jede Spalte ein mögliches Merkmal dieses Kurses repräsentiert. Eine „1“ in einer bestimmten Zelle zeigt an, dass der entsprechende Kurs dieses Merkmal aufweist (im Gegensatz zur „0“).

# One-Hot-Encoding und Multi-Label-Binarizer anwenden und in eine Matrix zusammenführen
encoder_category = OneHotEncoder(sparse_output=False)
encoded_categories = encoder_category.fit_transform(df[["Category"]])
encoder_tags = MultiLabelBinarizer()
encoded_tags = encoder_tags.fit_transform(df["Tags"])
encoded_matrix = np.hstack((encoded_categories, encoded_tags))

Nearest-Neighbors-Modell

Unsere Daten sind nun vorbereitet. Entsprechend können wir unser Empfehlungsmodell erstellen. Dazu verwenden wir den Nearest-Neighbors-Algorithmus, welcher recht einfach und effektiv für unser Beispiel ist. Der Algorithmus gehört zur Kategorie unüberwachtes Lernen und sucht in den Daten nach den „dichtesten Nachbarn“, also den ähnlichsten Elementen zu dem, was wir als Input verwenden. In unserem Fall: Kurse, die der Nutzer oder die Nutzerin bereits abgeschlossen hat.

Wir trainieren das Modell mit der vorbereiteten Matrix. Es lernt dabei, wie es die Ähnlichkeit zwischen verschiedenen Kursen basierend auf ihren Merkmalen messen kann.

# Nearest-Neighbors Modell
model = NearestNeighbors()
model.fit(encoded_matrix)

Empfehlung von Kursen

Mit der Funktion recommend_courses können wir nun Empfehlungen erzeugen. Diese Funktion nutzt das Modell in Kombination mit einer Liste von Kursen, die ein User bereits gekauft hat. Für jeden Kurs wird eine Liste an ähnlichen Kursen gefunden. Insgesamt sind das vier Kurse, auch wenn wir nur 3 Empfehlungen haben möchten. Das liegt einfach nur daran, dass der Input-Kurs selbst auch in der Liste vorhanden ist (mit einer Distanz von 0). Wenn wir durch alle Kurse durchiteriert sind, werden die Kurse aus dem Data Frame kopiert, Distanzen aggregiert, bereits gekaufte Kurse entfernt und sortiert. Aus der resultierenden Tabelle entnehmen wir dann die Top-3-Empfehlungen.

# Empfehlungen basierend auf Liste von Kursen
def recommend_courses(model, df, mat, user_courses, n_recommendations=3):
    user_indices = df[df["Name"].isin(user_courses)].index.tolist()
    distances, indices = [], []

    # Anwenden des Modells
    for idx in user_indices:
        d, i = model.kneighbors(
            mat[idx].reshape(1, -1), n_neighbors=n_recommendations + 1
        )
        distances.extend(d.flatten())
        indices.extend(i.flatten())

    # Kurse aus 'df' entnehmen und sortieren
    rec_courses = df.iloc[np.unique(indices)].copy()
    rec_courses["Distance"] = [
        np.mean([distances[j] for j in range(len(distances)) if indices[j] == i])
        for i in rec_courses.index
    ]

    # Bereits abgeschlossene Kurse entfernen und sortieren
    rec_courses = rec_courses[~rec_courses["Name"].isin(user_courses)]
    rec_courses = rec_courses.sort_values("Distance", ascending=True)

    # Top-Auswahl an Empfehlungen zurückgeben
    return rec_courses[:n_recommendations]

Anzeigen der Empfehlungen

Schließlich haben wir eine Funktion namens show_recommendations, die die eben beschriebene Empfehlungsfunktion nutzt, um die empfohlenen Kurse für jeden User anzuzeigen:

# Funktion zeigt einige Empfehlungen an
def show_recommendations(model, df, encoded_matrix, users_courses):
    number_of_users = len(users_courses)
    for i in range(number_of_users):
        rec = recommend_courses(model, df, encoded_matrix, users_courses[i])
        print(str(i + 1), ": ", rec["Name"].tolist())

Testen des Empfehlungssystems

Nun möchten wir das System natürlich testen! Dazu erstellen wir drei Test-User, welche je zwei Kurse schon gekauft haben:

# Liste an Kursen, die der jeweilige User bereits gekauft hat
users_courses = [
    ["Python für Anfänger", "Webentwicklung mit Django"],
    ["Robotik und Automatisierung", "Netzwerktechnik"],
    ["Digitale Bildbearbeitung", "3D-Modellierung"],
]

Mal sehen, welche Empfehlungen es nun für diese User gibt:

# Zeige Empfehlungen an
show_recommendations(model, df, encoded_matrix, users_courses)

Output:

1 :  ['Java für Anfänger', 'Data Science mit Python', 'Webdesign mit HTML und CSS']
2 :  ['Cloud Computing', 'SQL-Datenbanken', 'Einführung in die Informatik']
3 :  ['UI/UX-Design', 'Spieleentwicklung', 'Audio- und Videobearbeitung']

Ich finde, die Empfehlungen ergeben Sinn:

  • User 1 hat bereits Python-Grundlagen und Webentwicklung mit Django (ein Python-Framework) gelernt. Die erste Empfehlung ist auch ein Anfängerkurs, die zweite Empfehlung beinhaltet Python, die dritte Empfehlung hat mit Webdesign zu tun.
  • User 2 ist nicht ganz so in der Programmierung, sondern etwas mehr auf Technologie- oder Hardware-Ebene unterwegs. Hier ergeben Themen wie Cloud Computing, Datenbanken und Informatik-Grundlagen durchaus Sinn.
  • User 3 ist mehr im kreativen Bereich tätig. Da sind UX-Design, Spieleentwicklung und Audio-/Videobearbeitung passend!

Zusammenfassung

In diesem Post haben wir ein einfaches, aber effektives Empfehlungssystem erstellt, das auf einer Kursplattform ähnliche Kurse empfehlen kann. Der Ansatz ist Nearest Neighbors, welcher möglichst ähnliche Kurse findet, basierend auf Kategorien und Tags. Hier ist es wichtig zu erwähnen, dass für den gezeigten Ansatz eine gute Datenpflege elementar ist. Das ist besonders beim inhaltsbasierten Ansatz wichtig im Vergleich zum kollaborativen Ansatz.

Hier sind noch einige Möglichkeiten, wie man das System erweitern könnte:

  • Kollaborativer Ansatz: Wie bereits erwähnt, werden hier nur Kursinformationen miteinander verglichen; im kollaborativen Ansatz würde man die Ähnlichkeit zu anderen Usern miteinbeziehen.
  • Nutzung von Nutzerfeedback: Anstatt sich nur auf die bereits gekauften Kurse zu stützen, könnten wir auch Feedback, wie z.B. Bewertungen oder Kommentare, integrieren.
  • Weitere Merkmale: Wir haben nur Kategorien und Tags genutzt, doch weitere Beispiele wären die Schwierigkeit des Kurses, der Preis, die Länge oder die Sprache.

Wenn du ein Wunschthema hast oder mir Feedback geben willst, schreibe gerne einen Kommentar oder schicke eine Mail an mail@thorejohannsen.de.

Ähnliche Beiträge

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert