<p dir="auto">In several PRs (e.g. <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="328562762" data-permission-text="Title is private" data-url="https://github.com/scikit-learn/scikit-learn/issues/11182" data-hovercard-type="issue" data-hovercard-url="/scikit-learn/scikit-learn/issues/11182/hovercard" href="https://github.com/scikit-learn/scikit-learn/issues/11182">#11182</a> <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="395595325" data-permission-text="Title is private" data-url="https://github.com/scikit-learn/scikit-learn/issues/12916" data-hovercard-type="pull_request" data-hovercard-url="/scikit-learn/scikit-learn/pull/12916/hovercard" href="https://github.com/scikit-learn/scikit-learn/pull/12916">#12916</a>) the question arises whether we need to deprecate some object before it can be removed or changed. This goes back to defining what is public API in scikit-learn.</p>
<p dir="auto">The lest controversial definition is that,</p>
<ul dir="auto">
<li>import paths with that include a module with a leading <code class="notranslate">_</code> are private</li>
<li>other modules are public.</li>
</ul>
<p dir="auto">However, you could do, for instance,</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from sklearn.cluster.dbscan_ import NearestNeighbors"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">sklearn</span>.<span class="pl-s1">cluster</span>.<span class="pl-s1">dbscan_</span> <span class="pl-k">import</span> <span class="pl-v">NearestNeighbors</span></pre></div>
<p dir="auto">Does it mean that we are supposed to preserve backward compatibility on <code class="notranslate">sklearn.cluster.dbscan_.NearestNeighbors</code> in terms of import path? How about <code class="notranslate">sklearn.preprocessing.data.sparse</code> (<code class="notranslate">scipy.sparse</code>)?</p>
<p dir="auto">I guess not, meaning that just because we have an import path without an underscore does not mean that it is part of the public API. At the very least it also needs to be documented or used in examples.</p>
<p dir="auto">If we take this definition,</p>
<ul dir="auto">
<li>most of <code class="notranslate">sklearn.utils</code>, is public API (as documented <a href="https://scikit-learn.org/stable/modules/classes.html#module-sklearn.utils" rel="nofollow">https://scikit-learn.org/stable/modules/classes.html#module-sklearn.utils</a>) but certainly not all 151 objects listed in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="145199979" data-permission-text="Title is private" data-url="https://github.com/scikit-learn/scikit-learn/issues/6616" data-hovercard-type="issue" data-hovercard-url="/scikit-learn/scikit-learn/issues/6616/hovercard?comment_id=245085954&amp;comment_type=issue_comment" href="https://github.com/scikit-learn/scikit-learn/issues/6616#issuecomment-245085954">#6616 (comment)</a></li>
<li><code class="notranslate">sklearn.utils.fixes</code> is not.</li>
<li><code class="notranslate">sklearn.externals</code> are not (except for <code class="notranslate">sklearn.externals.joblib</code>) that we previously used in examples.</li>
</ul>
<p dir="auto">This would mean that we can e.g. remove <code class="notranslate">sklearn.externals.six</code> in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="395595325" data-permission-text="Title is private" data-url="https://github.com/scikit-learn/scikit-learn/issues/12916" data-hovercard-type="pull_request" data-hovercard-url="/scikit-learn/scikit-learn/pull/12916/hovercard" href="https://github.com/scikit-learn/scikit-learn/pull/12916">#12916</a> without a deprecation warning (but possibly with a what's new entry). I have a hard time seeing a user reasonably complaining that we didn't go through a deprecation cycle there.</p>
<p dir="auto">This would also help resolving the "public vs private utils" discussion in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="145199979" data-permission-text="Title is private" data-url="https://github.com/scikit-learn/scikit-learn/issues/6616" data-hovercard-type="issue" data-hovercard-url="/scikit-learn/scikit-learn/issues/6616/hovercard" href="https://github.com/scikit-learn/scikit-learn/issues/6616">#6616</a></p>
<p dir="auto">WDYT, do you have other ideas of how we should define what is public API in scikit-learn?</p>
<p dir="auto">cc <a class="team-mention js-team-mention notranslate" data-error-text="Failed to load team members" data-id="11523" data-permission-text="Team members are private" data-url="/orgs/scikit-learn/teams/core-devs/members" data-hovercard-type="team" data-hovercard-url="/orgs/scikit-learn/teams/core-devs/hovercard" href="https://github.com/orgs/scikit-learn/teams/core-devs">@scikit-learn/core-devs</a></p>
<p dir="auto">This is maybe for 1.0. Recently we started marking files like <code class="notranslate">model_selection._split</code> private, so that everything has a single canonical import:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from sklearn.model_selection import cross_val_score"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">sklearn</span>.<span class="pl-s1">model_selection</span> <span class="pl-k">import</span> <span class="pl-s1">cross_val_score</span></pre></div>
<p dir="auto">For many (older?) models that's not the case, we have</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from sklearn.linear_model.logistic import LogisticRegression
from sklearn.linear_model import LogisticRegression"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">sklearn</span>.<span class="pl-s1">linear_model</span>.<span class="pl-s1">logistic</span> <span class="pl-k">import</span> <span class="pl-v">LogisticRegression</span>
<span class="pl-k">from</span> <span class="pl-s1">sklearn</span>.<span class="pl-s1">linear_model</span> <span class="pl-k">import</span> <span class="pl-v">LogisticRegression</span></pre></div>
<p dir="auto">etc.<br>
I think it would be nice to make all the files that are not the canonical import (according to the API documentation) private (with deprecation obviously).<br>
That might be a bit annoying for existing users that used long import paths, but it makes auto-complete much more helpful and the module structure much less confusing for newcomers.</p>
<p dir="auto">For example <code class="notranslate">sklearn.linear_model.ridge</code> is a module, while <code class="notranslate">sklearn.linear_model.ridge_regression</code> is a function that implements ridge regression and <code class="notranslate">sklearn.linear_model.Ridge</code> is a class that implements ridge regression. From the names this is totally unclear.</p>