I’m working on a program that does OCR on a US business card and tries to return information like first name, last name, etc. The challenge is how to do that.
So far I’ve built the following data files:
first_names.txt (Contains 23k+ first names)
last_names.txt (Contains 86k+ last names)
job_title.txt (Contains 500+ job titles)
us_cities.txt (Contains 10k+ us cities)
states_full.txt (Contains full names of all US states)
states_abv.txt (Contains all US state abbreviations)
The goal was for me to tokenize the OCR data by spaces and try to award “weight” to each string based on the likeliness of it being a certain type of data.
For example, a string earlier in the text blob is more likely to be the name, company, or title. Likewise, if a string is found in first_names.txt or last_names.txt, then it will have more weight towards first/last name.
This approach sounds ok in theory, but I’m wondering about the best way to approach it from a programming perspective. (PHP, not that language matters) The tricky part is that some token’s weight are relative to other tokens. For example:
- If a token seems likely to be a first name, then it is likely that the next token is a last name.
- Some tokens are related to each other, but if things are exploded by spaces, I’m not sure how to relate them. Example, “Anne Marie, FL” would be considered three tokens – “Anne”, “Marie”, and “FL”. Worse yet, “Anne” and “Marie” would gain weight towards being a first name. Now, if weight is also awarded based on position, a previous string with first name weight could win, freeing these strings up to be detected as city.
I know there’s a lot of smart people out there, so maybe someone has an idea on this one!
It’s helpful to know the exceptions (e.g. a town named Mary Sue), but end users should be pleased if your software can handle the most likely cases. Names can be sorted by relative frequency of occurrence in each category: personal name, company name, city name. For companies, the number of employees can be used to calculate relative likelihood. For cities, population.
Do you already have rules to check the relative position of the line containing each token?
There are certainly quite a few business card formats, but if you have several hundred sample business cards you should be able to identify some common format rules. Having just a few rules could help immensely. One rule might be “80% of all cards have the address beneath the personal name and company name,” Although your sample of business cards may not be truly representative of all possible business cards, all languages, etc., etc., it’s a start. Even a few 50% and 80% rules could simplify your task.
You can probably think up several rules using a ridiculous example.
is more likely than
That suggests we can consider the relative Y-position of personal and company names relative to postal codes. Although personal name, job title, and company name may follow in any of several orders, postal codes are likely to be located below company names. Postal codes will be closer to city names, etc.
Although a word like “Samantha” could be part of a personal name, a street name, or a company name, it’s most likely a person name. You should be able to find databases that list the relative frequency of birth names, the population of towns with the name “Samantha”, and the number of registered corporations with the name “Samantha.” Even partial databases would be helpful to establish some reasonable guesstimates of likelihood.
Other possible rules: