Saturday, November 30, 2013

Measuring and validating the algorithm


In order to measure the performance and validate the algorithm described in the previous post, I created a validation script (attached below). The code randomly splits the character set in two and evaluates the similarity score. The assumption is that the two subsets of the same script should come out with a good similarity score (0 being identity - same character set). This is done 150 times for each of the scripts and outputs the average score received. The results are displayed below. For comparison, with this algorithm, the lowest similarity score between scripts is ~0.25 (between Thai and Gujarati) and the highest is ~25.24 (between Greek and Telugu).

Telugu: 2.17015555556
Cyrillic: 1.64583333333
Greek: 1.57917647059
Malayalam: 2.70133333333
Thai: 1.98205128205
Latin: 1.80256410256
Gujarati: 2.85166666667
Hebrew: 1.5647985348
Devanagari: 1.81041666667
Arabic: 2.29111111111
Tamil: 4.74801742919

The results are surprisingly good for such a simple algorithm (below 3 with the exception of Tamil). It seems to do better with the "straight - lined" scripts, such as Latin, Greek and Hebrew, than with the "round" scripts such as Tamil, Gujarati and Malayalam. I hope to improve the algorithm in the future, to reach a point where validation scores approach 0.


# -----------------------------------------------------------------------------
#
#  This script was created by Tamar Rucham
#
#  Measures the the algorithm in data_collection and languages_heatmap_results
#
# -----------------------------------------------------------------------------

from freetype import *
from data_collection import CalcChar, scripts

def run(chars, face):
    total_chars, total_contours, total_lines, total_curves = 0,0,0,0

    for singleChar in chars:
        ch = unichr(singleChar)
        contours, lines, curves = CalcChar(ch, face)

        total_chars = total_chars + 1
        total_contours = total_contours + contours
        total_lines = total_lines + lines
        total_curves = total_curves + curves

    return {'evarage_lines': float(total_lines)/float(total_chars), 'evarage_curves': float(total_curves) / float(total_chars)}

if __name__ == '__main__':
    import numpy
    import json
    import copy
    import random
    from languages_heatmap_results import getDiff


    face = Face('data/Arial Unicode.ttf')
    face.set_char_size( 48*64 )

    num_iterations = 150

    for scriptName, charsRange in scripts.items():
        total_diff = 0

        for iteration in range(num_iterations):
            diff = 0

            # Create two random subsets of the characters
            charsSlice1 = copy.deepcopy(charsRange)
            charsSlice2 = []
            for i in range(len(charsRange) / 2):
                # Dynamically get the len of the remaining of the array
                randIdx = random.randint(0, len(charsSlice1) - 1)
                charsSlice2.append(charsSlice1.pop(randIdx))

            slice1 = run(charsSlice1, face)
            slice2 = run(charsSlice2, face)
            total_diff += getDiff(slice1, slice2)

        print scriptName, ': ', (total_diff / float(num_iterations))

No comments:

Post a Comment