[ad_1]
Chào mừng bạn đến với loạt bài của tôi về AI nhân quả, nơi chúng ta sẽ khám phá sự tích hợp lý luận nhân quả vào các mô hình học máy. Mong đợi khám phá một số ứng dụng thực tế trên các bối cảnh kinh doanh khác nhau.
Trong bài viết trước chúng tôi đã đề cập sử dụng Double Machine Studying và Lập trình tuyến tính để tối ưu hóa chiến lược điều trị. Lần này chúng ta sẽ tiếp tục với chủ đề khám phá tối ưu hóa tối ưu hóa hiệu quả xử lý phi tuyến tính trong Định giá & Khuyến mãi.
Nếu bạn bỏ lỡ bài viết cuối cùng về Double Machine Studying và Linear Programming, hãy xem thử tại đây:
Bài viết này sẽ giới thiệu cách chúng tôi có thể tối ưu hóa hiệu quả xử lý phi tuyến tính trong việc định giá (nhưng các ý tưởng này cũng có thể được áp dụng trên các lĩnh vực tiếp thị và các lĩnh vực khác).
Trong bài viết này tôi sẽ giúp bạn hiểu:
- Tại sao việc định giá lại có tác động xử lý phi tuyến tính?
- Những công cụ nào trong hộp công cụ AI nguyên nhân của chúng tôi phù hợp để ước tính hiệu quả điều trị phi tuyến tính?
- Lập trình phi tuyến tính có thể được sử dụng như thế nào để tối ưu hóa việc định giá?
- Một nghiên cứu điển hình đã hoạt động bằng Python tìm hiểu cách chúng tôi có thể kết hợp hộp công cụ AI nhân quả và lập trình phi tuyến tính để tối ưu hóa ngân sách định giá.
Sổ ghi chép đầy đủ có thể được tìm thấy ở đây:
Lợi nhuận giảm dần
Hãy lấy ví dụ về một nhà bán lẻ điều chỉnh giá của một sản phẩm. Ban đầu, việc giảm giá có thể dẫn đến doanh số bán hàng tăng lên đáng kể. Tuy nhiên, khi họ tiếp tục giảm giá, mức tăng doanh số bán hàng có thể bắt đầu chững lại. Chúng tôi gọi đây là lợi nhuận giảm dần. Như minh họa dưới đây, ảnh hưởng của lợi nhuận giảm dần nói chung là phi tuyến tính.
Lợi nhuận giảm dần có thể được quan sát trên nhiều lĩnh vực khác nhau ngoài giá cả. Một số ví dụ phổ biến là:
- Tiếp thị – Việc tăng chi tiêu cho truyền thông xã hội có thể tăng khả năng thu hút khách hàng, nhưng theo thời gian, việc nhắm mục tiêu đến những đối tượng mới, chưa được khai thác sẽ trở nên khó khăn hơn.
- Trồng trọt – Việc bổ sung phân bón vào ruộng có thể làm tăng năng suất cây trồng đáng kể ban đầu, nhưng tác dụng này sẽ nhanh chóng giảm đi.
- Sản xuất – Việc bổ sung thêm nhiều công nhân vào quy trình sản xuất sẽ nâng cao hiệu quả, nhưng mỗi công nhân bổ sung có thể đóng góp ít hơn vào tổng sản lượng.
Điều này khiến tôi bắt đầu tự hỏi, nếu lợi nhuận giảm dần phổ biến đến vậy, thì kỹ thuật nào trong hộp công cụ AI Nhân quả của chúng tôi có khả năng xử lý vấn đề này?
Hộp công cụ
Có hai câu hỏi chính mà chúng tôi sẽ đặt ra để giúp xác định phương pháp nào từ hộp công cụ AI nhân quả phù hợp với vấn đề Định giá của chúng tôi:
- Nó có thể xử lý các phương pháp điều trị liên tục?
- Nó có thể nắm bắt được hiệu quả điều trị phi tuyến tính không?
Dưới đây chúng ta có thể thấy một bản tóm tắt về mức độ phù hợp của từng phương pháp:
- So sánh điểm xu hướng (PSM) – Việc điều trị cần phải ở dạng nhị phân ❌
- Đối sánh điểm xu hướng nghịch đảo (IPSM) – Việc điều trị cần phải ở dạng nhị phân ❌
- T-Learner — Việc điều trị cần phải nhị phân ❌
- Học máy kép (DML) — Hiệu quả điều trị là tuyến tính ❌
- Người học mạnh mẽ gấp đôi (DR) – Việc điều trị cần phải ở dạng nhị phân ❌
- S-Learner – Có thể xử lý các phương pháp điều trị liên tục và các mối quan hệ phi tuyến tính giữa phương pháp điều trị và kết quả nếu sử dụng thuật toán học máy thích hợp (ví dụ: tăng cường độ dốc) 💚
S-Learner
Chữ “S” trong S-Learner xuất phát từ việc nó là một “mô hình duy nhất”. Một mô hình học máy tùy ý được sử dụng để dự đoán kết quả bằng cách sử dụng phương pháp điều trị, các yếu tố gây nhiễu và các biến số khác làm đặc điểm. Sau đó, mô hình này được sử dụng để ước tính sự khác biệt giữa các kết quả có thể xảy ra trong các điều kiện điều trị khác nhau (điều này mang lại cho chúng ta hiệu quả điều trị).
Một số lợi ích dành cho S-Learner:
- Nó có thể xử lý cả phương pháp điều trị nhị phân và liên tục.
- Nó có thể sử dụng bất kỳ thuật toán học máy nào, giúp chúng tôi linh hoạt nắm bắt các mối quan hệ phi tuyến tính cho cả đặc điểm và phương pháp điều trị.
Một lời cảnh báo: thiên vị chính quy hóa! Các thuật toán học máy hiện đại sử dụng tính năng chính quy hóa để ngăn chặn tình trạng trang bị quá mức – nhưng điều này có thể gây tổn hại đến các vấn đề nguyên nhân. Lấy siêu tham số tính năng tối đa từ các phương pháp cây tăng cường độ dốc – ở một số cây, có khả năng việc xử lý sẽ không được đưa vào mô hình. Điều này sẽ làm giảm tác dụng của việc điều trị.
Khi sử dụng S-Learner, tôi khuyên bạn nên suy nghĩ kỹ về các tham số chính quy hóa, ví dụ như đặt tính năng tối đa thành 1.0 (tắt tính năng chính quy hóa tính năng một cách hiệu quả).
Tối ưu hóa giá
Giả sử chúng tôi có một số sản phẩm và muốn tối ưu hóa giá của chúng với ngân sách khuyến mại đã đặt. Đối với mỗi sản phẩm, chúng tôi đào tạo một S-Learner (sử dụng tính năng tăng cường độ dốc) với cách xử lý được đặt là mức chiết khấu và kết quả được đặt là tổng số đơn đặt hàng. S-Leaners của chúng tôi đưa ra một mô hình phức tạp có thể được sử dụng để ước tính tác động của các mức chiết khấu khác nhau. Nhưng làm thế nào để tối ưu hóa mức chiết khấu cho từng sản phẩm?
Đường cong phản ứng
Các kỹ thuật tối ưu hóa như lập trình tuyến tính (hoặc thậm chí phi tuyến tính) dựa vào việc có một dạng phản hồi rõ ràng. Các kỹ thuật học máy như rừng ngẫu nhiên và tăng cường độ dốc không mang lại cho chúng ta điều này (không giống như hồi quy tuyến tính). Tuy nhiên, đường cong phản hồi có thể chuyển kết quả đầu ra của S-Learner thành dạng toàn diện, cho thấy kết quả phản ứng như thế nào với phương pháp điều trị.
Nếu bạn chưa thể hình dung rõ cách chúng ta có thể tạo đường cong phản hồi, đừng lo lắng, chúng tôi sẽ đề cập đến vấn đề này trong nghiên cứu điển hình về Python!
Phương trình Michaelis-Menton
Có một số phương trình mà chúng ta có thể sử dụng để ánh xạ S-Learner tới một đường cong phản hồi. Một trong số đó là phương trình Micaelis-Menton.
Phương trình Micaelis-Menton thường được sử dụng trong động học enzyme (nghiên cứu tốc độ enzyme xúc tác các phản ứng hóa học) để mô tả tốc độ phản ứng enzyme.
- v — là tốc độ phản ứng (đây là phản ứng được chuyển đổi của chúng tôi, do đó, tổng số đơn đặt hàng trong ví dụ về giá của chúng tôi)
- Vmax – là tốc độ phản ứng tối đa (chúng ta sẽ gọi đây là alpha, một thông số chúng ta cần tìm hiểu)
- Km – là nồng độ cơ chất (chúng ta sẽ gọi đây là lambda, một thông số chúng ta cần tìm hiểu)
- S — là hằng số Michaelis (đây là cách xử lý của chúng tôi, vì vậy mức chiết khấu trong ví dụ về giá của chúng tôi)
Nguyên tắc của nó cũng có thể được áp dụng cho các lĩnh vực khác, đặc biệt khi xử lý các hệ thống mà việc tăng đầu vào không làm tăng đầu ra theo tỷ lệ do các yếu tố bão hòa. Dưới đây chúng tôi hình dung các giá trị khác nhau của alpha và lamda ảnh hưởng đến đường cong như thế nào:
def michaelis_menten(x, alpha, lam):
return alpha * x / (lam + x)
Sau khi có đường cong phản hồi, tiếp theo chúng ta có thể nghĩ đến việc tối ưu hóa. Micaelis-Menton cho chúng ta một hàm phi tuyến tính. Vì vậy lập trình phi tuyến tính là một lựa chọn thích hợp.
Lập trình phi tuyến tính
Chúng tôi đã đề cập đến lập trình tuyến tính trong bài viết trước của tôi. Lập trình phi tuyến tính cũng tương tự nhưng hàm mục tiêu và/hoặc các ràng buộc về bản chất là phi tuyến tính.
Lập trình bình phương tối thiểu tuần tự (SLSQP) là một thuật toán được sử dụng để giải các bài toán lập trình phi tuyến tính. Nó cho phép cả các ràng buộc về bình đẳng và bất bình đẳng, khiến nó trở thành một lựa chọn hợp lý cho trường hợp sử dụng của chúng tôi.
- Ràng buộc về bình đẳng, ví dụ: Tổng ngân sách quảng cáo bằng £100k
- Hạn chế về bất bình đẳng, ví dụ Giảm giá cho mỗi sản phẩm từ £1 đến £10
SciPy có cách triển khai SLSQP dễ sử dụng:
Tiếp theo, chúng tôi sẽ minh họa mức độ hiệu quả của sự kết hợp giữa phương trình S-Learner, Micaelis-Menton và lập trình phi tuyến tính!
Lý lịch
Trong lịch sử, các nhóm khuyến mại đã sử dụng phán đoán chuyên môn của mình để đưa ra mức giảm giá cho 3 sản phẩm hàng đầu của họ. Với điều kiện kinh tế hiện tại, họ buộc phải giảm 20% ngân sách quảng cáo tổng thể. Họ tìm đến nhóm Khoa học dữ liệu để tư vấn cách họ có thể thực hiện việc này đồng thời giảm thiểu tổn thất trong các đơn đặt hàng.
Quá trình tạo dữ liệu
Chúng tôi thiết lập quy trình tạo dữ liệu với các đặc điểm sau:
- 4 đặc điểm có mối quan hệ phức tạp với số lượng đơn hàng
- Hiệu quả điều trị tuân theo phương trình Micaelis-Menton
def data_generator(n, tau_weight, alpha, lam):# Set variety of options
p=4
# Create options
X = np.random.uniform(measurement=n * p).reshape((n, -1))
# Nuisance parameters
b = (
np.sin(np.pi * X(:, 0))
+ 2 * (X(:, 1) - 0.5) ** 2
+ X(:, 2) * X(:, 3)
)
# Create therapy and therapy impact
T = np.linspace(200, 10000, n)
T_mm = michaelis_menten(T, alpha, lam) * tau_weight
tau = T_mm / T
# Calculate end result
y = b + T * tau + np.random.regular(measurement=n) * 0.5
y_train = y
X_train = np.hstack((X, T.reshape(-1, 1)))
return y_train, X_train, T_mm, tau
Các tính năng X là các biến gây nhiễu:
Chúng tôi sử dụng trình tạo dữ liệu để tạo mẫu cho 3 sản phẩm, mỗi sản phẩm có tác dụng điều trị khác nhau:
np.random.seed(1234)n=100000
y_train_1, X_train_1, T_mm_1, tau_1 = data_generator(n, 1.00, 2, 5000)
y_train_2, X_train_2, T_mm_2, tau_2 = data_generator(n, 0.25, 2, 5000)
y_train_3, X_train_3, T_mm_3, tau_3 = data_generator(n, 2.00, 2, 5000)
S-Learner
Chúng tôi có thể đào tạo S-Learner bằng cách sử dụng bất kỳ thuật toán học máy nào và bao gồm việc xử lý và hiệp phương sai dưới dạng các tính năng:
def train_slearner(X_train, y_train):mannequin = LGBMRegressor(random_state=42)
mannequin.match(X_train, y_train)
yhat_train = mannequin.predict(X_train)
mse_train = mean_squared_error(y_train, yhat_train)
r2_train = r2_score(y_train, yhat_train)
print(f'MSE on prepare set is {spherical(mse_train)}')
print(f'R2 on prepare set is {spherical(r2_train, 2)}')
return mannequin, yhat_train
Chúng tôi đào tạo S-Learner cho từng sản phẩm:
np.random.seed(1234)model_1, yhat_train_1 = train_slearner(X_train_1, y_train_1)
model_2, yhat_train_2 = train_slearner(X_train_2, y_train_2)
model_3, yhat_train_3 = train_slearner(X_train_3, y_train_3)
Hiện tại đây chỉ là một mô hình dự đoán – Dưới đây chúng tôi hình dung nó hoạt động tốt như thế nào trong công việc này:
Trích xuất tác dụng điều trị
Tiếp theo, chúng tôi sẽ sử dụng S-learner để trích xuất hiệu quả điều trị cho toàn bộ phạm vi giá trị điều trị (số tiền chiết khấu) trong khi giữ các đặc điểm khác ở giá trị trung bình của chúng.
Chúng tôi bắt đầu bằng cách trích xuất kết quả mong đợi (số lượng chỉ định) cho toàn bộ phạm vi giá trị điều trị:
def extract_treated_effect(n, X_train, mannequin):# Set options to imply worth
X_mean_mapping = {'X1': (X_train(:, 0).imply()) * n,
'X2': (X_train(:, 1).imply()) * n,
'X3': (X_train(:, 2).imply()) * n,
'X4': (X_train(:, 3).imply()) * n}
# Create DataFrame
df_scoring = pd.DataFrame(X_mean_mapping)
# Add full vary of therapy values
df_scoring('T') = X_train(:, 4).reshape(-1, 1)
# Calculate end result prediction for handled
handled = mannequin.predict(df_scoring)
return handled, df_scoring
Chúng tôi thực hiện việc này cho từng sản phẩm:
treated_1, df_scoring_1 = extract_treated_effect(n, X_train_1, model_1)
treated_2, df_scoring_2 = extract_treated_effect(n, X_train_2, model_2)
treated_3, df_scoring_3 = extract_treated_effect(n, X_train_3, model_3)
Sau đó, chúng tôi trích xuất kết quả mong đợi (số lượng lệnh) khi xử lý được đặt thành 0:
def extract_untreated_effect(n, X_train, mannequin):# Set options to imply worth
X_mean_mapping = {'X1': (X_train(:, 0).imply()) * n,
'X2': (X_train(:, 1).imply()) * n,
'X3': (X_train(:, 2).imply()) * n,
'X4': (X_train(:, 3).imply()) * n,
'T': (0) * n}
# Create DataFrame
df_scoring = pd.DataFrame(X_mean_mapping)
# Add full vary of therapy values
df_scoring
# Calculate end result prediction for handled
untreated = mannequin.predict(df_scoring)
return untreated
Một lần nữa, chúng tôi làm điều này cho từng sản phẩm:
untreated_1 = extract_untreated_effect(n, X_train_1, model_1)
untreated_2 = extract_untreated_effect(n, X_train_2, model_2)
untreated_3 = extract_untreated_effect(n, X_train_3, model_3)
Bây giờ chúng ta có thể tính toán hiệu quả can thiệp cho toàn bộ các giá trị can thiệp:
treatment_effect_1 = treated_1 - untreated_1
treatment_effect_2 = treated_2 - untreated_2
treatment_effect_3 = treated_3 - untreated_3
Khi so sánh kết quả này với hiệu quả điều trị thực tế mà chúng tôi đã lưu từ trình tạo dữ liệu, chúng tôi có thể thấy S-Learner rất hiệu quả trong việc ước tính hiệu quả điều trị cho toàn bộ phạm vi giá trị điều trị:
Bây giờ chúng ta có dữ liệu về hiệu quả điều trị này, chúng ta có thể sử dụng nó để xây dựng đường cong phản ứng cho từng sản phẩm.
Michaelis-Menton
Để xây dựng các đường cong phản hồi, chúng ta cần một công cụ khớp đường cong. SciPy có một triển khai tuyệt vời mà chúng tôi sẽ sử dụng:
Chúng tôi bắt đầu bằng cách thiết lập chức năng mà chúng tôi muốn tìm hiểu:
def michaelis_menten(x, alpha, lam):
return alpha * x / (lam + x)
Sau đó, chúng ta có thể sử dụng Curve_fit để tìm hiểu các tham số alpha và lambda:
def response_curves(treatment_effect, df_scoring):maxfev = 100000
lam_initial_estimate = 0.001
alpha_initial_estimate = max(treatment_effect)
initial_guess = (alpha_initial_estimate, lam_initial_estimate)
popt, pcov = curve_fit(michaelis_menten, df_scoring('T'), treatment_effect, p0=initial_guess, maxfev=maxfev)
return popt, pcov
Chúng tôi thực hiện việc này cho từng sản phẩm:
popt_1, pcov_1 = response_curves(treatment_effect_1, df_scoring_1)
popt_2, pcov_2 = response_curves(treatment_effect_2, df_scoring_2)
popt_3, pcov_3 = response_curves(treatment_effect_3, df_scoring_3)
Bây giờ chúng ta có thể đưa các tham số đã học vào hàm michaelis menten để giúp chúng ta hình dung việc khớp đường cong đã hoạt động tốt như thế nào:
treatment_effect_curve_1 = michaelis_menten(df_scoring_1('T'), popt_1(0), popt_1(1))
treatment_effect_curve_2 = michaelis_menten(df_scoring_2('T'), popt_2(0), popt_2(1))
treatment_effect_curve_3 = michaelis_menten(df_scoring_3('T'), popt_3(0), popt_3(1))
Chúng ta có thể thấy rằng việc lắp đường cong đã làm rất tốt!
Bây giờ chúng ta đã có thông số alpha và lambda cho từng sản phẩm, chúng ta có thể bắt đầu nghĩ đến việc tối ưu hóa phi tuyến tính…
Lập trình phi tuyến tính
Chúng tôi bắt đầu bằng cách thiết lập đối chiếu tất cả các thông tin cần thiết để tối ưu hóa:
- Một danh sách tất cả các sản phẩm
- Tổng ngân sách khuyến mãi
- Ngân sách dành cho từng sản phẩm
- Các thông số cho từng sản phẩm từ đường cong phản ứng Michaelis Menten
# Checklist of merchandise
merchandise = ("product_1", "product_2", "product_3")# Set whole finances to be the sum of the imply of every product diminished by 20%
total_budget = (df_scoring_1('T').imply() + df_scoring_2('T').imply() + df_scoring_3('T').imply()) * 0.80
# Dictionary with min and max bounds for every product - set as +/-20% of max/min low cost
budget_ranges = {"product_1": (df_scoring_1('T').min() * 0.80, df_scoring_1('T').max() * 1.2),
"product_2": (df_scoring_2('T').min() * 0.80, df_scoring_2('T').max() * 1.2),
"product_3": (df_scoring_3('T').min() * 0.80, df_scoring_3('T').max() * 1.2)}
# Dictionary with response curve parameters
parameters = {"product_1": (popt_1(0), popt_1(1)),
"product_2": (popt_2(0), popt_2(1)),
"product_3": (popt_3(0), popt_3(1))}
Tiếp theo, chúng tôi thiết lập hàm mục tiêu – Chúng tôi muốn tối đa hóa các đơn hàng nhưng vì chúng tôi sẽ sử dụng phương pháp tối thiểu hóa, chúng tôi trả về số âm của tổng đơn hàng dự kiến.
def objective_function(x, merchandise, parameters):sum_orders = 0.0
# Unpack parameters for every product and calculate anticipated orders
for product, finances in zip(merchandise, x, strict=False):
L, okay = parameters(product)
sum_orders += michaelis_menten(finances, L, okay)
return -1 * sum_orders
Cuối cùng, chúng ta có thể chạy tối ưu hóa để xác định ngân sách tối ưu để phân bổ cho từng sản phẩm:
# Set preliminary guess by equally sharing out the overall finances
initial_guess = (total_budget // len(merchandise)) * len(merchandise)# Set the decrease and higher bounds for every product
bounds = (budget_ranges(product) for product in merchandise)
# Set the equality constraint - constraining the overall finances
constraints = {"sort": "eq", "enjoyable": lambda x: np.sum(x) - total_budget}
# Run optimisation
outcome = reduce(
lambda x: objective_function(x, merchandise, parameters),
initial_guess,
technique="SLSQP",
bounds=bounds,
constraints=constraints,
choices={'disp': True, 'maxiter': 1000, 'ftol': 1e-9},
)
# Extract outcomes
optimal_treatment = {product: finances for product, finances in zip(merchandise, outcome.x, strict=False)}
print(f'Optimum promo finances allocations: {optimal_treatment}')
print(f'Optimum orders: {spherical(outcome.enjoyable * -1, 2)}')
Kết quả đầu ra cho chúng ta biết ngân sách khuyến mại tối ưu cho mỗi sản phẩm là bao nhiêu:
Nếu bạn kiểm tra chặt chẽ các đường cong phản hồi, bạn sẽ thấy rằng kết quả tối ưu hóa là trực quan:
- Giảm nhẹ ngân sách cho sản phẩm 1
- Giảm đáng kể ngân sách cho sản phẩm 2
- Tăng ngân sách cho sản phẩm 3 một cách đáng kể
Hôm nay chúng tôi đề cập đến sự kết hợp mạnh mẽ giữa phương trình S-Learner, Micaelis-Menton và lập trình phi tuyến tính! Dưới đây là một số suy nghĩ kết thúc:
- Như đã đề cập trước đó, khi sử dụng S-Learner hãy cẩn thận với xu hướng chính quy hóa!
- Tôi đã chọn sử dụng phương trình Micaelis-Menton để xây dựng đường cong phản hồi của mình – Tuy nhiên, phương trình này có thể không phù hợp với bài toán của bạn và có thể được thay thế bằng các phép biến đổi khác phù hợp hơn.
- Việc sử dụng SLSQP để giải các bài toán lập trình phi tuyến mang lại cho bạn sự linh hoạt trong việc sử dụng cả ràng buộc đẳng thức và bất đẳng thức.
- Tôi đã chọn tập trung vào Định giá & Khuyến mãi, nhưng khuôn khổ này có thể được mở rộng sang ngân sách Tiếp thị.
[ad_2]
Source link