NGramJ"> CNgram"> ]> &ngramj;, smart ngram algorithms

What is &ngramj;?

ngrams are a rather classical instrument in Natural Language Processing (NLP) applications.

&ngramj; is a Java based library containing two types of ngram based applications. It's major focus is to provide robust and state of the art language recognition (or language guessing how some call it more correctly). Both types are meant to be embedded into larger applications.

Language recognition is not the only NLP application of ngrams and &ngramj; can be used as a building block in all kinds of differing applications. However Langugage recognition was my major application and therefore &ngramj; is somewhat streamlined for this.

&ngramj;
This uses ngrams of bytes to determine from a sequence of bytes both language and encoding. In symbols:
&ngramj; : byte[] --> (Language, Encoding)
&cngram;
This uses ngrams of characters to determine the langauge of a character sequence. In symbols
&cngram; : char[] --> Language
If you think of applying ngrams to files: &ngramj; is the right thing, if you do not know what encoding the files use. On the other hand if you know the encoding, it is better to explicitely use the encoding to read the file and apply &cngram; afterward.

Once you are in a program and treat Strings and other kinds of character sequences, &cngram; is the only reasonable way to go.

The &cngram; library has been developed under consideration of multithreading and performance requirements. &cngram; has also a language recognition mechanism which (to some extend) successfully recognizes mixed language documents.

Caution: For historical reasons &ngramj; sometimes refers to the (older) byte based ngrams excluding the newer addition of &cngram;. I'm sorry about the confusion.

There are alternative Java implementations of n-Grams.

Practical Usages

Other Applications

Apart from language/encoding recognition one can do more things with ngrams. None of them have been precanned into &ngramj; however.

Currently ngrams of other entities than bytes and characters are used, e.g. based on words. But this is beyond current &ngramj;.

Getting Started

Lets assume, you want to run &ngramj;. Developer information is elsewhere.

The process is very easy

  1. Download it from Sourceforge
  2. Decide between &cngram; and &ngramj;
If you have problems, please ask!

Download Instructions

It is assumed, that you have a recent (1.4+) Java environment on your computer. This is because, the programm has been precompiled for Java 1.4. At least the (older) byte-&ngramj; part has been carefully coded and tested to run with Java 1.1 when you add the repackaged collections-jdk1.2.jar which once kicked arround in the internet. I lost track of it. I'm not aware if these repackaged collections are a legal problem, but I'm also not sure if really anyone needs Java 1.1 anymore.

If you don't have Java, please, download java here.

&ngramj; currently comes in two different packages (VVV is some lengthy version information):

ngramj-VVV.bin.zip
A prebuild version with the basic jar archives with everything included to run instantly.
ngramj-VVV.all.zip
The complete development system, if you want to hack away yourself.

For the actual download go to the Sourceforge Download Page.

Decide Which Type

Run either byte &ngramj; or character &cngram; Here are some common cases.

You have files with text of unknown encoding.
Use byte &ngramj; to determine both encoding and language.
You have files with text of known encoding.
Use &cngram; to determine language or mixed language documents.
You don't have files but Strings within your Application.
Use &cngram; to determine language or mixed language Strings.
You have structured files in XML/HTML.
Usually encoding is not the problem, but you need to get rid of the markup by using a parser first, then use &cngram; to determine language or mixed language documents. Note: The parser has to be started somehow differently.

Use &cngram;

Usage is very simple.

  1. Unpack cngram.jar from the binary download.
  2. Type cngram.jar on the commandline. This is an self executing jar and this works on JRE installations from version 1.2. If your JRE is misconfigured use the equivalent call
    java -jar cngram.jar
  3. This command has several options, which are essentially self explaining.
  4. Note A: Some options are rather for testing than for usage.
  5. Most common call is
    cngram.jar -lang2 YOUR_FILENAME FILE_ENCODING
    which calls the new enhanced language determination. (-lang uses the old algorithm, -lang2b calls the new algorithm twice to demonstrate speedup.)
  6. Note B: File encoding for input files with &cngram; is optional, if you don't give on explicitely, ISO-8859-1 is used.
  7. When a metrics class is requested, you have to provide the full qualified classname of a class implementing de.spieleck.app.cngram.NGramMetric, thus describing a way how different ngram profiles are compared. Note, the de.spieleck.app.cngram.RawMetric seems to be the most common used.

Use &ngramj;

For historical reasons &ngramj; does not have such a simple commandline like &cngram;.

Unpack ngramj.jar from the binary download.

The call for language and encoding determination is.
ngramj.jar YOUR_FILENAME

Other calls are:

How Does it Work?

General Setting

An ngram is a (short) sequence of atoms like bytes, characters, words or whatsoever. In this settings we only care about bytes or characters. Though ngrams of words are a more recent technology.

As it turns out many properties of a underlying text (for example language, style, but even thematic focus) have a statistical stable impact on the ngram profile of this text. The ngram profile is the (statistical) distribution of ngrams, that is how often a certain ngram appears in a certain sequence.

Once you know you are hunting for a set of properties which is well reflected by a set of corresponding profiles, you can setup an automated search for these properties by the following steps.

  1. For each property create a reference profile from sample texts.
  2. For a text with unknown property, determine it's text profile and check if it is close to a reference profile.

The above description is far from being an algorithm. Actually there has to be some careful investigation if a property is refleced by ngrams profiles. You have to set up reference profiles from (as large as possible) reference suits of texts with that property. And you have to precise what you mean with closeness of two ngram profiles.

&ngramj; only cares about byte or character based ngrams. While there are other applications, the major application of this is the recognition of the language of a document. This is a somehow easier part of ngram application, for several reasons. To name two:

The &cngram; part of &ngramj; however uses a somewhat more elaborate notion of competitive ngram closeness which in the end assigns language percentages to a piece of text. This measurement is good enough that not only texts in one language but also texts with two major languages have been successfully classified with &ngramj;!

Technologies Used

&ngramj; is a very basic library. It is solely based on the following base technologies:

Since &ngramj; is more about algorithms, datastructures and some math there is no need to use other libraries. Java is more than enough. However we might add some log4j or so in an update, to ease error finding.

Software used

For running

Well of course it is a Java project. But beside an arbitrary JRE 1.2 or later (JRE 1.1 probably works when you have the plugin Collection Classes ) following things are (more or less) necessary for &ngramj;:

Nothing, unless you want to run the de.spieleck.app.ngramj.servlet.PhoneServlet on your server. The you need a servlet container of course.

For building

Apache Ant 1.6+
Is used as the prefered build tool for &ngramj;.
Saxon
Is used as my favourite XSLT engine, the one built in in JDK1.4 works also, but is slow and memory consuming. Saxon 6.5.x is definately necessary to build this documentation.
Spieleck Zip Task
A Ant-Zip-Task which allows to ad a directory prefix to all files compressed. Making a nicer Zip-file layout without the need to copy files back and forth.

Contact

Sourceforge provides every project with forums. Just go to the &ngramj; Forum page.

There is also a developer list. Both list are no traffic at time of this writing. Fell free to join.

How to Contribute?

Please help us and contribute, whatever you did with &ngramj;. Or even whatever you would like to do with it.

But there might be other things you want us to know.

Please contact us via our SourceForge pages.

There is also Sourceforge SVN repository for &ngramj;.

Developer Information

This will not be interesting to you, unless you consider doing programming work arround or in &ngramj;.

If you first want to build &ngramj; yourself you might want to look to the &ngramj; build section.

Note: Currently &ngramj; has been developed to the point, where it is useful for my initial task and some other simple applications. There might be entirely different tasks to be accomplished with &ngramj;

Please feel free to join or contribute!

Files and Directories

There are two basic download formats available. If you want to inspect the code, for fun or to improve it, the ...-all.zip is for you!

Depending on the version of the zip file you downloaded you will have some or all of the below files:

ngramj.jar
The &ngramj; classes bundled as self executable.
cngram.jar
The &cngram; classes bundled as self executable.
lib/
A directory with jar files required to run &ngramj;
doc/
The directory with (this) documentation and javadoc in html format.
src/
The sourcecode for &ngramj;, together with documentation source.
build.xml
The Ant job to build &ngramj;, jar file, documentation and javadoc.
build.properties
Properties moved out of build.xml file.
build.number
Version counting file.
ChangeLog.txt
Textual description of version changes. Not extremely carefully maintained.
LICENSE.txt
The text of the used license.
README.txt
Coarse project intro for non html people.
README-license.txt
Notice about the license of used components.

Building &ngramj;

This still has to be written.

General policy. &ngramj; provides a working ant file which does not use any special libraries unless you try to package distributions.

Javadocs

Here is the JavaDoc main index.

Be sure you have read the principles page, this should help you figuring what is going on.

Recommended start for reading classes:

The source code of both classes can also work as samples how the algorithms can be built into other application. It's not that difficult after all.

Changelog

This can also be found in the ChangeLog.txt file.

&changelog;

License

&ngramj; is Open Source published under the so called LGPL. This is:

          

    Copyright (C)   

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Also add information on how to contact you by electronic and paper mail.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the
  library `Frob' (a library for tweaking knobs) written by James Random Hacker.

  , 1 April 1990
  Ty Coon, President of Vice

That's all there is to it!


        ]]>
        

Design Decisions

I document this, cause this is IMHO the hardest thing to determine ad hoc given a bunch of more or less quality code.

Good performance

I use to be a performance geek. (byte) &ngramj; wasn't that bad in it times, but its basic design is still Java 1.1.8 some decisions are possibly to revisit after such a long time.

Competitive Scoring

&cngram; contains a new mechanism to be efficient at task which require many documents to be matched against a set of profiles.

This technique is based on (slightly costly) preprocessing of a set of profiles. Therefore the commandline version is actually slightly slower. But after preprocessing new texts can be classified without additional memory and without actually ever creating any ngram objects. The algorithm immediately competitively scores the text against the given sample profiles. It is needs time O(textlength * number of languages). With a relatively small proportional factor. Whereas the classical method to first convert a given a text into a profile, costs memory proprotional to the different ngrams in the text. And only afterward this profile has to be matched against prescribed profiles which costs time depending on the number of profiles and the number of total profiles involved. If you have very many sample languages and very short texts, the classical method might be superior to the new one.

While the new technique was mainly implemented to achieve high performance in tasks where many documents have to be language classified, it turns out that it can provide different, probably better results:

To avoid memory allocations all ngram scoring has to be "on the fly" based on a currently seen short segment of text. This restrictrion actually allows for some "context" to creep into evaluation. That is a actual ngram can score different depending on preceeding ngrams. This does actually happen. Look at the word "question". When it is analyzed alone it recognized as being French with some tendencies to Italian, Spanish and English. However analyzed as part of the phrase "To be or not to be, this is the question" the preceeding strong English context scores it as being English with a littlebit of French.

Note the new technique of profile preprocessing could be easily ported back to (byte) &ngramj;, but this hasn't been done yet.

Ternary Search Tries reimplemented

The competitive sampling procedure relies on a fast implementation of ternary search tries. This trie is "reentrant" in the sense, that you can proceed descending the tree after you found a match.

E.g. say we are parsing the String quest and we are currently proceeding the t. Then we have to look at the following ngrams in sequence: the 1-gram t, then the 2-gram st, then the 3-gram est. In a search trie of reversed ngrams we can first determine the leaf for t and then proceed into the subtrees for first ts and second tse, thus the lookup of all ngrams ending up with t can be done by only one traversal down the search trie.

No GUI

This is a library and the executables are mere demos and samples how to embed the library.

Other Information

Other information arround the &ngramj; project.

See subcategories on the left hand side.

Just that it doesn't get lost :-)

Alternative (Java) Implementations

There seem to be two contenders in the Open Source Java sphere.

Both projects however seem to have pulled some code from the ancient 2001 &ngramj; versions. With Nutch i'm not entirely sure, but TCatNG even contains &ngramj;'s misspellings and strange ad hoc random number generators. On the other hand, we have drawn some of our character based language profiles from the Nutch project.

After all, if you need something additional, you might consider joining forces and work with &ngramj;.

Outside the Java universe there are plenty of other implementation in whatever languages (C, Perl, Python and more).

Other Projects of Us

Well this is some advertisement. Other open source projects where we are major contributors are:

Jacson.
This is about platform independ parsing, filtering and extracting text files in a highly configurable fashion. It also features ant integration.
JTourney.
A tournament managment software for conducting round based tournaments.

What is spieleck.de?

<advertisement>
Well, it is my domain and that is why I use the namespace for my projects. spieleck.de is an semi experimental server to quickly try out ideas, some of them might survive or even go productive.
</advertisement>

Well, and for those of you who do not speak German: Spiel is game and Eck is corner and that that what it all was meant to be: A place to play and toy arround on the net.

References

http://odur.let.rug.nl/~vannoord/TextCat/
The original text_cat PERL version for byte based ngrams like byte &ngramj; The .lm profiles used for language/encoding evaluation by &ngramj; are mostly taken from the text_cat sources. The page contains links to many more interesting things!
http://www.nonlineardynamics.com/trenkle/papers/sdair-94-bc.ps.gz
Some theoretical basis of this program.
Comparing Two Language Identification Schemes.
(PDF - PS) In the Proceedings of the 3rd International Conference on the the Statistical Analysis of Textual Data (JADT'95), Rome, Italy, Dec. 1995.
Language Identifier: A Computer Program for Automatic Natural-Language Identification of On-line Text,
(PDF) Kenneth R. Beesley, 1988. Published in Proceedings of the 29th Annual Conference of the American Translators Association, 12-16 October 1988, pp. 47-54
Nutch
Nutch contains a language identification algorithm which is somehow between (byte)&ngramj; and &cngram;. Note that &cngram; can read Nutch language reference profiles, the &cngram; format is backward compatible. Actually some &cngram; language profiles have been taken from the Nutch project.
W3C about n_grams
Hmm, didn't know there is a standard, we read a proprietary format ... yet.