-
Notifications
You must be signed in to change notification settings - Fork 178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementation of CoverBounds class #98
Conversation
Clustering functions such as `DBSCAN` accept `metric='precomputed'`, which requires a square distance (similarity) matrix to be passed as, in this case, `inverse_X`. However, the mapper isn't aware when precomputed matrices are being passed in, so when it slices according to the filter function values and hypercubes, the square-ness is un-squared. This PR adds a kludgey way to tell the mapper that a precomputed matrix is being passed in. When set to `True`, the slice will feed a square matrix to `clusterer.fit()`
Hello @leesteinberg, Thank you for updating !
Comment last updated on July 10, 2018 at 08:57 Hours UTC |
Codecov Report
@@ Coverage Diff @@
## master #98 +/- ##
==========================================
+ Coverage 86.5% 87.15% +0.64%
==========================================
Files 6 6
Lines 415 436 +21
Branches 89 94 +5
==========================================
+ Hits 359 380 +21
Misses 37 37
Partials 19 19
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the pull request. I think the idea is there, but there are a few things I'm hoping can change before we merge the pull request. Right now there is a lot of repeated logic between both Cover and CoverBounds. I think it might work better to merge them both into one class, or rearrange so the repetition can be inherited properly.
kmapper/cover.py
Outdated
n_cubes=10, | ||
perc_overlap=0.2, | ||
# Deprecated parameters: | ||
nr_cubes=None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rm these parameters, nr_cubes and overlap_perc. only necessary in the base class for backwards compatibility.
kmapper/cover.py
Outdated
self.limits = limits | ||
|
||
# Check limits can actually be handled and are set appropriately | ||
NoneType = type(None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
defining this NoneType variable is weird. Why do it? Please just use type(None) when you need it.
kmapper/cover.py
Outdated
|
||
# If self.limits is array-like | ||
if isinstance(self.limits, np.ndarray): | ||
dump_arr = np.zeros(self.limits.shape) # dump_arr is used so we can change the values of self.limits from None to the min/max |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put comment on line above code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does dump_arr
mean? Maybe a better name would be limits_array
?
kmapper/cover.py
Outdated
'Actual Minima: %s\tInput Minima: %s\n' % (np.min(indexless_data, axis=0), bounds_arr[:,0])+ \ | ||
'Actual Maxima: %s\tInput Maxima: %s\n' % (np.max(indexless_data, axis=0), bounds_arr[:,1])) | ||
|
||
else: # It must be None, as we checked to see if it is array-like or None in __init__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this will only apply bounds if bounds are given, otherwise just behave as the base class. What about making this a little more explicit and not duplicating logic.
What do you think about something like
if isinstance(self.limits, np.ndarray):
<existing logic>
else:
super().find_bins(<params>)
This won't work exactly, but I think could take advantage of the inheritance a little better as there is a lot of repeated logic.
I agree with all the changes. Not sure how to deal with the last one. In principle, the Alternatively, could split Let me know what you think. In the meantime I'll push the other changes up. |
Thank you! I like your idea of rolling CoverBounds into Cover. The original intention was for different cover classes to enable things like hexagonal covers or stranger tilings. Bounds seem like the kind of feature that could be applied to many types of covers. |
How would you feel if I did both? A HexagonalCover would only need to modify the |
Doing both sounds fine. Making it easier to extend sounds preferable.
|
I'm just re-looking at the current version of the code. From what I can tell, a hexagonal (or other) covering would only need to modify the If this is the case, it might be best to just use the current Let me know your thoughts. |
That sounds like a fine idea to me! What do you think about also adding a stub of a class for It could be as simple as
|
Done as requested. Seems to pass the tests, and the class acts as before when no |
Adds a
CoverBounds
class - works similarly toCover
class, but requires extra variable:limits: Numpy array (n_dimension, 2)
------ The (min,max) desired value for a given dimension
This allows a cover to be defined where the limits of the cover are user defined, rather than being the minimum/maximum value of the function. Useful to ensure a series of networks are created with identical parameters.