{"id":40,"date":"2012-02-04T10:16:07","date_gmt":"2012-02-04T15:16:07","guid":{"rendered":"https:\/\/michaelnielsen.org\/ddi\/?p=40"},"modified":"2012-02-04T10:16:16","modified_gmt":"2012-02-04T15:16:16","slug":"how-to-combine-multiple-notions-of-relevance-in-search","status":"publish","type":"post","link":"https:\/\/michaelnielsen.org\/ddi\/how-to-combine-multiple-notions-of-relevance-in-search\/","title":{"rendered":"How to combine multiple notions of relevance in search?"},"content":{"rendered":"<p>In earlier posts I&#8217;ve described two different ways we can assess how relevant a given webpage is to a search query: (1) the <a href=\"https:\/\/michaelnielsen.org\/ddi\/documents-as-geometric-objects-how-to-rank-documents-for-full-text-search\/\">cosine   similarity<\/a> measure; and (2) the <a href=\"https:\/\/michaelnielsen.org\/blog\/lectures-on-the-google-technology-stack-1-introduction-to-pagerank\/\">PageRank<\/a>, which is a query-independent measure of the importance of a page. While it&#8217;s good that we have multiple insights into what makes a webpage relevant, it also gives rise to a problem: how should we combine these two measures to determine the ranking of a particular webpage for a particular search query?<\/p>\n<p>In fact, in practice the problem gets much more complex than this, because there are more than two useful notions of search relevance. For instance, we&#8217;d surely also wish to incorporate a relevance measure that quantifies how likely or unlikely a given page is to be spam.  By doing that we could ensure that pages which are likely to be spam receive a much lower ranking.  We might also wish to incorporate a measure which ranks a page based on how close together the words in the search query are on that page.  Once you start to think about it, we humans combine a very large number of factors when assessing the usefulness of a webpage.  This is reflected in the fact that, according to Google, their search engine combines not just two or three measures of relevance but <a href=\"http:\/\/www.google.com\/about\/corporate\/company\/tech.html\">more   than 200 measures<\/a> of relevance.  How should we best combine all these multiple measures in order to determine how relevant a page is to a given query?<\/p>\n<p>You might think that the right approach would be to think hard about the meaning of measures like cosine similarity and PageRank, and then on the basis of that understanding, to figure out optimal ways of combining those measures.  This approach is certainly worth pursuing, but it suffers from a problem: it doesn&#8217;t scale very well.  Even if you come up with a good way of combining cosine similarity and PageRank, how would you combine 200 different measures?  It&#8217;s not so obvious.  And if you decide to trial the addition of a 201st measure of relevance, how exactly should you incorporate it into your algorithm, and how should you check to see whether or not it improves search results?<\/p>\n<p>In this post, I&#8217;ll describe an approach to combining multiple measures of relevance that doesn&#8217;t require us to consider the details of the individual measures.  Instead, the procedure I describe lets the machine automatically <em>learn<\/em> how to combine different measures. It does this with the help of a set of <em>training data<\/em>, where humans have ranked some set of webpages according to their relevance to some set of training queries.  The idea is to figure out the best way of combining the measures of relevance in order to reproduce the results of the training data.  Whatever method of combination is found is then applied more broadly, to all queries, and all webpages.  The big advantage of this machine learning approach is that it lets us easily combine many different notions of search relevance.  But it also has some drawbacks, as we&#8217;ll see.<\/p>\n<p>The post is based principally on Chapter 15 of the <a href=\"http:\/\/www.amazon.com\/Introduction-Information-Retrieval-Christopher-Manning\/dp\/0521865719\">book<\/a> about information retrieval by Manning, Raghavan, and Sch\\&#8221;utze. The book is also available for <a href=\"http:\/\/nlp.stanford.edu\/IR-book\/information-retrieval-book.html\">free   on the web<\/a>.<\/p>\n<p>Originally, I intended this post to be a mix of theory and working code to illustrate how the theory works in practice.  This is the style I&#8217;ve used for many earlier posts, and is the style I intend to use whenever possible.  However, I ran into a problem when I attempted to do that for the current post.  The problem was that if I wanted to construct interesting examples (and ask interesting questions about those examples), I needed to add a <em>lot<\/em> of extra context in order for things to make sense.  It would have tripled (or more) the length of an already long post.  I ultimately decided the extra overhead wasn&#8217;t worth the extra insight.  Instead, the post focuses on the theory.  However, I have included a few pointers to libraries which make it easy to construct your own working code, if you&#8217;re so inclined.  At some point I expect I&#8217;ll come back to this question, in a context where it makes much more sense to include working code.<\/p>\n<p>As usual, I&#8217;ll finish the introduction with the caveat that I&#8217;m not an expert on any of this. I&#8217;m learning as I go, and there may be mistakes or misunderstandings in the post.  Still, I hope the post is useful. At some point, I&#8217;ll stop adding this caveat to my posts, but I&#8217;m still a long way from being expert enough to do that!  Also as per usual, the post will contain some simple <em>exercises<\/em> for the reader, some slightly harder <em>problems<\/em>, and also some <em>problems for   the author<\/em>, which are things I&#8217;d like to understand better.<\/p>\n<h3>General approach<\/h3>\n<p>In this section, I&#8217;ll work through some simple hypothetical examples, using them to build up a set of heuristics about how to rank webpages. These heuristics will ultimately suggest a complete algorithm for learning how to rank webpages from a set of training data.<\/p>\n<p>One small point about nomenclature: I&#8217;m going to switch from talking about &#8220;webpages&#8221; (or &#8220;pages&#8221;), and start referring instead to &#8220;documents&#8221;.  In part this is because the document terminology is more standard.  But it&#8217;s also because the techniques apply more broadly than the web.<\/p>\n<p>To keep things simple and concrete in our hypothetical examples, we&#8217;ll assume that for any given query and document we have just two different measures of relevance, let&#8217;s say the cosine similarity and the PageRank (or some other similar measure, if we&#8217;re working with documents not from the web).  We&#8217;ll call these <em>features<\/em>.  And so for any given query and document pair <img src='https:\/\/s0.wp.com\/latex.php?latex=%28q%2Cd%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='(q,d)' title='(q,d)' class='latex' \/> we have a <em>feature vector<\/em>:<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=+++%5Cvec+%5Cpsi%28q%2Cd%29+%3D+%5Cleft%5B+%5Cbegin%7Barray%7D%7Bc%7D+%5Cmbox%7BPageRank%7D%28q%2Cd%29+%5C%5C++++++++%5Cmbox%7Bcosine+similarity%7D%28q%2Cd%29+%5Cend%7Barray%7D+%5Cright%5D.+&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='   \\vec \\psi(q,d) = \\left[ \\begin{array}{c} \\mbox{PageRank}(q,d) \\\\        \\mbox{cosine similarity}(q,d) \\end{array} \\right]. ' title='   \\vec \\psi(q,d) = \\left[ \\begin{array}{c} \\mbox{PageRank}(q,d) \\\\        \\mbox{cosine similarity}(q,d) \\end{array} \\right]. ' class='latex' \/>\n<p>Actually, the PageRank of a document doesn&#8217;t depend on the query <img src='https:\/\/s0.wp.com\/latex.php?latex=q&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='q' title='q' class='latex' \/>, but in general we&#8217;ll allow the features in the feature vector to depend on the query.  Also, in general there will be more than two features, and so the feature vector might have quite a few components. But it turns out that the generalization beyond the two-dimensional case is straightforward, so we&#8217;ll stick with two dimensions for now.<\/p>\n<p>Our broad goal can now be restated in the language of feature vectors. What we want is to find an algorithm which combines the different components of the feature vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cpsi%28q%2Cd%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\psi(q,d)' title='\\vec \\psi(q,d)' class='latex' \/> in order to rank the document <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> for any particular query <img src='https:\/\/s0.wp.com\/latex.php?latex=q&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='q' title='q' class='latex' \/>. Our task is to find an algorithm which does a pretty good job doing this ranking.<\/p>\n<p>To get some insight into how we should solve this problem, let&#8217;s suppose we have an extremely simple set of training data.  We&#8217;ll suppose a human operator has ranked three documents <img src='https:\/\/s0.wp.com\/latex.php?latex=d_1%2C+d_2%2C+d_3&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d_1, d_2, d_3' title='d_1, d_2, d_3' class='latex' \/> for just a single query <img src='https:\/\/s0.wp.com\/latex.php?latex=q&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='q' title='q' class='latex' \/>.  Of course, real training data will need to involve many more documents and queries, but we can learn a lot by starting with this.  We have three feature vectors for these three cases, <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cpsi%28q%2Cd_1%29%2C+%5Cvec+%5Cpsi%28q%2Cd_2%29%2C+%5Cvec+%5Cpsi%28q%2Cd_3%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\psi(q,d_1), \\vec \\psi(q,d_2), \\vec \\psi(q,d_3)' title='\\vec \\psi(q,d_1), \\vec \\psi(q,d_2), \\vec \\psi(q,d_3)' class='latex' \/>.  I&#8217;ve illustrated these in the following diagram &#8211; to avoid clutter, rather than write <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cpsi%28q%2Cd_j%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\psi(q,d_j)' title='\\vec \\psi(q,d_j)' class='latex' \/> repeatedly in the diagram, I&#8217;ve labelled each vector simply by its document number, <img src='https:\/\/s0.wp.com\/latex.php?latex=d_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d_j' title='d_j' class='latex' \/>, as well as (in parentheses) by its order of relevance as ranked by a human operator:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/michaelnielsen.org\/ddi\/wp-content\/uploads\/2012\/02\/svm_test_data.png\" width=\"260px\"><\/p>\n<p>There are a few reasonable observations: <\/p>\n<ul>\n<li> If a feature vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cpsi%28q%2Cd%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\psi(q,d)' title='\\vec \\psi(q,d)' class='latex' \/> is up and to the right of   <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cpsi%28q%2Cd%27%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\psi(q,d&#039;)' title='\\vec \\psi(q,d&#039;)' class='latex' \/> then it&#8217;s better along both axes (PageRank and   cosine similarity).  It seems reasonable to conclude that <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> is a   better result than <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/>.\n<li> Coversely, if <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cpsi%28q%2Cd%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\psi(q,d)' title='\\vec \\psi(q,d)' class='latex' \/> is down and to the left of   <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cpsi%28q%2Cd%27%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\psi(q,d&#039;)' title='\\vec \\psi(q,d&#039;)' class='latex' \/> then <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> should always be ranked below <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/>.\n<li> The hard cases are when <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cpsi%28q%2Cd%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\psi(q,d)' title='\\vec \\psi(q,d)' class='latex' \/> is up and to the left   of <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cpsi%28q%2Cd%27%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\psi(q,d&#039;)' title='\\vec \\psi(q,d&#039;)' class='latex' \/>, or down and to the right, in which case it&#8217;s   not entirely clear <\/ul>\n<p> Note, by the way, that I don&#8217;t want to claim that that these observations are &#8220;proveable&#8221; in any way: they&#8217;re just reasonable observations, at least for the particular features (cosine similarity and PageRank) that we&#8217;re using.  The idea here is simply to figure out some reasonable heuristics which we will eventually combine to suggest an algorithm for learning how to rank webpages.<\/p>\n<p>With the observations above as motivation we&#8217;ll adopt the heuristic that it is the <em>vector of feature differences<\/em> <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cphi%28q%2Cd%2Cd%27%29+%3A%3D+%5Cvec+%5Cpsi%28q%2Cd%29-%5Cvec+%5Cpsi%28q%2Cd%27%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\phi(q,d,d&#039;) := \\vec \\psi(q,d)-\\vec \\psi(q,d&#039;)' title='\\vec \\phi(q,d,d&#039;) := \\vec \\psi(q,d)-\\vec \\psi(q,d&#039;)' class='latex' \/> that determines whether <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> should be ranked above <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/>, or vice versa.  In other words, we&#8217;re going to require that the relative ranking of <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/> is a function of the components of <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cphi%28q%2Cd%2Cd%27%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\phi(q,d,d&#039;)' title='\\vec \\phi(q,d,d&#039;)' class='latex' \/>, and not of either individual feature vector alone.  So the problem now becomes: how should we use <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cphi%28q%2Cd%2Cd%27%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\phi(q,d,d&#039;)' title='\\vec \\phi(q,d,d&#039;)' class='latex' \/> to rank <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/>?  A clue is provided by looking at the vectors of feature differences for our training data:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/michaelnielsen.org\/ddi\/wp-content\/uploads\/2012\/02\/svm_feature_differences.png\" width=\"350px\"><\/p>\n<p>I haven&#8217;t labelled the vectors explicitly with <img src='https:\/\/s0.wp.com\/latex.php?latex=q%2C+d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='q, d' title='q, d' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/>, but it&#8217;s pretty easy to figure out which is which, if you look carefully. Instead, I&#8217;ve labelled each feature difference vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cphi%28q%2Cd%2Cd%27%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\phi(q,d,d&#039;)' title='\\vec \\phi(q,d,d&#039;)' class='latex' \/> with a filled in oval when <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> is ranked better than <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/>, and with a star when <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/> is ranked better than <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/>.  Examining the vectors carefully, we see that the vectors with an oval all &#8220;point the same way&#8221; as one another, while the vectors with a star also all point the same way as one another, but in the opposite direction.  We can make this intuition more precise by saying that the two sets of vectors are separated into two half-spaces by a line:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/michaelnielsen.org\/ddi\/wp-content\/uploads\/2012\/02\/svm_half_space.png\" width=\"350px\"><\/p>\n<p>So one way we could determine whether a feature difference vector is labelled by an oval or a cross is simply by determining which half-space it is in, i.e., by determing which side of the line it&#8217;s on.  Or to reformulate it in our original terms: we can tell whether a webpage <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> ranks higher than a webpage <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/> simply by determining which half-space the feature difference vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cphi%28q%2Cd%2Cd%27%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\phi(q,d,d&#039;)' title='\\vec \\phi(q,d,d&#039;)' class='latex' \/> is in.<\/p>\n<p>In higher-dimensional feature spaces this idea generalizes to separating the feature difference vectors into two half-spaces which are on opposite sides of a <em>separating hyperplane<\/em>.  A convenient way of specifying this separating hyperplane, in any number of dimensions, is to introduce a normal vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> to the hyperplane.  I&#8217;ve illustrated such a normal vector below for two dimensions, but you should imagine that we&#8217;re working in higher dimensions:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/michaelnielsen.org\/ddi\/wp-content\/uploads\/2012\/02\/svm_normal_vector.png\" width=\"350px\"><\/p>\n<p>The condition for a feature difference vector to be in (say) the upper half-space is that <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cphi%28q%2Cd%2Cd%27%29+%5Ccdot+%5Cvec+w+%3E+0&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\phi(q,d,d&#039;) \\cdot \\vec w &gt; 0' title='\\vec \\phi(q,d,d&#039;) \\cdot \\vec w &gt; 0' class='latex' \/>.  To be in the lower half-space the condition is that <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cphi%28q%2Cd%2Cd%27%29+%5Ccdot+%5Cvec+w+%3C+0%26%2391%3B%2Flatex%26%2393%3B.++Summing+everything+up%2C+we+can+check+whether+the+document+%26%2391%3Blatex%26%2393%3Bd%26%2391%3B%2Flatex%26%2393%3B+should+be+ranked+above+or+below+%26%2391%3Blatex%26%2393%3Bd%27%26%2391%3B%2Flatex%26%2393%3B+simply+by+computing+the+sign+of+%26%2391%3Blatex%26%2393%3B%5Cvec+%5Cphi%28q%2Cd%2Cd%27%29+%5Ccdot+%5Cvec+w%26%2391%3B%2Flatex%26%2393%3B.++The+above+observations+suggest+an+algorithm+for+using+the+feature+difference+vectors+to+determine+search+relevance.++It%27s+a+pretty+obvious+generalization+of+what+I%27ve+just+described%2C+but+at+the+risk+of+repeating+myself+I%27ll+write+it+all+out+explicitly.++To+start%2C+we+assume+that+a+set+of+training+data+has+been+provided+by+human+operators.++Those+operators+have+been+given+a+set+of+training+queries+%26%2391%3Blatex%26%2393%3Bq_1%2Cq_2%2C%5Cldots%2Cq_m%26%2391%3B%2Flatex%26%2393%3B+and+training+documents+%26%2391%3Blatex%26%2393%3Bd_1%2Cd_2%2C%5Cldots%2Cd_n%26%2391%3B%2Flatex%26%2393%3B.++For+each+training+query+they%27ve+ranked+each+training+document+in+order+of+relevance+to+that+query.++They+might+decide%2C+for+example%2C+that+for+the+query+%26%2391%3Blatex%26%2393%3Bq_1%26%2391%3B%2Flatex%26%2393%3B%2C+the+document+%26%2391%3Blatex%26%2393%3Bd_%7B17%7D%26%2391%3B%2Flatex%26%2393%3B+should+be+the+top-ranked+query%2C+%26%2391%3Blatex%26%2393%3Bd_5%26%2391%3B%2Flatex%26%2393%3B+the+second-ranked+query%2C+and+so+on.++This+training+data+provides+us+with+a+whole+lot+of+feature+difference+vectors+%26%2391%3Blatex%26%2393%3B%5Cvec+%5Cphi%28q_i%2Cd_j%2Cd_k%29%26%2391%3B%2Flatex%26%2393%3B.++These+vectors+can+be+divided+up+into+two+sets.++The+first+set%2C+which+we%27ll+call+training+data+set+%26%2391%3Blatex%26%2393%3BA%26%2391%3B%2Flatex%26%2393%3B%2C+contains+those+feature+difference+vectors+for+which+%26%2391%3Blatex%26%2393%3Bd_j%26%2391%3B%2Flatex%26%2393%3B+has+been+ranked+more+highly+than+%26%2391%3Blatex%26%2393%3Bd_k%26%2391%3B%2Flatex%26%2393%3B.++The+second+set%2C+which+we%27ll+call+training+data+set+%26%2391%3Blatex%26%2393%3BB%26%2391%3B%2Flatex%26%2393%3B%2C+contains+those+feature+difference+vectors+for+which+%26%2391%3Blatex%26%2393%3Bd_k%26%2391%3B%2Flatex%26%2393%3B+has+been+ranked+more+highly+than+%26%2391%3Blatex%26%2393%3Bd_j%26%2391%3B%2Flatex%26%2393%3B.++We+then+find+a+separating+hyperplane+that+separates+these+two+data+sets%2C+i.e.%2C+with+the+%3Cem%3Eupper+half-space%3C%2Fem%3E+containing+data+set+%5Blatex%5DA&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\phi(q,d,d&#039;) \\cdot \\vec w &lt; 0&#091;\/latex&#093;.  Summing everything up, we can check whether the document &#091;latex&#093;d&#091;\/latex&#093; should be ranked above or below &#091;latex&#093;d&#039;&#091;\/latex&#093; simply by computing the sign of &#091;latex&#093;\\vec \\phi(q,d,d&#039;) \\cdot \\vec w&#091;\/latex&#093;.  The above observations suggest an algorithm for using the feature difference vectors to determine search relevance.  It&#039;s a pretty obvious generalization of what I&#039;ve just described, but at the risk of repeating myself I&#039;ll write it all out explicitly.  To start, we assume that a set of training data has been provided by human operators.  Those operators have been given a set of training queries &#091;latex&#093;q_1,q_2,\\ldots,q_m&#091;\/latex&#093; and training documents &#091;latex&#093;d_1,d_2,\\ldots,d_n&#091;\/latex&#093;.  For each training query they&#039;ve ranked each training document in order of relevance to that query.  They might decide, for example, that for the query &#091;latex&#093;q_1&#091;\/latex&#093;, the document &#091;latex&#093;d_{17}&#091;\/latex&#093; should be the top-ranked query, &#091;latex&#093;d_5&#091;\/latex&#093; the second-ranked query, and so on.  This training data provides us with a whole lot of feature difference vectors &#091;latex&#093;\\vec \\phi(q_i,d_j,d_k)&#091;\/latex&#093;.  These vectors can be divided up into two sets.  The first set, which we&#039;ll call training data set &#091;latex&#093;A&#091;\/latex&#093;, contains those feature difference vectors for which &#091;latex&#093;d_j&#091;\/latex&#093; has been ranked more highly than &#091;latex&#093;d_k&#091;\/latex&#093;.  The second set, which we&#039;ll call training data set &#091;latex&#093;B&#091;\/latex&#093;, contains those feature difference vectors for which &#091;latex&#093;d_k&#091;\/latex&#093; has been ranked more highly than &#091;latex&#093;d_j&#091;\/latex&#093;.  We then find a separating hyperplane that separates these two data sets, i.e., with the &lt;em&gt;upper half-space&lt;\/em&gt; containing data set [latex]A' title='\\vec \\phi(q,d,d&#039;) \\cdot \\vec w &lt; 0&#091;\/latex&#093;.  Summing everything up, we can check whether the document &#091;latex&#093;d&#091;\/latex&#093; should be ranked above or below &#091;latex&#093;d&#039;&#091;\/latex&#093; simply by computing the sign of &#091;latex&#093;\\vec \\phi(q,d,d&#039;) \\cdot \\vec w&#091;\/latex&#093;.  The above observations suggest an algorithm for using the feature difference vectors to determine search relevance.  It&#039;s a pretty obvious generalization of what I&#039;ve just described, but at the risk of repeating myself I&#039;ll write it all out explicitly.  To start, we assume that a set of training data has been provided by human operators.  Those operators have been given a set of training queries &#091;latex&#093;q_1,q_2,\\ldots,q_m&#091;\/latex&#093; and training documents &#091;latex&#093;d_1,d_2,\\ldots,d_n&#091;\/latex&#093;.  For each training query they&#039;ve ranked each training document in order of relevance to that query.  They might decide, for example, that for the query &#091;latex&#093;q_1&#091;\/latex&#093;, the document &#091;latex&#093;d_{17}&#091;\/latex&#093; should be the top-ranked query, &#091;latex&#093;d_5&#091;\/latex&#093; the second-ranked query, and so on.  This training data provides us with a whole lot of feature difference vectors &#091;latex&#093;\\vec \\phi(q_i,d_j,d_k)&#091;\/latex&#093;.  These vectors can be divided up into two sets.  The first set, which we&#039;ll call training data set &#091;latex&#093;A&#091;\/latex&#093;, contains those feature difference vectors for which &#091;latex&#093;d_j&#091;\/latex&#093; has been ranked more highly than &#091;latex&#093;d_k&#091;\/latex&#093;.  The second set, which we&#039;ll call training data set &#091;latex&#093;B&#091;\/latex&#093;, contains those feature difference vectors for which &#091;latex&#093;d_k&#091;\/latex&#093; has been ranked more highly than &#091;latex&#093;d_j&#091;\/latex&#093;.  We then find a separating hyperplane that separates these two data sets, i.e., with the &lt;em&gt;upper half-space&lt;\/em&gt; containing data set [latex]A' class='latex' \/> (where <img src='https:\/\/s0.wp.com\/latex.php?latex=d_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d_j' title='d_j' class='latex' \/> is ranked more highly than <img src='https:\/\/s0.wp.com\/latex.php?latex=d_k&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d_k' title='d_k' class='latex' \/> for <img src='https:\/\/s0.wp.com\/latex.php?latex=q_i&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='q_i' title='q_i' class='latex' \/>), and a <em>lower   half-space<\/em> containing data set <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>.<\/p>\n<p>Suppose now that <img src='https:\/\/s0.wp.com\/latex.php?latex=q&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='q' title='q' class='latex' \/> is <em>any<\/em> query &#8211; not necessarily a training query.  And suppose <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/> are any two documents, not just training documents.  We rank <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> above <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/> for query <img src='https:\/\/s0.wp.com\/latex.php?latex=q&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='q' title='q' class='latex' \/> if the feature difference vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cphi%28q%2Cd%2Cd%27%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\phi(q,d,d&#039;)' title='\\vec \\phi(q,d,d&#039;)' class='latex' \/> lies in the upper half-space.  And we rank <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> below <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/> if it lies in the lower half-space.  This completes the description of the algorithm.<\/p>\n<p>There are many problems with this basic algorithm.  One problem becomes evident by going back to our primitive training data and adding an extra document:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/michaelnielsen.org\/ddi\/wp-content\/uploads\/2012\/02\/svm_augmented_data.png\" width=\"320px\"><\/p>\n<p>Inspecting the feature difference vectors reveals a problem:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/michaelnielsen.org\/ddi\/wp-content\/uploads\/2012\/02\/svm_augmented_feature_differences.png\" width=\"260px\"><\/p>\n<p>I&#8217;ve simplified the picture by showing only the feature difference vectors <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cphi%28q%2Cd%2Cd%27%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\phi(q,d,d&#039;)' title='\\phi(q,d,d&#039;)' class='latex' \/> in data set <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/>, i.e., those for which <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> ranks more highly than <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/>; data set <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/> contains the negation of those vectors.  It should be clear that there is no half-space which can be used to divide up the vectors into two sets.  It&#8217;s not geometrically possible.  The way we&#8217;ll deal with this is by modifying the algorithm in such a way as to find a half-space which <em>approximately<\/em> divides the two sets of feature difference vectors into half-spaces.  I&#8217;ll explain how to do this approximate division later in the post.  <\/p>\n<p>Before getting to the approximate division, though, we&#8217;ll warm up by figuring out much more explicitly how to do the division into two half-spaces when it <em>is<\/em> possible.  It&#8217;s all very well for me to glibly say that we should &#8220;figure out which half-space the vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cphi%28q%2Cd%2Cd%27%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\phi(q,d,d&#039;)' title='\\phi(q,d,d&#039;)' class='latex' \/> is in&#8221;, but how can we actually do this in practice? In the next section I&#8217;ll introduce <em>support vector machines<\/em>, which are a way of doing this kind of division explicitly.  Once we&#8217;ve understood the basics of support vector machines, we&#8217;ll come back to the question of how to divide two sets of vectors into approximate half-spaces.<\/p>\n<h3>Problems<\/h3>\n<ul>\n<li> Suppose the basic algorithm that I&#8217;ve described works, i.e., a   division into half-spaces is possible.  Suppose that for a   particular query <img src='https:\/\/s0.wp.com\/latex.php?latex=q&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='q' title='q' class='latex' \/> the document <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> is ranked above <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/>   is ranked above <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;&#039;' title='d&#039;&#039;' class='latex' \/>.  Prove that the algorithm will rank <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> above   <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;&#039;' title='d&#039;&#039;' class='latex' \/>. <\/ul>\n<h3>Support vector machines<\/h3>\n<p>Support vector machines are a technique for partitioning two sets of vectors (data set <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> and data set <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>) into half-spaces separated by a <em>separating hyperplane<\/em>.  The technique is guaranteed to work whenever such a partitioning is possible, and whatsmore the partitioning is optimal, in a sense I&#8217;ll make precise.  In this section I&#8217;ll describe briefly how support vector machines work.<\/p>\n<p>As an aside, you&#8217;ll note that the notion of search (and related topics) wasn&#8217;t mentioned anywhere in the last paragraph.  That&#8217;s because support vector machines aren&#8217;t about search.  Instead, they&#8217;re a general technique for dividing sets of vectors into half-spaces, a technique which can be applied to many different problems in machine learning and artificial intelligence, not just search.  So support vector machines are a useful technique to understand, even if you&#8217;re not especially interested in search.  End of aside.<\/p>\n<p><em>A priori<\/em> if someone just gives you two sets of vectors, <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>, it&#8217;s not always going to be clear whether a partitioning into two half-spaces is possible.  But let&#8217;s assume that such a partitioning is possible, and we&#8217;ll return later to what happens when it&#8217;s not.  What we&#8217;d like to do is to find an explicit way of specifying a separating hyperplane:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/michaelnielsen.org\/ddi\/wp-content\/uploads\/2012\/02\/svm_problem.png\" width=\"350px\"><\/p>\n<p>Note that in the last section our separating hyperplanes passed through the origin.  But for support vector machines we&#8217;ll also allow hyperplanes which don&#8217;t pass through the origin.  One way to explicitly specify such a hyperplane is as the set of vectors <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x' title='\\vec x' class='latex' \/> satisfying the equation:<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=+++%5Cvec+w+%5Ccdot+%5Cvec+x+%2B+b+%3D+0%2C+&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='   \\vec w \\cdot \\vec x + b = 0, ' title='   \\vec w \\cdot \\vec x + b = 0, ' class='latex' \/>\n<p>where <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> is a vector normal to the separating hyperplane, and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> is a constant.  Together, <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> specify the hyperplane. The goal of the support vector machine is to take data sets <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>, and use them to construct values for <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> which specify a separating hyperplane.  Whatsmore, we&#8217;ll try to do this in such a way that we maximize the size of the &#8220;wedge&#8221; between the two data sets,<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/michaelnielsen.org\/ddi\/wp-content\/uploads\/2012\/02\/svm_wedge.png\" width=\"360px\"><\/p>\n<p>where we require that the two edges of the wedge (called <em>support<\/em> or <em>supporting hyperplanes<\/em>) be parallel to the separating hyperplane itself. In other words, the goal is to choose the separating hyperplane (i.e., to choose <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/>) in such a way that these two supporting hyperplanes are as far apart from one another as possible.<\/p>\n<p>Let me mention, by the way, that I&#8217;m not mad keen on the notations we&#8217;ve been using, such as <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/>.  Unfortunately, it&#8217;s not going to get any better &#8211; we have some <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cxi&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\xi' title='\\xi' class='latex' \/>&#8216;s and <img src='https:\/\/s0.wp.com\/latex.php?latex=C&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='C' title='C' class='latex' \/>&#8216;s in our near future, and I&#8217;m sorry to say that the origin of those notations won&#8217;t be much more transparent than the origins of <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/>.  I&#8217;m using what seems to be standard notation in the support vector machine literature, but it&#8217;s not very good notation, in my opinion: it has little or no mnemonic value, and is very non-uniform to boot.  While I&#8217;m complaining, I&#8217;ll mention one more thing: the vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> is sometimes known as the <em>weight vector<\/em>, again, for reasons which seem obscure.  End of rant.<\/p>\n<p>Let&#8217;s get back to the problem of choosing <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> so that the two supporting hyperplanes are as far apart from one another as possible.  To do that, we need to figure out a way of expressing the distance between the two supporting hyperplanes in terms of <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/>.  Without any loss of generality, we&#8217;ll suppose that the separating hyperplane is halfway between the two supporting hyperplanes:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/michaelnielsen.org\/ddi\/wp-content\/uploads\/2012\/02\/svm_halfway.png\" width=\"360px\"><\/p>\n<p>Let&#8217;s fix our attention on one of the two supporting hyperplanes, say, the one that is &#8220;higher up&#8221; in the picture above.  We&#8217;ll suppose, also without any loss of generality, that this is the hyperplane supporting data set <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/>.  By rescaling <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> if necessary, we can ensure that this support hyperplane has the equation<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=+++%5Cvec+w+%5Ccdot+%5Cvec+x+%2B+b+%3D+1%2C+&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='   \\vec w \\cdot \\vec x + b = 1, ' title='   \\vec w \\cdot \\vec x + b = 1, ' class='latex' \/>\n<p>and so the constraint that this hyperplane support data set <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> may be expressed as <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w+%5Ccdot+%5Cvec+x+%2B+b+%5Cgeq+1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w \\cdot \\vec x + b \\geq 1' title='\\vec w \\cdot \\vec x + b \\geq 1' class='latex' \/>.  This is an important constraint: it&#8217;s the constraint on data set <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/>.<\/p>\n<h3>Exercises<\/h3>\n<ul>\n<li> If you&#8217;re not comfortable with hyperplanes you may not   immediately see why the kind of rescaling of <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> which   I did in the last paragraph is always possible.  If this is the   case, then write out an explicit proof. <\/ul>\n<p>We can now determine the distance between the supporting and separating hyperplane by introducing a vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5CDelta&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\Delta' title='\\Delta' class='latex' \/> which is: (a) normal to both hyperplanes, and (b) connects the two hyperplanes.  A bit more precisely, <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5CDelta+%3A%3D+%5Cvec+x%27-%5Cvec+x&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\Delta := \\vec x&#039;-\\vec x' title='\\vec \\Delta := \\vec x&#039;-\\vec x' class='latex' \/>, where <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x&#039;' title='\\vec x&#039;' class='latex' \/> is in the supporting hyperplane and <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x' title='\\vec x' class='latex' \/> is the projection of <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x&#039;' title='\\vec x&#039;' class='latex' \/> onto the separating hyperplane:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/michaelnielsen.org\/ddi\/wp-content\/uploads\/2012\/02\/svm_Delta.png\" width=\"360px\"><\/p>\n<p>Our goal is to find the length of <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5CDelta&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\Delta' title='\\vec \\Delta' class='latex' \/>.  Taking the difference of the equations <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w+%5Ccdot+%5Cvec+x%27+%2B+b+%3D+1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w \\cdot \\vec x&#039; + b = 1' title='\\vec w \\cdot \\vec x&#039; + b = 1' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w+%5Ccdot+%5Cvec+x+%2B+b+%3D+0&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w \\cdot \\vec x + b = 0' title='\\vec w \\cdot \\vec x + b = 0' class='latex' \/>, we have <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w+%5Ccdot+%5Cvec+%5CDelta+%3D+1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w \\cdot \\vec \\Delta = 1' title='\\vec w \\cdot \\vec \\Delta = 1' class='latex' \/>.  Since <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5CDelta&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\Delta' title='\\vec \\Delta' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> are both normal to the separating hyperplane, and thus parallel, it follows that <img src='https:\/\/s0.wp.com\/latex.php?latex=%5CDelta+w+%3D+1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\Delta w = 1' title='\\Delta w = 1' class='latex' \/>, where I am omitting the <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Ccdot&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\cdot' title='\\vec \\cdot' class='latex' \/> in order to denote length.  It follows that the distance from the separating to the supporting hyperplane is <img src='https:\/\/s0.wp.com\/latex.php?latex=%5CDelta+%3D+1%2Fw&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\Delta = 1\/w' title='\\Delta = 1\/w' class='latex' \/>.<\/p>\n<p>We chose the separating hyperplane to be halfway between the two supporting hyperplanes, and so the total size of the wedge is <img src='https:\/\/s0.wp.com\/latex.php?latex=2%5CDelta+%3D+2%2Fw&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='2\\Delta = 2\/w' title='2\\Delta = 2\/w' class='latex' \/>.  As a result, maximizing the size of the wedge is equivalent to maximizing <img src='https:\/\/s0.wp.com\/latex.php?latex=2%2Fw&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='2\/w' title='2\/w' class='latex' \/>.  This is subject to the constraint on data set <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/>, namely that <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w+%5Ccdot+%5Cvec+x_j+%2B+b+%5Cgeq+1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w \\cdot \\vec x_j + b \\geq 1' title='\\vec w \\cdot \\vec x_j + b \\geq 1' class='latex' \/> for all the vectors <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x_j' title='\\vec x_j' class='latex' \/> in data set <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/>.  There&#8217;s also a similar constraint for data set <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>,<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=+++%5Cvec+w+%5Ccdot+%5Cvec+x_j+%2B+b+%5Cleq+-1+&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='   \\vec w \\cdot \\vec x_j + b \\leq -1 ' title='   \\vec w \\cdot \\vec x_j + b \\leq -1 ' class='latex' \/>\n<p>for all the vectors <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x_j' title='\\vec x_j' class='latex' \/> in data set <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>.  The supporting hyperplane for data set <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/> satisfies this condition with equality.<\/p>\n<h3>Exercises<\/h3>\n<ul>\n<li> Prove that <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w+%5Ccdot+x+%2B+b+%3D+-1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w \\cdot x + b = -1' title='\\vec w \\cdot x + b = -1' class='latex' \/> is the equation for the   supporting hyperplane for data set <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>. <\/ul>\n<p>There is a reasonably nice way of combining the two sets of constraint inequalities for data sets <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>.  That&#8217;s to label each vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x_j' title='\\vec x_j' class='latex' \/> with a value <img src='https:\/\/s0.wp.com\/latex.php?latex=y_j+%3D+%2B1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='y_j = +1' title='y_j = +1' class='latex' \/> if <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x_j' title='\\vec x_j' class='latex' \/> is in data set <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/>, and with <img src='https:\/\/s0.wp.com\/latex.php?latex=y_j+%3D+-1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='y_j = -1' title='y_j = -1' class='latex' \/> if <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x_j' title='\\vec x_j' class='latex' \/> is in data set <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>.  With these labels, we can now express the constraints on <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> in a single set of inequalities<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=+++y_j+%28%5Cvec+w+%5Ccdot+%5Cvec+x_j+%2B+b%29+%5Cgeq+1%2C+&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='   y_j (\\vec w \\cdot \\vec x_j + b) \\geq 1, ' title='   y_j (\\vec w \\cdot \\vec x_j + b) \\geq 1, ' class='latex' \/>\n<p>with equality holding if the vector in question is on a supporting hyperlane (a so-called <em>support vector<\/em>).  This single set of inequalities represents the constraint that <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> really do define separating and supporting hyperplanes for data sets <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>, and that the distance between the supporting hyperplanes is <img src='https:\/\/s0.wp.com\/latex.php?latex=2%2Fw&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='2\/w' title='2\/w' class='latex' \/>.<\/p>\n<p>Rather than maximize <img src='https:\/\/s0.wp.com\/latex.php?latex=2%2Fw&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='2\/w' title='2\/w' class='latex' \/> subject to the above constraints, it&#8217;s conventional to instead minimize <img src='https:\/\/s0.wp.com\/latex.php?latex=w%5E2%2F2+%3D+%5Cvec+w+%5Ccdot+%5Cvec+w+%2F2&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='w^2\/2 = \\vec w \\cdot \\vec w \/2' title='w^2\/2 = \\vec w \\cdot \\vec w \/2' class='latex' \/>, subject to the same constraints.  This is obviously equivalent, and the reason we make this change will become clear shortly.<\/p>\n<p>Summing up, our problem is to find <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> which minimize the value of:<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=+++%5Cfrac%7Bw%5E2%7D%7B2%7D+&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='   \\frac{w^2}{2} ' title='   \\frac{w^2}{2} ' class='latex' \/>\n<p>subject to the constraints<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=+++y_j+%28%5Cvec+w+%5Ccdot+%5Cvec+x_j+%2B+b%29+%5Cgeq+1%2C+&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='   y_j (\\vec w \\cdot \\vec x_j + b) \\geq 1, ' title='   y_j (\\vec w \\cdot \\vec x_j + b) \\geq 1, ' class='latex' \/>\n<p>where <img src='https:\/\/s0.wp.com\/latex.php?latex=y_j+%3D+%2B1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='y_j = +1' title='y_j = +1' class='latex' \/> if <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x_j' title='\\vec x_j' class='latex' \/> is in data set <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/>, and <img src='https:\/\/s0.wp.com\/latex.php?latex=y_j+%3D+-1&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='y_j = -1' title='y_j = -1' class='latex' \/> if <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x_j' title='\\vec x_j' class='latex' \/> is in data set <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>.<\/p>\n<p>This formulation of our problem represents real progress. The reason is that the problem just described is an instance of a very well-known type of problem in mathematics and computer science, called a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Quadratic_programming\">quadratic   programming problem<\/a>.  Although quadratic programs don&#8217;t in general have simple, closed-form solutions, they&#8217;ve been studied for decades and are well understood, and there are good algorithms and libraries for solving them.  It&#8217;s because quadratic programs are so well understood that we changed from maximizing <img src='https:\/\/s0.wp.com\/latex.php?latex=2%2Fw&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='2\/w' title='2\/w' class='latex' \/> to minimizing <img src='https:\/\/s0.wp.com\/latex.php?latex=w%5E2%2F2&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='w^2\/2' title='w^2\/2' class='latex' \/> (the <img src='https:\/\/s0.wp.com\/latex.php?latex=1%2F2&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='1\/2' title='1\/2' class='latex' \/> is conventional, since it simplifies certain other expressions in the theory of quadratic programming).  Indeed, quadratic programs are so well understood that not only are there many libraries for solving quadratic programs, some of those libraries have been specially designed to solve the quadratic programs which arise from support vector machines.  Here&#8217;s a rather lengthy <a href=\"http:\/\/www.support-vector-machines.org\/SVM_soft.html\">list of   libraries and packages<\/a> which are designed for support vector machines, and you may wish to experiment with those libraries.<\/p>\n<p>Incidentally, one potentially confusing thing about the quadratic programming problem posed above &#8211; and one of the reasons I complain about the notation &#8211; is to be clear on exactly what is being solved for.  The <img src='https:\/\/s0.wp.com\/latex.php?latex=y_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='y_j' title='y_j' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x_j' title='\\vec x_j' class='latex' \/> are <em>known<\/em> input data, which should be regarded as fixed, and the task is to solve for <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/>.  This is obviously rather different from the traditional use of <img src='https:\/\/s0.wp.com\/latex.php?latex=x&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='x' title='x' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=y&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='y' title='y' class='latex' \/> to denote what we&#8217;re solving for, and it&#8217;s good to keep this clearly in mind.<\/p>\n<p>We can now explain what a support vector machine actually <em>is.<\/em> We have some problem &#8211; like the search ranking problem &#8211; which generate sets of training data, <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>, in a vector space.  The support vector machine will find the parameters <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> for the separating hyperplane, so that the &#8220;wedge&#8221; between these two data sets is maximized, i.e., the distance between the supporting hyperplanes is maximized.  We can then use the parameters <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> to classify new problem instances <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x' title='\\vec x' class='latex' \/> as being of type <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> or type <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>.  In particular, we classify <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x' title='\\vec x' class='latex' \/> as being of type <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> if <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w+%5Ccdot+%5Cvec+x+%2B+b+%5Cgeq+0&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w \\cdot \\vec x + b \\geq 0' title='\\vec w \\cdot \\vec x + b \\geq 0' class='latex' \/>, and of type <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/> if <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w+%5Ccdot+%5Cvec+x+%2B+b+%3C+0%26%2391%3B%2Flatex%26%2393%3B.++A+support+vector+machine+is+an+example+of+a+%3Ca+href%3D%22http%3A%2F%2Fen.wikipedia.org%2Fwiki%2FLinear_classifier%22%3Elinear+++classifier%3C%2Fa%3E%3A+a+decision+procedure+which+makes+a+classification+decision+%28%60%60Is+page+%5Blatex%5Dd&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w \\cdot \\vec x + b &lt; 0&#091;\/latex&#093;.  A support vector machine is an example of a &lt;a href=&quot;http:\/\/en.wikipedia.org\/wiki\/Linear_classifier&quot;&gt;linear   classifier&lt;\/a&gt;: a decision procedure which makes a classification decision (``Is page [latex]d' title='\\vec w \\cdot \\vec x + b &lt; 0&#091;\/latex&#093;.  A support vector machine is an example of a &lt;a href=&quot;http:\/\/en.wikipedia.org\/wiki\/Linear_classifier&quot;&gt;linear   classifier&lt;\/a&gt;: a decision procedure which makes a classification decision (``Is page [latex]d' class='latex' \/> ranked higher than page <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/>&#8220;) using some linear function of the feature vector describing the problem instance. It&#8217;s a <em>binary<\/em> linear classifier, since the classification is into two types.  Such classifiers are useful because they have such generality.  Have a bunch of photos, and want to classify which are photos of fish?  Spend some time (or money) generating training data, and some more time coming up with a few features that seem like they might be helpful.  Then find a support vector machine which can be used to classify more problem instances, and see how well it works! Of course, nothing guarantees that it&#8217;ll work well, but with good feature selection it seems that if often really does work well in practice.<\/p>\n<p>I won&#8217;t go any deeper into the theory or practice of support vector machines in this post.  Instead, we&#8217;ll return to the question of how to deal with the fact that sometimes it&#8217;s <em>not<\/em> possible to separate the training data into two half-spaces.  What we&#8217;ll see is that it is possible to do an approximate separation, using the same techniques of quadratic programming.  This is known as a support vector machine with a <em>soft margin<\/em>.  Once we&#8217;ve understood how that works I&#8217;ll come back to what this all means in the context of search.<\/p>\n<h3>Support vector machines with a soft margin<\/h3>\n<p>In our earlier discussion of search, we saw an example where the feature difference vectors in a set of training data cannot be partitioned into two half-spaces (again, as earlier, this diagram only shows feature difference vectors <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+%5Cphi%28q%2Cd%2Cd%27%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec \\phi(q,d,d&#039;)' title='\\vec \\phi(q,d,d&#039;)' class='latex' \/> where <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> should be ranked higher than <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/>, i.e., it shows only data set <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/>):<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/michaelnielsen.org\/ddi\/wp-content\/uploads\/2012\/02\/svm_augmented_feature_differences.png\" width=\"260px\"><\/p>\n<p>What can we do in this situation?  There is a way of modifying the support vector machine idea to find an approximate way of partitioning two sets of vectors into half-spaces.  The idea is to allow some of the vectors to slightly violate the half-space constraints.  We compensate for these violations by paying a penalty in the function being minimized.  This will ensure that any violations are quite small.<\/p>\n<p>The way this idea is implemented is as follows.  We introduce some <em>slack variables<\/em> <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cxi_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\xi_j' title='\\xi_j' class='latex' \/>, one for each vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x_j' title='\\vec x_j' class='latex' \/>.  The size of the slack variable <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cxi_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\xi_j' title='\\xi_j' class='latex' \/> will determine how much violation of the half-space constraint is allowed for the vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x_j' title='\\vec x_j' class='latex' \/>.  In particular, the constraints on the vectors are now relaxed to be<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=+++y_j+%28%5Cvec+w+%5Ccdot+%5Cvec+x_j+%2B+b%29+%5Cgeq+1-%5Cxi_j.+&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='   y_j (\\vec w \\cdot \\vec x_j + b) \\geq 1-\\xi_j. ' title='   y_j (\\vec w \\cdot \\vec x_j + b) \\geq 1-\\xi_j. ' class='latex' \/>\n<p>We also impose the constraint on the slack variables that<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=+++%5Cxi_j+%5Cgeq+0%2C+&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='   \\xi_j \\geq 0, ' title='   \\xi_j \\geq 0, ' class='latex' \/>\n<p>simply so as to ensure that we&#8217;re not over-constraining our vectors by picking a negative value for <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cxi_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\xi_j' title='\\xi_j' class='latex' \/>.  The larger a given <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cxi_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\xi_j' title='\\xi_j' class='latex' \/> the more the vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x_j' title='\\vec x_j' class='latex' \/> can violate the partitioning into half-spaces.  For that reason we introduce a new term in the function we want to minimize, in order to penalize excursions from the half-space:<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=+++%5Cfrac%7Bw%5E2%7D%7B2%7D+%2B+C+%5Csum_j+%5Cxi_j.+&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='   \\frac{w^2}{2} + C \\sum_j \\xi_j. ' title='   \\frac{w^2}{2} + C \\sum_j \\xi_j. ' class='latex' \/>\n<p>Here <img src='https:\/\/s0.wp.com\/latex.php?latex=C+%3E+0&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='C &gt; 0' title='C &gt; 0' class='latex' \/> is called the <em>soft margin parameter<\/em>.  If <img src='https:\/\/s0.wp.com\/latex.php?latex=C&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='C' title='C' class='latex' \/> is large, then we pay a substantial penalty even for small excursions from the half-spaces.  On the other hand, if <img src='https:\/\/s0.wp.com\/latex.php?latex=C&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='C' title='C' class='latex' \/> is small then we pay only a small penalty, and so we can expect larger excursions from the half-spaces.<\/p>\n<p>The problem defined in the last paragraph is (again) a quadratic program, and standard algorithms and libraries can be used to solve the program.  Also as in the last section, given a solution to the program we can use that solution as a binary linear classifier.  In particular, suppose <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w' title='\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> appear in such a solution.  Then given a new problem instance <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x' title='\\vec x' class='latex' \/> to be classified, we classify it as being of type <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> if <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w+%5Ccdot+%5Cvec+x+%2B+b+%5Cgeq+0&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w \\cdot \\vec x + b \\geq 0' title='\\vec w \\cdot \\vec x + b \\geq 0' class='latex' \/>, and of type <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/> if <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+w+%5Ccdot+%5Cvec+x+%2B+b+%3C+0%26%2391%3B%2Flatex%26%2393%3B.++An+issue+that+I+haven%27t+addressed+-+and+don%27t+yet+know+how+to+solve+-+is+how+to+choose+the+soft+margin+parameter%2C+%26%2391%3Blatex%26%2393%3BC%26%2391%3B%2Flatex%26%2393%3B.++As+a+starting+point+for+understanding+this+choice%2C+let+me+at+least+state+the+following%3A++%3Cstrong%3ETheorem%3A%3C%2Fstrong%3E+A+solution+to+the+quadratic+program+above+always+exists.+++This+is+a+major+improvement+over+the+situation+without+the+soft+margin%2C+where+it%27s+not+even+guaranteed+that+a+solution+will+exist.++It+means+that+no+matter+what+the+training+data+or+soft+margin+parameter%2C+we+can+always+build+a+binary+linear+classifier+using+the+support+vector+machine+with+that+soft+margin.+++++I+won%27t+give+the+proof+of+the+theorem%2C+but+the+intuition+is+simple+enough%3A+for+any+choice+of+%5Blatex%5D%5Cvec+w&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec w \\cdot \\vec x + b &lt; 0&#091;\/latex&#093;.  An issue that I haven&#039;t addressed - and don&#039;t yet know how to solve - is how to choose the soft margin parameter, &#091;latex&#093;C&#091;\/latex&#093;.  As a starting point for understanding this choice, let me at least state the following:  &lt;strong&gt;Theorem:&lt;\/strong&gt; A solution to the quadratic program above always exists.   This is a major improvement over the situation without the soft margin, where it&#039;s not even guaranteed that a solution will exist.  It means that no matter what the training data or soft margin parameter, we can always build a binary linear classifier using the support vector machine with that soft margin.     I won&#039;t give the proof of the theorem, but the intuition is simple enough: for any choice of [latex]\\vec w' title='\\vec w \\cdot \\vec x + b &lt; 0&#091;\/latex&#093;.  An issue that I haven&#039;t addressed - and don&#039;t yet know how to solve - is how to choose the soft margin parameter, &#091;latex&#093;C&#091;\/latex&#093;.  As a starting point for understanding this choice, let me at least state the following:  &lt;strong&gt;Theorem:&lt;\/strong&gt; A solution to the quadratic program above always exists.   This is a major improvement over the situation without the soft margin, where it&#039;s not even guaranteed that a solution will exist.  It means that no matter what the training data or soft margin parameter, we can always build a binary linear classifier using the support vector machine with that soft margin.     I won&#039;t give the proof of the theorem, but the intuition is simple enough: for any choice of [latex]\\vec w' class='latex' \/> and <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/>, by choosing <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cxi_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\xi_j' title='\\xi_j' class='latex' \/> sufficiently large we can ensure that <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x_j' title='\\vec x_j' class='latex' \/> satisfies the constraints.  A fairly standard continuity and compactness argument should do the trick (modulo some reasonable assumptions, e.g., that we&#8217;re working in finite dimensions and with finite data sets).<\/p>\n<p>While the theorem above is an encouraging start, it&#8217;s not what we really want.  What we&#8217;d like is to understand how best to choose <img src='https:\/\/s0.wp.com\/latex.php?latex=C&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='C' title='C' class='latex' \/>. Ideally, this means understanding how different choices of <img src='https:\/\/s0.wp.com\/latex.php?latex=C&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='C' title='C' class='latex' \/> impact the solutions which are found, and being more precise about what sorts of excursions from the half-spaces we are willing to allow, and what impact this has on the quality of classifications.  This is, obviously, a challenging theoretical program!  However, for the very practical problem of combining different relevancy factors in search, I think a great deal of progress could be made simply by trying out different values of <img src='https:\/\/s0.wp.com\/latex.php?latex=C&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='C' title='C' class='latex' \/>, and testing to see which value empirically gives the best results.  Trial-and-error is often better than being smart.<\/p>\n<h3>Problems<\/h3>\n<ul>\n<li> Above, I talked about the soft margin parameter <img src='https:\/\/s0.wp.com\/latex.php?latex=C&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='C' title='C' class='latex' \/> being   &#8220;large&#8221; or &#8220;small&#8221;, but didn&#8217;t explain exactly what I meant.   How could we make these notions more precise?\n<li> Suppose the data sets have the property that data set <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/> is the   negation of data set <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>, i.e., for each vector <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec+x&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='\\vec x' title='\\vec x' class='latex' \/> in <img src='https:\/\/s0.wp.com\/latex.php?latex=A&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='A' title='A' class='latex' \/>,   there is a corresponding vector <img src='https:\/\/s0.wp.com\/latex.php?latex=-%5Cvec+x&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='-\\vec x' title='-\\vec x' class='latex' \/> in <img src='https:\/\/s0.wp.com\/latex.php?latex=B&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='B' title='B' class='latex' \/>, and vice versa.   (This is the case in the search problem, for example.)  Prove that   if a value for <img src='https:\/\/s0.wp.com\/latex.php?latex=b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b' title='b' class='latex' \/> appears in a solution to the quadratic program,   then there is also a solution to the quadratic program with value   <img src='https:\/\/s0.wp.com\/latex.php?latex=-b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='-b' title='-b' class='latex' \/>.  In fact, it&#8217;s possible to prove (though we won&#8217;t do so) that   the solution to the quadratic program is unique, and so we must have   <img src='https:\/\/s0.wp.com\/latex.php?latex=b%3D-b&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b=-b' title='b=-b' class='latex' \/>, and therefore <img src='https:\/\/s0.wp.com\/latex.php?latex=b%3D0&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b=0' title='b=0' class='latex' \/>.  It follows that for the search problem   we can assume <img src='https:\/\/s0.wp.com\/latex.php?latex=b%3D0&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='b=0' title='b=0' class='latex' \/> in the solution to the quadratic program.\n<\/ul>\n<h3>Problems for the author<\/h3>\n<ul>\n<li> The modifications to the support vector machine model made in   this section are quite <em>ad hoc<\/em>.  In particular, choosing the   penalty to be <img src='https:\/\/s0.wp.com\/latex.php?latex=C+%5Csum_j+%5Cxi_j&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='C \\sum_j \\xi_j' title='C \\sum_j \\xi_j' class='latex' \/> seems to me to be quite unmotivated.   Is there some natural geometric way of deriving this model?  Even   better, is there a principled way of deriving the model? <\/ul>\n<h3>Search revisited<\/h3>\n<p>Let&#8217;s return to the problem of search.  As we saw in the last section, we can use training data to build a support vector machine (with soft margin) that, given a query, <img src='https:\/\/s0.wp.com\/latex.php?latex=q&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='q' title='q' class='latex' \/>, will tell us whether a document <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> is more relevant than <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/>, or vice versa.  Of course, this ranking decision won&#8217;t in any sense be &#8220;provably&#8221; optimal &#8211; it&#8217;s not even clear what that would mean, exactly.  But the support vector machine has the advantage that it takes into account all the different relevancy information we have (all the different features), and it does so in a way that reflects the training data.<\/p>\n<h3>Problems<\/h3>\n<ul>\n<li> Suppose that the relevancy ranking algorithm just described   ranks the document <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> above <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/>, and <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;' title='d&#039;' class='latex' \/> is ranked above <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;&#039;' title='d&#039;&#039;' class='latex' \/>,   for some query <img src='https:\/\/s0.wp.com\/latex.php?latex=q&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='q' title='q' class='latex' \/>.  Prove that it will also rank <img src='https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d' title='d' class='latex' \/> above <img src='https:\/\/s0.wp.com\/latex.php?latex=d%27%27&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='d&#039;&#039;' title='d&#039;&#039;' class='latex' \/>. <\/ul>\n<p>How can we use this support vector machine in practice?  One way is as follows.  Suppose we have <img src='https:\/\/s0.wp.com\/latex.php?latex=n&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='n' title='n' class='latex' \/> documents.  A user enters a query <img src='https:\/\/s0.wp.com\/latex.php?latex=q&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='q' title='q' class='latex' \/>. Then because we can easily compare any two documents in the collection, we can use a sort algorithm such as quicksort to produce a rank ordering of the <img src='https:\/\/s0.wp.com\/latex.php?latex=n&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='n' title='n' class='latex' \/> documents, using <img src='https:\/\/s0.wp.com\/latex.php?latex=O%28n+%5Clog+n%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='O(n \\log n)' title='O(n \\log n)' class='latex' \/> comparisons.<\/p>\n<p>This approach isn&#8217;t really the best, though.  Suppose, for comparison, that you had <img src='https:\/\/s0.wp.com\/latex.php?latex=n&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='n' title='n' class='latex' \/> documents and wanted to figure out the top <img src='https:\/\/s0.wp.com\/latex.php?latex=10&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='10' title='10' class='latex' \/> documents (say), as ranked by PageRank.  You could do a single pass over all <img src='https:\/\/s0.wp.com\/latex.php?latex=n&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='n' title='n' class='latex' \/> documents, keeping a running tally of the best <img src='https:\/\/s0.wp.com\/latex.php?latex=10&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='10' title='10' class='latex' \/> documents found to date.  That&#8217;d take <img src='https:\/\/s0.wp.com\/latex.php?latex=O%28n%29&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='O(n)' title='O(n)' class='latex' \/> running time, which is significantly faster.<\/p>\n<p>Of course, we can apply the same idea with our support vector machine. Simply do a single pass over all <img src='https:\/\/s0.wp.com\/latex.php?latex=n&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='n' title='n' class='latex' \/> documents, maintaining a running tally of the best <img src='https:\/\/s0.wp.com\/latex.php?latex=10&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='10' title='10' class='latex' \/> documents found to date.  More precisely, each time you examine a new document, simply compare it to the current list of the top <img src='https:\/\/s0.wp.com\/latex.php?latex=10&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='10' title='10' class='latex' \/> documents, using the support vector machine, and if the new document is better than any of those, update the list.<\/p>\n<p>Quite aside from being significantly faster than ranking all documents, a major advantage of the running tally method is that it is easily run on a large cluster.  Each machine simply computes the top <img src='https:\/\/s0.wp.com\/latex.php?latex=10&#038;bg=ffffff&#038;fg=000000&#038;s=0' alt='10' title='10' class='latex' \/> documents stored on that machine, and then those short lists are merged at a central location.<\/p>\n<p>This post has introduced a simple technique which can be used to combine different notions of search relevancy.  It&#8217;s very much an introduction, and there are a huge number of problems I have not addressed.  Perhaps the biggest one is this: how well does this procedure work in practice?  That is, does it give a satisfying search experience, one which is significantly improved by the addition of new relevancy factors?  I&#8217;d love to test this out, but I don&#8217;t have good enough trial data (yet) to do a really good test.  Maybe someone can point to some real data along these lines.<\/p>\n<p>At this point in the original drafting of this post, I began enumerating problems one might want to think about in applying these ideas to improve a real search engine.  The list quickly became very long: there&#8217;s a lot to think about!  So rather than list all those problems, I&#8217;ll conclude with just a couple of problems which you may ponder.  Enjoy!<\/p>\n<h3>Problems for the author<\/h3>\n<ul>\n<li> Suppose we&#8217;re running a real-life search engine, and were   thinking of introducing an additional feature.  How could we use A\/B   testing to determine whether or not that additional feature does a   little or a lot to help improve relevancy ranking?\n<li> At the beginning of this post I proposed figuring out (by   thinking hard!) a principled way of combining cosine similarity and   PageRank to come up with a composite measure of relevance.  Find   such a principled way of making the combination.  I expect that the   value in attacking this problem will lie not so much in whatever   explicit combination I find, but rather in better understanding   <em>how<\/em> to make such combinations.  It may also shed some light   on when we expect the machine learning approach to work well, and   when we&#8217;d expect it to work poorly. <\/ul>\n<p>  <em>Interested in more?  Please <a href=\"htp:\/\/www.michaelnielsen.org\/ddi\/feed\/>subscribe to this blog<\/a>, or <a href=\"http:\/\/twitter.com\/\\#!\/michael_nielsen\">follow me on Twitter<\/a>.  You may also enjoy reading my new book about  open science, <a href=\"http:\/\/www.amazon.com\/Reinventing-Discovery-New-Networked-Science\/dp\/product-description\/0691148902\">Reinventing Discovery<\/a>.<\/em> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>In earlier posts I&#8217;ve described two different ways we can assess how relevant a given webpage is to a search query: (1) the cosine similarity measure; and (2) the PageRank, which is a query-independent measure of the importance of a page. While it&#8217;s good that we have multiple insights into what makes a webpage relevant,&hellip; <a class=\"more-link\" href=\"https:\/\/michaelnielsen.org\/ddi\/how-to-combine-multiple-notions-of-relevance-in-search\/\">Continue reading <span class=\"screen-reader-text\">How to combine multiple notions of relevance in search?<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-40","post","type-post","status-publish","format-standard","hentry","category-uncategorized","entry"],"_links":{"self":[{"href":"https:\/\/michaelnielsen.org\/ddi\/wp-json\/wp\/v2\/posts\/40","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/michaelnielsen.org\/ddi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michaelnielsen.org\/ddi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michaelnielsen.org\/ddi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michaelnielsen.org\/ddi\/wp-json\/wp\/v2\/comments?post=40"}],"version-history":[{"count":0,"href":"https:\/\/michaelnielsen.org\/ddi\/wp-json\/wp\/v2\/posts\/40\/revisions"}],"wp:attachment":[{"href":"https:\/\/michaelnielsen.org\/ddi\/wp-json\/wp\/v2\/media?parent=40"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michaelnielsen.org\/ddi\/wp-json\/wp\/v2\/categories?post=40"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michaelnielsen.org\/ddi\/wp-json\/wp\/v2\/tags?post=40"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}