joeerl

joeerl

Creator of Erlang - Fondly Remembered

The similarity challenge

(Programming challenge #1)

I’m often asked if I can think of any good problems to solve - well yes - here’s a problem I’ve been working on for years. It’s really difficult (and BTW it formed the subject of Chapter 27 (Sherlock’s last cast) - the final chapter in my Erlang book

Here’s the problem.

Given a large set of paragraphs find the most similar paragraphs in the set.

Why is this an interesting problem?

Finding similarities between things is an essential step in reducing
entropy - much of science happens because somebody notices that two
apparently different things have certain similarities.

Use cases:

  1. I have an idea - I write it down in a single paragraph that
    describes the idea. I then want to know “has anybody else had the same
    or a very similar idea” - ie search all paragraphs and find the most
    similar paragraph to what I have just written.

Comment: This is a very useful idea - often I have what I think is a
new idea I write it down, when search a bit only to find I had a
similar idea 20 years ago …

  1. Given a very large document (say 5-10,000 paragraphs) can I reduce
    the size of the document by finding very similar paragraphs.

Given two files A and B can I find a partition so that A = A1 ++ C ++
A2 and B = B1 ++ C ++ B2 (++ means append) in which case I can create
a file C and replace the common parts in A and B by links, or
translusions to C.

  1. Given a very large document can I find two paragraphs A and B that
    are so similar that one of them can be removed.

Now to the problems:

First I’ll define an input format.

The input is a JSON file like this:

[{“tag”““1”},{“value”:” the content of paragrpah 1"},
{“tag”:“2”},{“value”:" paragraph 2"},
…]

Tags identify the paragraphs, values are the paragraph data. I’m also
set a limit on paragraph sizes (say no longer than 1KB)

The program

$find_similarities <input> <output>

Finds the most similar paragraphs in writing the results to a
file

We also programs to create reasonable input data - so, for example a
program to take a typical input and turn it into a appropriate input
file is needed.

For starters we might use the Elixir Documentation or the set of RFCs

It would be fantastic to reduce the entropy of the set of all RFC’s –
I suspect they cut-and paste heavily in writing them. Many RFCs
reproduce the text from earlier RFCs so a similarity detector could
hopefully be used to reduce the total amount of text.

Algorithms

I have played with some similarities detectors for years now the problem is
that they are very slow.

Essentially we do this (pseudo code)

L = []
forall pairs of paragraphs A,B in <input>
  L += compute similarity(A,B)
end
then sort L and display the first few entries

This is essentially O(N^2) algorithm - and is painfully slow for large
data sets.

As for the similarity measures.

The best I have found (so far) is

This is very good for medium length paragraphs but very slow.

Keyword extraction using TF-IDF and consine similarity is good

(this was the method I described in my Erlang book) - a lot faster but
less accurate.

The Jaccard Index might be OK - I haven’t tried this

Or Levenenshtein distance - I haven’t tried this

If we want to detect similarities caused by cut-and-pasting text (ie
exact copies) then the rsync algorithms are great which just uses a
Rolling hash - Wikipedia algorithm. This is used in
plagiarism detection algorithms and is very fast.
See also this paper
https://www.andrew.cmu.edu/course/15-749/READINGS/required/cas/tridgell96.pdf

As a first step to solving this it would be good for somebody to write
code to generate test input data sets - with appropriate files names -
say _500.json might be a file containing 500 paragraphs from

Feel free to solve this in any other language or cross-post to any
other lists - I’m primarilty interested in the solution and algorithms
not the langauge used to solve the problem.

Any takers?

Any ideas for good similarity algorithms?

Most Liked

Qqwy

Qqwy

TypeCheck Core Team

This is a very interesting, but difficult, problem.

I completely agree with @AstonJ that a slight difference in wording can already completely change something’s meaning:

Let’s eat, grandma!

vs

Let’s eat grandma!

However, if you, for a given paragraph, just want to find a ‘top ten’ of similar paragraphs (after which it falls to the user to see if they indeed describe a similar idea), then that is definitely possible. You will still have many false positives (similar wordings, completely different meanings) as well as many false negatives (usage of synonyms or other ways to describe the same idea with completely different words).

The best bets here are probably the fuzzy text searching algorithms that already see widespread use in the web-search-engines we use every day.

Out of the listed algorithm possibilities, I’ve only worked with the Levenshtein distance before: It works well if you are comparing words, short strings, or have a limited alphabet (so it is great for spellcheckers or comparing DNA sequences), but rather slow for longer strings with a large alphabet (and we might consider a ‘word’ a symbol in an alphabet, I guess?) Also, it will greatly be influenced by the word-order, rather than which words they are.


A very interesting application that I really like, which does something similar but for symbols, is http://shapecatcher.com/ . Here, you draw whatever symbol you like, and it attempts to match this against a unicode-symbol, by comparing it with the "shape context"s of all shapes in its database More info.

If we’re able to generate a “paragraph context” in a sort of similar way, then that might speed up the searching tremendously (basically: Once we’ve indexed many paragraphs, we can find matching ones in linear time, or even go all the way into MapReduce-land and divide-and-conquer the wits out of this problem).

joeerl

joeerl

Creator of Erlang - Fondly Remembered

Thanks

I’ve read quite a few papers - but if you have any specific recommendations I’d appreciate it.

I don’t know why you say Elixir is not suitable for these algorithms - I’ve implemented many of the algorithms in “Managing Gigabytes” by Moffit and Bell ( a wonderful book BTW) and didn’t notice any performance problems - as soon as you start using ets tables etc. you’re virtually programming in C, so the low level operations are done in C and the high level operations (list comprehensions etc) are done in Erlang - the combination is pretty fast.

My purpose is understanding not performance - and good algorithms are key here.

Cheers

joeerl

joeerl

Creator of Erlang - Fondly Remembered

I found this book “Mining of Massive Datasets”
http://infolab.stanford.edu/~ullman/mmds/booka.pdf by Leskovec Rajaraman and Ullman.

Chapter 3 is brilliant and has a load of great references.

This is worthy of a close and careful reading - having slogged my way through the “Dragon book” I know that anything that Ullman has blessed is well worth the study.

Where Next?

Popular in Discussions Top

blackode
Elixir Upgrading is so Simple in Ubuntu and It worked for me Ubuntu 16.04 git clone https://github.com/elixir-lang/elixir.git cd elixir...
New
chuck
Let me start by stating an assumption: Phoenix is a great approach to building REST APIs. There are many reasons for this, but I will ass...
New
lucaong
Hello Elixir and Nerves community, I have been working for a while on an open-source embedded key-value database for Elixir, that I call...
230 13924 124
New
IVR
Hi all, I’ve seen a number of related threads in the past, but I’d still be very curious to hear an up-to-date opinion on this topic. I...
New
New
PragTob
Hey everyone, this has been on my mind for some time and I’d love your input on it! TLDR: I feel like maps are superioer for storing and...
New
RudManusachi
What configs will make sense to put to runtime.exs? – A bit of how I configure apps: I have generic configs in config/config.exs, dev...
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
tomekowal
Hey guys! I want to create a toy project that shows a chart of temperature over time and updates every 5 seconds. I feel LiveView is per...
New
opsb
We’re considering our architecture from a viewpoint of scaling our traffic heavily over the next 6 months. Our current deployment is runn...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29377 241
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43622 214
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement