<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta>
      <journal-title-group>
        <journal-title>ACM, New
York, NY, USA, Article</journal-title>
      </journal-title-group>
    </journal-meta>
    <article-meta>
      <title-group>
        <article-title>Realtime query completion via deep language models</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Po-Wei Wang∗</string-name>
          <email>poweiw@cs.cmu.edu</email>
          <xref ref-type="aff" rid="aff3">3</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Huan Zhang∗</string-name>
          <email>ecezhang@ucdavis.edu</email>
          <xref ref-type="aff" rid="aff2">2</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Vijai Mohan</string-name>
          <email>vijaim@amazon.com</email>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Inderjit S. Dhillon∗</string-name>
          <email>isd@amazon.com</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>J. Zico Kolter</string-name>
          <email>zkolter@cs.cmu.edu</email>
          <xref ref-type="aff" rid="aff4">4</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>Amazon &amp; UT Austin</institution>
          ,
          <addr-line>Palo Alto, CA</addr-line>
          ,
          <country country="US">United States</country>
        </aff>
        <aff id="aff1">
          <label>1</label>
          <institution>Amazon</institution>
          ,
          <addr-line>Palo Alto, CA</addr-line>
          ,
          <country country="US">United States</country>
        </aff>
        <aff id="aff2">
          <label>2</label>
          <institution>Electrical and Computer Engineering</institution>
          ,
          <addr-line>UC Davis, Davis, CA</addr-line>
          ,
          <country country="US">United States</country>
        </aff>
        <aff id="aff3">
          <label>3</label>
          <institution>Machine Learning Dept, Carnegie Mellon University</institution>
          ,
          <addr-line>Pittsburgh, PA</addr-line>
          ,
          <country country="US">United States</country>
        </aff>
        <aff id="aff4">
          <label>4</label>
          <institution>School of Computer Science, Carnegie Mellon University</institution>
          ,
          <addr-line>Pittsburgh, PA</addr-line>
          ,
          <country country="US">United States</country>
        </aff>
      </contrib-group>
      <pub-date>
        <year>2018</year>
      </pub-date>
      <volume>4</volume>
      <issue>9</issue>
      <abstract>
        <p>Search engine users nowadays heavily depend on query completion and correction to shape their queries. Typically, the completion is done by database lookup which does not understand the context and cannot generalize to prefixes not in the database. In this paper, we propose to use unsupervised deep language models to complete and correct the queries given an arbitrary prefix. We address two main challenges that renders this method practical for large-scale deployment: 1) we propose a modified beam search process which integrates with a completion distance based error correction model, combining the error correction process (as a potential function) together with the language model; and 2) we show how to eficiently perform our modified beam search process on CPU to complete the queries with error correction in real time, by exploiting the greatly overlapped forward propagation process and conducting amortized dynamic programming on the search tree, along with both SIMD-level and thread level parallelism. We outperform the of-the-shelf Keras implementation by a factor of 50, thus allowing us to generate query suggestions in real time (generating top 16 completions within 16 ms). Experiments on two large scale datasets from AOL and Amazon.com show that the method substantially increases hit rate over standard approaches, reduces the memory footprint of database lookup based approach by over two orders of magnitude, and is capable of handling tail queries.</p>
      </abstract>
      <kwd-group>
        <kwd>Query completion</kwd>
        <kwd>query correction</kwd>
        <kwd>deep learning</kwd>
        <kwd>realtime</kwd>
      </kwd-group>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>-</title>
      <p>∗Work performed while at A9.com, an Amazon subsidiary
Permission to make digital or hard copies of part or all of this work for personal or
classroom use is granted without fee provided that copies are not made or distributed
for profit or commercial advantage and that copies bear this notice and the full citation
on the first page. Copyrights for third-party components of this work must be honored.
For all other uses, contact the owner/author(s).</p>
      <p>SIGIR eCom’18, July 2018, Ann Arbor, Michigan, USA
© 2018 Copyright held by the owner/author(s).</p>
      <p>ACM ISBN 123-4567-24-567/08/06.
https://doi.org/10.475/123_4</p>
    </sec>
    <sec id="sec-2">
      <title>INTRODUCTION</title>
      <p>Search completion is the problem of taking the prefix of a search
query from a user and generating several candidate completions.
This problem has enormous potential utility and monetary value
to any search provider: the more accurately an engine can find the
desired completions for a user (or indeed, potentially steer the user
towards high-value completions), the more quickly it can lead the
user to their desired goal.</p>
      <p>This paper proposes a realtime search completion architecture
based upon deep character-level language models. The basic idea
is that instead of looking up possible completions from a generic
database, we perform search under a deep-network-based language
model to find the most likely completions of the user’s current input.
This allows us to integrate the power of deep language models, that
have been shown to perform extremely well on complex language
modeling and prediction tasks, with the desired goal of finding a
good completion. Although this is a conceptually simple strategy
(and one which has been considered before, as we highlight below
in the literature survey), there are two key elements required to
make this of practical use for a search engine provider, which
together make up the primary technical contributions of the paper: 1)
The completion must be error correcting, able to handle small errors
in the user’s initial input and provide completions for the most
likely “correct” input. We propose such an approach that combines
a character-level language model with an edit-distance-based
potential function, combining the two using a tree-based beam search
algorithm; 2) The completion must be realtime, able to produce
highquality potential completions in time that is not even perceivable
to the user. We achieve this by developing an eficient tree-based
version of beam search and an amortized dynamic programming
algorithm for error correction based on completion distance (our
proposed editing distance variant) along the search tree, exploiting
thread-level and SIMD-level CPU-based computation for a single
query, and through numerous optimizations to the implementation
that we discuss below.</p>
      <p>We evaluate the method on the AOL search dataset, a dataset
consisting of over 36 million total search queries, as well as on an
Amazon product search dataset containing over 100 million user
search queries. Our proposed method substantially outperforms
highly optimized standard search completion algorithms in terms
of its hit rate (the benefit of the deep language model and the
error correction), while being fast enough to execute in real time
for search engines. Our approach is also very memory eficient
and reduces the memory usage of database lookup based query
completion system by at least two orders of magnitude; in addition,
we can handle tail queries, which are the queries that are rarely
seen and for which database lookup based approach cannot give
any query completions. The experiments on AOL search dataset
and code are publicly available online 1.
2
2.1</p>
    </sec>
    <sec id="sec-3">
      <title>RELATED WORK</title>
    </sec>
    <sec id="sec-4">
      <title>Background on search completion</title>
      <p>Here we review existing approaches to search query completion
and error correction. Broadly speaking, two types of query
completions are most relevant to our work, database lookup methods and
learning-based approaches.</p>
      <p>
        Database Lookup. One of the most intuitive ways to do query
completion is to do a database lookup. That is, given a prefix, we can
fetch all the known queries matching the prefix and return the most
frequent candidates. This is called the “most popular completion”
(MPC) [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ], which corresponds to the maximum likelihood estimator
for P (completion | prefix ). The database lookup can be eficiently
implemented by a trie [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ]. For instance, it takes only 15µ s to give
16 suggestions for a query in our own trie-based implementation.
However, due to the long-tail nature [
        <xref ref-type="bibr" rid="ref20">20</xref>
        ] of the search queries,
many prefixes might not exist in the database; for example, in the
AOL search data, 28% of the queries are unique. An excellent survey
of these current “classical” approaches is given in Cai et al. [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ].
      </p>
      <p>
        Learning-based. In addition to database lookup approaches, in
recent years there have been a number of approaches that use
learning-based methods for query completion. Sordoni et al. [
        <xref ref-type="bibr" rid="ref19">19</xref>
        ]
use a translation model at the word level to output single-word
search query suggestions, and also model consecutive sessions of
the same user. Liu et al. [
        <xref ref-type="bibr" rid="ref12">12</xref>
        ] proposed a word-based method for code
completion, but focused solely on greedy stochastic sampling for
the prediction. Mitra and Craswell [
        <xref ref-type="bibr" rid="ref14">14</xref>
        ] also used neural networks
combined with a database-based model to handle tail queries, but
focused on CNN approaches that just output the single most likely
word-level completion. Shokouhi [
        <xref ref-type="bibr" rid="ref18">18</xref>
        ] used logistic regression to
learn a personalized query ranking model, specific to individual
users. All these approaches are relevant but fairly orthogonal to our
own, as we focus here on character-level modeling, beam search,
and realtime completion. Finally, Park and Chiba [
        <xref ref-type="bibr" rid="ref15">15</xref>
        ] very recently
published an approach similar to ours, which uses a character-level
language model for completion. But their approach focuses on the
use of embeddings (such as word2vec) to produce “intelligent”
completions that make use of additional context, and the approach does
not handle error correction; they also do not report the prediction
time of their completions, which is a key driver for our work.
2.2
      </p>
    </sec>
    <sec id="sec-5">
      <title>Error correction for queries</title>
      <p>Our work also relates to methods on error and spelling correction
approaches, which again are roughly divided into heuristic models
and learning-based approaches.
1https://github.com/xflash96/query_completion</p>
      <p>
        Heuristic models. Whitelaw et al. [
        <xref ref-type="bibr" rid="ref22">22</xref>
        ] proposed generating
candidate sets that contain common errors for given prefixes, then
searching these based upon the current query. Similarly, Martins
and Silva [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ] use a ternary search tree to accelerate the search
within candidate sets for spelling correction in general. The
approaches are nice in that they are easily parallelizable at runtime,
but are relatively “brute force”, and cannot handle previously
unseen permutations.
      </p>
      <p>
        Learning-based Model. On the learning side, Duan and Hsu [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ]
train an n-gram Markov model combined with A* search to
determine candidate misspelling; this is similar to our approach except
with a much richer language model replacing the simple n-gram
model, which creates several challenges in the search procedure
itself. Likewise, Xie et al. [
        <xref ref-type="bibr" rid="ref23">23</xref>
        ] use a similar character-level model
with attention, but do so in the context of error correcting an entire
paragraph of text, and don’t focus on the same realtime aspects
that we do.
3
      </p>
    </sec>
    <sec id="sec-6">
      <title>BACKGROUND ON QUERY COMPLETION</title>
      <p>When a user types any prefix string s in the search engine, the query
completion function will start to recommend the best r completions,
each denoted sˆ, according to certain metrics. For example, one might
want to maximize the probability that a recommendation is clicked.
The conditional probability can be formulated as</p>
      <p>P (sˆ | s ) := P (completion | prefix ),
and the goal of query completion in the setting is to find the top
r most probable strings sˆ which potentially also maximize some
additional metric, such as the click-through rate.</p>
      <p>Denote s1:m as the first m characters in string s. We first discuss
the query completion in a simplified setting, in which all
completions must contain the prefix exactly, that is: sˆ1:m = s1:m , and
P (sˆ1:n | s1:m ) = P (sˆm+1:n | s1:m ) = P (sˆm+1:n | sˆ1:m ),
(2)
where n is the total length of a completion. Note that the probability
is defined in the sequence domain, which contains exponentially
many candidate strings. To simplify the model, we can apply the
conditional probability formula recursively and have
(1)
(3)
P (sˆm+1:n | sˆ1:m ) =
t =m
n−1</p>
      <p>Y P (sˆt +1 | sˆ1:t ).</p>
      <p>This way, we only need to model P (sˆt +1 | sˆ1:t ), that is, the
probability of the next character under the current prefix. This is precisely
a character-level language model, and we can learn it in an
unsupervised manner using a variety of methods, though here we focus on
the popular approach of using recurrent neural networks (RNNs)
for this character-level language model. Character-level models
are the right fidelity for the search completion task, because they
satisfy the customer’s expectation from the user interface, and
additionally, word-level models or sequence-to-sequence probabilities
would not be able to model probabilities under all partial strings.
3.1</p>
    </sec>
    <sec id="sec-7">
      <title>The Unsupervised Language Model</title>
      <p>
        We first focus on the language model term P (sˆt +1 | sˆ1:t ), the
probability of next character under the current prefix. RNNs in general,
and variants like long short term memory networks (LSTMs) [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ], are
extremely popular for high-fidelity character level modeling, and
achieve state-of-the-art performance for a number of datasets [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ].
Since they can be trained from unsupervised data (e.g., just datasets
of many unannotated search queries), we can easily adapt the model
to whatever terms users are actually searching for in the dataset,
with the potential to adapt to new searches, products, etc, simply
by occasionally retraining the model on all data collected up to the
current point.
      </p>
      <p>
        Although character-level language modeling is a fairly standard
approach, we briefly highlight the model we use for completeness.
Consider a recurrent neural network with hidden state ht at time t .
We want to encode the prefix sˆ1:t and predict the next character
using ht . We follow fairly standard approaches here and use an
LSTM model, in particular the specific implementation from the
Keras library [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ]2, which is defined by the recurrences
it = σ (Wxi xt + Whi ht −1 + bi ) ,
ft = σ Wx f xt + Whf ht −1 + bf ,
ot = σ (Wxoxt + Whoht −1 + bo ) ,
ct = it ⊙ tanh (Wxc xt + Whc ht −1 + bc ) + ft ⊙ ct −1,
ht = ot ⊙ tanh (ct ) ,
in which ht , b ∈ Rd , xt ∈ R|C |, ∀t , Wxi ,Wx f ,Wxo ,Wxc and
Whi ,Whf ,Who ,Whc are the forward kernel and recurrent kernel
with corresponding dimensions, σ is the sigmoid activation
function, and ⊙ is the element-wise product. We use a one-hot encoding
of characters as input, a two-layer LSTM with 256 to 1024 hidden
units (more discussion on these choices below), and for prediction
of character sˆt +1, we feed the hidden layer ht to a softmax function
P (sˆt +1 = i | sˆ1:t ) = softmax (i; Wsoftmaxht ) =
exp(wiT ht )
Pj|C= 1| exp(wTj ht )
(9)
,
for all i in the character set C and train the language model to
maximize the log likelihood (minimize the categorical cross-entropy
loss),
minimize −
      </p>
      <p>W
s ∈S |s | t =1</p>
      <p>X ns X|s| log P (st +1 | s1:t ),
where S denotes the set of queries, |s | is the length of query s and ns
is the number of times query s appears in the dataset. Further, we
pad all queries with an end-of-sequence symbol to predict whether
the query is complete.
3.2</p>
    </sec>
    <sec id="sec-8">
      <title>Stochastic Search and Beam Search</title>
      <p>
        Once we have the language model, we can evaluate the probability
P (sˆm+1:n | sˆ1:m ) for any prefix sˆ1:m , but would ideally like to find
the completion with the highest probability. Enumerating all the
possible strings is not an option because we have exponentially
many candidates. Indeed, finding the best sequence probability,
which is called the “decoding problem”, is NP-hard [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ], so we have
to rely on approximations.
2Note that, as we describe below, we won’t actually use the Keras library at prediction
time, but we do use it for training
(4)
(5)
(6)
(7)
(8)
(10)
      </p>
      <p>The most naive way to do so is simply via sampling: we sample
the next character (according to its probability of occurrence) given
the current prefix, until we hit an end-of-sequence (EOS) symbol:
For t = m; ; t ++ :
sˆt +1 ∼ P (sˆt +1 | sˆ1:t );</p>
      <p>If sˆt +1== EOS : break;
This method produces output that looks intuitively reasonable.
However, it is biased toward longer sequences (as we can possibly
miss the EOS symbol even if it has a relatively large probability)
with short-term dependencies and clearly does not generate the
most probable sequences, because sampling in a greedy fashion is
clearly not the same as sampling from the sequence space.</p>
      <p>That is, we really need to do a better approximate search to
get better results. One classic way to do this is to perform beam
search, that is, perform breadth-first search while keeping the top- r
candidates. We illustrate the algorithm as follows:
cand := {s1:m : 0}, result := { }
For t = m; cand is not empty; t ++:
cand := the most probable (r − |result|) candidates in candnew;
Move s1:t +1 from cand to result if st +1 is EOS symbol;
By performing beam search we can consistently obtain a more
probable set of completions compared to stochastic search.</p>
      <p>However, there are two issues with the above method. First,
it does not handle error correction (which is necessary for any
practical type of completion) since the completion always attempts
to find sequences that fit the current prefix exactly. 3 Second, as we
show below, a naive implementation of this model is extremely slow,
often taking on the order of one second to produce 16 completions
for a given prefix. Thus, in the next two sections, we present our
primary technical contributions, which address both these issues.
4</p>
    </sec>
    <sec id="sec-9">
      <title>COMPLETION WITH ERROR CORRECTION</title>
      <p>Most of the time, query completion is more than completing over a
ifxed prefix. The input prefix might contain mistakes and sometimes
we would also like to insert keywords in the prefix. Traditionally,
the database community handles the two features by first doing a
pass of error correction by matching the input to a typo database
generated by permuting characters, then matching the database
again on the permuted terms for insertion completion [17, chap.
14]. Our observation is that with a language-model-based approach,
we can handle the spelling correction and insertion completion all
in one model.
4.1</p>
    </sec>
    <sec id="sec-10">
      <title>Error correction via the noisy channel model</title>
      <p>Following the convention in the previous section, define s1:m and
sˆ1:n to be the prefix and completion string of length m and n,
respectively. Diferent from the previous section, we no longer constrain
3A character-level LSTM alone only gives the probability of the input/completion
sequence. It could not control the trade-of between the probability of user typos and
the likelihood of a completion, thus an error model is necessary.
the beginning of completions to be identical to the prefix so that
we can “correct” the user input. Thus, the problem of finding the
most probable completion becomes
Now let us derive the maximum-a-posteriori (MAP) estimate of the
above problem. Using Bayes’ theorem, (11) can be rewritten as
arg max P (sˆ1:n | s1:m )</p>
      <p>sˆ1:n
arg max P (s1:m | sˆ1:n )P (sˆ1:n ) .</p>
      <p>sˆ1:n P (s1:m )
Because s1:m never changes, P (s1:m ) can be considered as a constant.
Thus, solving (12) is equivalent to maximizing the following:
arg max log P (s1:m | sˆ1:n ) + log P (sˆ1:n ).</p>
      <p>
        sˆ1:n
This MAP estimate is called the noisy channel model [
        <xref ref-type="bibr" rid="ref10 ref2">2, 10</xref>
        ] in NLP,
in which the first part log P (s1:m | sˆ1:n ) models the noisy channel
of user inputs, and the second part log P (sˆ1:n ) models the prior. For
example, when using the noisy channel model for error correction
in a paragraph, we can assume that users have a constant
probability to make a typo for each letter. Under such assumption, the
noisy channel log P (s1:m | sˆ1:n ) is proportional to the edit distance
(Levenshtein distance). For the prior part, we can plug in whatever
P (sˆ1:n ) we have for the paragraph, like the n-gram transitional
probability or the language model. However, error correction for
queries is essentially diferent from that for paragraphs; in query
completion the user inputs are always incomplete. Thus, we must
perform the completion and error correction at the same time. One
consequence of such a constraint is that we can no longer use the
edit distance function directly.
4.2
      </p>
    </sec>
    <sec id="sec-11">
      <title>Edit Distance v.s. Completion Distance</title>
      <p>The edit distance function, which returns the minimum changes
(add/substitute/delete) to transform one string into another, is a
natural candidate to measure the number of corrections between
user inputs and completions. Assume that the probability by which
users make an error is constant, like 2%. As we mentioned before,
the noisy channel under such an assumption can be written as
log P (s1:m | sˆ1:n ) = −α · edit distance(s1:m , sˆ1:n ),
(14)
where α = − log 2%. Note that to handle incomplete prefix and
insertion completion, we should not incur penalties for the completions.
That is, we should not count the edit distance for adding words after
the last character (of terms) from the user input. This can be done
by modifying the transition function in the edit distance algorithm.
To be specific, we change the penalty to an indicator when dealing
with the “add” operation in the edit distance algorithm; we define
the new transition function to be
distnew(j-1) + I (sj−1 , last char) add;

distnew(j)= min distcompl(j-1) + 1 substitute;

distcompl(j) + 1 delete;

(15)
We called the new edit distance function a “completion distance”,
in a way that the completion “pokemon go plus” for the prefix
“poke go” would not incur unwanted penalties, because the added
(11)
(12)
(13)
characters are proper completions (only append character after
terms).</p>
      <p>
        To perform error correction under the noisy channel model, we
still need to integrate the noisy channel (distance function) with
our LSTM-based language model (the prior), which can only be
evaluated once in the forward direction because of the beam search
procedure. Recall that the dynamic programming algorithm [
        <xref ref-type="bibr" rid="ref21">21</xref>
        ] of
edit (completion) distance costs O (m · t ) to compare two strings of
length m and t . If we apply the algorithm to every candidate in the
beam search for the incremental length t which ranges from 1 to n,
it would add O (|C |rm · n2) overhead to the beam search procedure,
where |C | is the size of character set, r is the number of candidates
we keep, and n is the length of the final completion. This overhead
is not afordable, and we need to modify the dynamic programming
algorithm for completion distance to amortize it on the search tree.
We can exploit the fact that every new candidate in the beam search
procedure originates incrementally from a previous candidate. That
is, only one character is changed. Thus, if we can maintain the last
column in the completion distance algorithm, that is distcompl, ∀j,
for every candidate, we can save the repeated efort in building the
edit distance table. The resulting algorithm is summarized below:
cand := {empty string “ ”: 0}, result := { }
For t = 0; cand is not empty; t ++:
Maintain the last col of distnew for P (s1:m | sˆ1:t ) ∀sˆ1:t ∈ cand;
By such bookkeeping, we are able to amortize the completion
distance algorithm over the beam search procedure, making it n times
faster (from O (|C |rm · n2) to O (|C |rm · n)).
4.4
      </p>
    </sec>
    <sec id="sec-12">
      <title>Extensions</title>
      <p>
        While we are using the simple assumption (2% user error rate)
in this paper, the error correction algorithm can be generalized
in various ways [10, chap. 5]. For example, we can plug in the
frequency statistics in the transition function of edit distance [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ]
or learn it directly from the corpus [
        <xref ref-type="bibr" rid="ref22">22</xref>
        ]. Finally, we note that this
idea of inserting a noisy channel model naturally generalizes to
contexts other than edit distance. For example, many product search
engines wish to drive the user not simply to a high-probability
completion, but to a completion that is likely to lead to an actual
sale. By modifying the prior probability to more heavily weight
high-value completions, we can efectively optimize metrics other
than simple completion probability using this approach.
5
      </p>
    </sec>
    <sec id="sec-13">
      <title>REALTIME COMPLETION</title>
      <p>Starting with the system as proposed previously, the key challenge
that remains now is to perform such completions in real time.
Response time is crucial for query completion because unless the user
can see completions as they type the query, the results will likely
have very little value. The bar we set for ourselves in this work is to
provide 16 candidate completions in about 20 milliseconds on
current hardware.4 The 20 milliseconds budget, combined with typical
network latency, is similar to the pace that a user types in the query;
we need to complete faster than typing to make our realtime
completion usable in practice. Unfortunately, a naive implementation of
beam search with the model trained above (using of-the-shelf
implementations), requires more than one second to complete forward
propagation through the network and beam search.</p>
      <p>In this section, we now provide a detailed breakdown of how we
have empirically improved this performance by a factor of over 50x
in order to achieve sub-20-ms completion times.
5.1</p>
    </sec>
    <sec id="sec-14">
      <title>LSTM over a Tree</title>
      <p>First, we observe that all new candidates in the beam search process
are extensions from the old candidates because of the BFS property.
In this case, the forward propagations would greatly overlap. If we
can maintain ht for every old candidate, extending one character
for new candidates would require only one forward propagation
step. That is, we amortize the LSTM forward propagation over the
search tree. The algorithm is illustrated below.
cand := {s1:m : (hm , 0)}, result := { };
For t = m; cand is not empty; t ++:
candnew :=  s1:t +1 : (ht , log P (s1:t | s1:m ) + log P (st +1 | s1:t )) 

for every st +1 ∈ C, for every s1:t ∈ cand 



cand := the most probable r − |result| candidates in candnew
Move s1:t +1 from cand to result if st +1 is EOS symbol
Bump ht to ht +1 by one step of LSTM on st +1, ∀s1:t +1 ∈cand
Note that the initialization takes O (md2), and the four lines in the
loop cost O (r |C |d ), O (r |C |), O (r ), and O (rd2), where m is the length
of s1:m , d is the hidden dimension of LSTM, |C | is the length of
character set C, and r is the number of completions required. Using
this approach, the complexity for computing r completions for
ddimensional LSTM reduces from O (n2rd (d + |C |)) to O (nrd (d + |C |))
for sequence with maximum length n. A naive C implementation
shows that the running time for such search drops to 250 ms from
over 1 sec.
5.2</p>
    </sec>
    <sec id="sec-15">
      <title>CPU implementation and LSTM tweaks</title>
      <p>Although GPUs appear to be most suitable for computation in deep
learning, for this particular application we found that the CPU is
actually better suited to the task. This is due to the need for
branching and maintaining relatively complex data structures in the beam
search process, along with the integration of the edit distance
computation. Thus, implementation on a GPU requires a process that
frequently shufles very small amounts of data (each new character)
between the CPU and GPU and can be very ineficient. We thus
implemented the entire beam search, error correction and forward
propagation in C on the CPU.</p>
      <p>However, after moving to a pure CPU implementation, it is the
case that initially about 90% of the time is spent on computing
4Experiments are carried on an Intel Xeon E5-2670 machine. We use up to 8 threads,
and test it on the error-corrected query completion model with 512 hidden units. For
each input, 16 suggestions are generated.
the matrix-vector product in the LSTM. By properly moving to
batch matrix-matrix operations with a minibatch that contains all r
candidates maintained by beam search, we can substantially speed
this up; By grouping together the product between the W matrices
and ht for all r candidates maintained by the beam search procedure,
we can use matrix-matrix products, which have significantly better
cache eficiency even on the CPU. We use the Intel MKL BLAS, and
the total of these optimizations further reduces the running time to
75ms. By further parallelizing the updates via 8 OpenMP threads
brings completion time down to 25 ms.</p>
      <p>Finally, one of the most subtle but surprising speedups we
attained was through a slightly tweaked LSTM implementation. With
the optimizations above, computing the sigmoid terms in the LSTM
actually took a surprisingly large 30% of the total computation time.
This is due to the fact that 1) our LSTM implementation uses a hard
sigmoid activation, which as a clipping operation requires branch
prediction; and 2) the fact that the activations we need to apply the
sigmoid to are not consecutive in the hidden state vector means
we cannot perform fast vectorized operations. By simply grouping
together the terms it , ft , ot in the hidden state, and by using Intel
SSE-based operations for the hard sigmoid, we further reduce the
completion time down to 13.3ms, or 16.3ms if we include the error
correction procedure.
6</p>
    </sec>
    <sec id="sec-16">
      <title>EXPERIMENTAL RESULTS</title>
      <p>
        We evaluate our method on the AOL search dataset [
        <xref ref-type="bibr" rid="ref16">16</xref>
        ], a public
dataset of real-world searches from 2006, as well as an internal
dataset of product search queries from Amazon.com. The AOL
dataset contains 36 million total queries, with 10 million of these
being unique, illustrating the long tail in these search domains. We
set a maximum sequence length for the queries at 60 characters, as
this contained 99.5% of all queries. The Amazon dataset contains
a random sample of about 110 million product search queries that
users typed on the Amazon.com web site during 2017 (we excluded
sexually explicit and culturally insensitive or inappropriate queries).
      </p>
      <p>Training and testing splits. For each example in the dataset, we
choose a random cutting point (always after two characters in
the string), and treat all characters beforehand as the prefix and
all characters afterwards as the completion. For examples in the
validation and test set, we use these prefixes and actual completions
to evaluate the completions that our method predicts. In the training
set, we discard the cutting points and just train on the entire queries.</p>
      <p>For the AOL dataset, we use a test set size of 330K queries, and
use the rest for training. For the Amazon dataset we use a test set
size of 1 million queries. We create training and testing splits to
evaluate our method using two diferent strategies:
• Prefix splitting: sort the queries according to the MD5 hash
of the prefix, and then split. This ensures that data in the test
set does not contain an exact prefix match in the training
set.
• Time splitting: For both the AOL and Amazon datasets, we
sort the queries by timestamp and split. This mimics making
predictions online as new data comes in.</p>
    </sec>
    <sec id="sec-17">
      <title>Training language model</title>
      <p>We trained our character-level language model on the characters
of all the queries in the training set. We trained each model for 3-4
epochs over the entire dataset, and applied early stopping if the
validation loss did not improve for more than 50, 000 mini-batches.
We used a 2-layer LSTM with 256, 512, 1024 hidden dimensions with
dropout of 0.5 between the two LSTM layers (no dropout within
a single layer), and used Adam optimizer to train with a
minibatch size of 256. We use cross-entropy loss weighted by query
length for training. For each model, we select the learning rate
from {10−2, 10−3, 10−4}, weight decay from {10−7, 10−8, 10−9, 0} and
gradient norm clipping from {0.01, 0.001, 0.0001, 0.00001}. We also
conduct experiments on replacing LSTM with Gated Recurrent
Unit (GRU), as GRU has lower computation cost compared to LSTM.
Training and validation losses for each datasets, under the two
diferent splittings and varying LSTM/GRU dimensions, are shown
in Table 1. We observe that with the same model size, GRU usually
shows slightly worse performance than LSTM, and increasing the
hidden dimension does help in improving model performance.</p>
      <p>Our training time on a NVIDIA V100 GPU (on AWS P3 instance)
for the AOL dataset is 17, 18 and 24 hours for LSTM with 256, 512,
and 1024 neurons, respectively. For the Amazon dataset, we remove
all duplicate queries and apply per instance weight as the number
of occurrences of each query to reduce the number of training
examples to iterate over. The training time for the Amazon dataset
is roughly three times longer than the AOL dataset using a batch size
of 256. However, we found that if we increase the batch size to 1024,
we can speed up the training by a factor of 2.2 because of increased
GPU utilization, without noticeable performance loss. As a result,
we can run one epoch of the Amazon dataset in approximately 6
hours, and training on the entire dataset can be done within one
day.</p>
      <p>We evaluated relatively few other architectures for this model,
as the goal here is to use the character-level language model for
completion rather than attain state-of-the-art results on language
modeling in general. It is worth noting that the validation loss is
lower than the training loss in Table 1, and the two losses becomes
closer when the LSTM/GRU size is increased, indicating that our
models are still in the regime of under-fitting, and even larger
LSTM sizes may be used for improving performance. However, the
requirement of completing the queries in real-time forbids us from
using a larger model, as we will show shortly in the next section.
6.2</p>
    </sec>
    <sec id="sec-18">
      <title>Runtime evaluation</title>
      <p>Compared with the traditional database lookup based query
completion system, one challenge of our deep learning based approach
is its prediction time. Here we summarize the speedups achieved
by the diferent optimizations discussed in Section 5 in Table 2, and
report the time to give 16 suggestions for a prefix. A naive
implementation in Keras would result in a prediction time of over one
second per query, which is intolerable in the case of completing the
user’s query in real time, where a completion time close to typing
speed is desired. With all the optimization techniques applied, we
observe over 50X speedup comparing with a naive beam search
implementation. These optimizations are crucial to make our deep
learning based query completion practical as an online service.</p>
      <p>One interesting point to note is that stochastic search in this
setting actually takes three times longer with all the same optimization
techniques applied than beam search, to generate the same number
of completion candidates. This is due to the fact that stochastic
search tends to generate completions that are much longer than
those of beam search, interestingly making the “simpler” method
here actually substantially slower while giving worse completions
(which we will evaluate shortly).</p>
      <p>As an online service, it is important to pay attention to the
worstcase performance, especially because the nature of user query
preifxes have a long-tail nature. In Table 3, we measure the prediction
time using 100,000 real user query prefixes from Amazon.com, and
report the Top-Percentiles (TPS) performance. A TP99 of 12 ms
indicates that 99% of user requests can be served under 12 milliseconds.
In Figure 1, we plot the cumulative distribution function (CDF)
of prediction time. We observe that the distribution of prediction
time given real user query prefixes does have a very long tail. We
desire that the response time of our query completion service is
close to user typing speed, thus LSTM with 1024 hidden neurons
is unsuitable for our use case despite showing the best prediction
performance.</p>
    </sec>
    <sec id="sec-19">
      <title>Performance evaluation</title>
      <p>Finally, we evaluate the actual performance of the completion
approaches, both comparing the performance of our beam search
method to stochastic search (evaluated by log likelihood under the
model), and comparing our completion method to a heavily
optimized in-memory trie-base completion model, the standard data
structure for completion given string prefixes.</p>
      <p>Stochastic Search vs. Beam Search. In Table 5 we highlight the
performance of beam search versus stochastic search for query
completion, evaluated in terms of log likelihood under the model.
Over all models, splitting methods and LSTM sizes, beam search
produces substantially better results in terms of log likelihood; in
addition, it is 3x faster as mentioned above. Thus we believe that
beam search is necessary in our real-time query completion task,
justifying our eforts on optimizing its runtime. Note that in this
case we are not including any error correction, as it is not trivial to
integrate this into the stochastic search setting, and we wanted a
direct comparison on sample likelihood.</p>
      <p>Our approach vs. database lookup. Finally, we compare our total
approach (beam search with error correction) to a trie-based (i.e.,
prefix lookup) completion model. We compare the approach using
a combination of two metrics: 1) probabilistic coverage, which
is simply the empirical conditional probability of the predicted
completion given the prefix:</p>
      <p>X Pˆ(completion i | prefix ),
i
(16)
where Pˆ is the empirical probability for the whole dataset (counts
of completion i over all other queries with the same prefix in the
whole dataset); and 2) hit rate, which simply lists the number of
times a completion appears in the entire dataset. Because the error
correction model adjusts the prefix, it is not possible to compute
probabilistic coverage exactly, but we can still get a sense of how
likely the completions are based upon how often they occur using
the hit rate metric. Table 4 shows the performance of the trie-based
approach, beam search, and beam search with error correction
under these metrics. Our models generally outperform trie-based
approaches in all settings, the one exception being probabilistic
coverage on the time-based training/testing split. This is
possibly due to some amount of shift over time in the search query
terms. And although we cannot generate coverage numbers for the
error-correction method, the significantly larger hit rate suggests
that it is indeed giving better completions than all the alternative
approaches.</p>
      <p>Further, we note that in addition to these numbers, there are a
few notable disadvantages with trie-based lookup. The trie data
structure we compare to is very memory intensive (requires keeping
prefixes for all relevant queries in memory), and takes a minimum
of 11 GB of RAM for the entire AOL search data set, and over 50 GB
of RAM for the Amazon dataset. Our deep learning based language
model approach uses over two magnitudes less memory, even at
its largest configuration (LSTM-1024), as shown in Table 6. It is
worth mentioning that the Amazon dataset we used in experiments
contains user queries that are sampled from one month’s data on
amazon.com; if we want to utilize complete data from the month, it
can be memory intensive to use the trie-based approach, while our
deep learning based approach does not have this limitation and in
general, a learning based approach can benefit more from having a
bigger dataset.</p>
      <p>Additionally, if a prefix has not been seen before in the dataset,
the trie-based approach will ofer no completions. In our test set
of the Amazon dataset, which contains user queries from a time
period subsequent to the training data, we observe that there are a
substantial fraction of queries which do not appear in the training
data. A trie-based query approach cannot give these queries as
suggestions, whereas our deep learning based approach can still
make suggestions using its language model. Furthermore, the
triebased approach is not amenable to error correction in isolation, as
candidate corrections need to be proposed prior to lookup in the
database; the process of repeatedly generating these candidates and
performing the lookups will work for at most 2 edits, whereas our
approach empirically easily handles completions that include 4-5
edits; this is reflected in the significantly higher hit rate in Table 4.
7</p>
    </sec>
    <sec id="sec-20">
      <title>CONCLUSIONS</title>
      <p>In this paper, we have presented a search query completion
approach based upon character-level deep language models. We
proposed a method for integrating the approach with an error
correction framework and showed that candidate completions with
error correction can be eficiently generated using beam search. We
further described several optimizations that enabled the system to
deliver results in real time, including a CPU-based custom LSTM
implementation. We demonstrated the efectiveness of our method
on two large-scale datasets from AOL and Amazon, and showed
that our proposed deep learning based query completion model
is able to jointly produce better completions than simple prefix
lookup, while simultaneously being able to generate the candidates
in real time.</p>
      <p>Acknowledgment. The authors thank Juzer Arsiwala for his
help on preparing Amazon training dataset.
1.0
0.8
0.6
F
D
C0.4
0.2
0.0
1.0
0.8
1.0
0.8</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>Ziv</given-names>
            <surname>Bar-Yossef</surname>
          </string-name>
          and
          <string-name>
            <given-names>Naama</given-names>
            <surname>Kraus</surname>
          </string-name>
          .
          <year>2011</year>
          .
          <article-title>Context-sensitive query auto-completion</article-title>
          .
          <source>In Proceedings of the 20th international conference on World wide web. ACM</source>
          ,
          <volume>107</volume>
          -
          <fpage>116</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>Eric</given-names>
            <surname>Brill and Robert C Moore</surname>
          </string-name>
          .
          <year>2000</year>
          .
          <article-title>An improved error model for noisy channel spelling correction</article-title>
          .
          <source>In Proceedings of the 38th Annual Meeting on Association for Computational Linguistics. Association for Computational Linguistics</source>
          ,
          <fpage>286</fpage>
          -
          <lpage>293</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>Fei</given-names>
            <surname>Cai</surname>
          </string-name>
          , Maarten De Rijke, et al.
          <year>2016</year>
          .
          <article-title>A survey of query auto completion in information retrieval</article-title>
          .
          <source>Foundations and Trends® in Information Retrieval</source>
          <volume>10</volume>
          ,
          <issue>4</issue>
          (
          <year>2016</year>
          ),
          <fpage>273</fpage>
          -
          <lpage>363</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>François</given-names>
            <surname>Chollet</surname>
          </string-name>
          et al.
          <year>2015</year>
          . Keras. https://github.com/fchollet/keras. (
          <year>2015</year>
          ).
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>Junyoung</given-names>
            <surname>Chung</surname>
          </string-name>
          , Sungjin Ahn, and
          <string-name>
            <given-names>Yoshua</given-names>
            <surname>Bengio</surname>
          </string-name>
          .
          <year>2016</year>
          .
          <article-title>Hierarchical multiscale recurrent neural networks</article-title>
          .
          <source>arXiv preprint arXiv:1609.01704</source>
          (
          <year>2016</year>
          ).
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>Huizhong</given-names>
            <surname>Duan</surname>
          </string-name>
          and Bo-June Paul Hsu.
          <year>2011</year>
          .
          <article-title>Online spelling correction for query completion</article-title>
          .
          <source>In Proceedings of the 20th international conference on World wide web. ACM</source>
          ,
          <volume>117</volume>
          -
          <fpage>126</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>G David</given-names>
            <surname>Forney</surname>
          </string-name>
          .
          <year>1973</year>
          .
          <article-title>The Viterbi algorithm</article-title>
          .
          <source>Proc. IEEE 61</source>
          ,
          <issue>3</issue>
          (
          <year>1973</year>
          ),
          <fpage>268</fpage>
          -
          <lpage>278</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <given-names>Sepp</given-names>
            <surname>Hochreiter</surname>
          </string-name>
          and
          <string-name>
            <given-names>Jürgen</given-names>
            <surname>Schmidhuber</surname>
          </string-name>
          .
          <year>1997</year>
          .
          <article-title>Long short-term memory</article-title>
          .
          <source>Neural computation 9</source>
          ,
          <issue>8</issue>
          (
          <year>1997</year>
          ),
          <fpage>1735</fpage>
          -
          <lpage>1780</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <surname>Bo-June Paul</surname>
            Hsu and
            <given-names>Giuseppe</given-names>
          </string-name>
          <string-name>
            <surname>Ottaviano</surname>
          </string-name>
          .
          <year>2013</year>
          .
          <article-title>Space-eficient data structures for top-k completion</article-title>
          .
          <source>In Proceedings of the 22nd international conference on World Wide Web. ACM</source>
          ,
          <volume>583</volume>
          -
          <fpage>594</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <given-names>Dan</given-names>
            <surname>Jurafsky</surname>
          </string-name>
          and James H Martin. [n. d.].
          <source>Speech and language processing</source>
          . Vol.
          <volume>3</volume>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          [11]
          <string-name>
            <surname>Mark</surname>
            <given-names>D</given-names>
          </string-name>
          <string-name>
            <surname>Kernighan</surname>
          </string-name>
          , Kenneth W Church, and William A Gale.
          <year>1990</year>
          .
          <article-title>A spelling correction program based on a noisy channel model</article-title>
          .
          <source>In Proceedings of the 13th conference on Computational linguistics-Volume 2. Association for Computational Linguistics</source>
          ,
          <fpage>205</fpage>
          -
          <lpage>210</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          [12]
          <string-name>
            <surname>Chang</surname>
            <given-names>Liu</given-names>
          </string-name>
          , Xin Wang, Richard Shin, Joseph E Gonzalez, and
          <string-name>
            <given-names>Dawn</given-names>
            <surname>Song</surname>
          </string-name>
          .
          <year>2016</year>
          . Neural Code Completion. (
          <year>2016</year>
          ).
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          [13]
          <string-name>
            <given-names>Bruno</given-names>
            <surname>Martins and Mário J Silva</surname>
          </string-name>
          .
          <year>2004</year>
          .
          <article-title>Spelling correction for search engine queries</article-title>
          .
          <source>In Advances in Natural Language Processing</source>
          . Springer,
          <fpage>372</fpage>
          -
          <lpage>383</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          [14]
          <string-name>
            <given-names>Bhaskar</given-names>
            <surname>Mitra</surname>
          </string-name>
          and
          <string-name>
            <given-names>Nick</given-names>
            <surname>Craswell</surname>
          </string-name>
          .
          <year>2015</year>
          .
          <article-title>Query auto-completion for rare prefixes</article-title>
          .
          <source>In Proceedings of the 24th ACM International on Conference on Information and Knowledge Management. ACM</source>
          ,
          <volume>1755</volume>
          -
          <fpage>1758</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          [15]
          <string-name>
            <given-names>Dae</given-names>
            <surname>Hoon</surname>
          </string-name>
          Park and
          <string-name>
            <given-names>Rikio</given-names>
            <surname>Chiba</surname>
          </string-name>
          .
          <year>2017</year>
          .
          <article-title>A Neural Language Model for Query Auto-Completion</article-title>
          .
          <source>In Proceedings of the 40th International ACM SIGIR Conference on Research and Development in Information Retrieval. ACM</source>
          ,
          <volume>1189</volume>
          -
          <fpage>1192</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          [16]
          <string-name>
            <surname>Greg</surname>
            <given-names>Pass</given-names>
          </string-name>
          , Abdur Chowdhury, and
          <string-name>
            <given-names>Cayley</given-names>
            <surname>Torgeson</surname>
          </string-name>
          .
          <year>2006</year>
          .
          <article-title>A picture of search</article-title>
          .
          <source>In Proceedings of the 1st international conference on Scalable information systems. ACM</source>
          ,
          <volume>1</volume>
          .
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          [17]
          <string-name>
            <given-names>Toby</given-names>
            <surname>Segaran</surname>
          </string-name>
          and
          <string-name>
            <given-names>Jef</given-names>
            <surname>Hammerbacher</surname>
          </string-name>
          .
          <year>2009</year>
          .
          <article-title>Beautiful data: the stories behind elegant data solutions. "</article-title>
          <string-name>
            <surname>O'Reilly Media</surname>
          </string-name>
          ,
          <source>Inc.".</source>
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          [18]
          <string-name>
            <given-names>Milad</given-names>
            <surname>Shokouhi</surname>
          </string-name>
          .
          <year>2013</year>
          .
          <article-title>Learning to personalize query auto-completion</article-title>
          .
          <source>In Proceedings of the 36th international ACM SIGIR conference on Research and development in information retrieval. ACM</source>
          ,
          <volume>103</volume>
          -
          <fpage>112</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref19">
        <mixed-citation>
          [19]
          <string-name>
            <surname>Alessandro</surname>
            <given-names>Sordoni</given-names>
          </string-name>
          , Yoshua Bengio, Hossein Vahabi, Christina Lioma, Jakob Grue Simonsen, and
          <string-name>
            <surname>Jian-Yun Nie</surname>
          </string-name>
          .
          <year>2015</year>
          .
          <article-title>A hierarchical recurrent encoder-decoder for generative context-aware query suggestion</article-title>
          .
          <source>In Proceedings of the 24th ACM International on Conference on Information and Knowledge Management. ACM</source>
          ,
          <volume>553</volume>
          -
          <fpage>562</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref20">
        <mixed-citation>
          [20]
          <string-name>
            <surname>Idan</surname>
            <given-names>Szpektor</given-names>
          </string-name>
          , Aristides Gionis, and
          <string-name>
            <given-names>Yoelle</given-names>
            <surname>Maarek</surname>
          </string-name>
          .
          <year>2011</year>
          .
          <article-title>Improving recommendation for long-tail queries via templates</article-title>
          .
          <source>In Proceedings of the 20th international conference on World wide web. ACM</source>
          ,
          <volume>47</volume>
          -
          <fpage>56</fpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref21">
        <mixed-citation>
          [21]
          <string-name>
            <surname>Robert</surname>
            <given-names>A</given-names>
          </string-name>
          <string-name>
            <surname>Wagner and Michael J Fischer</surname>
          </string-name>
          .
          <year>1974</year>
          .
          <article-title>The string-to-string correction problem</article-title>
          .
          <source>Journal of the ACM (JACM) 21</source>
          ,
          <issue>1</issue>
          (
          <year>1974</year>
          ),
          <fpage>168</fpage>
          -
          <lpage>173</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref22">
        <mixed-citation>
          [22]
          <string-name>
            <surname>Casey</surname>
            <given-names>Whitelaw</given-names>
          </string-name>
          , Ben Hutchinson, Grace Y Chung, and
          <string-name>
            <given-names>Gerard</given-names>
            <surname>Ellis</surname>
          </string-name>
          .
          <year>2009</year>
          .
          <article-title>Using the web for language independent spellchecking and autocorrection</article-title>
          .
          <source>In Proceedings of the 2009 Conference on Empirical Methods in Natural Language Processing: Volume 2-Volume 2. Association for Computational Linguistics</source>
          ,
          <fpage>890</fpage>
          -
          <lpage>899</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref23">
        <mixed-citation>
          [23]
          <string-name>
            <surname>Ziang</surname>
            <given-names>Xie</given-names>
          </string-name>
          , Anand Avati, Naveen Arivazhagan, Dan Jurafsky, and Andrew Y Ng.
          <year>2016</year>
          .
          <article-title>Neural language correction with character-based attention</article-title>
          .
          <source>arXiv preprint arXiv:1603.09727</source>
          (
          <year>2016</year>
          ).
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>