I’m trying to find a way without just hard coding to create a categorical distribution over all characters given a character but with similar looking ones having higher probability. For example, if the input is ‘l’ then 1,j,!,/,I,t would be characters considered similar looking and should have a higher probability than other letters. Is there a way to do this without hard coding a distribution for every character?

The reason for this is I'm trying to create an algorithm that noises human names similar to the noise you'd expect in a dataset that are due to human error. For example, "Frank" could be noised by a person to be like "Fr4nk" (maybe they quickly doubled checked their work and they mistook the '4' for an 'a') or something like "Dell" could easily be miss inputted by a person as "De11" or "DeII"(These are actually capital i's rather than l's). I'm trying to create an algorithm to replicate this accurately.

  • $\begingroup$ Reminds me of NetHack's wipeout_text table for when you screw up an engraving. $\endgroup$ – Aaron Rotenberg Feb 7 at 15:10
  • $\begingroup$ this actually might be what I need. What was the purpose of this? $\endgroup$ – user8714896 Feb 7 at 21:21
  • $\begingroup$ What, the NetHack table? It is used in the game when you write in the dust and then smudge it by moving. The game picks a random subset of the letters in the message and replaces them with their corresponding "smudged" versions. The table only lists one possible smudge for each letter, so I doubt that it actually solves your problem. $\endgroup$ – Aaron Rotenberg Feb 7 at 22:15

I will assume, based on the way you presented the problem, that you only care about errors where single characters are replaced with other single characters—as opposed to merging two adjacent characters into a similar-looking single character, splitting a single character into two similar-looking adjacent characters, etc.

One option would be to build a table of confusion likelihood by using an existing OCR algorithm on an MNIST-style dataset of supervised character images. This does not eliminate the lookup table of probabilities, but it avoids having to construct the table by hand.

As I'm guessing you already know, each entry in this type of dataset is an image together with a label for which character that image supposedly represents. A typical neural network trained for this dataset can output, for any image, a score for each possible character that represents the algorithm's confidence that the image represents that character.

Given an image and the OCR algorithm's score of each possible output character, what you want to do is look at the score of each of the wrong outputs, i.e. the scores assigned to characters other than the one listed on the image's label. An image of a lowercase letter L is likely to have a high score not only for lowercase L but also for uppercase letter I, the digit 1, etc. You can average this information over all the images in the dataset [*] to form a score for each character pair $(a, b)$ of "probability of guessing character $b$ when it was actually supposed to be character $a$".

The dataset and OCR algorithm you choose will obviously affect your results. You will probably get different results using a dataset with handwritten letters in plain white on a black background than using a dataset of Street View house numbers (besides the fact that the house numbers only contain digits).

[*] If you are using an ML model that was trained on the same dataset you are using for building the table, you might want to only use the test dataset for building this table rather than also including the training dataset. Even though you would only be using the scores from the wrong outputs here, you want to avoid any possibility of things getting skewed somehow by overfitting.

  • $\begingroup$ I was thinking of something sort of similar but simpler. Take all digitized images of characters and do template matching over all but themselves to get a score of similarity then divide that score by the sum of scores to get the probability. Someone told me I was insane for that idea, but seems practical. I'm not against training a model for this but seems like a bit of overkill. $\endgroup$ – user8714896 Feb 7 at 21:19
  • $\begingroup$ @user8714896 I was figuring you could probably find a model that has already been trained by someone else. $\endgroup$ – Aaron Rotenberg Feb 7 at 22:11
  • $\begingroup$ that's also a really good idea. I wasn't sure if I could cause this seems like a super niche problem. $\endgroup$ – user8714896 Feb 7 at 22:15
  • $\begingroup$ The point of my answer is to take your niche problem (find similar-looking letters) and reduce it to a widely-studied problem (given an image, guess how likely the image is to represent each letter). $\endgroup$ – Aaron Rotenberg Feb 7 at 22:20
  • $\begingroup$ That'll work for sure, but you brought up the other issue of 1 letter being mistaken for 2, which that adds another layer that was worth considering that I did not consider previously. $\endgroup$ – user8714896 Feb 7 at 22:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.