{"id":15551439,"url":"https://github.com/seatonullberg/mobo","last_synced_at":"2025-03-29T01:45:57.682Z","repository":{"id":57442545,"uuid":"148699526","full_name":"seatonullberg/mobo","owner":"seatonullberg","description":"A rational and extensible algorithm for solving multi-objective optimization problems","archived":false,"fork":false,"pushed_at":"2019-11-18T02:11:56.000Z","size":322,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-07T01:35:51.486Z","etag":null,"topics":["multi-objective","optimization","optimization-algorithms"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seatonullberg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-13T21:20:28.000Z","updated_at":"2019-11-18T02:11:58.000Z","dependencies_parsed_at":"2022-09-26T17:21:15.096Z","dependency_job_id":null,"html_url":"https://github.com/seatonullberg/mobo","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seatonullberg%2Fmobo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seatonullberg%2Fmobo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seatonullberg%2Fmobo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seatonullberg%2Fmobo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seatonullberg","download_url":"https://codeload.github.com/seatonullberg/mobo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246126669,"owners_count":20727594,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["multi-objective","optimization","optimization-algorithms"],"created_at":"2024-10-02T14:05:00.284Z","updated_at":"2025-03-29T01:45:57.665Z","avatar_url":"https://github.com/seatonullberg.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mobo\n\n## Introduction\n\n`mobo` is an algorithm to solve multi-objective problems without imposing the bias of weights. Rather than converging to a single 'optimal' solution, `mobo` produces an ensamble of rational solutions which may then be further downselected according to the constraints of a particular application.\n\n## Installation\n\n`mobo` can be installed simply with pip.\n\n```bash\n$ python3 -m pip install mobo\n```\n\nFor testing or development you will need to clone the repo.\n\n```bash\n$ git clone https://github.com/seatonullberg/mobo.git\n$ cd mobo\n$ python3 -m pip install -r requirements.txt\n$ python3 -m pip install -e .\n```\n\n## Example\n\nAn introductory example, fitting a polynomial, is available in the [examples directory](./examples). Snippets of that example will be shown here. The first step in preparing an optimizer is to define the parameters which are being optimized.\n\n```python\nparameters = [\n        Parameter(\"a\", -1.0, 1.0),\n        Parameter(\"b\", -2.0, 0.0),\n        Parameter(\"c\", 0.0, 1.0)\n]\n```\n\nEach parameter has a name, a lower bound, and an upper bound. Next, it is necessary to define the quantities of interest which will be evaluated with the fitted parameters.\n\n```python\nqois = [\n        QoI(\"pt0\", evaluate_pt0, -0.062),\n        QoI(\"pt1\", evaluate_pt1, 0.05),\n        QoI(\"pt2\", evaluate_pt2, -1.4),\n        QoI(\"pt3\", evaluate_pt3, 2.0)\n]\n```\n\nEach quantity of interest has a name, an associated evaluation function, and a target value. The evaluation function should take only a dict mapping parameter names to their values as its argument and return a float.\n\n```python\n# target coefficients: 0.3, -1.2, 0.5\npolynomial = lambda a, b, c, x: a*x**3 + b*x**2 + c*x\n\n# target: -0.062\ndef evaluate_pt0(params):\n    x = -0.1\n    return polynomial(params[\"a\"], params[\"b\"], params[\"c\"], x)\n```\n\nAfter these fundamental components are defined, the mobo-centric components should be chosen.\n\n```python\nclusterer = KmeansClusterer(n_clusters=2)\nerror_calculator = SquaredErrorCalculator()\nfilters = [ParetoFilter(), PercentileFilter()]\nprojector = PCAProjector()\n```\n\nA clusterer is required to partition the parameter space, an error calculator is required to determine a cost, filters are used to purge poor parameterizations, and a projector is used to project a high dimensional parameter space down to 2D for more effective clustering. Since this algorithm is iterative, each iteration requires a 'local' configuration which is passed into a 'global' configuration before finally constructing the optimizer.\n\n```python\nlocal_config = LocalConfiguration(\n    n_samples, clusterer, error_calculator, filters, projector\n)\nlocal_configurations = [local_config for _ in range(n_iterations)]\nglobal_config = GlobalConfiguration(\n    n_samples, local_configurations, parameters, qois\n)\n```\n\nOnce the global configuration has been constructed, execution of the optimizer is trivial.\n\n```python\noptimizer = Optimizer(global_config)\noptimizer()\n```\n\nAs an aside, you may notice that this optimizer is a callable object. I use this theme in many objects which only expose publicly a single method. After optimization you will be left with some data files representing the results of each iteration. If you were to visualize the final results, you should see something like this.\n\n![polynomial fit results](./figures/polynomial_predictions.png)\n\nThe black line is the target polynomial, the black dots are the points used as quantities of interest, the blue lines are the predictions from cluster 0 and the red lines are predictions from cluster 1. As you can see, the fit is quite close. Other choices of points to evaluate should yield similar results so long as they are near the local extrema. The following plot attempts to illustrate some of the internal mechanics.\n\n![polynomial cluster results](./figures/polynomial_clusters.png)\n\nThe points are parameters projected down onto their primary PCA vectors. Blue points correspond to parameterizations from cluster 0 and red from cluster 1. This view is essentially what the KDE sampler \"sees\" when it is selecting new parameterizations. This view helps to show why the parameters in different clusters are producing distinct predictions.\n\n## Algorithm Description\n\nTODO\n\n## Acknowledgements\n\nThe implementation of this algorithm is based upon work I contributed to in [pypospack](https://github.com/eragasa/pypospack). The `pypospack` project is the focus of [this dissertation](http://phillpot.mse.ufl.edu/wp-content/uploads/2019/08/2019_Ragasa_Dissertation.pdf) which you may be interested in reading for a more in-depth description of the mathematics involved or alternative applications of the algorithm.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseatonullberg%2Fmobo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseatonullberg%2Fmobo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseatonullberg%2Fmobo/lists"}