Bỏ qua tới nội dung chính
Quay lại tin tức

Phân bổ ngân sách tự giải thích

Towards Data Science· Hoda Rezvanjoo· 11/8/2026general

Làm thế nào để đa dạng hóa ngân sách mà không làm mất đi các giá trị bóng (shadow price) giải thích kết quả. Bài viết Cách phân bổ ngân sách tự giải thích đã xuất hiện lần đầu trên Towards Data Science.

Khoa học Dữ liệu Phân bổ ngân sách tự giải thích Cách đa dạng hóa ngân sách mà không làm mất đi các giá trị bóng (shadow price) giải thích kết quả. Hoda Rezvanjoo Ngày 11/8/2026 6 phút đọc Hình ảnh nổi bật được tạo bằng công cụ tạo hình ảnh của OpenAI và chỉnh sửa bởi tác giả. Nếu để mặc định, bộ tối ưu hóa sẽ phân bổ toàn bộ ngân sách 20.000 bảng Anh cho một kênh duy nhất. Thêm một quy tắc buộc phải phân bổ một phần nhỏ cho kênh thứ hai, bộ tối ưu hóa sẽ tuân thủ, nhưng đồng thời cũng trả về một con số âm nhỏ bên cạnh quy tắc đó. Con số này có nghĩa là giới hạn bạn đặt ra đang gây bất lợi, và nó cho biết chính xác chi phí của sự bất lợi đó. Nhiều quy trình tối ưu hóa dừng lại ở việc phân bổ. Lý do đằng sau sự phân chia đã nằm sẵn trong phép toán, miễn phí, và điều duy nhất ngăn cách bạn với nó là một quyết định mô hình hóa tưởng chừng vô hại. Đây là về việc không bỏ qua điều đó. Hãy bắt đầu với lý do tại sao phiên bản dễ dàng thất bại. Cách tiếp cận rõ ràng là chấm điểm từng kênh theo lợi nhuận trên mỗi bảng Anh và cấp vốn cho những kênh chiến thắng. Nó tạo ra một bảng sạch sẽ và một kế hoạch mà không ai có thể sử dụng. Việc xếp hạng giả định mỗi lựa chọn đứng độc lập, nhưng phân bổ ngân sách là một quyết định có liên kết. Mỗi bảng Anh bạn cấp cho một kênh là một bảng Anh mà các kênh khác mất đi. Thêm một quy tắc duy nhất, "giữ ít nhất 3.000 bảng Anh ở đây", và một danh sách đã sắp xếp sẽ không có gì để nói. Vì vậy, đây là một bài toán tối ưu hóa có ràng buộc, và Lập trình Tuyến tính (Linear Programming - LP) là công cụ tiêu chuẩn cho những bài toán đó. Tuy nhiên, lý do để sử dụng nó không phải là việc phân bổ. Đó là một sản phẩm phụ mà hầu hết mọi người đều bỏ qua. Khi một LP liên tục hoàn thành, nó cũng có thể cung cấp giá trị đối ngẫu (dual value) của các ràng buộc: mục tiêu sẽ thay đổi bao nhiêu nếu bạn nới lỏng một quy tắc đi một đơn vị. Sản phẩm phụ đó chính là lời giải thích. Và nó chỉ có giá trị khi mô hình vẫn là một LP liên tục. Đây chính là lúc quyết định tưởng chừng vô hại xuất hiện. Một LP đơn giản sẽ đổ toàn bộ ngân sách vào kênh tốt nhất và bỏ đói các kênh còn lại. Giải pháp tự nhiên là một công tắc bật/tắt, một biến nhị phân "chạy kênh này hay không". Nó giải quyết vấn đề đổ dồn. Nó cũng biến mô hình thành một chương trình số nguyên hỗn hợp (mixed-integer program), nơi các giá trị bóng LP (LP shadow price) đã giúp giải thích không còn trực tiếp khả dụng. Bạn có được sự phân chia nhưng mất đi lý do. Cách giải quyết là tạo ra sự đa dạng hóa mà không cần công tắc. Chia ngân sách của mỗi kênh thành các dải (band), và làm cho mỗi dải chi phí ít hơn dải trước đó. ```python from dataclasses import dataclass @dataclass class Platform: name: str productivity: float # KPI lịch sử trên mỗi đơn vị chi tiêu min_spend: float = 0.0 # giới hạn chính sách tùy chọn # Các lát cắt liên tiếp của tổng ngân sách, mỗi lát mang lại lợi suất cận biên thấp hơn. BRACKETS = [(0.25, 1.00), (0.35, 0.65), (0.40, 0.35)] # (phần ngân sách, lợi suất cận biên) ``` Lát cắt đầu tiên của một kênh mạnh có giá trị lớn. Lát cắt thứ ba của nó có giá trị ít hơn lát cắt đầu tiên của một đối thủ yếu hơn, vì vậy bộ tối ưu hóa tự động phân bổ tiền. Không có biến nhị phân, do đó các giá trị bóng LP quen thuộc vẫn khả dụng. Lợi suất giảm dần trở thành hình học thay vì logic. Nếu không có lợi suất giảm dần, LP sẽ tập trung toàn bộ ngân sách vào kênh hoạt động hiệu quả nhất. Việc thêm lợi suất cận biên giảm dần cho phép cùng một mô hình LP đa dạng hóa mà không cần đưa ra các quyết định nhị phân. Một lưu ý về năng suất: đây chỉ là chỉ số hiệu suất lịch sử trên mỗi đơn vị chi phí (KPI per pound), một tỷ lệ được quan sát, không phải là ước tính nhân quả. Điều này giúp giảm yêu cầu về dữ liệu đủ thấp cho một nhóm nhỏ, với cái giá là thừa hưởng bất kỳ sai lệch nào đã có sẵn trong các con số. Đây là một sự đánh đổi công bằng khi nó là một lựa chọn có chủ đích. Mô hình vẫn ngắn gọn. PuLP giữ cho nó gần với mô tả rõ ràng của vấn đề. ```python import pulp def allocate(budget, platforms): model = pulp.LpProblem("budget_allocation", pulp.LpMaximize) slices = {} for p in platforms: slices[p.name] = [ (pulp.LpVariable(f"x_{p.name}_b{i}", lowBound=0, upBound=frac * budget), y) for i, (frac, y) in enumerate(BRACKETS) ] model += pulp.lpSum( p.productivity * y * var for p in platforms for (var, y) in slices[p.name] ) model += (pulp.lpSum(var for p in platforms for (var, _) in slices[p.name]) <= budget, "total_budget") for p in platforms: if p.min_spend > 0: model += (pulp.lpSum(var for (var, _) in slices[p.name]) >= p.min_spend, f"min_{p.name}") model.solve(pulp.PULP_CBC_CMD(msg=False)) return model, slices ``` Một chi tiết đáng giá ở cuối: mỗi ràng buộc đều có một tên. Một ràng buộc không tên vẫn có hiệu lực, nhưng nó không thể cho biết sau đó rằng nó đã có hiệu lực. Việc đặt tên cho chúng cho phép sự phân chia phản hồi. Và phản hồi là toàn bộ vấn đề. Mỗi ràng buộc được đặt tên báo cáo hai điều: liệu nó có chặt (tight) hay không và giá trị bóng (shadow price) của nó. ```python def interpret(model): binding, shadow = [], {} for name, con in model.constraints.items(): shadow[name] = round(con.pi, 4) if con.pi is not None else None if con.slack is not None and abs(con.slack) < 1e-6: binding.append(name) return binding, shadow ``` Đọc các dấu hiệu và kế hoạch bắt đầu nói rõ ràng. Một giới hạn ngân sách ràng buộc là tích cực: thêm một đơn vị chi phí sẽ mang lại nhiều lợi nhuận hơn. Một mức chi tiêu tối thiểu ràng buộc là tiêu cực: việc buộc tiền vào một kênh yếu hơn đã tốn chừng đó. Giá trị bóng bằng 0 là một quy tắc đã được viết ra nhưng không bao giờ ảnh hưởng đến quyết định này. Hãy xem nó thay đổi. Với 20.000 bảng Anh, hai nền tảng, một mục tiêu tạo khách hàng tiềm năng và mức sàn 3.000 bảng Anh cho mỗi nền tảng. LinkedIn đã biến 9.500 bảng Anh thành 300 khách hàng tiềm năng, Facebook biến 8.000 bảng Anh thành 150 khách hàng tiềm năng. ```python platforms = [ Platform("linkedin", productivity=300/9500, min_spend=3000), Platform("facebook", productivity=150/8000, min_spend=3000), ] model, slices = allocate(20000, platforms) ``` Chúng gần nhau, vì vậy sự phân chia ổn định gần mức 60/40 nghiêng về LinkedIn. Chỉ có ngân sách ràng buộc, và cả hai mức sàn đều không hoạt động. Năng suất đã thúc đẩy nó; không có quy tắc nào can thiệp. Bây giờ, hãy làm cho LinkedIn rõ ràng mạnh hơn, 380 khách hàng tiềm năng trên 9.500 bảng Anh so với 30 khách hàng tiềm năng trên 4.200 bảng Anh, và giảm mức sàn của Facebook xuống 500 bảng Anh. LinkedIn nhận 19.500 bảng Anh trong khi Facebook giữ đúng mức tối thiểu 500 bảng Anh. Mức sàn đó hiện ràng buộc, với giá trị bóng âm. Đây là con số từ

Nguồn tin: Towards Data Science — Tác giả: Hoda Rezvanjoo. Bản dịch tiếng Việt do AI thực hiện, có thể có sai sót.