OSullivan – chatgpz.de – KI-Tools & Praxiswissen https://chatgpz.de Unabhängige Tests, Anleitungen und Hintergründe zu KI-Tools. Mon, 27 Jan 2025 05:33:43 +0000 de-DE hourly 1 https://wordpress.org/?v=6.4.2 234900186 Optimieren von Budgets mit Advertising -Combine -Modellen in Python | Von Ryan O’Sullivan | Januar 2025 https://chatgpz.de/machine-learning/optimieren-von-budgets-mit-advertising-combine-modellen-in-python-von-ryan-osullivan-januar-2025/ https://chatgpz.de/machine-learning/optimieren-von-budgets-mit-advertising-combine-modellen-in-python-von-ryan-osullivan-januar-2025/#respond Mon, 27 Jan 2025 05:33:43 +0000 http://chatgpz.de/machine-learning/optimieren-von-budgets-mit-marketing-mix-modellen-in-python-von-ryan-osullivan-januar-2025/ [ad_1]

Teil 3 einer praktischen Anleitung, mit der Sie MMM in PYMC beherrschen können

10 min lesen

Vor 17 Stunden

Foto von TOWFIqu Barbhuiya An Unplash

Willkommen in Teil 3 meiner Serien über Advertising Combine Modeling (MMM), einem praktischen Leitfaden, mit dem Sie MMM beherrschen können. In dieser Serie werden wir wichtige Themen wie Modelltraining, Validierung, Kalibrierung und Budgetoptimierung behandeln, die alle mit dem leistungsfähigen Pymc-Advertising Python -Paket. Egal, ob Sie neu in MMM sind oder Ihre Fähigkeiten schärfen möchten, in dieser Serie werden Sie praktische Werkzeuge und Erkenntnisse zur Verbesserung Ihrer Marketingstrategien ausstatten.

Wenn Sie Teil 2 verpasst haben, schauen Sie es sich hier an:

In der dritten Folge der Serie werden wir abdecken, wie wir anfangen können, den Geschäftswert aus unseren Advertising -Combine -Modellen zu erhalten, indem wir die folgenden Bereiche abdecken:

  • Warum möchten Unternehmen ihre Marketingbudgets optimieren?
  • Wie können wir die Ausgaben unseres Advertising -Combine -Modells verwenden, um Budgets zu optimieren?
  • Eine Python -Walkthrough, die zeigt, wie die Budgets mithilfe von Budgets optimiert werden können Pymc-Advertising.

Das vollständige Notizbuch finden Sie hier:

Benutzergenerierte Bild

Dieses berühmte Zitat (von John Wanamaker, denke ich?!) Zeigt sowohl die Herausforderung als auch die Chancen im Advertising. Während moderne Analysen einen langen Weg zurückgelegt haben, bleibt die Herausforderung related: Verständnis, welche Teile Ihres Marketingbudgets Wert liefern.

Marketingkanäle können in Bezug auf ihre Leistung und ROI aufgrund mehrerer Faktoren erheblich variieren:

  • Publikum Reichweite und Engagement – Einige Kanäle sind effektiver darin, bestimmte Aussichten zu erreichen, die an Ihre Zielgruppe ausgerichtet sind.
  • Akquisitionskosten – Die Kosten für die Erreichung der Aussichten unterscheiden sich zwischen Kanälen.
  • Kanalsättigung – Überbeanspruchung eines Marketingkanals kann zu sinkenden Renditen führen.

Diese Variabilität schafft die Möglichkeit, kritische Fragen zu stellen, die Ihre Marketingstrategie verändern können:

Benutzergenerierte Bild

Eine effektive Budgetoptimierung ist ein kritischer Bestandteil moderner Marketingstrategien. Durch die Nutzung der Ergebnisse von MMM können Unternehmen fundierte Entscheidungen darüber treffen, wo ihre Ressourcen für maximale Auswirkungen zugewiesen werden können. MMM bietet Einblicke in die Artwork und Weise, wie verschiedene Kanäle zum Gesamtumsatz beitragen und es uns ermöglichen, Verbesserungs- und Optimierungsmöglichkeiten zu ermitteln. In den folgenden Abschnitten werden wir untersuchen, wie wir MMM -Ausgaben in umsetzbare Budgetzuweisungsstrategien umsetzen können.

2.1 Antwortkurven

Eine Antwortkurve kann die Ausgaben von MMM in eine umfassende Kind umsetzen und zeigen, wie der Verkauf auf die Ausgaben für jeden Marketingkanal reagiert.

Benutzergenerierte Bild

Die Antwortkurven allein sind sehr mächtig und ermöglichen es uns, was-wenn-wenn-Szenarien auszuführen. Mit der obigen Antwortkurve als Beispiel könnten wir schätzen, wie der Vertriebsbeitrag aus sozialen Veränderungen mehr ausgibt. Wir können auch visuell sehen, wo die Rückgänge in Kraft treten. Aber was ist, wenn wir versuchen möchten, komplexere Was-wäre-wenn-Szenarien wie die Optimierung der Budgets der Kanalebene bei einem festen Gesamtbudget zu beantworten? Hier kommt die lineare Programmierung ins Spiel – lassen Sie uns dies im nächsten Abschnitt untersuchen!

2.2 Lineare Programmierung

Die lineare Programmierung ist eine Optimierungsmethode, mit der die optimale Lösung einer linearen Funktion bei einigen Einschränkungen ermittelt werden kann. Es ist ein sehr vielseitiges Software aus dem Operations -Forschungsbereich, erhält jedoch nicht oft die Anerkennung, die es verdient. Es wird verwendet, um Probleme mit den Planung, Transport- und Ressourcenzuweisung zu lösen. Wir werden untersuchen, wie wir es verwenden können, um Marketingbudgets zu optimieren.

Versuchen wir, die lineare Programmierung mit einem einfachen Budgetoptimierungsproblem zu verstehen:

  • Entscheidungsvariablen (x): Dies sind die unbekannten Mengen, die wir für die optimalen Werte für die Marketingausgaben für jeden Kanal schätzen möchten.
  • Objektive Funktion (z): Die lineare Gleichung, die wir versuchen, z.
  • Einschränkungen: Einige Einschränkungen der Entscheidungsvariablen, die normalerweise durch lineare Ungleichheiten dargestellt werden, z.
Benutzergenerierte Bild

Der Schnittpunkt aller Einschränkungen bildet eine realisierbare Area, die die Menge aller möglichen Lösungen ist, die die angegebenen Einschränkungen erfüllen. Das Ziel der linearen Programmierung ist es, den Punkt innerhalb des realisierbaren Bereichs zu finden, der die objektive Funktion optimiert.

Angesichts der Sättigungstransformation, die wir für jeden Marketingkanal anwenden, ist die Optimierung von Budgets der Kanalebene tatsächlich ein nichtlineares Programmierungsproblem. Die sequentielle Programmierung der kleinsten Quadrate (SLSQP) ist ein Algorithmus zur Lösung nichtlinearer Programmierprobleme. Es ermöglicht sowohl Gleichheit als auch Ungleichheit, dass es für unseren Anwendungsfall eine vernünftige Wahl macht.

  • Gleichstellungsbeschränkungen zB Gesamtmarketingbudget beträgt 50 Mio. GBP
  • Ungleichheitsbeschränkungen EG Channel Stage Budgets zwischen 5 Mio. GBP und 15 Mio. GBP

Scipy hat eine großartige Implementierung von SLSQP:

Das folgende Beispiel zeigt, wie wir es verwenden können:

from scipy.optimize import reduce

consequence = reduce(
enjoyable=objective_function, # Outline your ROI operate right here
x0=initial_guess, # Preliminary guesses for spends
bounds=bounds, # Channel-level finances constraints
constraints=constraints, # Equality and inequality constraints
technique='SLSQP'
)
print(consequence)

Das Schreiben von Budgetoptimierungscode von Grund auf ist eine komplexe, aber sehr lohnende Übung. Glücklicherweise die Pymc-Advertising Das Crew hat das starke Heben durchgeführt und bietet einen robusten Rahmen für die Ausführung von Budgetoptimierungsszenarien. Im nächsten Abschnitt werden wir untersuchen, wie ihr Paket den Budgetallokationsprozess optimieren und es für Analysten zugänglicher macht.

Jetzt verstehen wir, wie wir die Ausgabe von MMM verwenden können, um Budgets zu optimieren. Lassen Sie uns sehen, wie viel Wert wir mit unserem Modell aus dem letzten Artikel fahren können! In dieser Vorgehensweise werden wir abdecken:

  • Daten simulieren
  • Coaching des Modells
  • Validierung des Modells
  • Antwortkurven
  • Budgetoptimierung

3.1 Simulation von Daten

Wir werden den Datengeneratprozess aus dem ersten Artikel wiederverwenden. Wenn Sie eine Erinnerung an den Datengeneratprozess wünschen, schauen Sie sich den ersten Artikel an, in dem wir eine detaillierte Vorgehensweise gemacht haben:

np.random.seed(10)

# Set parameters for information generator
start_date = "2021-01-01"
durations = 52 * 3
channels = ("television", "social", "search")
adstock_alphas = (0.50, 0.25, 0.05)
saturation_lamdas = (1.5, 2.5, 3.5)
betas = (350, 150, 50)
spend_scalars = (10, 15, 20)

df = dg.data_generator(start_date, durations, channels, spend_scalars, adstock_alphas, saturation_lamdas, betas)

# Scale betas utilizing most gross sales worth - that is so it's akin to the fitted beta from pymc (pymc does characteristic and goal scaling utilizing MaxAbsScaler from sklearn)
betas_scaled = (
((df("tv_sales") / df("gross sales").max()) / df("tv_saturated")).imply(),
((df("social_sales") / df("gross sales").max()) / df("social_saturated")).imply(),
((df("search_sales") / df("gross sales").max()) / df("search_saturated")).imply()
)

# Calculate contributions
contributions = np.asarray((
spherical((df("tv_sales").sum() / df("gross sales").sum()), 2),
spherical((df("social_sales").sum() / df("gross sales").sum()), 2),
spherical((df("search_sales").sum() / df("gross sales").sum()), 2),
spherical((df("demand").sum() / df("gross sales").sum()), 2)
))

df(("date", "demand", "demand_proxy", "tv_spend_raw", "social_spend_raw", "search_spend_raw", "gross sales"))

Benutzergenerierte Bild

3.2 Coaching des Modells

Wir werden das Modell jetzt aus dem ersten Artikel neu ausbauen. Wir werden die Trainingsdaten auf die gleiche Weise wie beim letzten Mal vorbereiten von:

  • Daten in Funktionen und Ziel aufteilen.
  • Erstellen von Indizes für Zug- und Auszeitscheiben.

Da der Schwerpunkt dieses Artikels jedoch nicht auf der Modellkalibrierung liegt, werden wir die Nachfrage eher als Kontrollvariable als Demand_proxy einbeziehen. Dies bedeutet, dass das Modell sehr intestine kalibriert ist – obwohl dies nicht sehr realistisch ist, werden wir einige gute Ergebnisse erzielen, um zu veranschaulichen, wie wir Budgets optimieren können.

# set date column
date_col = "date"

# set consequence column
y_col = "gross sales"

# set advertising variables
channel_cols = ("tv_spend_raw",
"social_spend_raw",
"search_spend_raw")

# set management variables
control_cols = ("demand")

# create arrays
X = df((date_col) + channel_cols + control_cols)
y = df(y_col)

# set take a look at (out-of-sample) size
test_len = 8

# create practice and take a look at indexs
train_idx = slice(0, len(df) - test_len)
out_of_time_idx = slice(len(df) - test_len, len(df))

mmm_default = MMM(
adstock=GeometricAdstock(l_max=8),
saturation=LogisticSaturation(),
date_column=date_col,
channel_columns=channel_cols,
control_columns=control_cols,
)

fit_kwargs = {
"tune": 1_000,
"chains": 4,
"attracts": 1_000,
"target_accept": 0.9,
}

mmm_default.match(X(train_idx), y(train_idx), **fit_kwargs)

3.3 Validieren des Modells

Bevor wir uns mit der Optimierung befassen, überprüfen wir unser Modell intestine. Zuerst überprüfen wir die wahren Beiträge:

channels = np.array(("television", "social", "search", "demand"))

true_contributions = pd.DataFrame({'Channels': channels, 'Contributions': contributions})
true_contributions= true_contributions.sort_values(by='Contributions', ascending=False).reset_index(drop=True)
true_contributions = true_contributions.model.bar(subset=('Contributions'), shade='lightblue')

true_contributions

Benutzergenerierte Bild

Wie erwartet übereinstimmt unser Modell sehr eng auf die wahren Beiträge:

mmm_default.plot_waterfall_components_decomposition(figsize=(10,6));
Benutzergenerierte Bild

3.4 Antwortkurven

Bevor wir uns mit der Budgetoptimierung befassen, schauen wir uns die Antwortkurven an. Es gibt zwei Möglichkeiten, die Antwortkurven in der zu betrachten Pymc-Advertising Paket:

  1. Direkte Antwortkurven
  2. Reaktionskurven für Kostenanteile

Beginnen wir mit den direkten Antwortkurven. In den direkten Antwortkurven erstellen wir einfach ein Streudiagramm von wöchentlichen Ausgaben gegen den wöchentlichen Beitrag für jeden Kanal.

Nachfolgend zeichnen wir die direkten Antwortkurven auf:

fig = mmm_default.plot_direct_contribution_curves(show_fit=True, xlim_max=1.2)
(ax.set(xlabel="spend") for ax in fig.axes);
Benutzergenerierte Bild

Die Kosten für die Kosten für die Kosten für die Kosten für die Kosten sind eine various Möglichkeit, die Wirksamkeit von Kanälen zu vergleichen. Wenn δ = 1,0, bleibt der Kanalausgaben auf dem gleichen Niveau wie die Trainingsdaten. Wenn Δ = 1,2, wird der Kanalausgaben um 20percenterhöht.

Im Folgenden zeichnen wir die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten für die Kosten: Antwort:

mmm_default.plot_channel_contributions_grid(begin=0, cease=1.5, num=12, figsize=(15, 7));
Benutzergenerierte Bild

Wir können auch die X-Achse ändern, um absolute Ausgabenwerte zu zeigen:

mmm_default.plot_channel_contributions_grid(begin=0, cease=1.5, num=12, absolute_xrange=True, figsize=(15, 7));
Benutzergenerierte Bild

Die Antwortkurven sind großartige Werkzeuge, um die Planung zukünftiger Marketingbudgets auf Kanalebene zu erstellen. Lassen Sie sie als nächstes in die Handlung setzen und einige Budgetoptimierungsszenarien ausführen!

3.5 Budgetoptimierung

Lassen Sie uns zunächst ein paar Parameter einstellen:

  • perc_change: Dies wird verwendet, um die Einschränkung um Min und Max für jeden Kanal zu setzen. Diese Einschränkung hilft uns, das Szenario realistisch zu halten, und bedeutet, dass wir die Reaktionskurven nicht zu weit außerhalb dessen extrapolieren, was das Modell im Coaching gesehen hat.
  • Budget_len: Dies ist die Länge des Haushaltsszenarios in Wochen.

Wir werden zunächst die gewünschte Länge des Price range -Szenarios verwenden, um die jüngste Datenperiode auszuwählen.

perc_change = 0.20
budget_len = 12
budget_idx = slice(len(df) - test_len, len(df))
recent_period = X(budget_idx)(channel_cols)

recent_period

Benutzergenerierte Bild

Anschließend verwenden wir diesen letzten Zeitraum, um allgemeine Budgetbeschränkungen und Kanalbeschränkungen auf wöchentlicher Ebene festzulegen:

# set general finances constraint (to the closest £1k)
finances = spherical(recent_period.sum(axis=0).sum() / budget_len, -3)

# file the present finances break up by channel
current_budget_split = spherical(recent_period.imply() / recent_period.imply().sum(), 2)

# set channel degree constraints
lower_bounds = spherical(recent_period.min(axis=0) * (1 - perc_change))
upper_bounds = spherical(recent_period.max(axis=0) * (1 + perc_change))

budget_bounds = {
channel: (lower_bounds(channel), upper_bounds(channel))
for channel in channel_cols
}

print(f'General finances constraint: {finances}')
print('Channel constraints:')
for channel, bounds in budget_bounds.objects():
print(f' {channel}: Decrease Certain = {bounds(0)}, Higher Certain = {bounds(1)}')

Benutzergenerierte Bild

Jetzt ist es Zeit, unser Szenario zu betreiben! Wir füttern die relevanten Daten und Parameter und erhalten die optimalen Ausgaben zurück. Wir vergleichen es mit der Übernahme des Gesamtbudgets und der Aufteilung des aktuellen Price range -Cut up -Proportionen (die wir als tatsächliche Ausgaben bezeichnet haben).

model_granularity = "weekly"

# run situation
allocation_strategy, optimization_result = mmm_default.optimize_budget(
finances=finances,
num_periods=budget_len,
budget_bounds=budget_bounds,
minimize_kwargs={
"technique": "SLSQP",
"choices": {"ftol": 1e-9, "maxiter": 5_000},
},
)

response = mmm_default.sample_response_distribution(
allocation_strategy=allocation_strategy,
time_granularity=model_granularity,
num_periods=budget_len,
noise_level=0.05,
)

# extract optimum spend
opt_spend = pd.Sequence(allocation_strategy, index=recent_period.imply().index).to_frame(identify="opt_spend")
opt_spend("avg_spend") = finances * current_budget_split

# plot precise vs optimum spend
fig, ax = plt.subplots(figsize=(9, 4))
opt_spend.plot(type='barh', ax=ax, shade=('blue', 'orange'))

plt.xlabel("Spend")
plt.ylabel("Channel")
plt.title("Precise vs Optimum Spend by Channel")
plt.legend(("Optimum Spend", "Precise Spend"))
plt.legend(("Optimum Spend", "Precise Spend"), loc='decrease proper', bbox_to_anchor=(1.5, 0.0))

plt.present()

Benutzergenerierte Bild

Wir können sehen, dass der Vorschlag das Price range von digitalen Kanälen in das Fernsehen übertragen. Aber wie wirkt sich auf den Umsatz aus?

Um den Beitrag der optimalen Ausgaben zu berechnen, müssen wir den neuen Ausgabenwert professional Kanal sowie alle anderen Variablen im Modell einfügen. Wir haben nur eine Nachfrage, daher ernähren wir den Mittelwert aus der jüngsten Periode dafür. Wir werden auch den Beitrag der durchschnittlichen Ausgaben auf die gleiche Weise berechnen.

# create dataframe with optimum spend
last_date = mmm_default.X("date").max()
new_dates = pd.date_range(begin=last_date, durations=1 + budget_len, freq="W-MON")(1:)
budget_scenario_opt = pd.DataFrame({"date": new_dates,})
budget_scenario_opt("tv_spend_raw") = opt_spend("opt_spend")("tv_spend_raw")
budget_scenario_opt("social_spend_raw") = opt_spend("opt_spend")("social_spend_raw")
budget_scenario_opt("search_spend_raw") = opt_spend("opt_spend")("search_spend_raw")
budget_scenario_opt("demand") = X(budget_idx)(control_cols).imply()(0)

# calculate general contribution
scenario_contrib_opt = mmm_default.sample_posterior_predictive(
X_pred=budget_scenario_opt, extend_idata=False
)

opt_contrib = scenario_contrib_opt.imply(dim="pattern").sum()("y").values

# create dataframe with avg spend
last_date = mmm_default.X("date").max()
new_dates = pd.date_range(begin=last_date, durations=1 + budget_len, freq="W-MON")(1:)
budget_scenario_avg = pd.DataFrame({"date": new_dates,})
budget_scenario_avg("tv_spend_raw") = opt_spend("avg_spend")("tv_spend_raw")
budget_scenario_avg("social_spend_raw") = opt_spend("avg_spend")("social_spend_raw")
budget_scenario_avg("search_spend_raw") = opt_spend("avg_spend")("search_spend_raw")
budget_scenario_avg("demand") = X(budget_idx)(control_cols).imply()(0)

# calculate general contribution
scenario_contrib_avg = mmm_default.sample_posterior_predictive(
X_pred=budget_scenario_avg , extend_idata=False
)

avg_contrib = scenario_contrib_avg.imply(dim="pattern").sum()("y").values

# calculate % improve in gross sales
print(f'% improve in gross sales: {spherical((opt_contrib / avg_contrib) - 1, 2)}')

Benutzergenerierte Bild

Die optimalen Ausgaben verleihen uns einen Umsatzsteigerung von 6%! Das ist beeindruckend, vor allem, da wir das Gesamtbudget festgelegt haben!

Heute haben wir gesehen, wie leistungsstarke Budgetoptimierung sein kann. Es kann Organisationen mit monatlicher/vierteljährlicher/jährlicher Haushaltsplanung und Prognose helfen. Wie immer kommt der Schlüssel zu guten Empfehlungen zurück, um ein robustes, intestine kalibriertes Modell zu haben.

[ad_2]

]]>
https://chatgpz.de/machine-learning/optimieren-von-budgets-mit-advertising-combine-modellen-in-python-von-ryan-osullivan-januar-2025/feed/ 0 6801
Der Kompromiss zwischen Genauigkeit und Interpretierbarkeit ist eine Lüge | von Conor O’Sullivan | Okt. 2024 https://chatgpz.de/machine-learning/der-kompromiss-zwischen-genauigkeit-und-interpretierbarkeit-ist-eine-luege-von-conor-osullivan-okt-2024/ https://chatgpz.de/machine-learning/der-kompromiss-zwischen-genauigkeit-und-interpretierbarkeit-ist-eine-luege-von-conor-osullivan-okt-2024/#respond Wed, 16 Oct 2024 09:18:41 +0000 http://chatgpz.de/machine-learning/der-kompromiss-zwischen-genauigkeit-und-interpretierbarkeit-ist-eine-luege-von-conor-osullivan-okt-2024/ [ad_1]

Wenn wir das Gesamtbild betrachten, sind Black-Field-Modelle nicht genauer

Foto von Nathan Cima An Unsplash

Als ich als Datenwissenschaftler anfing, erwartete ich, modernste Modelle zu verwenden. XGBoost, Neuronale Netze. Diese Dinge sind komplex und interessant und würden sicherlich zu Verbesserungen führen. Ich wusste nicht, dass die Fashions vor einer Hürde standen – sie anderen Menschen zu erklären.

Wer hätte gedacht, dass Sie die Entscheidungen Ihrer automatisierten Systeme verstehen müssen?

Zu meiner Freude stolperte ich in den Kaninchenbau von Modellunabhängige Methoden. Damit könnte ich das Beste aus beiden Welten haben. Ich könnte Black-Field-Modelle trainieren und sie dann mit Methoden wie erklären Gestalten, KALK, PDPs, ALEs Und Friedmans H-Stat. Wir müssen Genauigkeit nicht mehr gegen Interpretierbarkeit eintauschen!

Nicht so schnell. Dieses Denken ist fehlerhaft.

Bei unserem Streben nach bester Leistung verfehlen wir oft den Sinn des maschinellen Lernens: genaue Vorhersagen auf der Grundlage neuer, unsichtbarer Daten zu treffen. Lassen Sie uns diskutieren, warum komplexe Modelle nicht immer der beste Weg sind, dies zu erreichen. Auch wenn wir sie mit anderen Methoden erklären können.

[ad_2]

]]>
https://chatgpz.de/machine-learning/der-kompromiss-zwischen-genauigkeit-und-interpretierbarkeit-ist-eine-luege-von-conor-osullivan-okt-2024/feed/ 0 4573
Validierung der kausalen Auswirkungen der synthetischen Kontrollmethode | von Ryan O’Sullivan | Juni 2024 https://chatgpz.de/machine-learning/validierung-der-kausalen-auswirkungen-der-synthetischen-kontrollmethode-von-ryan-osullivan-juni-2024/ https://chatgpz.de/machine-learning/validierung-der-kausalen-auswirkungen-der-synthetischen-kontrollmethode-von-ryan-osullivan-juni-2024/#respond Sun, 09 Jun 2024 04:26:01 +0000 http://chatgpz.de/machine-learning/validierung-der-kausalen-auswirkungen-der-synthetischen-kontrollmethode-von-ryan-osullivan-juni-2024/ [ad_1]

Kausale KI: Erforschung der Integration kausalen Denkens in maschinelles Lernen

Foto von Irina Inga An Unsplash

Willkommen zu meiner Serie über kausale KI, in der wir die Integration kausalen Denkens in Modelle des maschinellen Lernens untersuchen. Freuen Sie sich auf eine Reihe praktischer Anwendungen in unterschiedlichen Geschäftskontexten.

Im letzten Artikel behandelten wir Messung des intrinsischen kausalen Einflusses Ihrer Marketingkampagnen. In diesem Artikel werden wir uns mit Validierung der kausalen Wirkung der synthetischen Kontrollen.

Wenn Sie den letzten Artikel zum Thema intrinsischer kausaler Einfluss verpasst haben, können Sie ihn hier nachlesen:

In diesem Artikel konzentrieren wir uns auf das Verständnis der synthetischen Kontrollmethode und untersuchen, wie wir die geschätzten kausalen Auswirkungen validieren können.

Folgende Aspekte werden behandelt:

  • Was ist die synthetische Kontrollmethode?
  • Welche Herausforderung versucht es zu bewältigen?
  • Wie können wir die geschätzten kausalen Auswirkungen validieren?
  • Eine Python-Fallstudie mit realistischen Google-Trenddaten, die zeigt, wie wir die geschätzte kausale Auswirkung der synthetischen Kontrollen validieren können.

Das vollständige Notizbuch finden Sie hier:

Was ist es?

Die synthetische Kontrollmethode ist eine kausale Technik, die verwendet werden kann, um die kausale Wirkung einer Intervention oder Behandlung zu beurteilen, wenn eine randomisierte kontrollierte Studie (RCT) oder ein A/B-Check nicht möglich struggle. Sie wurde ursprünglich 2003 von Abadie und Gardezabal vorgeschlagen. Das folgende Dokument enthält eine großartige Fallstudie, die Ihnen dabei hilft, die vorgeschlagene Methode zu verstehen:

https://net.stanford.edu/~jhain/Paper/JASA2010.pdf

Vom Benutzer erstelltes Bild

Lassen Sie uns einige der Grundlagen selbst durchgehen … Die synthetische Kontrollmethode erstellt eine kontrafaktische Model der Behandlungseinheit, indem sie eine gewichtete Kombination von Kontrolleinheiten erstellt, die weder die Intervention noch die Behandlung erhalten haben.

  • Behandelte Einheit: Die Einheit, die die Intervention erhält.
  • Steuergeräte: Eine Reihe ähnlicher Einheiten, bei denen die Intervention nicht durchgeführt wurde.
  • Kontrafaktisch: Erstellt als gewichtete Kombination der Kontrolleinheiten. Ziel ist es, für jede Kontrolleinheit Gewichte zu finden, die zu einem kontrafaktischen Ergebnis führen, das der behandelten Einheit in der Zeit vor der Intervention möglichst nahe kommt.
  • Kausale Auswirkungen: Der Unterschied zwischen der Behandlungseinheit nach der Intervention und der kontrafaktischen Scenario.

Wenn wir die Dinge wirklich vereinfachen wollten, könnten wir es als lineare Regression betrachten, bei der jede Kontrolleinheit ein Merkmal und die Behandlungseinheit das Ziel ist. Der Zeitraum vor der Intervention ist unser Trainingssatz und wir verwenden das Modell, um unseren Zeitraum nach der Intervention zu bewerten. Der Unterschied zwischen dem tatsächlichen und dem vorhergesagten Wert ist die kausale Auswirkung.

Nachfolgend finden Sie einige Beispiele, die verdeutlichen, wann wir einen Einsatz in Betracht ziehen könnten:

  • Bei einer TV-Marketingkampagne können wir das Publikum nicht nach dem Zufallsprinzip in diejenigen einteilen, die die Kampagne sehen können und diejenigen, die sie nicht sehen können. Wir könnten jedoch sorgfältig eine Area auswählen, um die Kampagne zu testen, und die übrigen Regionen als Kontrolleinheiten verwenden. Sobald wir die Wirkung gemessen haben, könnte die Kampagne in anderen Regionen eingeführt werden. Dies wird oft als Geo-Carry-Check bezeichnet.
  • Politische Veränderungen, die in einigen Regionen eingeführt werden, in anderen jedoch nicht – Beispielsweise kann ein Gemeinderat eine politische Veränderung in Kraft setzen, um die Arbeitslosigkeit zu senken. Andere Regionen, in denen die Politik nicht umgesetzt wurde, könnten als Kontrolleinheiten dienen.

Welche Herausforderung versucht es zu bewältigen?

Wenn wir eine hohe Dimensionalität (viele Merkmale) mit begrenzten Beobachtungen kombinieren, kann ein überangepasstes Modell entstehen.

Nehmen wir zur Veranschaulichung das Beispiel des Geo-Lifts. Wenn wir wöchentliche Daten aus dem letzten Jahr als Zeitraum vor der Intervention verwenden, erhalten wir 52 Beobachtungen. Wenn wir uns dann entscheiden, unsere Intervention in mehreren Ländern Europas zu testen, erhalten wir ein Verhältnis von Beobachtung zu Merkmal von 1:1!

Wir haben bereits darüber gesprochen, wie die synthetische Kontrollmethode mithilfe einer linearen Regression implementiert werden könnte. Das Verhältnis von Beobachtung zu Merkmal bedeutet jedoch, dass es sehr wahrscheinlich ist, dass die lineare Regression überanpasst, was zu einer schlechten Schätzung der kausalen Auswirkungen in der Zeit nach der Intervention führt.

Bei der linearen Regression können die Gewichte (Koeffizienten) für jedes Merkmal (Kontrolleinheit) negativ oder positiv sein und ihre Summe kann eine Zahl größer als 1 ergeben. Die synthetische Kontrollmethode lernt die Gewichte jedoch unter Anwendung der folgenden Einschränkungen:

  • Beschränkung der Gewichte auf die Summe von 1
  • Gewichte müssen ≥ 0 sein
Vom Benutzer generiertes Bild

Diese Einschränkungen helfen bei der Regularisierung und vermeiden eine Extrapolation über den Bereich der beobachteten Daten hinaus.

Es ist erwähnenswert, dass Ridge- und Lasso-Regression dies in Bezug auf die Regularisierung erreichen können und in einigen Fällen sinnvolle Alternativen sind. Aber wir werden dies in der Fallstudie testen!

Wie können wir die geschätzten kausalen Auswirkungen validieren?

Eine wohl noch größere Herausforderung besteht in der Tatsache, dass wir die geschätzten kausalen Auswirkungen in der Zeit nach der Intervention nicht validieren können.

Wie lang sollte meine Vorinterventionsphase sein? Sind wir sicher, dass wir unsere Vorinterventionsphase nicht überangepasst haben? Wie können wir wissen, ob unser Modell in der Nachinterventionsphase intestine verallgemeinert werden kann? Was ist, wenn ich verschiedene Implementierungen der synthetischen Kontrollmethode ausprobieren möchte?

Wir könnten nach dem Zufallsprinzip einige Beobachtungen aus der Zeit vor der Intervention auswählen und sie zur Validierung zurückhalten. Doch wir haben bereits die Herausforderungen hervorgehoben, die sich aus der begrenzten Anzahl an Beobachtungen ergeben, sodass wir die Dinge möglicherweise sogar noch schlimmer machen!

Was wäre, wenn wir vor der Intervention eine Artwork Simulation durchführen könnten? Könnte uns das helfen, einige der oben hervorgehobenen Fragen zu beantworten und Vertrauen in die von unseren Modellen geschätzten kausalen Auswirkungen zu gewinnen? Alles wird in der Fallstudie erklärt!

Hintergrund

Nachdem Sie die Finanzabteilung davon überzeugt haben, dass Markenmarketing einen echten Mehrwert schafft, kommt das Marketingteam auf Sie zu und fragt Sie nach Geo-Carry-Exams. Jemand von Fb hat ihnen gesagt, dass das der nächste große Development ist (obwohl es dieselbe Particular person struggle, die ihnen gesagt hat, dass Prophet ein gutes Prognosemodell ist) und sie möchten wissen, ob sie es zur Messung ihrer neuen, bevorstehenden TV-Kampagne verwenden können.

Sie sind ein wenig besorgt, da das Marketinganalyseteam bei Ihrem letzten Geo-Carry-Check der Meinung struggle, es wäre eine gute Idee, mit dem verwendeten Vorinterventionszeitraum herumzuexperimentieren, bis ein schöner, großer kausaler Einfluss festgestellt würde.

Dieses Mal schlagen Sie vor, eine „Vorinterventionssimulation“ durchzuführen und anschließend vor Beginn des Exams den Vorinterventionszeitraum zu vereinbaren.

Sehen wir uns additionally an, wie eine „Simulation vor einer Intervention“ aussieht!

Erstellen der Daten

Um dies so realistisch wie möglich zu gestalten, habe ich einige Google-Trenddaten für die Mehrheit der europäischen Länder extrahiert. Der Suchbegriff ist nicht related. Tun Sie einfach so, als wäre es der Umsatz Ihres Unternehmens (und Sie sind in ganz Europa tätig).

Wenn Sie jedoch wissen möchten, wie ich an die Google-Trenddaten gekommen bin, sehen Sie sich mein Notizbuch an:

Unten sehen wir den Datenrahmen. Wir haben Verkäufe der letzten 3 Jahre in 50 europäischen Ländern. Das Marketingteam plant, seine TV-Kampagne in Großbritannien durchzuführen.

Vom Benutzer erstelltes Bild

Jetzt kommt der clevere Teil. Wir werden eine Intervention in den letzten 7 Wochen der Zeitreihe simulieren.

np.random.seed(1234)

# Create intervention flag
masks = (df('date') >= "2024-04-14") & (df('date') <= "2024-06-02")
df('intervention') = masks.astype(int)

row_count = len(df)

# Create intervention uplift
df('uplift_perc') = np.random.uniform(0.10, 0.20, measurement=row_count)
df('uplift_abs') = spherical(df('uplift_perc') * df('GB'))
df('y') = df('GB')
df.loc(df('intervention') == 1, 'y') = df('GB') + df('uplift_abs')

Lassen Sie uns nun die tatsächlichen und kontrafaktischen Verkäufe in ganz GB darstellen, um unsere Ergebnisse in die Praxis umzusetzen:

def synth_plot(df, counterfactual):

plt.determine(figsize=(14, 8))
sns.set_style("white")

# Create plot
sns.lineplot(information=df, x='date', y='y', label='Precise', shade='b', linewidth=2.5)
sns.lineplot(information=df, x='date', y=counterfactual, label='Counterfactual', shade='r', linestyle='--', linewidth=2.5)
plt.title('Artificial Management Technique: Precise vs. Counterfactual', fontsize=24)
plt.xlabel('Date', fontsize=20)
plt.ylabel('Metric Worth', fontsize=20)
plt.legend(fontsize=16)
plt.gca().xaxis.set_major_formatter(plt.matplotlib.dates.DateFormatter('%Y-%m-%d'))
plt.xticks(rotation=90)
plt.grid(True, linestyle='--', alpha=0.5)

# Excessive the intervention level
intervention_date = '2024-04-07'
plt.axvline(pd.to_datetime(intervention_date), shade='ok', linestyle='--', linewidth=1)
plt.textual content(pd.to_datetime(intervention_date), plt.ylim()(1)*0.95, 'Intervention', shade='ok', fontsize=18, ha='proper')

plt.tight_layout()
plt.present()

synth_plot(df, 'GB')
Vom Benutzer erstelltes Bild

Nachdem wir nun eine Intervention simuliert haben, können wir untersuchen, wie intestine die synthetische Kontrollmethode funktioniert.

Vorverarbeitung

Alle europäischen Länder außer GB werden als Kontrolleinheiten (Merkmale) festgelegt. Die Behandlungseinheit (Ziel) ist der Umsatz in GB mit der angewandten Intervention.

# Delete the unique goal column so we do not use it as a function by chance
del df('GB')

# set function & targets
X = df.columns(1:50)
y = 'y'

Regression

Unten habe ich eine Funktion eingerichtet, die wir mit verschiedenen Vorinterventionszeiträumen und verschiedenen Regressionsmodellen (z. B. Ridge, Lasso) wiederverwenden können:

def train_reg(df, start_index, reg_class):

df_temp = df.iloc(start_index:).copy().reset_index()

X_pre = df_temp(df_temp('intervention') == 0)(X)
y_pre = df_temp(df_temp('intervention') == 0)(y)

X_train, X_test, y_train, y_test = train_test_split(X_pre, y_pre, test_size=0.10, random_state=42)

mannequin = reg_class
mannequin.match(X_train, y_train)

yhat_train = mannequin.predict(X_train)
yhat_test = mannequin.predict(X_test)

mse_train = mean_squared_error(y_train, yhat_train)
mse_test = mean_squared_error(y_test, yhat_test)
print(f"Imply Squared Error practice: {spherical(mse_train, 2)}")
print(f"Imply Squared Error check: {spherical(mse_test, 2)}")

r2_train = r2_score(y_train, yhat_train)
r2_test = r2_score(y_test, yhat_test)
print(f"R2 practice: {spherical(r2_train, 2)}")
print(f"R2 check: {spherical(r2_test, 2)}")

df_temp('pred') = mannequin.predict(df_temp.loc(:, X))
df_temp('delta') = df_temp('y') - df_temp('pred')

pred_lift = df_temp(df_temp('intervention') == 1)('delta').sum()
actual_lift = df_temp(df_temp('intervention') == 1)('uplift_abs').sum()
abs_error_perc = abs(pred_lift - actual_lift) / actual_lift
print(f"Predicted carry: {spherical(pred_lift, 2)}")
print(f"Precise carry: {spherical(actual_lift, 2)}")
print(f"Absolute error share: {spherical(abs_error_perc, 2)}")

return df_temp, abs_error_perc

Zu Beginn halten wir es einfach und verwenden eine lineare Regression, um die kausalen Auswirkungen anhand einer kurzen Vorinterventionsphase abzuschätzen:

df_lin_reg_100, pred_lift_lin_reg_100 = train_reg(df, 100, LinearRegression())
Vom Benutzer erstelltes Bild

Betrachtet man die Ergebnisse, schneidet die lineare Regression nicht besonders intestine ab. Aber das ist angesichts des Verhältnisses von Beobachtung zu Merkmal nicht überraschend.

synth_plot(df_lin_reg_100, 'pred')
Vom Benutzer erstelltes Bild

Synthetische Kontrollmethode

Lassen Sie uns direkt loslegen und sehen, wie es im Vergleich zur synthetischen Kontrollmethode abschneidet. Unten habe ich eine ähnliche Funktion wie zuvor eingerichtet, aber die synthetische Kontrollmethode mithilfe von sciPy angewendet:

def synthetic_control(weights, control_units, treated_unit):

artificial = np.dot(control_units.values, weights)

return np.sqrt(np.sum((treated_unit - artificial)**2))

def train_synth(df, start_index):

df_temp = df.iloc(start_index:).copy().reset_index()

X_pre = df_temp(df_temp('intervention') == 0)(X)
y_pre = df_temp(df_temp('intervention') == 0)(y)

X_train, X_test, y_train, y_test = train_test_split(X_pre, y_pre, test_size=0.10, random_state=42)

initial_weights = np.ones(len(X)) / len(X)

constraints = ({'kind': 'eq', 'enjoyable': lambda w: np.sum(w) - 1})

bounds = ((0, 1) for _ in vary(len(X)))

consequence = decrease(synthetic_control,
initial_weights,
args=(X_train, y_train),
technique='SLSQP',
bounds=bounds,
constraints=constraints,
choices={'disp': False, 'maxiter': 1000, 'ftol': 1e-9},
)

optimal_weights = consequence.x

yhat_train = np.dot(X_train.values, optimal_weights)
yhat_test = np.dot(X_test.values, optimal_weights)

mse_train = mean_squared_error(y_train, yhat_train)
mse_test = mean_squared_error(y_test, yhat_test)
print(f"Imply Squared Error practice: {spherical(mse_train, 2)}")
print(f"Imply Squared Error check: {spherical(mse_test, 2)}")

r2_train = r2_score(y_train, yhat_train)
r2_test = r2_score(y_test, yhat_test)
print(f"R2 practice: {spherical(r2_train, 2)}")
print(f"R2 check: {spherical(r2_test, 2)}")

df_temp('pred') = np.dot(df_temp.loc(:, X).values, optimal_weights)
df_temp('delta') = df_temp('y') - df_temp('pred')

pred_lift = df_temp(df_temp('intervention') == 1)('delta').sum()
actual_lift = df_temp(df_temp('intervention') == 1)('uplift_abs').sum()
abs_error_perc = abs(pred_lift - actual_lift) / actual_lift
print(f"Predicted carry: {spherical(pred_lift, 2)}")
print(f"Precise carry: {spherical(actual_lift, 2)}")
print(f"Absolute error share: {spherical(abs_error_perc, 2)}")

return df_temp, abs_error_perc

Ich lasse den Zeitraum vor der Intervention unverändert, um einen fairen Vergleich mit der linearen Regression zu ermöglichen:

df_synth_100, pred_lift_synth_100 = train_synth(df, 100)
Vom Benutzer erstelltes Bild

Wow! Ich gebe zu, dass ich mit einer so deutlichen Verbesserung nicht gerechnet habe!

synth_plot(df_synth_100, 'pred')
Vom Benutzer erstelltes Bild

Vergleich der Ergebnisse

Lassen Sie uns noch nicht zu weit ausholen. Im Folgenden führen wir noch ein paar Experimente durch, in denen wir Modelltypen und Zeiträume vor der Intervention untersuchen:

# run regression experiments
df_lin_reg_00, pred_lift_lin_reg_00 = train_reg(df, 0, LinearRegression())
df_lin_reg_100, pred_lift_lin_reg_100 = train_reg(df, 100, LinearRegression())
df_ridge_00, pred_lift_ridge_00 = train_reg(df, 0, RidgeCV())
df_ridge_100, pred_lift_ridge_100 = train_reg(df, 100, RidgeCV())
df_lasso_00, pred_lift_lasso_00 = train_reg(df, 0, LassoCV())
df_lasso_100, pred_lift_lasso_100 = train_reg(df, 100, LassoCV())

# run artificial management experiments
df_synth_00, pred_lift_synth_00 = train_synth(df, 0)
df_synth_100, pred_lift_synth_100 = train_synth(df, 100)

experiment_data = {
"Technique": ("Linear", "Linear", "Ridge", "Ridge", "Lasso", "Lasso", "Artificial Management", "Artificial Management"),
"Information Measurement": ("Massive", "Small", "Massive", "Small", "Massive", "Small", "Massive", "Small"),
"Worth": (pred_lift_lin_reg_00, pred_lift_lin_reg_100, pred_lift_ridge_00, pred_lift_ridge_100,pred_lift_lasso_00, pred_lift_lasso_100, pred_lift_synth_00, pred_lift_synth_100)
}

df_experiments = pd.DataFrame(experiment_data)

Wir verwenden den folgenden Code, um die Ergebnisse zu visualisieren:

# Set the model
sns.set_style="whitegrid"

# Create the bar plot
plt.determine(figsize=(10, 6))
bar_plot = sns.barplot(x="Technique", y="Worth", hue="Information Measurement", information=df_experiments, palette="muted")

# Add labels and title
plt.xlabel("Technique")
plt.ylabel("Absolute error share")
plt.title("Artificial Controls - Comparability of Strategies Throughout Totally different Information Sizes")
plt.legend(title="Information Measurement")

# Present the plot
plt.present()

Vom Benutzer erstelltes Bild

Die Ergebnisse für den kleinen Datensatz sind wirklich interessant! Wie erwartet hat die Regularisierung geholfen, die Schätzungen der kausalen Auswirkungen zu verbessern. Die synthetische Kontrolle ging dann noch einen Schritt weiter!

Die Ergebnisse des großen Datensatzes legen nahe, dass längere Zeiträume vor der Intervention nicht immer besser sind.

Ich möchte Ihnen jedoch zeigen, wie wertvoll die Durchführung einer Simulation vor der Intervention ist. Es gibt so viele Möglichkeiten, die Sie mit Ihrem eigenen Datensatz erkunden könnten!

Heute haben wir uns mit der synthetischen Kontrollmethode beschäftigt und wie Sie die kausalen Auswirkungen validieren können. Ich möchte Ihnen noch ein paar abschließende Gedanken mit auf den Weg geben:

  • Aufgrund ihrer Einfachheit ist die synthetische Steuerungsmethode eine der am häufigsten eingesetzten Techniken aus dem Werkzeugkasten der kausalen KI.
  • Leider wird dieser Wert auch am häufigsten missbraucht. Lassen Sie uns das R CausalImpact-Paket ausführen und den Zeitraum vor der Intervention ändern, bis wir eine Steigerung sehen, die uns gefällt. 😭
  • Aus diesem Grund empfehle ich dringend, vor der Intervention Simulationen durchzuführen, um das Testdesign im Voraus zu vereinbaren.
  • Die synthetische Kontrollmethode ist ein intensiv erforschter Bereich. Es lohnt sich, die vorgeschlagenen Anpassungen Augmented SC, Strong SC und Penalized SC zu prüfen.

Alberto Abadie, Alexis Diamond und Jens Hainmueller (2010) Synthetische Kontrollmethoden für vergleichende Fallstudien: Schätzung der Auswirkungen des kalifornischen Tabakkontrollprogramms, Journal of the American Statistical Affiliation, 105:490, 493–505, DOI: 10.1198/jasa.2009.ap08746

[ad_2]

]]>
https://chatgpz.de/machine-learning/validierung-der-kausalen-auswirkungen-der-synthetischen-kontrollmethode-von-ryan-osullivan-juni-2024/feed/ 0 1273