Jaccard Index
en.wikipedia.org
en.wikipedia.org
Jaccard Similarity's history is also quite interesting. From my blog:
> In the late 19th century, the United States and several European nations were focused on developing strategies for weather forecasting, particularly for storm warnings. In 1884, Sergeant John Finley of the U.S. Army Signal Corps conducted experiments aimed at creating a tornado forecasting program for 18 regions in the United States east of the Rockies. To the surprise of many, Finley claimed his programs were 95.6% to 98.6% accurate, with some areas even achieving a 100% accuracy rate. Upon publishing his findings, Finley's methods were criticized by contemporaries who pointed out flaws in his verification strategies and proposed their solutions. This sparked a renewed interest in weather prediction, which is now referred to as the "Finley Affair."
> One of these contemporaries was Grove Karl Gilbert. Just two months after Finley's publication, Gilbert pointed out that, based on Finley's strategy, a 98.2% accuracy rate could be achieved simply by forecasting no tornado warning. Gilbert then introduced an alternative strategy, which is now known as Jaccard Similarity.
> So why is it named Jaccard Similarity? As it turns out, nearly three decades after Sergeant John Finley's tornado forecasting program in the 1880s, Paul Jaccard independently developed the same concept while studying the distribution of alpine flora.
I essentially wanted to use this as a way to flexibly filter out items without having to come up with a regex for every line item.
I wonder if anyone has done this before...
I had an idea Splunk had them built in? But it's about 5 lines of Python anyway.
Of note: the author of that library is none other than Daniel Lemire [3], whose articles pop up quite often on HN
[1] https://roaringbitmap.org/
[2] https://roaringbitmap.readthedocs.io/en/latest/#roaringbitma...
For example, perhaps one person likes Reddit and HN, while someone else likes HN and SO.
Then their Jaccard Index would be 1/3, since they have one thing in common out of three.
* Technically it computes "similarity" (larger number == more similar), but `1 - Jaccard Index` is a distance (smaller number == more similar).
It was developed by Grove Karl Gilbert in 1884 as his ratio of verification (v)[1] and now is frequently referred to as the Critical Success Index in meteorology.[2] It was later developed independently by Paul Jaccard…
It's an odd set of linkages to get there. First, "Dr. David J. Rogers of the New York Botanical Gardens" proposed a problem to Tanimoto, who published the writeup in an internal IBM report in 1958. (I understand there was a lot of mathematical research in taxonomy at the time.) In 1960 Rogers and Tanimoto published an updated version in Science.
In 1973 Adamson and Bush at Sheffield University developed a method for the automatic classification of chemical structures. They tried Dice, phi, and Sneath as their comparison methods but not Tanimoto. In their updated 1975 publication write "Several coefficients have been proposed based on this criterion", with a list of citations, including the Rogers and Tanimoto paper as citation 14.
In 1986, Peter Willett at Sheffield revisits this work and finds that Tanimoto gives overall better results when applied to what are now called cheminformatics "fingerprints". He uses "Tanimoto", with no direct citation for the source of that definition.
This similarity method is easy to implement, and many organizations already have pre-computed fingerprints (they are used as pre-filters for graph queries), so the concept and nomenclature takes off almost immediately, with "Tanimoto" as the preferred named.
It's not until 1991 that can find a paper in my field referring to the earlier work by Jaccard (the paper uses "Tanimoto (Jaccard)").
I have found some papers in related fields (eg, in IR and mass spectra analysis) which reference Tanimoto similarity, but nothing to the extent that my field uses it.
> In machine learning, it is known as the Matthews correlation coefficient (MCC) ... introduced by biochemist Brian W. Matthews in 1975.[1] Introduced by Karl Pearson,[2] and also known as the Yule phi coefficient from its introduction by Udny Yule in 1912
If one has a set of pairs that are similar, one can look for common bag differences in the matches. These can correspond to extra characters inserted in the identifier names for that particular program (for example, prefixes or suffixes related to module name or variable types.) Once these are found they can be used to tweak the similarity score.
jaccard = lambda A, B: len(set(A).intersection(set(B))) / len(set(A).union(set(B)))
I was happy to see Matthew's correlation coefficient (MCC) used in the recent "1st and Future - Player Contact Detection" Kaggle competition. MCC balances the eight confusion matrix ratios, and I've gotten excellent results when using it in the past.
One that makes it the better choice in situations where negative space should in fact be ignored. (comparing chest xrays are a typical example in medical imaging)
Suppose that one xray was taken in a larger machine, and therefore has more negative space around the lungs.
Also suppose that the algorithm delineated the lungs equally well in both cases (anatomically speaking).
If you assess performance using the jaccard index, the metric is equal in both cases, as it should be, indicating equal performance of the algorithm w.r.t. the ground truth.
Whereas anything that takes accuracy of true negatives into account will necessarily give a higher performance in the xray from the larger machine, even if the person xrayed and the lung outline were identical.
Obviously, a 100% perfect segmentation would of course register as perfect in both, but in practice one rarely deals with such perfect predictions.
In general, there is no metric that is universally "better" in all scenarios. One is expected to choose the metric that best suits the particular goal one wishes to validate against.
At reddit many moons ago before machine learning was a buzzword one early iteration of recommendations was based on Jaccard distance using the number of co-voters between subreddits. But with one twist: divide by the size of the smaller subreddit.
relatedness a b =
numerator = | voters on(a) ∩ voters on(b) |
denominator = | voters on(a) ∪ voters on(b) |
weight = min(|voters on(a)|, |voters on(b)|)
numerator / (weight*denominator)
That gives you a directional relatedness, that is programming->python but not necessarily python->programming. Used this way you account for the giant subreddit problem[1] automatically but now the results are less “amitheasshole is related to askreddit” and more like “linguisticshumor is a more niche version of linguistics”.The great thing is that it’s actually more actionable as far as recommendations go! Everybody has already heard of the bigger version of this subreddit, but they probably haven’t heard of the smaller versions. And it’s self-correcting: as a subreddit gets bigger we are less likely to recommend it, which is great because it needs our help less.
It's also easy to compute this because it lends itself to one giant SQL query that postgres or even sqlite[2] optimises reasonable well. It has some discontinuities around very tiny subredddits, so there was also a hack to just exclude them with a hack heuristic. It does get fairly static so once we've picked 3 subreddits to recommend if you're on subreddit A, if you don't like them we'll just keep showing them anyway. I had a hack in mind for that (use the computed values as random weights so we'll still occasionally show lower-scoring ones) but by this time people much smarter than I took over recommendations with more holistic solutions to the problem we were trying to solve in the first place. Still, as a first pass it worked great and based on my experience I'd recommend simple approaches like this before you break out the the linear algebra.
Side note, I tried co-commenters in addition to co-voters. The results tended more accurate in my spot tests but the difference fell away in more proper cross-validation testing and I didn't look into where the qualitative difference was. But since there are more votes than comments on small subreddits the number of recommendable subreddits was higher with votes. I reasoned that co-submitters (of posts) should be even more accurate but it was thrown off by a small number of spammers and I didn't want to mess with combining those tasks at the time.
[0]: https://news.ycombinator.com/item?id=22178517
[1]: that votes are distributed according to a power law, meaning that everybody has voted on the largest subreddits so most clustering approaches recommend askreddit to everybody. That's okay for product recommendations where "you should buy the most popular CPU, it's most popular for a reason" but for subreddits you already know that so we want a way to bias to the most "surprising" of your votes.
[2]: I prototyped it on sqlite on my laptop and even with close to the production amount of data it ran reasonable well. Not fast, but fine. This was on considerably less traffic to today, mind.
Can I send you a message and quote you in my thesis? You can shoot me a short message as well: violets.parr-0c@icloud.com
[1] http://www.mmds.org/ Chapter 3 [2] https://arxiv.org/abs/1706.05698
[1] https://papers.ssrn.com/sol3/papers.cfm?abstract_id=1658471
Reflection coefficient in electrical or acoustic (or elastic) transmission across two media is the difference of their impedances over the sum of them.
Difference over sum is a pattern you see a lot.
The Jaccard similarity between sets of uni- and bi-grams was a surprising effective metric.
DOG -> {d, o, g, do, og}
GOD -> {g, o, d, go, od}
intersection = {d, g, o}
union = {d, g, o, do, go, od, og}
J = 3 / 7 = ~43%