You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MIPLearn/0.2/customization/index.html

388 lines
17 KiB

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="../img/favicon.ico">
<title>Customization - MIPLearn</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/v4-shims.css">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/hack-font@3.3.0/build/web/hack.min.css">
<link href='//rsms.me/inter/inter.css' rel='stylesheet' type='text/css'>
<link href='//fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,700italic,400,300,600,700&subset=latin-ext,latin' rel='stylesheet' type='text/css'>
<link href="../css/bootstrap-custom.min.css" rel="stylesheet">
<link href="../css/base.min.css" rel="stylesheet">
<link href="../css/cinder.min.css" rel="stylesheet">
<link rel="stylesheet" href="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.18.0/build/styles/github.min.css">
<link href="../css/custom.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://cdn.jsdelivr.net/npm/html5shiv@3.7.3/dist/html5shiv.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/respond.js@1.4.2/dest/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<!-- Collapsed navigation -->
<div class="navbar-header">
<!-- Expander button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!-- Main title -->
<a class="navbar-brand" href="..">MIPLearn</a>
</div>
<!-- Expanded navigation -->
<div class="navbar-collapse collapse">
<!-- Main navigation -->
<ul class="nav navbar-nav">
<li >
<a href="..">Home</a>
</li>
<li >
<a href="../usage/">Usage</a>
</li>
<li >
<a href="../benchmark/">Benchmark</a>
</li>
<li >
<a href="../problems/">Problems</a>
</li>
<li class="active">
<a href="./">Customization</a>
</li>
<li >
<a href="../about/">About</a>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="#" data-toggle="modal" data-target="#mkdocs_search_modal">
<i class="fas fa-search"></i> Search
</a>
</li>
<li >
<a rel="prev" href="../problems/">
<i class="fas fa-arrow-left"></i> Previous
</a>
</li>
<li >
<a rel="next" href="../about/">
Next <i class="fas fa-arrow-right"></i>
</a>
</li>
<li>
<a href="https://github.com/ANL-CEEESA/MIPLearn/edit/dev/docs/customization.md"><i class="fab fa-github"></i> Edit on GitHub</a>
</li>
</ul>
</div>
</div>
</div>
<div class="container">
<div class="col-md-3"><div class="bs-sidebar hidden-print affix well" role="complementary">
<ul class="nav bs-sidenav">
<li class="first-level active"><a href="#customization">Customization</a></li>
<li class="second-level"><a href="#customizing-solver-parameters">Customizing solver parameters</a></li>
<li class="third-level"><a href="#selecting-the-internal-mip-solver">Selecting the internal MIP solver</a></li>
<li class="second-level"><a href="#customizing-solver-components">Customizing solver components</a></li>
<li class="third-level"><a href="#selecting-components">Selecting components</a></li>
<li class="third-level"><a href="#adjusting-component-aggressiveness">Adjusting component aggressiveness</a></li>
<li class="third-level"><a href="#evaluating-component-performance">Evaluating component performance</a></li>
<li class="third-level"><a href="#using-customized-ml-classifiers-and-regressors">Using customized ML classifiers and regressors</a></li>
</ul>
</div></div>
<div class="col-md-9" role="main">
<h1 id="customization">Customization</h1>
<h2 id="customizing-solver-parameters">Customizing solver parameters</h2>
<h3 id="selecting-the-internal-mip-solver">Selecting the internal MIP solver</h3>
<p>By default, <code>LearningSolver</code> uses <a href="https://www.gurobi.com/">Gurobi</a> as its internal MIP solver. Another supported solver is <a href="https://www.ibm.com/products/ilog-cplex-optimization-studio">IBM ILOG CPLEX</a>. To switch between solvers, use the <code>solver</code> constructor argument, as shown below. It is also possible to specify a time limit (in seconds) and a relative MIP gap tolerance.</p>
<pre><code class="language-python">from miplearn import LearningSolver
solver = LearningSolver(solver=&quot;cplex&quot;,
time_limit=300,
gap_tolerance=1e-3)
</code></pre>
<h2 id="customizing-solver-components">Customizing solver components</h2>
<p><code>LearningSolver</code> is composed by a number of individual machine-learning components, each targeting a different part of the solution process. Each component can be individually enabled, disabled or customized. The following components are enabled by default:</p>
<ul>
<li><code>LazyConstraintComponent</code>: Predicts which lazy constraint to initially enforce.</li>
<li><code>ObjectiveValueComponent</code>: Predicts the optimal value of the optimization problem, given the optimal solution to the LP relaxation.</li>
<li><code>PrimalSolutionComponent</code>: Predicts optimal values for binary decision variables. In heuristic mode, this component fixes the variables to their predicted values. In exact mode, the predicted values are provided to the solver as a (partial) MIP start.</li>
</ul>
<p>The following components are also available, but not enabled by default:</p>
<ul>
<li><code>BranchPriorityComponent</code>: Predicts good branch priorities for decision variables.</li>
</ul>
<h3 id="selecting-components">Selecting components</h3>
<p>To create a <code>LearningSolver</code> with a specific set of components, the <code>components</code> constructor argument may be used, as the next example shows:</p>
<pre><code class="language-python"># Create a solver without any components
solver1 = LearningSolver(components=[])
# Create a solver with only two components
solver2 = LearningSolver(components=[
LazyConstraintComponent(...),
PrimalSolutionComponent(...),
])
</code></pre>
<p>It is also possible to add components to an existing solver using the <code>solver.add</code> method, as shown below. If the solver already holds another component of that type, the new component will replace the previous one.</p>
<pre><code class="language-python"># Create solver with default components
solver = LearningSolver()
# Replace the default LazyConstraintComponent by one with custom parameters
solver.add(LazyConstraintComponent(...))
</code></pre>
<h3 id="adjusting-component-aggressiveness">Adjusting component aggressiveness</h3>
<p>The aggressiveness of classification components (such as <code>PrimalSolutionComponent</code> and <code>LazyConstraintComponent</code>) can
be adjusted through the <code>threshold</code> constructor argument. Internally, these components ask the ML models how confident
they are on each prediction (through the <code>predict_proba</code> method in the sklearn API), and only take into account
predictions which have probabilities above the threshold. Lowering a component's threshold increases its aggressiveness,
while raising a component's threshold makes it more conservative. </p>
<p>MIPLearn also includes <code>MinPrecisionThreshold</code>, a dynamic threshold which adjusts itself automatically during training
to achieve a minimum desired true positive rate (also known as precision). The example below shows how to initialize
a <code>PrimalSolutionComponent</code> which achieves 95% precision, possibly at the cost of a lower recall. To make the component
more aggressive, this precision may be lowered.</p>
<pre><code class="language-python">PrimalSolutionComponent(threshold=MinPrecisionThreshold(0.95))
</code></pre>
<h3 id="evaluating-component-performance">Evaluating component performance</h3>
<p>MIPLearn allows solver components to be modified, trained and evaluated in isolation. In the following example, we build and
fit <code>PrimalSolutionComponent</code> outside the solver, then evaluate its performance.</p>
<pre><code class="language-python">from miplearn import PrimalSolutionComponent
# User-provided set of previously-solved instances
train_instances = [...]
# Construct and fit component on a subset of training instances
comp = PrimalSolutionComponent()
comp.fit(train_instances[:100])
# Evaluate performance on an additional set of training instances
ev = comp.evaluate(train_instances[100:150])
</code></pre>
<p>The method <code>evaluate</code> returns a dictionary with performance evaluation statistics for each training instance provided,
and for each type of prediction the component makes. To obtain a summary across all instances, pandas may be used, as below:</p>
<pre><code class="language-python">import pandas as pd
pd.DataFrame(ev[&quot;Fix one&quot;]).mean(axis=1)
</code></pre>
<pre><code class="language-text">Predicted positive 3.120000
Predicted negative 196.880000
Condition positive 62.500000
Condition negative 137.500000
True positive 3.060000
True negative 137.440000
False positive 0.060000
False negative 59.440000
Accuracy 0.702500
F1 score 0.093050
Recall 0.048921
Precision 0.981667
Predicted positive (%) 1.560000
Predicted negative (%) 98.440000
Condition positive (%) 31.250000
Condition negative (%) 68.750000
True positive (%) 1.530000
True negative (%) 68.720000
False positive (%) 0.030000
False negative (%) 29.720000
dtype: float64
</code></pre>
<p>Regression components (such as <code>ObjectiveValueComponent</code>) can also be trained and evaluated similarly,
as the next example shows:</p>
<pre><code class="language-python">from miplearn import ObjectiveValueComponent
comp = ObjectiveValueComponent()
comp.fit(train_instances[:100])
ev = comp.evaluate(train_instances[100:150])
import pandas as pd
pd.DataFrame(ev).mean(axis=1)
</code></pre>
<pre><code class="language-text">Mean squared error 7001.977827
Explained variance 0.519790
Max error 242.375804
Mean absolute error 65.843924
R2 0.517612
Median absolute error 65.843924
dtype: float64
</code></pre>
<h3 id="using-customized-ml-classifiers-and-regressors">Using customized ML classifiers and regressors</h3>
<p>By default, given a training set of instantes, MIPLearn trains a fixed set of ML classifiers and regressors, then
selects the best one based on cross-validation performance. Alternatively, the user may specify which ML model a component
should use through the <code>classifier</code> or <code>regressor</code> contructor parameters. The provided classifiers and regressors must
follow the sklearn API. In particular, classifiers must provide the methods <code>fit</code>, <code>predict_proba</code> and <code>predict</code>,
while regressors must provide the methods <code>fit</code> and <code>predict</code></p>
<div class="admonition danger">
<p class="admonition-title">Danger</p>
<p>MIPLearn must be able to generate a copy of any custom ML classifiers and regressors through
the standard <code>copy.deepcopy</code> method. This currently makes it incompatible with Keras and TensorFlow
predictors. This is a known limitation, which will be addressed in a future version.</p>
</div>
<p>The example below shows how to construct a <code>PrimalSolutionComponent</code> which internally uses
sklearn's <code>KNeighborsClassifiers</code>. Any other sklearn classifier or pipeline can be used. </p>
<pre><code class="language-python">from miplearn import PrimalSolutionComponent
from sklearn.neighbors import KNeighborsClassifier
comp = PrimalSolutionComponent(classifier=KNeighborsClassifier(n_neighbors=5))
comp.fit(train_instances)
</code></pre></div>
</div>
<footer class="col-md-12 text-center">
<hr>
<p>
<small>Copyright © 2020, UChicago Argonne, LLC. All Rights Reserved.</small><br>
<small>Documentation built with <a href="http://www.mkdocs.org/">MkDocs</a>.</small>
</p>
</footer>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="../js/bootstrap-3.0.3.min.js"></script>
<script src="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.18.0/build/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script>var base_url = ".."</script>
<script src="../js/base.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script src="../js/mathjax.js"></script>
<script src="../search/main.js"></script>
<div class="modal" id="mkdocs_search_modal" tabindex="-1" role="dialog" aria-labelledby="searchModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">&times;</span>
<span class="sr-only">Close</span>
</button>
<h4 class="modal-title" id="searchModalLabel">Search</h4>
</div>
<div class="modal-body">
<p>
From here you can search these documents. Enter
your search terms below.
</p>
<form>
<div class="form-group">
<input type="text" class="form-control" placeholder="Search..." id="mkdocs-search-query" title="Type search term here">
</div>
</form>
<div id="mkdocs-search-results"></div>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div><div class="modal" id="mkdocs_keyboard_modal" tabindex="-1" role="dialog" aria-labelledby="keyboardModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="keyboardModalLabel">Keyboard Shortcuts</h4>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
</div>
<div class="modal-body">
<table class="table">
<thead>
<tr>
<th style="width: 20%;">Keys</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td class="help shortcut"><kbd>?</kbd></td>
<td>Open this help</td>
</tr>
<tr>
<td class="next shortcut"><kbd>n</kbd></td>
<td>Next page</td>
</tr>
<tr>
<td class="prev shortcut"><kbd>p</kbd></td>
<td>Previous page</td>
</tr>
<tr>
<td class="search shortcut"><kbd>s</kbd></td>
<td>Search</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
</body>
</html>