Các kỹ thuật tối ưu hóa trong Python
Python cung cấp nhiều kỹ thuật mạnh mẽ để giải các bài toán tối ưu hóa, từ các phương pháp dựa trên gradient đơn giản đến những thuật toán phức tạp hơn. Những kỹ thuật này giúp bạn hiệu quả trong việc tìm cực tiểu hoặc cực đại của hàm, dù là trong học máy, kỹ thuật hay nghiên cứu vận hành.
Phần này sẽ đề cập các kỹ thuật tối ưu hóa thường được triển khai trong Python, bao gồm hạ gradient, phương pháp Newton, phương pháp gradient liên hợp, các phương pháp quasi-Newton, phương pháp Simplex, và phương pháp vùng tin cậy.
Lưu ý: Xem DataLab này để xem toàn bộ mã dùng để tạo các trực quan trong phần này.
Cùng bắt đầu nhé!
Hạ gradient
Hạ gradient là một trong những kỹ thuật cơ bản nhất trong tối ưu hóa số. Đây là phương pháp lặp để tìm cực tiểu của một hàm bằng cách đi theo hướng âm của gradient (độ dốc) của hàm.
Ý tưởng cốt lõi là bắt đầu với một giá trị khởi tạo và cập nhật lặp lại bằng cách tiến về hướng dốc nhất cho đến khi hội tụ. Đây là một trong những kỹ thuật tối ưu hóa được dùng phổ biến nhất khi huấn luyện mô hình học máy, nơi mục tiêu là cực tiểu hóa hàm mất mát.
Phương pháp Newton
Phương pháp Newton là một kỹ thuật tối ưu hóa tìm cực tiểu bằng cách sử dụng cả gradient và đạo hàm bậc hai (ma trận Hessian) của hàm mục tiêu. Khác với hạ gradient chỉ dựa vào đạo hàm bậc một, phương pháp Newton tận dụng thông tin độ cong, cho phép hội tụ nhanh hơn, đặc biệt với các hàm lồi.
Dù hội tụ nhanh, phương pháp Newton yêu cầu tính ma trận Hessian, có thể tốn kém tính toán và không thực tế cho các bài toán quy mô lớn. Tuy vậy, nó rất hiệu quả với các bài toán nhỏ, trơn và lồi.

Phương pháp gradient liên hợp
Phương pháp gradient liên hợp là một kỹ thuật tối ưu hóa hiệu quả cho các bài toán quy mô lớn, đặc biệt khi việc lưu trữ ma trận Hessian là bất khả thi. Nó xây dựng dần các hướng liên hợp và tối ưu dọc theo chúng thay vì cần toàn bộ Hessian, nên phù hợp với các bài toán như cực tiểu hóa các hàm bậc hai lớn.
Phương pháp này hữu ích trong phân tích phần tử hữu hạn hoặc các ứng dụng học máy quy mô lớn, nơi tính toán ma trận trở nên nặng nề.

Các phương pháp quasi-Newton (BFGS)
Các phương pháp quasi-Newton, như thuật toán Broyden–Fletcher–Goldfarb–Shanno (BFGS), xấp xỉ ma trận Hessian thay vì tính trực tiếp. Những phương pháp này đạt hội tụ nhanh hơn hạ gradient bằng cách tận dụng thông tin bậc hai mà không phải chịu chi phí tính toán của việc tính toàn bộ Hessian.

Phương pháp Simplex
Phương pháp Simplex là một thuật toán được dùng rộng rãi để giải các bài toán quy hoạch tuyến tính (LP), nơi hàm mục tiêu và ràng buộc đều tuyến tính. Nó xem xét có hệ thống các đỉnh của vùng khả thi (một đa diện) và di chuyển đến đỉnh tối ưu nơi hàm mục tiêu đạt giá trị lớn nhất hoặc nhỏ nhất.

Phương pháp vùng tin cậy
Phương pháp vùng tin cậy là các thuật toán tối ưu hóa xây dựng một mô hình cục bộ của hàm mục tiêu trong một “vùng tin cậy” quanh nghiệm hiện tại.
Thay vì đi theo một hướng định trước (như trong hạ gradient), thuật toán xác định một bài toán con đơn giản hơn trong vùng tin cậy. Nó lặp lại việc giải bài toán con này để tinh chỉnh nghiệm. Những phương pháp này đặc biệt hiệu quả khi xử lý các bài toán phi tuyến phức tạp và mang lại độ ổn định tốt hơn so với các phương pháp dựa trên gradient truyền thống.

Các vùng tin cậy và bán kính khi cực tiểu hóa hàm Rosenbrock | Nguồn: Trust Region Methods của Shivangi Khare
Các gói Python phổ biến cho tối ưu hóa
Có nhiều thư viện và gói được thiết kế để hỗ trợ tối ưu hóa số. Mỗi gói có điểm mạnh và phạm vi ứng dụng riêng, nhưng dù bạn gặp bài toán tối ưu hóa nào, thường sẽ có một công cụ vững vàng trong Python để hỗ trợ.
Dưới đây là bốn gói tối ưu hóa phổ biến:
Tối ưu hóa trong SciPy (scipy.optimize)
Mô-đun scipy.optimize là một thư viện đa năng trong hệ sinh thái SciPy, cung cấp nhiều thuật toán cho cả bài toán tối ưu hóa không ràng buộc và có ràng buộc. Nó bao gồm các hàm để tìm cực tiểu của hàm vô hướng và đa biến, giải bài toán tìm nghiệm và fit đường cong cho dữ liệu.
Các hàm trong mô-đun này gồm:
minimize(): Hàm dùng để cực tiểu hóa một hàm vô hướng của một hoặc nhiều biến.
from scipy.optimize import minimize
def objective_function(x):
return x[0]**2 + x[1]**2
result = minimize(objective_function, [1, 1], method='BFGS')
print(result.x) # Optimal solution
# >>> [-1.07505143e-08 -1.07505143e-08]
root(): Tìm nghiệm của một hàm vectơ – cực kỳ hữu ích để giải các hệ phương trình phi tuyến.
from scipy.optimize import root
def equations(vars):
x, y = vars
return [x + 2*y - 3, x - y - 1]
result = root(equations, [0, 0])
print(result.x)
# >>> [1.66666667 0.66666667]
curve_fit(): Hàm này fit một đường cong với tập điểm dữ liệu và hữu ích cho việc fit dữ liệu và ước lượng tham số.
from scipy.optimize import curve_fit
import numpy as np
def model(x, a, b):
return a * np.exp(b * x)
x_data = np.array([1, 2, 3])
y_data = np.array([2.7, 7.4, 20.1])
params, covariance = curve_fit(model, x_data, y_data)
print(params) # Fitted parameters
# >>> [0.9981286 1.00089935]
CVXPY
CVXPY là một thư viện Python được thiết kế cho các bài toán tối ưu hóa lồi. Nó cho phép người dùng định nghĩa và giải các bài toán này bằng cú pháp khai báo cấp cao. CVXPY đơn giản hóa việc mô hình hóa các bài toán tối ưu hóa phức tạp bằng cách cho phép chỉ định hàm mục tiêu và ràng buộc theo cách tự nhiên, dễ đọc.
CVXPY cung cấp các tính năng sau:
- Cú pháp khai báo: CVXPY cung cấp cách trực quan để mô hình hóa bài toán tối ưu hóa bằng các biểu thức toán học trong Python.
- Bộ giải hiện đại: Tích hợp với các bộ giải tiên tiến như ECOS, SCS và OSQP, xử lý hiệu quả các bài toán lồi.
import cvxpy as cp
# Define variables
x = cp.Variable()
y = cp.Variable()
# Define constraints
constraints = [x + y == 1, x - y >= 2]
# Define the objective function
objective = cp.Minimize(x**2 + y**2)
# Formulate the problem
prob = cp.Problem(objective, constraints)
# Solve the problem
result = prob.solve()
print(f"Optimal value: {result}")
print(f"x: {x.value}, y: {y.value}")
# >>> Optimal value: 2.5
# x: 1.5, y: -0.5000000000000001
Pyomo
Pyomo là một gói mô hình hóa tối ưu hóa linh hoạt và toàn diện, hỗ trợ quy hoạch tuyến tính, phi tuyến và quy hoạch nguyên hỗn hợp. Nó được thiết kế cho các bài toán tối ưu hóa phức tạp và tích hợp mượt với các bộ giải như GLPK, CBC, và CPLEX.
Các tính năng của Pyomo bao gồm:
- Linh hoạt trong mô hình hóa: Pyomo cho phép định nghĩa bài toán tối ưu hóa với mức độ linh hoạt cao, bao gồm các ràng buộc và mục tiêu phức tạp.
- Tích hợp bộ giải: Hỗ trợ nhiều bộ giải, giúp linh hoạt trong việc chọn công cụ tốt nhất cho bài toán cụ thể.
Gurobi và CPLEX (qua Pyomo hoặc API trực tiếp)
Gurobi và CPLEX là các bộ giải hiệu năng cao cho các bài toán tối ưu hóa quy mô lớn. Chúng thường được dùng trong công nghiệp cho các tác vụ như tối ưu hóa chuỗi cung ứng, quản lý danh mục đầu tư và logistics.
Chúng cung cấp các thuật toán tiên tiến được thiết kế để xử lý hiệu quả các bài toán phức tạp và quy mô lớn.
- Gurobi: Truy cập qua Pyomo hoặc API trực tiếp, Gurobi nổi tiếng về tốc độ và độ tin cậy trong việc giải các bài toán quy hoạch tuyến tính, nguyên và bậc hai.
- CPLEX: Tương tự, CPLEX cung cấp năng lực tối ưu hóa mạnh mẽ và được dùng trong nhiều lĩnh vực để giải các bài toán vận hành và chiến lược phức tạp. Có thể truy cập qua Pyomo hoặc trực tiếp qua API của nó.
Các bộ giải này thường được sử dụng cho các bài toán ở quy mô công nghiệp, nơi hiệu quả tính toán và độ vững là tối quan trọng.
Ứng dụng thực tế của tối ưu hóa số trong Python
Như đã đề cập ở phần mở đầu, tối ưu hóa số đóng vai trò quan trọng trên nhiều lĩnh vực. Nó cung cấp các kỹ thuật thiết yếu để giải bài toán phức tạp và ra quyết định dựa trên dữ liệu.
Ví dụ:
- Học máy: Các mô hình về bản chất được huấn luyện bằng tối ưu hóa số. Điều này bao gồm việc tìm bộ tham số tối ưu để cực tiểu hóa hàm mất mát và định lượng mức độ mô hình dự đoán biến mục tiêu tốt đến đâu.
- Nghiên cứu vận hành: Các kỹ thuật tối ưu hóa giúp đưa ra quyết định chiến lược nhằm tối đa hóa hoặc tối thiểu hóa nhiều chỉ số vận hành. Bằng cách tối ưu hóa hàm mục tiêu dưới các ràng buộc, các nhà nghiên cứu vận hành có thể cải thiện hiệu quả trong những quy trình như quản lý chuỗi cung ứng, lập lịch nhân sự và hoạch định sản xuất.
- Tài chính: Tối ưu hóa số rất quan trọng trong lĩnh vực tài chính cho các tác vụ như tối ưu hóa danh mục. Nó giúp xác định phân bổ tài sản tốt nhất để tối đa hóa lợi nhuận hoặc tối thiểu hóa rủi ro.
- Thiết kế kỹ thuật: Tối ưu hóa số được áp dụng để thiết kế hệ thống và cấu trúc đáp ứng tiêu chí hiệu năng cụ thể trong khi tối thiểu hóa chi phí. Quy trình này giúp đạt các thiết kế hiệu quả cho mọi thứ từ cầu đường và máy bay đến quy trình sản xuất và hệ thống năng lượng.
Thực tiễn tốt nhất cho tối ưu hóa số trong Python
Để đạt kết quả tốt nhất cho nỗ lực tối ưu hóa trong Python, cần cân nhắc một số yếu tố. Hãy tuân thủ các thực tiễn tốt nhất sau:
Chọn đúng thuật toán
Chọn thuật toán tối ưu hóa phù hợp là chìa khóa để đạt kết quả tối ưu. Việc lựa chọn phụ thuộc vào bản chất bài toán:
- Tuyến tính vs. phi tuyến: Với bài toán tuyến tính, các kỹ thuật quy hoạch tuyến tính như Simplex hoặc điểm trong là phù hợp. Với bài toán phi tuyến, các phương pháp như hạ gradient, phương pháp Newton, hoặc quasi-Newton (ví dụ BFGS) có thể phù hợp hơn.
- Có ràng buộc vs. không ràng buộc: Với các bài toán có ràng buộc, cần dùng các thuật toán như Lập trình Bậc hai Tuần tự (SQP) hoặc các phương pháp xử lý ràng buộc nguyên bản (ví dụ phương pháp điểm trong). Các bài toán không ràng buộc có thể được giải hiệu quả bằng hạ gradient hoặc phương pháp Newton.
Chọn đúng thuật toán dựa vào đặc trưng của bài toán giúp đạt hội tụ nhanh hơn và nghiệm chính xác hơn.
Xử lý ràng buộc
Các ràng buộc trong bài toán tối ưu hóa có thể ảnh hưởng đáng kể đến lựa chọn thuật toán và chiến lược nghiệm. Có thể dùng nhiều cách tiếp cận để xử lý ràng buộc:
- Phương pháp phạt: Đưa ràng buộc vào hàm mục tiêu bằng cách thêm hạng phạt cho các vi phạm ràng buộc. Cách này biến một bài toán có ràng buộc thành bài toán không ràng buộc, cho phép dùng các phương pháp tối ưu hóa không ràng buộc.
- Phương pháp hàng rào: Dùng các hàm hàng rào để đảm bảo không vi phạm ràng buộc. Phương pháp hàng rào hoạt động bằng cách thêm một hạng hàng rào vào hàm mục tiêu, trở nên vô hạn khi tiến gần đến ràng buộc.
- Hỗ trợ nguyên bản: Tận dụng các bộ giải hỗ trợ ràng buộc một cách nguyên bản. Nhiều bộ giải hiện đại, như trong
scipy.optimizehoặc CVXPY, được thiết kế để xử lý ràng buộc trực tiếp và hiệu quả.
Chọn phương pháp xử lý ràng buộc phù hợp đảm bảo nghiệm khả thi và đáp ứng mọi yêu cầu đã nêu.
Chuẩn hóa và tiền xử lý
Chuẩn hóa và tiền xử lý dữ liệu đúng cách có thể cải thiện đáng kể hiệu năng của các thuật toán tối ưu hóa:
- Chuẩn hóa: Chuẩn hóa hoặc tiêu chuẩn hóa dữ liệu đầu vào để đảm bảo các đặc trưng đóng góp cân bằng vào hàm mục tiêu. Điều này giúp tránh các vấn đề về ổn định số và cải thiện tốc độ hội tụ.
- Tiền xử lý: Áp dụng các kỹ thuật như kỹ thuật đặc trưng hoặc giảm chiều để đơn giản hóa bài toán. Tiền xử lý phù hợp giúp giảm độ phức tạp của bài toán tối ưu hóa và tăng tốc quá trình tìm nghiệm.
Diễn giải kết quả
Diễn giải kết quả của các thuật toán tối ưu hóa bao gồm hiểu rõ một số khía cạnh:
- Chất lượng nghiệm: Đánh giá chất lượng nghiệm bằng cách kiểm tra xem nó có thỏa các điều kiện tối ưu và ràng buộc hay không. So sánh kết quả với các mốc chuẩn đã biết hoặc kiểm định bằng các kỹ thuật như cross-validation.
- Tiêu chí hội tụ: Đánh giá xem thuật toán tối ưu hóa đã hội tụ chưa bằng cách kiểm tra thông điệp hội tụ, số vòng lặp, hoặc mức thay đổi của giá trị hàm mục tiêu. Đảm bảo thuật toán đạt nghiệm gần với tối ưu thật.
- Độ chính xác số: Cân nhắc tác động của độ chính xác số đến kết quả. Các sai số số học nhỏ có thể tích lũy và ảnh hưởng đến nghiệm cuối, đặc biệt trong các bài toán quy mô lớn hoặc có dung sai chặt.
Kết luận
Tối ưu hóa số là nền tảng của giải quyết vấn đề hiện đại. Nó cung cấp các công cụ mạnh mẽ để đối mặt với những thách thức phức tạp trong các lĩnh vực như học máy, kỹ thuật, tài chính và nghiên cứu vận hành.
Hệ sinh thái thư viện tối ưu hóa phong phú của Python — như SciPy, CVXPY, và Pyomo — giúp các kỹ thuật tiên tiến này trở nên dễ tiếp cận hơn, trao quyền cho nhà nghiên cứu, kỹ sư và nhà khoa học dữ liệu thiết kế hệ thống hiệu quả, tối ưu hóa mô hình và đưa ra quyết định thông minh, dựa trên dữ liệu.
Với các kỹ thuật và thực tiễn tốt nhất phù hợp, giờ đây bạn đã sẵn sàng để tiếp cận và giải ngay cả những bài toán tối ưu hóa khó nhất trong Python. Hãy xem thêm các tài nguyên sau để tiếp tục học:
FAQs
Tối ưu hóa là gì?
Tối ưu hóa là quá trình tìm cực tiểu hoặc cực đại của một hàm bằng các phương pháp tính toán lặp thay vì các nghiệm giải tích.
Vì sao tối ưu hóa quan trọng?
Tối ưu hóa quan trọng vì nó giúp giải các bài toán thực tế phức tạp trong những lĩnh vực như học máy, kỹ thuật và tài chính, nơi các nghiệm trực tiếp là không thực tế hoặc không thể.
Những gói Python nào tốt nhất cho tối ưu hóa số?
Các gói Python phổ biến cho tối ưu hóa số gồm SciPy (tối ưu hóa mục đích chung), CVXPY (tối ưu hóa lồi), Pyomo (mô hình hóa linh hoạt), và các bộ giải mạnh như Gurobi và CPLEX, phù hợp cho ứng dụng quy mô công nghiệp.
Tối ưu hóa số được dùng trong học máy như thế nào?
Trong học máy, tối ưu hóa số được dùng để cực tiểu hóa hàm mất mát, thước đo mức độ mô hình dự đoán các biến mục tiêu.
Sự khác nhau giữa tối ưu hóa có ràng buộc và không ràng buộc là gì?
Tối ưu hóa không ràng buộc là tìm giá trị tối ưu của hàm mục tiêu mà không có hạn chế nào lên các biến. Ngược lại, tối ưu hóa có ràng buộc áp đặt các hạn chế (đẳng thức hoặc bất đẳng thức) lên các biến và yêu cầu nghiệm tối ưu phải thỏa các ràng buộc đó đồng thời tối ưu hóa hàm.

Tối ưu hóa là một trong những kỹ thuật chủ chốt trong học máy. Đó là một trong những điều đầu tiên tôi học, nhưng tôi nhanh chóng nhận ra phạm vi ứng dụng của nó vượt xa lĩnh vực ML.
Tối ưu hóa số đóng vai trò then chốt trong việc giải các bài toán phức tạp trên nhiều lĩnh vực. Thiếu nó, các nhà khoa học dữ liệu, nhà kinh tế, và kỹ sư đều sẽ loay hoay với các công cụ kém hiệu quả, tốn kém và đưa ra các quyết định không tối ưu.
Đó là lý do chúng ta sẽ đề cập đến tối ưu hóa trong Python trong bài viết này, bao gồm những gói thư viện, kỹ thuật và thực tiễn tốt nhất phổ biến.
Thắt dây an toàn, sẵn sàng cho hành trình, và cùng theo dõi với Sổ tay DataLab này.
Tối ưu hóa số là gì?
Với nhiều bài toán trong thực tế, rất khó để xác định trực tiếp nghiệm tốt nhất. Giải các bài toán đó đòi hỏi cách tiếp cận lặp, và đây là lúc tối ưu hóa số xuất hiện trong cuộc thảo luận.
Tối ưu hóa số là quá trình tìm giá trị nhỏ nhất hoặc lớn nhất của một hàm bằng các phương pháp tính toán lặp, trái ngược với nghiệm giải tích thu được qua các phép biến đổi đại số.
Khác với phương pháp giải tích, có thể cho nghiệm chính xác ở dạng đóng, tối ưu hóa số dựa vào các thuật toán xấp xỉ nghiệm tối ưu bằng cách cải thiện dần ước lượng qua nhiều vòng lặp.
Cách tiếp cận này đặc biệt hữu ích khi làm việc với các hàm:
Trong những trường hợp như vậy, việc thu được nghiệm chính xác bằng giải tích là không thể hoặc không thực tế, vì thế ta dùng phương pháp lặp.
Các dạng bài toán tối ưu hóa phổ biến
Trong tối ưu hóa số, các bài toán thường được phân loại dựa trên bản chất của hàm mục tiêu và sự có mặt hay vắng mặt của các ràng buộc.
Vì vậy, các dạng bài toán phổ biến có thể phân thành:
Tối ưu hóa không ràng buộc
Đây là dạng tối ưu hóa đơn giản nhất. Nó liên quan đến việc tìm cực tiểu hoặc cực đại của một hàm mục tiêu mà không hạn chế các biến.
Mục tiêu là xác định điểm mà tại đó hàm đạt giá trị tối ưu (cực tiểu hoặc cực đại) chỉ dựa trên cấu trúc toán học của nó.
Các kỹ thuật như hạ gradient hoặc phương pháp Newton thường được dùng để giải bài toán không ràng buộc (sẽ nói kỹ hơn bên dưới). Trọng tâm là cải thiện nghiệm lặp lại bằng cách đánh giá các đạo hàm của hàm.
Ví dụ, cực tiểu hóa hàm chi phí f(x) phụ thuộc vào một hoặc nhiều biến x, không có bất kỳ giới hạn nào về giá trị mà x có thể nhận, là một bài toán không ràng buộc điển hình.
Tối ưu hóa có ràng buộc
Ngược lại, các bài toán tối ưu hóa có ràng buộc liên quan đến việc tìm giá trị tối ưu của hàm mục tiêu dưới một hoặc nhiều ràng buộc lên các biến. Các ràng buộc này có thể ở dạng đẳng thức hoặc bất đẳng thức.
Thách thức trong tối ưu hóa có ràng buộc là vừa tối ưu hóa hàm, vừa đảm bảo nghiệm thỏa các ràng buộc đã cho.
Chẳng hạn, một bài toán tối ưu hóa có ràng buộc điển hình trong thiết kế kỹ thuật có thể là tối thiểu hóa chi phí vật liệu (hàm mục tiêu) đồng thời tuân thủ các giới hạn vật lý như độ bền hoặc trọng lượng (các ràng buộc).
Các phương pháp như nhân tử Lagrange, hàm phạt và phương pháp hàng rào thường được dùng để đưa các ràng buộc vào quá trình tối ưu hóa.
Tối ưu hóa tuyến tính so với phi tuyến
Trong tối ưu hóa tuyến tính, cả hàm mục tiêu và các ràng buộc đều… tuyến tính. Điều này có nghĩa là các phương trình hoặc bất đẳng thức tuyến tính biểu diễn mối quan hệ giữa các biến.
Không gian nghiệm cho các bài toán tối ưu hóa tuyến tính thường đơn giản và có cấu trúc tốt, thường dẫn đến nghiệm hiệu quả khi dùng các phương pháp như Simplex hoặc điểm trong.
Ví dụ kinh điển của tối ưu hóa tuyến tính là bài toán quy hoạch tuyến tính, trong đó mục tiêu có thể là tối đa hóa lợi nhuận (một hàm tuyến tính) dưới các ràng buộc nguồn lực (các bất đẳng thức tuyến tính).
Trái lại, tối ưu hóa phi tuyến liên quan đến hàm mục tiêu hoặc ràng buộc phi tuyến, khiến bài toán phức tạp hơn đáng kể.
Ta thường gặp các bài toán tối ưu hóa phi tuyến trong ứng dụng thực tế nơi mối quan hệ giữa các biến không đơn giản. Những bài toán này có thể có nhiều cực trị địa phương, làm cho việc giải khó khăn hơn so với bài toán tuyến tính.
Các kỹ thuật như phương pháp dựa trên gradient, phương pháp Newton, và thuật toán tiến hóa thường được dùng để giải quyết tối ưu hóa phi tuyến.
Một ví dụ về tối ưu hóa phi tuyến có thể là cực tiểu hóa một hàm năng lượng với các phụ thuộc vật lý phức tạp, như tối ưu hình dạng cánh máy bay để đạt hiệu suất khí động học, trong đó mối quan hệ giữa biến thiết kế và chỉ số hiệu năng là phi tuyến.