Method and apparatus for comparison of data strings5742706Abstract The present invention is a method and apparatus that measures the similarity of two images. Any information that can be discretely symbolized can be transformed into an image through so-called "image projection". This process is used to define otherwise discrete entities as part of a linear space, making it possible to calculate distances among those entities. A mechanism called a cluster allows association of otherwise discrete symbols, improving the matching abilities of the invention. Initially, the sequence of symbols is normalized. Then, a projection of the normalized sequence is created. The projection may be optionally generated with a cluster that assigns weights to the neighbors of a core symbol and/or with position weights that assigns weights to each position in the normalized image. Projection matching is then performed to determine match candidates for the string of symbols. Claims I claim: Description BACKGROUND OF THE PRESENT INVENTION
______________________________________
Encoding Table: {
______________________________________
31, 31, 31, 31, 31, 31, 31, 31,
/* 0-7 */
31, 31, 31, 31, 31, 31, 31, 31,
/* 8-15 */
31, 31, 31, 31, 31, 31, 31, 31,
/* 16-23 */
31, 31, 31, 31, 31, 31, 31, 31,
/* 24-31 */
31, 31, 31, 31, 31, 31, 31, 26,
/* 32-39 */
31, 31, 31, 31, 31, 27, 28, 31,
/* 40-47 */
31, 31, 31, 31, 31, 31, 31, 31,
/* 48-55 */
31, 31, 31, 31, 31, 31, 31, 31,
/* 56-63 */
31, 0, 1, 2, 3, 4, 5, 6, /* 64-71 */
7, 8, 9, 10, 11, 12, 13, 14,
/* 72-79 */
15, 16, 17, 18, 19, 20, 21, 22,
/* 80-87 */
23, 24, 25, 31, 31, 31, 31, 31,
/* 88-95 */
31, 0, 1, 2, 3, 4, 5, 6, /* 96-103 */
7, 8, 9, 10, 11, 12, 13, 14,
/* 104-111 */
15, 16, 17, 18, 19, 20, 21, 22,
/* 112-119 */
23, 24, 25, 31, 31, 31, 31, 31
/* 120-127 */
31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
/* 128-143 */
31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
/* 144-159 */
31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
/* 160-175 */
31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
/* 176-191 */
31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
/* 192-207 */
31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
/* 208-223 */
31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
/* 224-239 */
31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
/* 240-255 */
};
______________________________________
PROJECTION WITH CLUSTERS A cluster is a subset of the character set which contains a core character and any number of neighbor characters. Each character of the character set is a core character of a cluster. Each core character of a cluster has one or more neighbor characters. A cluster is used to represent relationships among characters. For example, the following cluster: {{MAP(`a`), 8}, {MAP(`s`), 2}, {MAP(`e`), 1}, {0, 0}} indicates that `s` and `e` are dose to `a` and `s` is closer to `a` than `e` is. The present invention uses an array of clusters, each cluster corresponds to a character in the character set as the core. That is, each character in the character set is the core character of its own cluster. Note that MAP() used above is to indicate that ASCII is usually not used for the comparison scheme of the present invention, and ASCII characters are mapped into a smaller set. The mapping function is used to reduce the size of the character set for memory optimization. The memory space for the full ASCII set may not be available. In addition, the actual symbols of interest, such as in a spelling checker, may be fewer than in the entire ASCII set. Therefore, the characters can be mapped into a smaller set. In one embodiment, characters are mapped into a space from 0 to 32. A cluster U.sub.i defines weights for neighbors of the core symbol or character i; u.sub.ii is the weight of i itself. Every symbol or character is the core of its cluster. In simple projection, a cluster has a core character as its only symbol, and the weight for the core is 1. When a cluster has more than one symbol, i.e. a core character and one or more neighbor characters, the core symbol or character is not only projected to its own closure but also its neighbors' closures. The projection becomes: C.sub.S.sbsb.i.sub.M(Si)+.vertline.D.vertline.+j =d.sub.j *u.sub.Sin C.sub.S.sbsb.i.sub.M(Si)+.vertline.D.vertline.-j =d.sub.j *u.sub.Sin (j=0,1,2, . . . , .vertline.D.vertline.-1) where n is a member of the cluster of S. Clusters are used to associate otherwise discrete symbols. The use of clusters can provide a means to tailor queries to provide desired results. For example, consider the word "communicate" and two misspellings of that word, namely "communikate" and "communigate". It may be desirable to implement the present invention so that "communikate" shows a higher degree of matching than "communigate" (because the "k" sound is more like the hard "c" sound of "communicate"). By including "k" in the cluster of "c", the present invention can show that "communikate" is more likely to be "communicate" than is "communigate". The present invention implements clusters through cluster tables. An example of a cluster table for the 26 lower case alpha characters is illustrated below. Referring to the cluster table, each row is a cluster, with the core character being identified in the leftmost column. The core character is followed by a series of pairs of values where the first value is the numeric representation of the character and the second value in the pair is the weight assigned to the character. The first value of each pair represents the numerical designation ("0" for "a", "1" for "b", "2" for "c", etc,) of a character in the cluster of the core character. The second number in each paired value represents the weight to be given the cluster character as a substitute for the core letter. The first pair is the core character itself and the value to be given when it is a match. The remaining pairs each represent a neighbor character and its assigned weight. For example, for the numeric representation "a", the first pair "›0, 8! represents letter "0" (i.e. "a") and its match weight of 8. A review of the table reveals that all core character have a weight of "8". In this example, a value of 8 is given for an exact match. Continuing with the cluster for the core character "a", the next pair is for the neighbor character "e", and its match weight of 4. the next two neighbor character, "o" (letter 14), and "s" (letter 18), have match weights of 2. The fourth neighbor character, "i", has a match weight of 4. For the letter "a", the letters "e" and "i" are more often by mistake than the letters "o" and "s". The cluster table values associated with each core character represent letters that may have the same sound as a letter (i.e. "k" and hard "c", "s" and "c") or that are near to each other on a standard "qwerty" keyboard, and are therefore likely to be a mis-stroke. The following cluster table is given by way of example only. Other cluster tables may be used without departing from the scope or spirit of the present invention.
______________________________________
cluster table: {
______________________________________
a: {{0,8}, {4,4}, {14,2}, {18,2}, {8,4}, {0,0}},
b: {{1,8}, {21,2}, {13,2}, {3,2}, {0,0}},
c: {{2,8}, {18,4}, {10,4}, {23,2}, {21,2}, {25,2}, {0,0}},
d: {{3,8}, {18,2}, {5,2}, {1,2}, {0,0}},
e: {{4,6}, {0,3}, {8,3}, {14,2}, {22,2}, {17,2}, {20,2}, {0,0}},
f: {{5,8}, {21,4}, {6,2}, {3,2}, {15,4}, {7,4}, {0,0}},
g: {{6,8}, {9,4}, {5,2}, {7,2}, {0,0}},
h: {{7,8}, {5,4}, {6,2}, {9,2}, {0,0}},
i: {{8,8}, {24,4}, {4,3}, {14,2}, {20,2}, {0,4}, {0,0}},
j: {{9,8}, {6,4}, {10,2}, {7,2}, {0,0}},
k: {{10,8}, {2,4}, {23,4}, {16,4}, {9,2}, {11,2}, {0,0}},
l: {{11,8}, {17,2}, {10,2}, {0,0}},
m: {{12,8}, {13,4}, {0,0}},
n: {{13,8}, {12,2}, {1,2}, {0,0}},
o: {{14,8}, {20,2}, {4,3}, {0,2}, {8,3}, {15,2}, {0,0}},
p: {{15,8}, {5,4}, {14,2}, {0,0}},
q: {{16,8}, {10,4}, {22,2}, {0,0}},
r: {{17,8}, {11,2}, {4,2}, {19,2}, {0,0}},
s: {{18,8}, {2,4}, {25,4}, {23,4}, {0,2}, {3,2}, {0,0}},
t: {{19,8}, {17,2}, {24,2}, {0,0}},
u: {{20,8}, {14,2}, {8,2}, {4,2}, {22,4}, {0,0}},
v: {{21,8}, {22,4}, {5,4}, {1,2}, {2,2}, {0,0}},
w: {{22,8}, {21,4}, {16,2}, {4,2}, {20,4}, {0,0}},
x: {{23,8}, {10,4}, {18,4}, {25,2}, {2,2}, {0,0}},
y: {{24,8}, {20,2}, {19,2}, {8,4}, {0,0}},
z: {{25,8}, {18,4}, {23,2}, {2,2}, {0,0}},
(other character's cluster)
{{26,8}, {0,0}},
{{27,8}, {0,0}},
{{28,8}, {0,0}},
{{29,8}, {0,0}},
{{30,8}, {0,0}},
{{31,8}, {0,0}}
______________________________________
The use of a cluster table is optional in the present invention. PROJECTION WITH POSITION WEIGHTS In addition to, or instead of, the use of weights in clusters, weights, w, can be assigned to each position in the normalized images. When a symbol is projected in the image, the distribution value and cluster weight can be multiplied with the weight associated with the symbol's position. Note that the weights are assigned to the normalized image instead of the original string. It is often the case that words are misspelled at the beginning rather than in the middle or end. The position table can be used to indicate that the first two positions of a word have twice the weight compared with others. Thus, the first two characters in the string will have more significant impact on the similarity comparison. So, if the beginnings of two words are the same, they are more likely to be the same word. The values of position weights are chosen to reflect the impact that the position has on the similarity comparison. Position weight is treated as a variable, not a constant, and its value can be selected to achieve the goal of representing the relative importance the position of a symbol or character has on a character or symbol string. When using position weights with cluster tables, the projection becomes: C.sub.S.sbsb.i.sub.M(Si)+.vertline.D.vertline.+j =d.sub.j *W.sub.M(Si) *u.sub.Sin C.sub.S.sbsb.i.sub.M(Si)+.vertline.D.vertline.-j =d.sub.j *W.sub.M(Si) *u.sub.Sin (j=0,1,2, . . . , .vertline.D.vertline.-1) When using position weights without clusters, the projection becomes: C.sub.S.sbsb.i.sub.M(Si)+.vertline.D.vertline.+j =d.sub.j *W.sub.M(Si) C.sub.S.sbsb.i.sub.M(Si)+.vertline.D.vertline.-j =d.sub.j *W.sub.M(Si) (j=0,1,2, . . . , .vertline.D.vertline.-1) The following code may be used to generate projections from a given symbol string:
______________________________________
* NAME
* zfmprojs - Projection Matching: generate projections
* DESCRIPTION
* generate projections from the string given and touch
* characters reached
*/
static eword
zfmprojs(pe.sub.-- p, str, slen, projs)
reg0 zfmpenv *pe.sub.-- p;
text *str;
eword slen;
ub2 *projs;
reg6 eword pp; /* count the positions in projection */
reg1 ub2 *prjptrl; /* pointers to go thru a proj */
reg7 ub2 *prjptrr;
reg3 ub2 *dptr; /* pointer to go thru dist› ! */
reg2 eword ss; /* score for a position */
reg8 zfmpclup
clstptr; /* pointer to go thru a cluster */
reg3 text ch; /* a char in the cluster */
reg9 text core; /* core char */
reg14 eword
score; /* score for the char */
reg10 eword
cc; /* *count the chars in string */
reg11 eword
sum; /* total score */
eword x0; /* beginning of a distribution */
/* following variables are copied from zfmpenv */
reg13 eword
size; /* size of the char set */
reg15 eword
neighbors;
/* neighbors */
reg12 ub2 *dist; /* distribution */
eword closure; /* size of the projection */
eword npos; /* number of positions */
ub2 *poswts; /* pointed to the weight table */
/* get info from the ZFMP structure */
size = pe.sub.-- p->pe.sub.--size;
neighbors
= pe.sub.-- p->pe.sub.--neighbors;
closure = pe.sub.-- p->pe.sub.--closure;
npos = pe.sub.-- p->pe.sub.--npos;
dist = pe.sub.-- p->pe.sub.--dist;
poswts = pe.sub.-- p->pe.sub.--poswts;
/* initialize work areas */
for (prjptrl = projs, pp = size * closure; pp; --pp, ++prjptrl)
{
*prjptrl = (ub2)0;
}
sum = (eword)0; /* sum is accumulated */
/* for each char (as a core) in the string */
for (cc = (eword)1, ++slen; cc < slen; ++cc, ++str)
{
core = *str;
/* check the range of the core */
if (core >= size)
{
continue;
}
/* locate the char in our projection */
if ((|cc) .vertline. .vertline. (slen == 1))
{
x0 = (eword)0; /* so that divived-by-0 won't happen */
}
else
{
x0 = cc * npos / slen;
}
/* get a cluster, for each char in the cluster, do . . . */
for (clstptr = (zfmpclup)pe.sub.-- p->pe.sub.-- clusters›core!;
clstptr->cl.sub.-- sc;
++clstptr)
{
ch = clstptr->cl.sub.-- ch;
/* get the score and mutiply the weigth */
score = (eword)clstptr->cl.sub.-- sc * poswts›x0!;
/* The char is touched. First compute the
points at the peak, than set prjptrl and
prjptrr at the left and the right of
the peak, respectively. */
prjptrl = projs + ch * closure + x0 + neighbors;
sum += *prjptrl = (ub2) (score * dist›0!);
prjptrr = (prjptrl--) + 1;
/* Priptrl and prjptrr are moving toward left
and right, away from the peak. The position
they point to have the same score, so that
ss is only calculated once. */
for (pp = neighbors, dptr = dist + 1;
pp;
--pp, --prjptrl, ++prjptrr, ++dptr)
{
ss = score * (*dptr); /* compute a score */
/* I am not sure whether to accumulate
points or to keep the highest one */
#ifndef ZFMPACCUMULATE
if (ss > *prjptrl)
{
sum += ss - *prjptrl;
*prjptrl = (ub2)ss;
}
if (ss > *prjptrr)
{
sum += ss - *prjptrr;
*prjptrr = (ub2)ss;
}
#else
sum += ss + ss;
*prjptrl += (ub2)ss;
*prjptrr += (ub2)ss;
#endif
}
}
}
return (sum);
}
______________________________________
PROJECTION MATCHING After a projection is generated, whether it be a simple projection, a projection with clusters, a projection with position weights, or a projection with both clusters and position weights, a comparison of the model projection and the query projection is made to determine the closeness of the match. The comparison is accomplished using a similarity function. A projection is a series of closures concatenated together. The similarity function .THETA. of the preferred embodiment of the present invention is defined as follows: ##EQU1## where P.sub.1 and P.sub.2 are two projections to be compared. When two projections are identical, or two original strings are identical, the similarity is 1. The lowest possible .THETA. is 0. FIG. 2 is a flow diagram illustrating the preferred embodiment of the present invention. At step 201, do zfmpopen() is performed. zfmpopen opens an environment in which other functions operate. It returns a handle to the open environment and this handle is kept and passed to other functions to refer to the same environment. poswts and dist are two 0-terminated integer arrays. They are used to adjust the behavior of the comparison mechanism. For example, the following setting: int poswts› !={2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; int disit› !={21, 20, 18, 15, 10, 6, 4, 2, 0}; gives more priority on the beginning of a string and compensates models that have their characters matched to nearby positions in the query. Usually poswts is longer than most of expected strings. The longer dist the more compensation is give on matched characters at different positions. But dist is not longer than poswts in the preferred embodiment of the present invention. An extreme case is: int poswts› !={1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; int dist› !={1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; which sets the string matching to a letter frequency comparison. The parameter clusters is an array of clusters, each cluster corresponds to a character in the character set as the core. Code for implementing zfmpopen() is illustrated in Appendix A. At step 202, zfmpquery() is executed on a query 203. The query is processed, a projection is calculated by calling zfmpprojs() at step 208, and the result is stored in memory. zfmpquery() sets a new query for an environment. Once a query is set, all comparisons made in the environment are based on this query. pe.sub.-- h indicates the environment, query is the query string, and qlen is the length of query. Code for implementing zfmpquery() is illustrated in Appendix B. At decision block 204, the argument "Get model?" is made. If the argument is true, the system proceeds to step 205. If the argument is false, their are no more models, and the system proceeds t6 step 206, where the best matches are displayed. At step 205, zfmpmodel() is executed. A model is processed by calling zfmpprojs() at step 208. A projection is returned and compared to the projection of the query. Code for implementing zfmpmodel is illustrated in Appendix C. At step 207, the similarity value for each model as compared to the query is provided. At step 208, zfmprojs() is used to normalize the input sequence and calculate and return its projection. zfmprojs() may use cluster tables and/or position weights as desired. PROJECTION GENERATION AND CODE LISTING FIGS. 5A-5B are flow diagrams that illustrate the invention's method for generating projections from a character string according to the computer code shown on pages 16-18 of the present application. The method begins at step 502. At step 504 variables are declared and an appropriate size is designated for each variable. These variables include (but are not limited to) "ch" for a character in the character string for which a projection is being performed; "core char" for a core character in a cluster of characters; "size" is the size of the character set, for example, the number of characters in the character set, e.g. 26 characters for the set of lower case alpha characters. (It is noted that a character string may use only a portion, and not all, of the character set). The variable "neighbors" stands for the characters neighboring a core character in a cluster of characters. The variable "npos" stands for the number of positions in the normalized string (for example, the number of slots shown in the normalized string on page 10). At step 508 variable values are obtained by opening a common structure (referred to as a "ZFMP" structure). Some of the variables referred to in steps 504 and 508 are set forth in box 506. At step 510, memory is allocated (work areas initialized) to perform the operations of flow charts 5A-5B. Also at step 510, the method of the invention checks for any errors in the character string. At step 512, each character in the character string is normalized according to the procedure described above. This is illustrated by the code equation "x0=cc*npos/slen; where x0 is the medium, cc is the character count, npos is the length of the normalized string, and slen is the length of the character string being normalized. In addition, the peak position of the character in the closure is determined. For example, if the character is the first character in the string, then the peak is at the beginning of the closure for that character. This is illustrated in the above example for the word "list". The peak for the character "L" is at the first "non-tail" position in the closure for "L". The tail is so that the distribution values can be placed in the closure. At step 514, for each character, the cluster for that character is obtained and a "score" value is generated for the core character and each neighbor character in the cluster. Fore example, if the character from the string is "a", a score value is generated for the closure for "a" as the core character, as well as for the closures for "o", "e", "s", and "i" respectively. The score value is generated pursuant to the code equation: score=(eword)clstptr.fwdarw.cl.sub.-- sc*poswts›x0!; As can be seen, this equation includes any position weight that may be assigned to the position in the string. At step 516 the values to the left and the right of the peak value are calculated. As described above, when a symbol is projected on the closure of a character in the character set, there is a distribution series so that values to the left and right of the peak value are calculated using the distribution series. The closure can be thought of as having a number of positions N with a "tail" on either side of length (D-1). When D=3 and N=8, for example, each character in the character set has a closure of length 8 with a two additional spaces at the beginning and two at the end for a total of 12. At decision block 518 the argument "More symbols remaining in the normalized string?" is made. If the argument is true, the system returns to step 512. If the argument is false, the system proceeds to step 520 and arranges the closures into a projection of the normalized string. That is, the closures that have been generated for the string (all characters in the string and any neighbor characters). These closures constitute the projection for that string. The process ends at step 520. FIG. 6 shows a flow chart that illustrates the invention's method according to the computer code shown in Appendix A. Operation begins at step 602. At step 604, variables are declared and an appropriate size is designated for each variable, as described in the comment "allocate and initialize zfmpenv structure" in Appendix A. At step 608 variable values are obtained by opening the common ZFMP structure. Some of the variables referred to in steps 604 and 608 are set forth in box 606. These variables include (but are not limited to) "size" which stands for the size of the character set, for example, the number of characters in the character set. "Maxsim", which stands for maximum similarity. This determines the degree of matching to indicate a match when doing projection matching. "Poswts" designates the weight assigned to each position in the normalized string. The variable "dist" is the distribution used in the invention, such as the distributions in distribution table #1 and distribution table #2 described above. The variable "clusters" designates the pair values assigned to each letter in a cluster table. Examples of these pair values are shown in the cluster table of page 14 in the specification. At step 610 the number of neighbors in a cluster of characters is counted. (for (i=0; disti›i!; ++i);/* ›sic! how many neighbors */neighbors=i=1); At step 612 the normalized size and closure size are counted. (for (i=0; poswts›i!; ++i);/* ›sic! how many positions */closure=i+neighbors*2; npos=i;) At step 614, work areas are initialized as shown below:
______________________________________
/* allocate ZFMP environment */
if (|(pe.sub.-- p = (zfmpenv *)malloc(sizeof(zfmpenv))))
return ((zfmpref *)0);
}
pe.sub.-- p->pe.sub.-- size = size;
pe.sub.-- p->pe.sub.-- maxsim = maxsim;
pe.sub.-- p->pe.sub.-- closure = closure;
pe.sub.-- p->pe.sub.-- neighbors = neighbors;
pe.sub.-- p->pe.sub.-- npos = npos;
pe.sub.-- p->pe.sub.-- dist = dist;
pe.sub.-- p->pe.sub.-- poswts = poswts;
pe.sub.-- p->pe.sub.-- clusters = clusters;
pe.sub.-- p->pe.sub.-- qprojs = 0;
pe.sub.-- p->pe.sub.-- mprojs = 0;
______________________________________
At step 616, memory is allocated as shown.
______________________________________
/* allocate memory */
if (|(pe.sub.-- p->pe.sub.-- qprojs = (ub2 *)malloc(sizeof(ub2) * size *
closure)) .vertline. .vertline.
|(pe.sub.-- p->pe.sub.-- mprojs = (ub2 *)malloc(sizeof(ub2) * size *
closure)))
zfmpclose((zfmpref *)pe.sub.-- p);
return ((zfmpref *)0);
}
zfmpopen stops at step 620.
______________________________________
FIG. 7 is a flow chart that illustrates the routine zfmpquery of step of FIG. 2 according to the computer code shown in Appendix B. This code generates a projection vector for the "query", that is, the string that is to be compared to the projection vectors of the model. This is accomplished by calling the routine "zfmprojs" of FIGS. 5A and 5B. Operation begins at step 702. At step 704, the variables values are set. This includes variables query (text string of the query), and qlen (query length). At step 706, a projection for the query is generated using zfmprojs routine. At step 708, the process ends. FIG. 8 is a flow chart that illustrates the invention's method of generating projections for the models and comparing each model's projection to the projection of the query to determine the degree of matching. This corresponds to step 205 of FIG. 2 of the present invention and according to the computer code shown in Appendix C. Operation begins at step 802. At step 804 variables are declared and an appropriate size is designated for each variable. At step 806 variable values are obtained by opening the common ZFMP structure. Some of the variables referred to in steps 804 and 806 are set forth in box 808. These variables include (but are not limited to) "model" which stands for a model character string for which a projection will be performed. "Mien" is another one of these variables; it designates the length of the model character string. "Sigma" stands for the total of projections (which is equal to the denominator of the equation on page 19). The variable "mprojs" designates the projection obtained for the model character string. Likewise, the variable "qprojs" denotes the projection obtained for the query character string. At step 810 projections are obtained for a model string. At step 812, the projection totals for the model are calculated as follows:
______________________________________
sigma = (ub4)zfmp.sub.-- c(pe.sub.-- h)->pe.sub.-- qsum +
zfmprojs(zfmp.sub.-- c(pe.sub.-- h), model,
mlen,
mprojs);
______________________________________
In other words, at step 812 part of the denominator and numerator (the part related to the model projection) of the equation illustrated in the section on projection matching is calculated. The part of the numerator that comes from the query is already calculated. At step 814, the difference between the model projection and the query projection is calculated as below:
______________________________________
/* calculate the difference */
delta = (eword)0;
for (i = zfmp.sub.-- c(pe.sub.-- h)->pe.sub.-- size * zfmp.sub.--
c(pe.sub.-- h)->pe.sub.-- closure;
i;
--i, ++qprojs, ++mprojs)
delta += *qprojs > *mprojs? (eword)*qprojs - *mprojs:
(eword)*mprojs - *qprojs;
}
return ((eword)((sigma - delta) * (zfmp.sub.-- c(pe.sub.-- h)->pe.sub.--
maxsim) /
sigma));
}
______________________________________
This algorithm differs from the equation for .THETA. given above in that a constant "maxsim" is used. This is used to ensure that integers will result from the equation, eliminating the need to work with fractions in the processing of the algorithm. The returned Value is then ratioed with the maxsim value to determine the degree of similarity. As discussed in the specification, no difference between the model projection and the query projection causes the left side of the equation shown in the section on projection matching to be equal to one. On the other hand, the greatest amount of difference (i.e., no similarity between the model and query projections) causes the left side of the equation to be equal to zero. The operation ends at step 816. EXAMPLE 1 As noted, the present invention can be implemented without using cluster tables or position weight tables. The invention can be implemented using one or both of the cluster table or position weight tables if desired. In this example the query is "communicate" and the model is "communicate" and no cluster table or position weight table is used. Query: Communicate Model: Communicate degree(maximum is 17) 16 similarity: 94.117645%:
______________________________________
query projection(a):
0 0 0 0 0 0 0 4 10 14 17 14 10 4 0 0
model projection(a):
0 0 0 0 0 0 0 4 10 14 17 14 10 4 0 0
query projection(c):
4 10 14 17 14 10 4 10 14 17 14 10 4 0 0 0
model projection(c):
4 10 14 17 14 10 4 10 14 17 14 10 4 0 0 0
query projection(e):
0 0 0 0 0 0 0 0 0 4 10 14 17 14 10 4
model projection(e):
0 0 0 0 0 0 0 0 0 4 10 14 17 14 10 4
query projection(i):
0 0 0 0 0 4 10 14 17 14 10 4 0 0 0 0
model projection(i):
0 0 0 0 0 4 10 14 17 14 10 4 0 0 0 0
query projection(m):
0 0 4 10 14 17 17 14 10 4 0 0 0 0 0 0
model projection(m):
0 0 4 10 14 17 14 10 4 0 0 0 0 0 0 0
query projection(n):
0 0 0 0 0 4 10 14 17 14 10 4 0 0 0 0
model projection(n):
0 0 0 0 4 10 14 17 14 10 4 0 0 0 0 0
query projection(o):
0 4 10 14 17 14 10 4 0 0 0 0 0 0 0 0
model projection(o):
0 4 10 14 17 14 10 4 0 0 0 0 0 0 0 0
query projection(t):
0 0 0 0 0 0 0 0 4 10 14 17 14 10 4 0
model projection(t):
0 0 0 0 0 0 0 0 4 10 14 17 14 10 4 0
query projection(u):
0 0 0 0 4 10 14 17 14 10 4 0 0 0 0 0
model projection(u):
0 0 0 4 10 14 17 14 10 4 0 0 0 0 0 0
______________________________________
Note that because cluster tables are not used, only the letters of the model (namely, a, c, e, i, m, n, o, t, and u), are used in the comparison. There are two peaks for the letter "c" because it is the first letter and the eighth letter in "communicate". There are two peaks for "m" in the query"communicate" but only one for the misspelled model "communicate". EXAMPLE 2 Example two illustrates a situation where a cluster table is used but the position weight table is not used. In this example, distribution table number 2 is used. query: communicate model: communicate degree(maximum is 136) 131 similarity: 96.323532%:
______________________________________
query 0 8 20 28 34 28 40 56 80 112 136 112 51 42 30 12
projection(a):
model 0 8 20 28 34 28 40 56 80 112 136 112 51 42 30 12
projection(a):
query 0 0 0 0 0 8 20 28 34 28 20 8 0 0 0 0
projection(b):
model 0 0 0 0 8 20 28 34 28 20 8 0 0 0 0 0
projection(b):
query 32 80 112 136 112 80 32 80 112 136 112 80 32 0 0 0
projection(c):
model 32 80 112 136 112 80 32 80 112 136 112 80 32 0 0 0
projection(c):
query 0 12 30 42 51 42 30 42 51 56 68 84 102 84 60 24
projection(e):
model 0 12 30 42 51 42 34 42 51 56 68 84 102 84 60 24
projection(e):
query 0 12 30 42 51 42 80 112 136 112 68 56 51 42 30 12
projection(i):
model 0 12 30 42 51 42 80 112 136 112 68 56 51 42 30 12
projection(i):
query 16 40 56 68 56 40 16 40 56 68 56 40 16 0 0 0
projection(k):
model 16 40 56 68 56 40 16 40 56 68 56 40 16 0 0 0
projection(k):
query 0 0 32 80 112 136 136 112 34 32 20 8 0 0 0 0
projection(m):
model 0 0 32 80 112 136 112 34 32 20 8 0 0 0 0 0
projection(m):
query 0 0 16 40 56 68 80 112 136 112 80 32 0 0 0 0
projection(n):
model 0 0 16 40 56 80 112 136 112 80 32 0 0 0 0 0
projection(n):
query 0 32 80 112 136 112 80 34 34 28 34 28 34 28 20 8
projection(o):
model 0 32 80 112 136 112 34 32 34 28 34 28 34 28 20 8
projection(o):
query 0 8 20 28 34 28 20 8 0 0 0 0 0 0 0 0
projection(p):
model 0 8 20 28 34 28 20 8 0 0 0 0 0 0 0 0
projection(p):
query 0 0 0 0 0 0 0 0 8 20 28 34 34 28 20 8
projection(r):
model 0 0 0 0 0 0 0 0 8 20 28 34 34 28 20 8
projection(r):
query 16 40 56 68 56 40 16 40 56 68 34 40 20 8 0 0
projection(s):
model 16 40 56 68 56 40 16 40 56 68 34 40 20 8 0 0
projection(s):
query 0 0 0 0 0 0 0 0 32 80 112 136 112 80 32 0
projection(t):
model 0 0 0 0 0 0 0 0 32 80 112 136 112 80 32 0
projection(t):
query 0 8 20 28 34 80 112 136 34 80 32 28 34 28 20 8
projection(u):
model 0 8 20 32 80 112 136 112 34 32 20 28 34 28 20 8
projection(u):
query 8 20 28 34 28 20 8 20 28 34 28 20 8 0 0 0
projection(v):
model 8 20 28 34 28 20 8 20 28 34 28 20 8 0 0 0
projection(v):
query 0 0 0 0 16 40 56 68 56 40 20 28 34 28 20 8
projection(w):
model 0 0 0 16 40 56 68 56 40 16 20 28 34 28 20 8
projection(w):
query 8 20 28 34 28 20 8 20 28 34 28 20 8 0 0 0
projection(x):
model 8 20 28 34 28 20 8 20 28 34 28 20 8 0 0 0
projection(x):
query 0 0 0 0 0 16 40 56 68 56 40 34 28 20 8 0
projection(y):
model 0 0 0 0 0 16 40 56 68 56 40 34 28 20 8 0
projection(y):
query 8 20 28 34 28 20 8 20 28 34 28 20 8 0 0 0
projection(z):
model 8 20 28 34 28 20 8 20 28 34 28 20 8 0 0 0
projection(z):
______________________________________
In this example, additional letters are tested because the cluster table is chosen. For example, the letter "a" is a core letter for the letters "e", "o", "s", and "i". The letter "c" is a core letter for the letters "s", "k", "x", "v", and "z". Therefore, the additional letters "b", "k", "p", "r", "s", "v", "w", "x", "y", and "z" are analyzed in addition to the letters in "communicate". Referring to the results above, there are two peaks for the letter "k", corresponding to the position of the letter "c" in "communicate". This is because "k" is in the cluster of the letter "c". There are also two peaks for each of the letters "s", "v", "x", and "z", all cluster letters of the letter "c". The peaks for these letters are smaller than that for the letter "k" because their match weight is lower. EXAMPLE 3 This example uses the position weight table, but not the cluster table. The position weight table is given by: {2, 2, 1, 1, 1, 1, 1, 1, 1, 1}. This means that the first two characters are given twice the weight as the remaining characters. This is because most spelling mistakes are made at the beginning of a word as opposed to the middle or end of a word. Distribution table number 2 is used. query: communicate model: communicate degree(maximum is 34) 32 similarity: 94.117645%:
______________________________________
query projection(a):
0 0 0 0 0 0 0 4 10 14 17 14 10 4 0 0
model projection(a):
0 0 0 0 0 0 0 4 10 14 17 14 10 4 0 0
query projection(c):
8 20 28 34 28 20 8 10 14 17 14 10 4 0 0 0
model projection(c):
8 20 28 34 28 20 8 10 14 17 14 10 4 0 0 0
query projection(e):
0 0 0 0 0 0 0 0 0 4 10 14 17 14 10 4
model projection(e):
0 0 0 0 0 0 0 0 0 4 10 14 17 14 10 4
query projection(i):
0 0 0 0 0 4 10 14 17 14 10 4 0 0 0 0
model projection(i):
0 0 0 0 0 4 10 14 17 14 10 4 0 0 0 0
query projection(m):
0 0 4 10 14 17 17 14 10 4 0 0 0 0 0 0
model projection(m):
0 0 4 10 14 17 14 10 4 0 0 0 0 0 0 0
query projection(n):
0 0 0 0 0 4 10 14 17 14 10 4 0 0 0 0
model projection(n):
0 0 0 0 4 10 14 17 14 10 4 0 0 0 0 0
query projection(o):
0 8 20 28 34 28 20 8 0 0 0 0 0 0 0 0
model projection(o):
0 8 20 28 34 28 20 8 0 0 0 0 0 0 0 0
query projection(t):
0 0 0 0 0 0 0 0 4 10 14 17 14 10 4 0
model projection(t):
0 0 0 0 0 0 0 0 4 10 14 17 14 10 4 0
query projection(u):
0 0 0 0 4 10 14 17 14 10 4 0 0 0 0 0
model projection(u):
0 0 0 4 10 14 17 14 10 4 0 0 0 0 0 0
______________________________________
The influence of the position weight table is seen in that the peaks for the first two letters, namely "c" and "o", are twice that of the peaks for the remaining letters, (34-17). Also note that the second occurrence of the letter "c" has only a peak of 17, versus the peak of 34 of the first occurrence. EXAMPLE 4 This example uses both a cluster table and a position weight table. The effect of the cluster table is shown by the additional cluster letters that are analyzed. The effect of the position weight table is shown for the letter "c" and "o", where the peak values are twice as high as for the other letters, (272-136). In addition, the first peaks for the cluster letters for "c", ("s", "k", "x", "v", and "z"), are twice as high as the second peak, illustrating the effect of the position weight table. The peaks for cluster letters for "o", ("u", "e", "a", "i", and "p"), are higher due to the position weight table. query: communicate model: communicate degree(maximum is 272) 263 similarity: 96.691177%:
______________________________________
query 0 16 40 56 68 56 40 56 80 112 136 112 51 42 30 12
projection(a):
model 0 16 40 56 68 56 40 56 80 112 136 112 51 42 30 12
projection(a):
query 0 0 0 0 0 8 20 28 34 28 20 8 0 0 0 0
projection(b):
model 0 0 0 0 8 20 28 34 28 20 8 0 0 0 0 0
projection(b):
query 64 160 224 272 224 160 64 80 112 136 112 80 32 0 0 0
projection(c):
model 64 160 224 272 224 160 64 80 112 136 112 80 32 0 0 0
projection(c):
query 0 24 60 84 102 84 60 42 51 56 68 84 102 84 60 24
projection(e):
model 0 24 60 84 102 84 34 42 51 56 68 84 102 84 60 24
projection(e):
query 0 24 60 84 102 84 80 112 136 112 68 56 51 42 30 12
projection(i):
model 0 24 60 84 102 84 80 112 136 112 68 56 51 42 30 12
projection(i):
query 32 80 112 136 112 80 32 40 56 68 56 40 16 0 0 0
projection(k):
model 32 80 112 136 112 80 32 40 56 68 56 40 16 0 0 0
projection(k):
query 0 0 32 80 112 136 136 112 34 32 20 8 0 0 0 0
projection(m):
model 0 0 32 80 112 136 112 34 32 20 8 0 0 0 0 0
projection(m):
query 0 0 16 40 56 68 80 112 136 112 80 32 0 0 0 0
projection(n):
model 0 0 16 40 56 80 112 136 112 80 32 0 0 0 0 0
projection(n):
query 0 64 160 224 272 224 160 34 34 28 34 28 34 28 20 8
projection(o):
model 0 64 160 224 272 224 34 64 34 28 34 28 34 28 20 8
projection(o):
query 0 16 40 56 68 56 40 16 0 0 0 0 0 0 0 0
projection(p):
model 0 16 40 56 68 56 40 16 0 0 0 0 0 0 0 0
projection(p):
query 0 0 0 0 0 0 0 0 8 20 28 34 34 28 20 8
projection(r):
model 0 0 0 0 0 0 0 0 8 20 28 34 34 28 20 8
projection(r):
query 32 80 112 136 112 80 32 40 56 68 34 40 20 8 0 0
projection(s):
model 32 80 112 136 112 80 32 40 56 68 34 40 20 8 0 0
projection(s):
query 0 0 0 0 0 0 0 0 32 80 112 136 112 80 32 0
projection(t):
model 0 0 0 0 0 0 0 0 32 80 112 136 112 80 32 0
projection(t):
query 0 16 40 56 68 80 112 136 34 80 32 28 34 28 20 8
projection(u):
model 0 16 40 56 80 112 136 112 34 32 20 28 34 28 20 8
projection(u):
query 16 40 56 68 56 40 16 20 28 34 28 20 8 0 0 0
projection(v):
model 16 40 56 68 56 40 16 20 28 34 28 20 8 0 0 0
projection(v):
query 0 0 0 0 16 40 56 68 56 40 20 28 34 28 20 8
projection(w):
model 0 0 0 16 40 56 68 56 40 16 20 28 34 28 20 8
projection(w):
query 16 40 56 68 56 40 16 20 28 34 28 20 8 0 0 0
projection(x):
model 16 40 56 68 56 40 16 20 28 34 28 20 8 0 0 0
projection(x):
query 0 0 0 0 0 16 40 56 68 56 40 34 28 20 8 0
projection(y):
model 0 0 0 0 0 16 40 56 68 56 40 34 28 20 8 0
projection(y):
query 16 40 56 68 56 40 16 20 28 34 28 20 8 0 0 0
projection(z):
model 16 40 56 68 56 40 16 20 28 34 28 20 8 0 0 0
projection(z):
______________________________________
EXAMPLE 5 This example illustrates a comparison of "communicate" and "communicate" without cluster table and without position weights, but using distribution table number 1. query: communicate model: communicate degree(maximum is 21) 20 similarity: 95.238098%:
______________________________________
query 0 0 0 0 0 0 0 4 10 14 17 19 21 19 17 14 10 4 0 0
projection(a):
model 0 0 0 0 0 0 0 4 10 14 17 19 21 19 17 14 10 4 0 0
projection(a):
query 4 10 14 17 19 21 19 17 14 17 19 21 19 17 14 10 4 0 0 0
projection(c):
model 4 10 14 17 19 21 19 17 14 17 19 21 19 17 14 10 4 0 0 0
projection(c):
query 0 0 0 0 0 0 0 0 0 4 10 14 17 19 21 19 17 14 10 4
projection(e):
model 0 0 0 0 0 0 0 0 0 4 10 14 17 19 21 19 17 14 10 4
projection(e):
query 0 0 0 0 0 4 10 14 17 19 21 19 17 14 10 4 0 0 0 0
projection(i):
model 0 0 0 0 0 4 10 14 17 19 21 19 17 14 10 4 0 0 0 0
projection(i):
query 0 0 4 10 14 17 19 21 21 19 17 14 10 4 0 0 0 0 0 0
projection(m):
model 0 0 4 10 14 17 19 21 19 17 14 10 4 0 0 0 0 0 0 0
projection(m):
query 0 0 0 0 0 4 10 14 17 19 21 19 17 14 10 4 0 0 0 0
projection(n):
model 0 0 0 0 4 10 14 17 19 21 19 17 14 10 4 0 0 0 0 0
projection(n):
query 0 4 10 14 17 19 21 19 17 14 10 4 0 0 0 0 0 0 0 0
projection(o):
model 0 4 10 14 17 19 21 19 17 14 10 4 0 0 0 0 0 0 0 0
projection(o):
query 0 0 0 0 0 0 0 0 4 10 14 17 19 21 19 17 14 10 4 0
projection(t):
model 0 0 0 0 0 0 0 0 4 10 14 17 19 21 19 17 14 10 4 0
projection(t):
query 0 0 0 0 4 10 14 17 19 21 19 17 14 10 4 0 0 0 0 0
projection(u):
model 0 0 0 4 10 14 17 19 21 19 17 14 10 4 0 0 0 0 0 0
projection(u):
______________________________________
EFFECTS OF OPTIONAL TABLES If a word such as "communicate" is misspelled as "communicate", generally we may say that these two words have 1 character different out of 11 characters. Thus, "communicate" is 91% similar to "communicate". However, the actual similarity of the two words is higher. Using the present invention, with cluster tables, position weights and distribution table number 1, the similarity becomes approximately 97%. Now compare the result of comparing "communicate" with "communikate" and "communigate". With cluster table above, a better similarity comes out when "communicate" is compared with "communikate" than compared with "communigate" (94.3% vs 91.7%). It means that "communikate" is more likely to be "communicate" than "communigate" is, since "k" and "c" sometimes may have same pronunciation, and "k" is in the cluster of "c". With the position weight table a better similarity (94.3% vs 92.2%) is achieved while comparing "communicate" with "communikate". A block diagram of the preferred embodiment of the present invention is illustrated in FIG. 3. A query string 301 is provided to normalizing block 302. Model vectors from model storage 313 are provided to normalizing block 302 on line 311. The normalizing block 302 normalizes the data string of S symbols into a normalized image of N symbols. The normalized image 303A of the query and the normalized image 303B of the model vector are provided to the projection generating block 304. A first memory means 305 for storing a cluster table is switchably coupled to projection generating means 304 through switch 307. A second memory means 306 for storing a position weight table is switchably coupled to projection generating means 304 through switch 308. Switches 307 and 308 can be independently controlled so that the projection vector 309 generated by projection generating block 304 may optionally include the effect of the cluster table 305 and/or the position weight table 306. The projection vector 309A of the normalized query 303A, and the projection vector 309B of the normalized model vector 303B, are provided to projection matching block 309. The projection matching block 310 generates a similarity value 312, representing the degree of similarity between the projection vector 309A of the query and the projection vector 309B of the model vector. The projection matching block 310 operates in accordance with the algorithm: ##EQU2## where P.sub.1 and P.sub.2 are two projections to be compared. When two projections are identical, or two original strings are identical, the similarity is 1. The lowest possible .THETA. is 0. The first, second, and third memory means of FIG. 3 can be implemented as three address regions in a single memory. In addition, the apparatus of FIG. 3 can be implemented on a processor as a plurality of processor executable instructions. Thus, a method and apparatus for comparing data strings has been described.
APPENDIX A
______________________________________
* zfmpopen - Projection Matching: open a ZFMP structure
* DESCRIPTION
* allocate and initialize zfmpenv structure
*/
zfmpref *
zfmpopen(size, maxsim, poswts, dist, clusters)
reg6 eword size;
reg12 eword maxsim;
reg8 ub2 *poswts;
reg7 ub2 *dist;
reg13 zfmpclut *clusters;
reg0 zfmpenv *pe.sub.-- p; /* pointer to return */
reg1 eword i;
/* following variables are calculated from the parameters */
reg4 eword neighbors;
reg5 eword closure;
reg10 eword npos;
/* We use array indexes instead of pointers, because we don't
want to distroy dist and poswts. The overhead is minor
since zfmpopen is only called once for each session. */
for (i = 0; dist›i!; ++i); /* ›sic! how many neighbors */
neighbors = i - 1;
for (i = 0; poswts›i!; ++i); /* ›sic! how many positions */
closure = i + neighbors * 2;
npos = i;
#ifdef DEBUG
printf("neighbors = %d, closure = %d, npos = %d.backslash.n",
neighbors, closure, npos);
printf ("dist› !: ");
for (i = 0; i < neighbors + 1; ++i) printf("%d ", dist›i!);
printf(".backslash.nposwts› !: ");
for (i = 0; i < npos; ++i) printf("%d, ", poswts›i!);
printf (".backslash.n");
#endif
/* allocate ZFMP environment */
if (|(pe.sub.-- p = (zfmpenv *)malloc(sizeof(zfmpenv))))
{
return ((zfmpref *)0);
}
pe.sub.-- p->pe.sub.-- size
= size;
pe.sub.-- p->pe.sub.-- maxsim
= maxsim;
pe.sub.-- p->pe.sub.-- closure
= closure;
pe.sub.-- p->pe.sub.-- neighbors
= neighbors;
pe.sub.-- p->pe.sub.-- npos
= npos;
pe.sub.-- p->pe.sub.-- dist
= dist;
pe.sub.-- p->pe.sub.-- poswts
= poswts;
pe.sub.-- p->pe.sub.-- clusters
= clusters;
pe.sub.-- p->pe.sub.-- qprojs
= 0;
pe.sub.-- p->pe.sub.-- mprojs
= 0;
/* allocate memory */
if (|(pe.sub.-- p->pe.sub.-- qprojs = (ub2 *)malloc(sizeof(ub2) * size *
closure))
.vertline. .vertline.
|(pe.sub.-- p->pe.sub.-- mprojs = (ub2 *)malloc(sizeof(ub2) * size *
closure)))
{
zfmpclose ((zfmpref *) pe.sub.-- p);
return ((zfmpref *)0);
}
/* cast and return */
return ((zfmpref *)pe.sub.-- p);
}
______________________________________
|
Same subclass Same class Consider this |
||||||||||
