<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Microsoft Web N-Gram</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/webngram/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/webngram/feed.xml</link>
    <description>Bringing you web-scale language model data.  Web N-Gram is joint project between Microsoft Bing and Microsoft Research.</description>
    <lastBuildDate>Tue, 16 Apr 2019 05:34:39 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Microsoft Research Speller Challenge is open for business</title>
      <link>https://docs.microsoft.com/archive/blogs/webngram/microsoft-research-speller-challenge-is-open-for-business</link>
      <pubDate>Thu, 20 Jan 2011 17:00:00 GMT</pubDate>
      <dc:creator><![CDATA[cthrash99]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/webngram/2011/01/20/microsoft-research-speller-challenge-is-open-for-business/</guid>
      <description><![CDATA[After a few bumps here and there we have the site up and running. &nbsp;If you prefer a write-up by...]]></description>
      <content:encoded><![CDATA[<p>After a few bumps here and there we have the <a title="Speller Challenge Home" href="https://spellerchallenge.com/">site</a> up and running. &nbsp;If you prefer a write-up by a professional writer on the subject, I'll refer you to this <a title="Press Release" href="https://blogs.msdn.com/b/msr_er/archive/2010/12/15/building-a-better-speller-bing-and-microsoft-research-offer-prizes-for-best-search-engine-spelling-alteration-services.aspx">announcement</a>.</p>
<p>Some of you may be wondering why certain design choices were made in the process of designing this challenge. &nbsp;I hope to address some of these today. &nbsp;Some additional FAQs are available on the official <a title="Speller Challenge FAQ" href="https://spellerchallenge.com/FAQ.aspx">site</a>.</p>
<p><strong>Why a web service?</strong></p>
<p>At the heart of this, much like it is for the Web N-Gram project, we're believers in data-driven discovery. &nbsp;We believe that the programmatically-accessed Web is very much the present and the future.&nbsp;</p>
<p>We also don't want to be in the business of hosting <i>your </i>code. &nbsp;Aside from the obvious security implications of us running third-party code here, we don't want to dictate what platform, tools, etc., that you can use. &nbsp;You decide, you host.</p>
<p><strong>Why REST?</strong></p>
<p>In a word, expedience. &nbsp;Because our input and output specifications are so simple, using a more formal structure such as SOAP would only serve to slow everything down, both in terms of development and runtime.</p>
<p><strong>Why the restrictions on the web service?</strong></p>
<p>There are two main restrictions on the web service. &nbsp;No redirects, and that MIME type must be text/plain. &nbsp;Both are motivated by our desire to prevent a malicious participant from making us inadvertently spamming an unsuspecting web site. &nbsp;Requiring the MIME type to be text/plain prevents you from pointing our code to a regular Web site (these generally return text/html as the MIME type, as they should.) &nbsp;Similarly, if you could redirect the request with a 301/302 HTTP response, you could easily appear to be a proper site at the time you're registering your web service URI, but redirect us to an unsuspecting third-party URl when it comes time to actually evaluate the speller. &nbsp;Granted these are not air-tight defenses against malicious intent, but it's better than nothing.</p>
<p><strong>What about the test data?</strong></p>
<p>We've prepared a human-judged corpus to get you started with the process. &nbsp;There are ~6000 phrases in this dataset, and these are the phrases with which we will call your web service <i>up until the final submission period.</i>&nbsp;&nbsp;For the final submission period we will obviously have a different corpus. &nbsp;We caution against tuning your algorithm too closely to the test dataset (a subject for a future blog.)</p>
<p>We're also encouraging folks with training data to share with the community. &nbsp;For Intellectual Property&nbsp;reasons we won't host these datasets, but we do provide a mechanism through which you can let the community know the availability.</p>
<p><strong>Where can I host my service?</strong></p>
<p>Naturally I would advise you to host your code in <a href="https://www.microsoft.com/windowsazure/" title="Windows Azure">Windows Azure</a>&nbsp;but there are no free options as of this writing there unless you already have an MSDN account (which itself is not free.) &nbsp;For the more budget-challenged,&nbsp;<a href="https://aws.amazon.com/free/" title="AWS Free Usage Tier">Amazon</a> and <a href="https://code.google.com/appengine/docs/whatisgoogleappengine.html" title="What is Google App Engine">Google</a> both offer some hosting for free. &nbsp;(This is not an endorsement.) &nbsp;There are surely many others. &nbsp;Keep in mind that while we don't intend to ever over-access your site, you are ultimately responsible for any charges or other issues with the hosting service of your choice, including rate-limiting.</p>
<p><b>What if I have more questions?</b></p>
<p>E-mail is always an option, but we strongly encourage you to use one of the social media options, for two reasons: (a) someone else have the same question and would benefit from a shared response, and (b) there are more of you than there are of us -- and one of you may already know the answer! &nbsp;This about <i>community,</i>&nbsp;folks!</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>The dirty secret about large-vocabulary hashes</title>
      <link>https://docs.microsoft.com/archive/blogs/webngram/the-dirty-secret-about-large-vocabulary-hashes</link>
      <pubDate>Mon, 27 Dec 2010 06:00:00 GMT</pubDate>
      <dc:creator><![CDATA[cthrash99]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/webngram/2010/12/27/the-dirty-secret-about-large-vocabulary-hashes/</guid>
      <description><![CDATA[The first step in the n-gram probability lookup process is to covert the input into tokens as...]]></description>
      <content:encoded><![CDATA[<p>The first step in the n-gram probability lookup process is to covert the input into tokens as discussed in an earlier <a href="https://blogs.msdn.com/b/webngram/archive/2010/11/29/the-messy-business-of-tokenization.aspx" title="The messy business of tokenization">post</a>. &nbsp;The second step is to covert each token into numerical IDs. &nbsp;The data structure used here is a kind of a hash.</p>
<p>You might be asking, why not a <a href="https://en.wikipedia.org/wiki/Trie" title="Wikipedia: Trie">trie</a>? &nbsp;The simple answer is size. &nbsp;If you have on the order of a billion words in your lexicon, a trie would generally be quite large. &nbsp;And large usually means slow, especially at this scale. &nbsp;What we need instead is a data structure that allows us to map the tokens to IDs without storing the lexicon itself, which is gigabytes in storage.</p>
<p>A number of techniques exist in this area but a property many of these have, ours included, is the possibility of false-negatives. &nbsp;This is to say that if you have a known token, the token will reliably map to a particular ID value, but if you have an&nbsp;<em>unknown</em> token, the ability to detect this is not guaranteed. &nbsp;Specifically, an in-vocabulary and out-of-vocabulary token can map to the same ID value. &nbsp;This is the trade-off to get the size down. &nbsp;Folks who study these sorts of things often talk in terms of <em>bits per token</em>, &nbsp;They often employ a secondary construct known as a&nbsp;<em>fingerprint</em>, to help reduce the odds of a false-positive. &nbsp;Of course the fingerprint also contributes towards the&nbsp;<em>bits per token</em>. so it comes down to keeping the error rate acceptably low.</p>
<p>Choosing a probabilistic hash instead of a data structure that embodies the lexicon also means that our service cannot do partial word wildcard lookups (i.e. you cannot find the probability of <code>chris*</code> and get the probability of <code>chris</code>, <code>christopher</code>, <code>christmas</code>, etc.). &nbsp;It does, however, allow us to use a tree-like structure to facilitate backoff lookup (see this <a href="https://blogs.msdn.com/b/webngram/archive/2010/10/11/language-modeling-102.aspx" title="Language Modeling 102">post</a> for more on this) as well as our generative-mode API (<a href="https://blogs.msdn.com/b/webngram/archive/2010/10/18/generative-mode-api.aspx" title="Generative-Mode API">post</a>) so it isn't all bad. &nbsp;Note that in order to produce the list of words in generative mode, we do have the ability to map IDs back to the token. &nbsp;In other words if we check the round-trip value of mapping a token to an ID and then back, we could test for the validity of the token. &nbsp;For performance reasons, we don't bother.</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Did you mean...Schwarzenegger?</title>
      <link>https://docs.microsoft.com/archive/blogs/webngram/did-you-mean-schwarzenegger</link>
      <pubDate>Wed, 15 Dec 2010 15:00:00 GMT</pubDate>
      <dc:creator><![CDATA[cthrash99]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/webngram/2010/12/15/did-you-mean-schwarzenegger/</guid>
      <description><![CDATA[You launch your favorite search engine and enter a term or two. &nbsp;Then near the top, the search...]]></description>
      <content:encoded><![CDATA[<p>You launch your favorite search engine and enter a term or two. &nbsp;Then near the top, the search engine helpfully suggests a possible alternate query, at which point you scratch your head and say "wha?" (or perhaps something more vulgar.)</p>
<p>You think you can do a better job? &nbsp;Now's your chance to prove it &mdash; Introducing the <b>Speller Challenge</b>!&nbsp; Win cash prizes!</p>
<p>Mosey on to <a title="Speller Challenge" href="https://spellerchallenge.com">https://spellerchallenge.com</a> and get a head start. &nbsp;The contest officially opens January 2011.</p>]]></content:encoded>
    </item>
    <item>
      <title>Well, do ya, P(&lt;UNK&gt;)?</title>
      <link>https://docs.microsoft.com/archive/blogs/webngram/well-do-ya-punk</link>
      <pubDate>Mon, 13 Dec 2010 09:00:00 GMT</pubDate>
      <dc:creator><![CDATA[cthrash99]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/webngram/2010/12/13/well-do-ya-punk/</guid>
      <description><![CDATA[Today we'll do a refresher on unigrams and the role of the P(&lt;UNK&gt;).
As you recall, for...]]></description>
      <content:encoded><![CDATA[<p>Today we'll do a refresher on unigrams and the role of the P(&lt;UNK&gt;).</p>
<p>As you recall, for unigrams, <code>P(x)</code>is simply the probability of encoutering <code>x</code>irrespective of words preceding it.&nbsp; A na&iuml;ve (and logical) way to compute this would be to simply take the number of times x is observed and divide it by the number of total words.&nbsp; This would be fine until you encounter a word you'd never seen before&mdash;what should the unigram probability of that term be?</p>
<p>One option is to say <code>P(x)</code> is 0 if x is out-of-vocabulary (OOV).&nbsp; This would be the right answer if you were dealing with <em>unsmoothed</em> models.&nbsp; What we have instead are <em>smoothed</em> models, which means that we like to attribute some nonzero probability to words however unlikely the particular words are. If you were computing joint probabilities involving multiple terms, you likely don't want&nbsp;a single term to 'doom' the overall probability to 0 just because it was OOV.&nbsp; So what we've done here is give the unknown word a small probability mass, and, since the overall probability needs to sum up to unity, we take it out of the denominator.&nbsp; If the counts of a word x is expressed as <code>C(x)</code> and count of all words expressed as <code>C(*)</code>, you'd have:</p>
<p style="padding-left: 30px;"><code>P(x)&nbsp;= C(x) / [1 + C(*)]<br />P(&lt;unk&gt;) = 1 / [1 + C(*)]</code></p>
<p>What the above equation shows is that we've given unknown words the equivalent probability of a word observed just once.</p>
<p>But what happens if you encounter multiple unknown terms while evaluating a joint probability?&nbsp; Since the probability mass represents <em>all</em> unknown terms, it has to be distributed amongst unknown terms.&nbsp; Therefore you divide it n-ways; the contribution of the unknown terms to the overall joint probability is thus [P(&lt;UNK&gt;)/n]^n.</p>]]></content:encoded>
    </item>
    <item>
      <title>Perf tips for using the N-Gram service with WCF</title>
      <link>https://docs.microsoft.com/archive/blogs/webngram/perf-tips-for-using-the-n-gram-service-with-wcf</link>
      <pubDate>Mon, 06 Dec 2010 06:00:00 GMT</pubDate>
      <dc:creator><![CDATA[cthrash99]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/webngram/2010/12/06/perf-tips-for-using-the-n-gram-service-with-wcf/</guid>
      <description><![CDATA[The support in Visual Studio for WCF makes writing a SOAP/XML application for the Web N-Gram service...]]></description>
      <content:encoded><![CDATA[<p>The support in Visual Studio for WCF makes writing a SOAP/XML application for the Web N-Gram service a pretty straightforward process. &nbsp;If you're new to this, the <a title="Web N-Gram Quick Start" href="https://web-ngram.research.microsoft.com/info/QuickStart.htm">Quick Start</a> guide might be helpful to you. &nbsp;There are a few tweaks you can make, however, to improve the performance of your application if you intend to call the service repeatedly. &nbsp;Today we'll cover a few tips.</p>
<ol>
<li><strong>Check your web proxy</strong><br />
<div>Your web proxy can be a bottleneck, especially in a corporate environment. &nbsp;Some proxies will limit the number of calls an application can make in a given amount of time, and will return 5xx (HTTP) responses when you exceed this limit. &nbsp;Oftentimes it's difficult to tell whether the web service is returning the error as opposed to your proxy, so check the error message carefully. &nbsp;If there's an alternative proxy you can use, try that one instead. &nbsp;Here's how you'd modify your application configuration file:<br />
<ol>
<li>Find your application configuration file. &nbsp;Generally, this file will be called <code>app.config</code> or <code>web.config</code></li>
<li>Find the binding your endpoint is using under 
<code>&lt;configuration&gt;&lt;system.serviceModel&gt;&lt;bindings&gt;&lt;wsHttpBinding&gt;</code> or equivalent</li>
<li>Set <code>useDefaultWebProy="false"</code>, and 
</li>
<li>Set <code>proxyAddress="https://your-proxy-name-and-maybe-port"</code> </li>
</ol></div>
</li>
<li><strong>Batch your calls</strong><br />
<div>If your task involves getting a bunch of probability values, the use of the batch methods is strongly encouraged. &nbsp;This is partly due to the amortization of XML parsing, and also partly due to how lookups are distributed in the cluster.  So instead of calling <code>GetProbability</code> or <code>GetConditionalProbability</code>, call <code>GetProbabilities</code> or <code>GetConditionalProbabilities</code> whenever possible.</div>
</li>
<li><strong>Reuse your WCF proxy</strong><br />
<div>There's no need to repeatedly create a client proxy for every call to the service. &nbsp;This is in fact a great overhead that's usually unnecessary. &nbsp;You might catch for faults (exceptions) and only recreate a client proxy in such an event. &nbsp;Bonus points if you have an exponential backoff during retries while dealing with network hiccups. &nbsp;</div>
</li>
<li><strong>Choose models wisely</strong>
<div>It turns out that the larger the model, the longer the lookups take. &nbsp;Body, as you might guess, is the largest; anchor and bquery are next largest, and title is the smallest.  You may also notice some performance difference between jun09 models and apr10 models due to some changes in how the data is hosted.</div>
</li>
</ol>
<p>Contribute your own tips!</p>]]></content:encoded>
    </item>
    <item>
      <title>The messy business of tokenization</title>
      <link>https://docs.microsoft.com/archive/blogs/webngram/the-messy-business-of-tokenization</link>
      <pubDate>Mon, 29 Nov 2010 06:00:00 GMT</pubDate>
      <dc:creator><![CDATA[cthrash99]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/webngram/2010/11/29/the-messy-business-of-tokenization/</guid>
      <description><![CDATA[So what exactly is a word, in the context of our N-Gram service? &nbsp;The devil, it is said, is in...]]></description>
      <content:encoded><![CDATA[<p>So what exactly is a word, in the context of our N-Gram service? &nbsp;The devil, it is said, is in the details.</p>
<p>As noted in earlier blog entries, our data comes straight from Bing. &nbsp;All tokens are case-folded and with a few exceptions, all punctuation is stripped. &nbsp;This means words like&nbsp;<em>I'm</em> or&nbsp;<em>didn't</em> are treated as two tokens each, even though we might consider them to be single words. &nbsp;Here is the aforementioned exceptions in the bing-body:jun09 dataset:</p>
<p style="padding-left: 30px;">
<code>.net<br />c++<br />c#<br />j#<br />g++<br />j++<br />com+<br />gdi+</code></p>
<p>The dataset qualification is critical here, because we aren't necessarily committed to keeping that set the same moving forward. &nbsp;But this could be a problem for the <code>GetConditionalProbability</code> method, because the definition of this method is&nbsp;<em>the probability of the last word in the given context</em>. &nbsp;Notice I used 'word' instead of token. &nbsp;Therein lies a compromise &mdash; for the purpose of <code>GetConditionalProbability</code> we use whitespace as a word boundary. &nbsp;An example might help illustrate this point: </p>
<p style="padding-left: 30px;"><code>GetConditionalProbability("bing-body:apr10:3", "on no, you didn't")</code></p>
<p>The input phrase has 5 tokens: <em>oh</em>, <em>no</em>, <em>you</em>, <em>didn</em>, and <em>t</em>. &nbsp;If we were simply using the token boundary we would return the value of <code>P(t|you didn)</code>, and ignore the three tokens preceding. &nbsp;But because we're using whitespace as boundaries, we return <code>P(t|you didn)&times;P(didn|no you)</code> and ignore the two preceding tokens. &nbsp;Subtle, yes, but crucial if you want predictable results.</p>
<p>We also have two special tokens, <code>&lt;s&gt;</code> and <code>&lt;/s&gt;</code>. &nbsp;These mean, beginning of segment and end of segment, respectively. &nbsp;These help you get probabilities at the segment boundaries. &nbsp;Here's an example:</p>
<pre class="scroll"><code class="cplusplus">&gt;&gt;&gt; import MicrosoftNgram
&gt;&gt;&gt; s = MicrosoftNgram.LookupService(model='urn:ngram:bing-body:apr10:2')
&gt;&gt;&gt; for t in s.Generate('&lt;s&gt;', maxgen=6): print t
...
('home', -1.3229439999999999)
('the', -1.389273)
('skip', -1.6477809999999999)
('search', -1.8886769999999999)
('a', -1.938218)
('this', -1.9436990000000001)</code></pre>
<p>&nbsp;This shows that in the body stream, the most common first word is&nbsp;<em>home</em>, and so on.</p>]]></content:encoded>
    </item>
    <item>
      <title>Wordbreakingisacinchwithdata</title>
      <link>https://docs.microsoft.com/archive/blogs/webngram/wordbreakingisacinchwithdata</link>
      <pubDate>Mon, 22 Nov 2010 06:00:00 GMT</pubDate>
      <dc:creator><![CDATA[cthrash99]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/webngram/2010/11/22/wordbreakingisacinchwithdata/</guid>
      <description><![CDATA[For the task of word-breaking, many different approaches exist. &nbsp;Today we're writing about a...]]></description>
      <content:encoded><![CDATA[<p>For the task of word-breaking, many different approaches exist. &nbsp;Today we're writing about a purely data-driven approach, and it's actually quite straightforward &mdash; all we do is a consider every character boundary as a potential for a word boundary, and compare the relative joint probabilities, with no insertion penalty applied. &nbsp;A data-driven approach is great because all you need is data, and you're covered: all languages, slang, neologisms and so forth.</p>
<p>The one tricky business with the algorithm as outlined above is that it can be computationally expensive, especially if the pre-word-broken string is long. &nbsp;But with reasonably aggressive pruning, a breadth-first-search is actually quite usable. &nbsp;The coding is nevertheless tedious, so we've prepared two modes by which you can experiment with word-breaking: an interactive Silverlight application, and a REST service. &nbsp;Official write-up is <a href="https://web-ngram.research.microsoft.com/info/break.html" title="Data-driven word-breaking">here</a>.</p>
<p>Shown here is a capture from the <a href="https://research.microsoft.com/en-us/um/people/kuansanw/wordbreaker/" title="WordBreaker4Web">WordBreaker4Web</a> app, breaking the title of this post:<br />
<img border="0" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/40/85/1157.wordbreakingisacinchwithdata.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/399x240/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-40-85/1157.wordbreakingisacinchwithdata.PNG" /></p>
<p>So what are some applications for such a service? &nbsp;One obvious example is URL or filename breaking. &nbsp;In the case of a domain names, spaces are not permitted so unless you want to substitute hyphens, you're only choice is to string the words together. &nbsp; This leads to rather long domain names such as this [N.B. examples are random, not intended as an endorsement]: insearchoftheworldsmostbeautifulwoman . &nbsp;Or perhaps this Internet meme: penisland, meant to be parsed as <em>pen island</em>, not <a href="https://www.urbandictionary.com/define.php?term=penisland" title="Urban Dictionary definition">some other way</a>. &nbsp;As for filename breaking, omission of space characters is still quite prevalent, as you're surely aware.</p>
<p>Other applications exist, too. &nbsp;Hash tags, seen throughout the Internet and quite prominently on Twitter (where we also <a title="webngram on Twitter" href="https://twitter.com/webngram">are</a>, by the way), are by nature words strung together with spaces removed. &nbsp;Here's an example, picking one of the trending terms at random:
</p>
<pre class="scroll"><code class="cplusplus">C:\bin\curl&gt;curl https://web-ngram.research.microsoft.com/ngramwordbreaker/break.svc/?p=imoneofthosepeople
i|m|one|of|those|people (-16.02505)
im|one|of|those|people (-16.56622)
i|m|oneof|those|people (-17.15775)
im|oneof|those|people (-17.69892)
imone|of|those|people (-17.93192)</code></pre>
<p>For those with sharp eyes will note that the REST service shown above doesn't provide a means to specify a language model. &nbsp;This is because we built an artificial model based on &lsquo;bing-title:apr10:2&rsquo; (that's right &ndash; bigram) with the n-grams drastically pruned for faster performance at the expense of accuracy. &nbsp;It nevertheless does a fairly decent job. &nbsp;Compare the speed between the REST service and the Silverlight demo app and the effect of the shrunk datset becomes quite obvious.</p>
<p>Does your Department of Licensing word break? &nbsp;Some of you may recall the news about a particular plate getting rejected in Colorado:
</p>
<pre class="scroll"><code class="cplusplus">C:\bin\curl&gt;curl https://web-ngram.research.microsoft.com/ngramwordbreaker/break.svc/?p=iluvtofu
iluv|tofu (-12.75313)
iluv|to|fu (-14.22803)</code></pre>
<p>So we think it was about 30x more likely that they loved bean curds. &nbsp;But who knows.</p>]]></content:encoded>
    </item>
    <item>
      <title>The fluid language of the Web</title>
      <link>https://docs.microsoft.com/archive/blogs/webngram/the-fluid-language-of-the-web</link>
      <pubDate>Mon, 15 Nov 2010 06:00:00 GMT</pubDate>
      <dc:creator><![CDATA[cthrash99]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/webngram/2010/11/15/the-fluid-language-of-the-web/</guid>
      <description><![CDATA[We prepared, as we had for the earlier dataset, the top-100K words list for the body stream for...]]></description>
      <content:encoded><![CDATA[<p>We prepared, as we had for the earlier dataset, the top-100K words list for the body stream for Apr10. &nbsp;You can download it <a title="Bing Body Apr10 Top 100k Words" href="https://web-ngram.research.microsoft.com/info/BingBodyApr10_Top100kWords.zip">here</a>.</p>
<p>We decided to take a closer look at the dataset to how the top 100K lists changed between Jun09 and Apr10. &nbsp;Our findings are interesting:</p>
<ul>
<li>The union of the word set is just shy of 110K. &nbsp;This means that <em>10% of the words either fell in or out of the top 100K</em>. &nbsp;This is a turnover rate higher than I expected.</li>
<li>Some words that are newly in the top list are what you'd expect (unigram log10 probability difference shown parenthetically):
<ul>
<li>espnlosangeles (21.88993), an ESPN satellite established during 2009</li>
<li>debate2010 (21.53613)</li>
</ul>
</li>
<li>Some words took a predictable jump:
<ul>
<li>ipad (2.560667), a product introduced mid-year</li>
</ul>
</li>
<li>Quite a few words newly in the mix are not conversational words:
<ul>
<li>childreplyhtml (22.09848)</li>
<li>focaladvid (21.76564)</li>
</ul>
</li>
</ul>
<p>Curious indeed.</p>]]></content:encoded>
    </item>
    <item>
      <title>Using the MicrosoftNgram Python Module</title>
      <link>https://docs.microsoft.com/archive/blogs/webngram/using-the-microsoftngram-python-module</link>
      <pubDate>Mon, 08 Nov 2010 06:00:00 GMT</pubDate>
      <dc:creator><![CDATA[cthrash99]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/webngram/2010/11/08/using-the-microsoftngram-python-module/</guid>
      <description><![CDATA[Over the past few posts I've shown some samples of the 
MicrosoftNgram Python module.&nbsp; Writing...]]></description>
      <content:encoded><![CDATA[<p>Over the past few posts I've shown some samples of the 
MicrosoftNgram Python module.&nbsp; Writing documentation is not something engineers 
I know enjoy doing; in fact the only available documentation right now is 
through <code>help(MicrosoftNgram)</code>.&nbsp; Here's an attempt to rectify the situation.</p>
<p>To get started, you'll of course need to get the module, 
which you can download <a href="https://web-ngram.research.microsoft.com/info/MicrosoftNgram-1.02.zip" title="MicrosoftNgram Python Module">here</a>. </p>
<p>The main class is named <code>LookupService</code>.&nbsp; An instance of this 
object encapsulates two crucial pieces of information (a) the user token, and 
(b) the language model of interest.&nbsp; The user token is a GUID issued by 
Microsoft Research.&nbsp; This is something we use to track the amount of usage; 
neither the phrases nor models used are tracked in the interest of protecting 
users' privacy.&nbsp; The language model is dataset against which you can query probabilities.&nbsp; Details on language models were covered in last week's <a href="https://blogs.msdn.com/b/webngram/archive/2010/10/25/who-doesn-t-like-models.aspx" title="Who doesn't like models?">post</a>, but in a nutshell there are three properties to a model: source, version, and order. &nbsp;The following instantiations of the constructor are all functionally equivalent, provided that (i) you use your actual GUID, not xx.., and (ii) for the first case, you've specified an environment variable called <code>NGRAM_TOKEN</code> and its value set to your GUID.</p>
<pre class="scroll"><code class="php">&gt;&gt;&gt; s = MicrosoftNgram.LookupService()
&gt;&gt;&gt; s.GetModel()
'bing-body/jun09/3'
&gt;&gt;&gt; s = MicrosoftNgram.LookupService(token='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')
&gt;&gt;&gt; s.GetModel()
'bing-body/jun09/3'
&gt;&gt;&gt; s = MicrosoftNgram.LookupService('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx')
&gt;&gt;&gt; s.GetModel()
'bing-body/jun09/3'
&gt;&gt;&gt; s = MicrosoftNgram.LookupService(token='xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',model='bing-body/jun09/3')
&gt;&gt;&gt; s.GetModel()
'bing-body/jun09/3'
&gt;&gt;&gt; s = MicrosoftNgram.LookupService('xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx','bing-body/jun09/3')
&gt;&gt;&gt; s.GetModel()
'bing-body/jun09/3'</code></pre>
<p>&nbsp;I prefer to set the environment variable, since I can't be bothered to memorize a GUID. &nbsp;Speaking of environment variables, note that MicrosoftNgram uses urllib under the covers, so if you need to specify a proxy, set <code>HTTP_PROXY</code> appropriately.</p>
<p>Once you have a <code>LookupService</code> object, you can call the various methods.&nbsp;
</p>
<pre class="scroll"><code class="php">&gt;&gt;&gt; s = MicrosoftNgram.LookupService(model='bing-body/apr10/5')
&gt;&gt;&gt; s.GetConditionalProbability('happy cat is happy')
-0.93900499999999998
&gt;&gt;&gt; s.GetConditionalProbability('happy cat is sad')
-4.2167089999999998
&gt;&gt;&gt; s.GetJointProbability('kthxbai')
-7.6080370000000004</code></pre>
<p>&nbsp;Well it's good to know that happy cat is 1000x more likely to be happy than sad. &nbsp;What else can happy cat be?</p>
<pre class="scroll"><code class="cplusplus">&gt;&gt;&gt; for t in s.Generate('happy cat is', maxgen=5): print t
...
('always', -0.36325089999999999)
('a', -0.89422170000000001)
('happy', -0.93900499999999998)</code></pre>
<p>So we know that happy cat is never sad (well, most likely anyway &mdash; bing-body/apr10 has a unigram cutoff of 10.) &nbsp;We can further infer that when computing the conditional probability above, we must have backed off to a lower-order n-gram.</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Who doesn't like models?</title>
      <link>https://docs.microsoft.com/archive/blogs/webngram/who-doesnt-like-models</link>
      <pubDate>Mon, 01 Nov 2010 06:00:00 GMT</pubDate>
      <dc:creator><![CDATA[cthrash99]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/webngram/2010/11/01/who-doesnt-like-models/</guid>
      <description><![CDATA[If there ever was an overloaded term in Computer Science, it's models.&nbsp; For instance, my...]]></description>
      <content:encoded><![CDATA[<p>If there ever was an overloaded term in Computer Science, it's models.&nbsp; For instance, my colleagues in the <a title="eXtreme Computing Group" href="https://research.microsoft.com/en-us/labs/xcg/default.aspx">eXtreme Computing Group</a> have this terrific ambition to model the entire <a title="Modeling the World -- Microsoft Technical Computing" href="https://www.modelingtheworld.com">world</a>!&nbsp; What we're talking about here is much simpler: it is a representation of a particular corpus.</p>
<p>One of the key insights in studying how documents are composed on the Web is that there are subtle but nevertheless distinct styles used, even in a single document.&nbsp; You know this intuitively -- when you form a query to your search engine, for example, you often string together keywords to form a phrase, but you wouldn't use the same phraseology in prose.&nbsp; Even in prose, the style in which we compose paragraphs will differ from how we compose titles or reference other material.</p>
<p>In the Web N-Gram service, we have collected from Bing textual data from four different sources (sometimes referred to as 'streams'): Body, Anchor, Title, and Query.&nbsp; To get the list of currently supported models, use this handy <a target="_blank" title="List of Models" href="https://web-ngram.research.microsoft.com/rest/lookup.svc/">URL</a>.&nbsp; </p>
<p>There are two different naming conventions used by our service: the URN form when using XML/SOAP, and the Path form for REST access.</p>
<p style="padding-left: 30px;">URN: urn:ngram:{source}:{version}:{order}</p>
<p style="padding-left: 30px;">Path: {source}/{version}/{order}</p>
<p>In this context, order=1 is unigram, order=2 is bigram, and so forth.</p>
<p>A number of papers have been published demonstrating computational tasks using different models.&nbsp; Here's one that appeared in <a title="ACM SIGIR" href="https://www.sigir.org/">SIGIR</a>: <a title="A Comparative Study of Bing Web N-gram Language  Models for Web Search and Natural Language Processing" href="https://research.microsoft.com/apps/pubs/default.aspx?id=135070">A Comparative Study of Bing Web N-gram Language  Models for Web Search and Natural Language Processing</a>.</p>]]></content:encoded>
    </item>
  </channel>
</rss>