[MRG] Locality Sensitive Hashing for approximate nearest neighbor search(GSoC)

I think this is too specific to LSH by random projection, and indeed to dense gaussian random projections (as opposed to sparse, simhash, etc.). I know you made something more generic initially, but I just don't see the benefit of storing this here. The current code is thus inconsistent about whether it's `GaussianRandomProjection`'s job to do the dot product or not (it is in `_create_tree`; it is not in `_convert_to_hash`).

The code in `_convert_to_hash` should really be used by `_create_tree`, too. But I'd forsee something more like storing a list of estimators as hash functions, where the estimators are something like `GaussianRandomProjectionHash` in the following:
```python
class ProjectionToHashMixin(object):
    """Turn a transformed real-valued array into a hash"""
    @staticmethod
    def _to_hash(projected):
        if projected.shape[1] % 8 != 0:
            raise ValueError('Require reduced dimensionality to be a multiple '
                             'of 8 for hashing')
        # XXX: perhaps non-copying operation better
        out = np.packbits((projected > 0).view(dtype='u1'))
        return out.reshape(projected.shape[0], -1)

    # TODO: using super's fit_transform is tricky in a mixin approach :(
    def fit_transform(self, X):
        self.fit(X)
        return self.transform(X)

    def transform(self, X):
        return self._to_hash(super(ProjectionToHashMixin, self).transform(X))


class GaussianRandomProjectionHash(ProjectionToHashMixin,
                                   GaussianRandomProjection):
    """Use GaussianRandomProjection to produce a cosine LSH fingerprint"""
    pass
```