<p dir="auto">This surfaces the discussion in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="105034406" data-permission-text="Title is private" data-url="https://github.com/scikit-learn/scikit-learn/issues/5216" data-hovercard-type="pull_request" data-hovercard-url="/scikit-learn/scikit-learn/pull/5216/hovercard" href="https://github.com/scikit-learn/scikit-learn/pull/5216">#5216</a>. Here are some precision differences than <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/JPFrancoia/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/JPFrancoia">@JPFrancoia</a> and I are looking at:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.utils.testing import assert_array_almost_equal

state = np.random.RandomState(0)
X = state.normal(loc=0, scale=100, size=(40, 20))
y = state.randint(0, 3, size=(40, 1))

# Train the LDA classifier. Use the eigen solver
lda_eigen = LDA(solver='eigen', n_components=5)
lda_eigen.fit(X, y)

lda_svd = LDA(n_components=5, solver='svd')
lda_svd.fit(X, y)
assert_array_almost_equal(lda_eigen.explained_variance_ratio_, lda_svd.explained_variance_ratio_)"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">numpy</span> <span class="pl-k">as</span> <span class="pl-s1">np</span>
<span class="pl-k">from</span> <span class="pl-s1">sklearn</span>.<span class="pl-s1">discriminant_analysis</span> <span class="pl-k">import</span> <span class="pl-v">LinearDiscriminantAnalysis</span>
<span class="pl-k">from</span> <span class="pl-s1">sklearn</span>.<span class="pl-s1">utils</span>.<span class="pl-s1">testing</span> <span class="pl-k">import</span> <span class="pl-s1">assert_array_almost_equal</span>

<span class="pl-s1">state</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-s1">random</span>.<span class="pl-v">RandomState</span>(<span class="pl-c1">0</span>)
<span class="pl-v">X</span> <span class="pl-c1">=</span> <span class="pl-s1">state</span>.<span class="pl-en">normal</span>(<span class="pl-s1">loc</span><span class="pl-c1">=</span><span class="pl-c1">0</span>, <span class="pl-s1">scale</span><span class="pl-c1">=</span><span class="pl-c1">100</span>, <span class="pl-s1">size</span><span class="pl-c1">=</span>(<span class="pl-c1">40</span>, <span class="pl-c1">20</span>))
<span class="pl-s1">y</span> <span class="pl-c1">=</span> <span class="pl-s1">state</span>.<span class="pl-en">randint</span>(<span class="pl-c1">0</span>, <span class="pl-c1">3</span>, <span class="pl-s1">size</span><span class="pl-c1">=</span>(<span class="pl-c1">40</span>, <span class="pl-c1">1</span>))

<span class="pl-c"># Train the LDA classifier. Use the eigen solver</span>
<span class="pl-s1">lda_eigen</span> <span class="pl-c1">=</span> <span class="pl-v">LDA</span>(<span class="pl-s1">solver</span><span class="pl-c1">=</span><span class="pl-s">'eigen'</span>, <span class="pl-s1">n_components</span><span class="pl-c1">=</span><span class="pl-c1">5</span>)
<span class="pl-s1">lda_eigen</span>.<span class="pl-en">fit</span>(<span class="pl-v">X</span>, <span class="pl-s1">y</span>)

<span class="pl-s1">lda_svd</span> <span class="pl-c1">=</span> <span class="pl-v">LDA</span>(<span class="pl-s1">n_components</span><span class="pl-c1">=</span><span class="pl-c1">5</span>, <span class="pl-s1">solver</span><span class="pl-c1">=</span><span class="pl-s">'svd'</span>)
<span class="pl-s1">lda_svd</span>.<span class="pl-en">fit</span>(<span class="pl-v">X</span>, <span class="pl-s1">y</span>)
<span class="pl-en">assert_array_almost_equal</span>(<span class="pl-s1">lda_eigen</span>.<span class="pl-s1">explained_variance_ratio_</span>, <span class="pl-s1">lda_svd</span>.<span class="pl-s1">explained_variance_ratio_</span>)</pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="AssertionError:
Arrays are not almost equal to 6 decimals

(shapes (20,), (3,) mismatch)
 x: array([  6.03795532e-01,   3.96204468e-01,   5.85621882e-16,
         3.18609950e-16,   2.08378911e-16,   1.21510637e-16,
         7.83079028e-17,   7.58612317e-17,   3.89040436e-17,...
 y: array([  5.52469269e-01,   4.47530731e-01,   7.08925911e-17])"><pre class="notranslate"><code class="notranslate">AssertionError:
Arrays are not almost equal to 6 decimals

(shapes (20,), (3,) mismatch)
 x: array([  6.03795532e-01,   3.96204468e-01,   5.85621882e-16,
         3.18609950e-16,   2.08378911e-16,   1.21510637e-16,
         7.83079028e-17,   7.58612317e-17,   3.89040436e-17,...
 y: array([  5.52469269e-01,   4.47530731e-01,   7.08925911e-17])
</code></pre></div>
<p dir="auto">Besides the fact that <code class="notranslate">lda_eigen</code> has the wrong number of components for the <code class="notranslate">explained_variance_ratio_</code> (according to the docs, it should have only <code class="notranslate">n_components=5</code>), there are numeric differences as well.</p>
<p dir="auto">The docs say that <a href="http://scikit-learn.org/stable/modules/generated/sklearn.discriminant_analysis.LinearDiscriminantAnalysis.html#sklearn.discriminant_analysis.LinearDiscriminantAnalysis" rel="nofollow">LDA.explained_variance_ratio_</a> should have only <code class="notranslate">n_components_</code>. But it doesn't.</p>
<p dir="auto">It looks like this bug only exists when we use the <code class="notranslate">eigen</code> solver, not the <code class="notranslate">svd</code> solver.</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="&gt;&gt;&gt; import numpy as np
&gt;&gt;&gt; from sklearn.lda import LDA
&gt;&gt;&gt; from sklearn.utils.testing import assert_equal
&gt;&gt;&gt;
&gt;&gt;&gt; state = np.random.RandomState(0)
&gt;&gt;&gt; X = state.normal(loc=0, scale=100, size=(40, 20))
&gt;&gt;&gt; y = state.randint(0, 3, size=(40, 1))
&gt;&gt;&gt;
&gt;&gt;&gt; # Train the LDA classifier. Use the eigen solver
&gt;&gt;&gt; lda_eigen = LDA(solver='eigen', n_components=5)
&gt;&gt;&gt; lda_eigen.fit(X, y)
&gt;&gt;&gt; assert_equal(lda_eigen.explained_variance_ratio_.shape, (5,))
AssertionError: Tuples differ: (20,) != (5,)

First differing element 0:
20
5

- (20,)
+ (5,)"><pre class="notranslate"><code class="notranslate">&gt;&gt;&gt; import numpy as np
&gt;&gt;&gt; from sklearn.lda import LDA
&gt;&gt;&gt; from sklearn.utils.testing import assert_equal
&gt;&gt;&gt;
&gt;&gt;&gt; state = np.random.RandomState(0)
&gt;&gt;&gt; X = state.normal(loc=0, scale=100, size=(40, 20))
&gt;&gt;&gt; y = state.randint(0, 3, size=(40, 1))
&gt;&gt;&gt;
&gt;&gt;&gt; # Train the LDA classifier. Use the eigen solver
&gt;&gt;&gt; lda_eigen = LDA(solver='eigen', n_components=5)
&gt;&gt;&gt; lda_eigen.fit(X, y)
&gt;&gt;&gt; assert_equal(lda_eigen.explained_variance_ratio_.shape, (5,))
AssertionError: Tuples differ: (20,) != (5,)

First differing element 0:
20
5

- (20,)
+ (5,)
</code></pre></div>
<p dir="auto">Looks like we fix either the docs or the code. Which one?</p>
<p dir="auto">Pinging <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/JPFrancoia/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/JPFrancoia">@JPFrancoia</a>.</p>
<p dir="auto">Addresses an issue in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="122161355" data-permission-text="Title is private" data-url="https://github.com/scikit-learn/scikit-learn/issues/6031" data-hovercard-type="issue" data-hovercard-url="/scikit-learn/scikit-learn/issues/6031/hovercard" href="https://github.com/scikit-learn/scikit-learn/issues/6031">#6031</a>.</p>