<h4 dir="auto">Description</h4>
<p dir="auto">I noticed that sklearn.metrics.pairwise.pairwise_distances function agrees with np.linalg.norm when using np.float64 arrays, but disagrees when using np.float32 arrays. See the code snippet below.</p>
<h4 dir="auto">Steps/Code to Reproduce</h4>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import numpy as np
import scipy
import sklearn.metrics.pairwise

# create 64-bit vectors a and b that are very similar to each other
a_64 = np.array([61.221637725830078125, 71.60662841796875,    -65.7512664794921875],  dtype=np.float64)
b_64 = np.array([61.221637725830078125, 71.60894012451171875, -65.72847747802734375], dtype=np.float64)

# create 32-bit versions of a and b
a_32 = a_64.astype(np.float32)
b_32 = b_64.astype(np.float32)

# compute the distance from a to b using numpy, for both 64-bit and 32-bit
dist_64_np = np.array([np.linalg.norm(a_64 - b_64)], dtype=np.float64)
dist_32_np = np.array([np.linalg.norm(a_32 - b_32)], dtype=np.float32)

# compute the distance from a to b using sklearn, for both 64-bit and 32-bit
dist_64_sklearn = sklearn.metrics.pairwise.pairwise_distances([a_64], [b_64])
dist_32_sklearn = sklearn.metrics.pairwise.pairwise_distances([a_32], [b_32])

# note that the 64-bit sklearn results agree exactly with numpy, but the 32-bit results disagree
np.set_printoptions(precision=200)

print(dist_64_np)
print(dist_32_np)
print(dist_64_sklearn)
print(dist_32_sklearn)"><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">import</span> <span class="pl-s1">scipy</span>
<span class="pl-k">import</span> <span class="pl-s1">sklearn</span>.<span class="pl-s1">metrics</span>.<span class="pl-s1">pairwise</span>

<span class="pl-c"># create 64-bit vectors a and b that are very similar to each other</span>
<span class="pl-s1">a_64</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-c1">61.221637725830078125</span>, <span class="pl-c1">71.60662841796875</span>,    <span class="pl-c1">-</span><span class="pl-c1">65.7512664794921875</span>],  <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">np</span>.<span class="pl-s1">float64</span>)
<span class="pl-s1">b_64</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-c1">61.221637725830078125</span>, <span class="pl-c1">71.60894012451171875</span>, <span class="pl-c1">-</span><span class="pl-c1">65.72847747802734375</span>], <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">np</span>.<span class="pl-s1">float64</span>)

<span class="pl-c"># create 32-bit versions of a and b</span>
<span class="pl-s1">a_32</span> <span class="pl-c1">=</span> <span class="pl-s1">a_64</span>.<span class="pl-en">astype</span>(<span class="pl-s1">np</span>.<span class="pl-s1">float32</span>)
<span class="pl-s1">b_32</span> <span class="pl-c1">=</span> <span class="pl-s1">b_64</span>.<span class="pl-en">astype</span>(<span class="pl-s1">np</span>.<span class="pl-s1">float32</span>)

<span class="pl-c"># compute the distance from a to b using numpy, for both 64-bit and 32-bit</span>
<span class="pl-s1">dist_64_np</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-s1">np</span>.<span class="pl-s1">linalg</span>.<span class="pl-en">norm</span>(<span class="pl-s1">a_64</span> <span class="pl-c1">-</span> <span class="pl-s1">b_64</span>)], <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">np</span>.<span class="pl-s1">float64</span>)
<span class="pl-s1">dist_32_np</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-s1">np</span>.<span class="pl-s1">linalg</span>.<span class="pl-en">norm</span>(<span class="pl-s1">a_32</span> <span class="pl-c1">-</span> <span class="pl-s1">b_32</span>)], <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">np</span>.<span class="pl-s1">float32</span>)

<span class="pl-c"># compute the distance from a to b using sklearn, for both 64-bit and 32-bit</span>
<span class="pl-s1">dist_64_sklearn</span> <span class="pl-c1">=</span> <span class="pl-s1">sklearn</span>.<span class="pl-s1">metrics</span>.<span class="pl-s1">pairwise</span>.<span class="pl-en">pairwise_distances</span>([<span class="pl-s1">a_64</span>], [<span class="pl-s1">b_64</span>])
<span class="pl-s1">dist_32_sklearn</span> <span class="pl-c1">=</span> <span class="pl-s1">sklearn</span>.<span class="pl-s1">metrics</span>.<span class="pl-s1">pairwise</span>.<span class="pl-en">pairwise_distances</span>([<span class="pl-s1">a_32</span>], [<span class="pl-s1">b_32</span>])

<span class="pl-c"># note that the 64-bit sklearn results agree exactly with numpy, but the 32-bit results disagree</span>
<span class="pl-s1">np</span>.<span class="pl-en">set_printoptions</span>(<span class="pl-s1">precision</span><span class="pl-c1">=</span><span class="pl-c1">200</span>)

<span class="pl-en">print</span>(<span class="pl-s1">dist_64_np</span>)
<span class="pl-en">print</span>(<span class="pl-s1">dist_32_np</span>)
<span class="pl-en">print</span>(<span class="pl-s1">dist_64_sklearn</span>)
<span class="pl-en">print</span>(<span class="pl-s1">dist_32_sklearn</span>)</pre></div>
<h4 dir="auto">Expected Results</h4>
<p dir="auto">I expect that the results from sklearn.metrics.pairwise.pairwise_distances would agree with np.linalg.norm for both 64-bit and 32-bit. In other words, I expect the following output:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="[ 0.0229059506440019884643266578905240749008953571319580078125]
[ 0.02290595136582851409912109375]
[[ 0.0229059506440019884643266578905240749008953571319580078125]]
[[ 0.02290595136582851409912109375]]"><pre class="notranslate"><code class="notranslate">[ 0.0229059506440019884643266578905240749008953571319580078125]
[ 0.02290595136582851409912109375]
[[ 0.0229059506440019884643266578905240749008953571319580078125]]
[[ 0.02290595136582851409912109375]]
</code></pre></div>
<h4 dir="auto">Actual Results</h4>
<p dir="auto">The code snippet above produces the following output for me:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="[ 0.0229059506440019884643266578905240749008953571319580078125]
[ 0.02290595136582851409912109375]
[[ 0.0229059506440019884643266578905240749008953571319580078125]]
[[ 0.03125]]"><pre class="notranslate"><code class="notranslate">[ 0.0229059506440019884643266578905240749008953571319580078125]
[ 0.02290595136582851409912109375]
[[ 0.0229059506440019884643266578905240749008953571319580078125]]
[[ 0.03125]]
</code></pre></div>
<h4 dir="auto">Versions</h4>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Darwin-16.6.0-x86_64-i386-64bit
('Python', '2.7.11 | 64-bit | (default, Jun 11 2016, 03:41:56) \n[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]')
('NumPy', '1.11.3')
('SciPy', '0.19.0')
('Scikit-Learn', '0.18.1')"><pre class="notranslate"><code class="notranslate">Darwin-16.6.0-x86_64-i386-64bit
('Python', '2.7.11 | 64-bit | (default, Jun 11 2016, 03:41:56) \n[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]')
('NumPy', '1.11.3')
('SciPy', '0.19.0')
('Scikit-Learn', '0.18.1')
</code></pre></div>
<p dir="auto">There is a new bug in master brunch, <code class="notranslate">scikit-learn/sklearn/utils/fixes.py</code><br>
in line 406: <code class="notranslate">if np_version &lt; (1, 12, 0):</code> , an error occured, <code class="notranslate">TypeError: unorderable types: str() &lt; int()</code>.<br>
It's because in the function :</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="def _parse_version(version_string):
    version = []
    for x in version_string.split('.'):
        try:
            version.append(int(x))
        except ValueError:
            # x may be of the form dev-1ea1592
            version.append(x)
    return tuple(version)"><pre class="notranslate"><code class="notranslate">def _parse_version(version_string):
    version = []
    for x in version_string.split('.'):
        try:
            version.append(int(x))
        except ValueError:
            # x may be of the form dev-1ea1592
            version.append(x)
    return tuple(version)
</code></pre></div>
<p dir="auto">However， my numpy version is：<code class="notranslate">1.12.0b1</code>, this funciotn return a tuple(1,12,'0b1') , but in line 406, It is compared with integer type, so the error occured.<br>
I just in a simple way to solve it. I change the code to <code class="notranslate">if np_version &lt; (1, 12, '0'):</code> in line 406, just change the third tuple index to string type.<br>
Of course, this is not a common method.</p>