Die Sortimentsoptimierung ist ein wichtiger Prozess im Einzelhandel, bei dem es darum geht, den idealen Produktmix zu finden, um die Nachfrage der Verbraucher zu befriedigen und gleichzeitig die zahlreichen logistischen Zwänge zu berücksichtigen. Die Einzelhändler müssen sicherstellen, dass sie die richtigen Produkte in der richtigen Menge und zur richtigen Zeit anbieten. Durch die Nutzung von data und Verbrauchererkenntnissen können Einzelhändler fundierte Entscheidungen darüber treffen, welche Artikel sie vorrätig halten, wie sie ihren Bestand verwalten und welche Produkte sie auf der Grundlage von Kundenpräferenzen, saisonalen Trends und Verkaufsmustern priorisieren sollten.
Für Einzelhandelsunternehmen ist die Optimierung des Sortiments von entscheidender Bedeutung, um ein Gleichgewicht zwischen Vielfalt und Effizienz herzustellen. Ein zu geringes Angebot kann die Kunden vergraulen, während ein zu großes Angebot zu Verwirrung, Überbeständen und niedrigeren Gewinnspannen führen kann. Die Optimierung des Produktsortiments hilft den Unternehmen, die Kundenzufriedenheit zu erhöhen, indem sie sicherstellen, dass beliebte Artikel verfügbar sind, und gleichzeitig Produkte mit geringer Leistung, die wertvollen Platz in den Regalen beanspruchen, eliminieren.
Die Wahlmodellierung ist ein effizienter Ansatz für die Sortimentsoptimierung, da sie einen data Rahmen für das Verständnis der Kundenpräferenzen und die Vorhersage der Wahl zwischen verschiedenen Produkten bietet. Durch die Analyse verschiedener Faktoren wie Preissensibilität, Produktmerkmale und Markentreue hilft die Wahlmodellierung Einzelhändlern zu ermitteln, welche Produkte am ehesten der Kundennachfrage entsprechen.
Letztlich können Einzelhändler mit Hilfe der Auswahlmodellierung den richtigen Produktmix anbieten, die Sortimente auf bestimmte Kundensegmente zuschneiden und die Regalfläche optimieren, um die Rentabilität oder sogar die Preisgestaltung der Artikel zu verbessern.
Wenn Sie noch nie etwas von Choice-Modellen gehört haben, können Sie unseren Artikel lesen, in dem die wichtigsten Konzepte mit Beispielen vorgestellt werden. In diesem Artikel konzentrieren wir uns hauptsächlich darauf, wie diskrete Auswahlmodelle zur Optimierung eines Produktsortiments verwendet werden können. Wir stellen Codebeispiele zur Verfügung, die auf der choice-learn-Bibliothek basieren, die data bei solchen Anwendungsfällen helfen soll.
Der mitgelieferte Code verwendet das Python-Paket choice-learn und ist in einem Notizbuch zu finden hier.
Einrichten: Installation von Python und Choice-Learn
In diesem Artikel stellen wir Code-Schnipsel zur Verfügung, um die Erklärungen zu begleiten. Der Code verwendet die Choice-Learn-Bibliothek, die effiziente Werkzeuge für die Modellierung von Wahlmöglichkeiten und verschiedene Anwendungen - wie Sortimentsoptimierung oder Preis - bietet. Choice-Learn ist über PyPI verfügbar, Sie können es einfach mit
Der Datensatz: Verkaufseinnahmen
Wir werden den TaFeng-Lebensmitteldatensatz verwenden. Sie können ihn von Kaggle herunterladen und in Ihrer Python-Umgebung mit choice-learn öffnen:
print(tafeng_df.head())
Der Datensatz besteht aus über 800.000 einzelnen Einkäufen in einem chinesischen Lebensmittelgeschäft. Für jeden Einkauf werden verschiedene Details bereitgestellt, darunter der gekaufte Artikel (PRODUCT_ID), der Preis, zu dem er verkauft wurde (SALES_PRICE), und die Altersgruppe des Kunden (AGE_GROUP).
Sie können feststellen, dass viele verschiedene Artikel angeboten werden und einige von ihnen nur selten verkauft werden. Um die Logistik zu rationalisieren, kann der Einzelhändler beschließen, die Anzahl der angebotenen Produkte zu reduzieren. Das Ziel in diesem Fall ist es, die optimale Teilmenge der zu verkaufenden Artikel zu ermitteln.
Zu diesem Zweck konzentrieren wir uns auf die umsatzstärksten Artikel, da diese mit größerer Wahrscheinlichkeit wieder gekauft werden und eine entscheidende Rolle bei der Gestaltung eines effizienteren und rentableren Sortiments spielen. Beachten Sie, dass wir dies hauptsächlich zur Vereinfachung des Beispiels tun und dass alle Artikel beibehalten werden könnten.
tafeng_df = tafeng_df.loc[
tafeng_df.PRODUCT_ID.isin(tafeng_df.PRODUCT_ID.value_counts().index[:20])
].reset_index(drop=True)
tafeng_df = tafeng_df.loc[
tafeng_df.AGE_GROUP.isin(["25-29", "40-44", "45-49", ">65", "30-34", "35-39", "50-54", "55-59", "60-64"] )
].reset_index(drop=True)
Kodieren wir auch die Alterskategorien mit einem heißen Wert alle zehn Jahre:
tafeng_df["zwanziger"]= tafeng_df.apply(lambda row: 1 if row["AGE_GROUP"]== "25-29" else 0, axis=1)
tafeng_df["thirties"]= tafeng_df.apply(
lambda Zeile: 1 if Zeile["AGE_GROUP"] in (["30-34", "35-39"]) sonst 0, Achse=1
)
tafeng_df["vierziger"]= tafeng_df.apply(
lambda Zeile: 1 if Zeile["AGE_GROUP"] in (["40-44", "45-49"]) sonst 0, Achse=1
)
tafeng_df["fünfziger"]= tafeng_df.apply(
lambda row: 1 if row["AGE_GROUP"] in (["50-54", "55-59"]) else 0, axis=1
)
tafeng_df["sixties_and_above"]= tafeng_df.apply(
lambda row: 1 if row["AGE_GROUP"] in (["60-64", ">65"]) else 0, axis=1
)
Nun, da unsere data fertig sind, müssen wir ein ChoiceDataset erstellen, das data in choice-learn. Dazu müssen die Merkmale festgelegt werden, die den Kontext beschreiben, in dem ein Kauf getätigt wird:
- Kundenmerkmale (gemeinsame Merkmale): die Altersgruppe
- Produktmerkmale (Artikelmerkmale): der Artikelpreis
Ein wichtiger Aspekt der Modellierung von Kaufentscheidungen besteht darin, dass wir die Merkmale aller zum Zeitpunkt des Kaufs verfügbaren Produkte benötigen, nicht nur die des ausgewählten Produkts. So können wir analysieren, wie die Preise der verschiedenen Produkte die Entscheidung des Kunden beeinflussen. Da diese Information im Datensatz nicht direkt verfügbar ist, gehen wir davon aus, dass bei jedem Kauf die Preise der anderen Artikel die gleichen sind wie beim vorherigen Verkauf.
id_to_index = {}
for i, product_id in enumerate(np.sort(tafeng_df.PRODUCT_ID.unique())):
id_to_index[product_id] = i
# Initialize the items price
prices = [[0] for _ in range(len(id_to_index))] for k, v in id_to_index.items():
prices[v][0] = tafeng_df.loc[tafeng_df.PRODUCT_ID == k].SALES_PRICE.to_numpy()[0] # Create the arrays that will constitute the ChoiceDataset
shared_features = [] items_features = [] choices = [] # For each bought item, we save:
# – the age representation (one-hot) of the customer
# – the price of all sold items
for i, row in tafeng_df.iterrows():
item_index = id_to_index[row.PRODUCT_ID] prices[item_index][0] = row.SALES_PRICE
shared_features.append(
row[[“twenties”, “thirties”, “forties”, “fifties”, “sixties_and_above”]].to_numpy()
)
items_features.append(prices)
choices.append(item_index)
Da wir nun alle Informationen haben, können wir den ChoiceDatensatz erstellen:
dataset = ChoiceDataset(
shared_features_by_choice=shared_features,
shared_features_by_choice_names=['twenties', 'thirties', 'forties', 'fifties', 'sixties_and_above'],
items_features_by_choice=items_features,
items_features_by_choice_names=["SALES_PRICE"],
choices=choices
)
Definition und Schätzung des Auswahlmodells
Wir werden ein Auswahlmodell entwickeln und schätzen, das die Wahrscheinlichkeit vorhersagt, mit der ein Kunde einen bestimmten Artikel aus einem ganzen Sortiment ähnlicher Produkte auswählt. Auf der Grundlage des verfügbaren Datensatzes definieren wir die folgende Nutzenfunktion für einen Artikel i, der von einem Kunden j in Betracht gezogen wird :
Diese Funktion stellt den Nutzen (oder die Zufriedenheit) dar, den ein Kunde aus der Wahl eines bestimmten Artikels zieht, wobei sowohl das Alter des Kunden als auch der Preis des Artikels eine Rolle spielen.
Weitere Einzelheiten zur Formulierung einer Nutzenfunktion finden Sie in unserem ersten Beitrag. Beachten Sie, dass ein anderes logisches - aber der Einfachheit halber nicht vorgestelltes - Modell darin bestehen könnte, eine Preissensitivität pro Alterskategorie zu schätzen.
Hier ist der Code zur Schätzung eines solchen Modells mit choice-learn:
model.add_coefficients(
coefficient_name=age_category, feature_name=age_category, items_indexes=list(range(20))
)
coefficient_name="price", feature_name="SALES_PRICE",items_indexes=list(range(20))
)
Sie können überprüfen, ob das Modell gut auf den Datensatz passt:
plt.plot(hist["train_loss"])
plt.xlabel("Epoche")
plt.ylabel("Negative Log-Likelihood")
plt.show(
Das optimale Sortiment finden
Mit den Kaufwahrscheinlichkeiten in der Hand können wir nun den durchschnittlichen Umsatz pro Kunde eines Sortiments A anhand der Formel schätzen:
Um das Sortiment zu finden, das den Umsatz maximiert, könnten wir alle möglichen Kombinationen bewerten und diejenige mit dem höchsten Durchschnittsumsatz auswählen. Ein effizienterer Ansatz ist jedoch die Verwendung von Lineare Programmierung (LP). Hier werden wir uns darauf konzentrieren, wie die Choice-Learn-Implementierung des Sortimentsoptimierers verwendet wird.
Es ist wichtig, zwischen der Maximierung der Einnahmen und der Maximierung der Gewinnspannen zu unterscheiden. Während der Umsatz wichtig ist, werden bei der Gewinnspanne die mit jedem Produkt verbundenen Kosten berücksichtigt. Je nach Ihrem Ziel sollten Sie eher auf den Gewinn als auf den reinen Umsatz hin optimieren.
Um das Sortiment zu optimieren, müssen wir mehrere wichtige Informationen bereitstellen:
- Das Gewicht, das wir jeder Alterskategorie geben wollen, ist der Anteil der Kunden
- Der Nutzen jedes Artikels (berechnet nach unserem Auswahlmodell) für jede Altersgruppe
- Der zu optimierende Wert für jedes Element (in diesem Fall der Umsatz)
- die Größe des Sortiments (z. B. 12 Artikel)
So funktioniert es mit der Wahl-Lernmethode:
from choice_learn.toolbox.assortment_optimizer import LatentClassAssortmentOptimizer
# Preis der einzelnen Artikel
future_prices = np.stack([items_features[-1]]*5, axis=0)
age_category = np.eye(5).astype("float32")
# Berechnung des Nutzens jedes Artikels anhand seines Preises und jeder Alterskategorie
vorhergesagter_nutzen = model.compute_batch_utility(shared_features_by_choice=age_category,
items_features_by_choice=future_prices,
available_items_by_choice=np.ones((5, 20)),
choices=None
)
age_category_weights = np.sum(shared_features, axis=0) / len(shared_features)
opt = LatentClassAssortmentOptimizer(
solver="or-tools", # Zu verwendender Solver, entweder "or-tools" oder "gurobi" (wenn Sie eine Lizenz haben)
class_weights=age_category_weights, # Gewichte der einzelnen Klassen
class_utilities=np.exp(predicted_utilities), # utilities in der Form (n_classes, n_items)
itemwise_values=future_prices[0][:, 0], # Werte zur Optimierung für jeden Artikel, hier der Preis, der zur Berechnung des Umsatzes verwendet wird
assortment_size=12) # Gewünschte Größe des Sortiments
Sortiment, opt_obj = opt.solve()
Wenn Sie den Code ausführen, sollten Sie etwas erhalten wie:
Das optimale Sortiment zur Maximierung des Umsatzes ist mit den Indizes der 1-Werte im Vektor angegeben. Dieses Sortiment führt theoretisch zu einem durchschnittlichen Umsatz pro Kunde von 134 Yuan. Sie können auch andere Kombinationen ausprobieren, aber sie werden alle zu einem niedrigeren Durchschnittserlös führen.
Ein anderes Ziel könnte darin bestehen, die Anzahl der Verkäufe zu maximieren. In diesem Szenario wird der artikelweise Wert für die Optimierung für alle Artikel auf 1 gesetzt, was zu einem anderen optimalen Sortiment führt.
Die Effizienz dieser Methode wird deutlich, wenn zusätzliche Beschränkungen eingeführt werden. So kann es zum Beispiel erforderlich sein, die begrenzte Regalfläche in Ihrem Geschäft zu berücksichtigen. In diesem Fall können Sie für ein Sortiment optimieren, dessen Gesamtgröße die verfügbare Regalfläche nicht überschreitet. Diese zusätzliche Einschränkung wird hier zusammen mit anderen, wie z. B. Preisstrategien, demonstriert.
Schlussfolgerung
Wenn Sie an der Optimierung des Sortiments oder der Preisgestaltung arbeiten, ist die Wahlmodellierung ein großartiges Werkzeug, das Sie sich unbedingt ansehen sollten. Choice-Learn bietet viele coole Beispiele auf seinem GitHub. Schauen Sie es sich an und hinterlassen Sie einen Stern, wenn Sie es nützlich finden!