{"id":7930,"date":"2023-01-30T21:15:42","date_gmt":"2023-01-30T21:15:42","guid":{"rendered":"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/"},"modified":"2023-01-30T21:15:42","modified_gmt":"2023-01-30T21:15:42","slug":"yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak","status":"publish","type":"post","link":"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/","title":{"rendered":"Yandex scrapes Google and other SEO learnings from the source code leak"},"content":{"rendered":"<p>\u201cFragments\u201d of <a href=\"https:\/\/searchengineland.com\/yandex-search-ranking-factors-leak-392323\" target=\"_blank\" rel=\"noopener\">Yandex\u2019s codebase leaked online<\/a> last week. Much like Google, Yandex is a platform with many aspects such as email, maps, a taxi service, etc. The code leak featured chunks of all of it.\u00a0<\/p>\n<p>According to the documentation therein, Yandex\u2019s codebase was folded into one large repository called Arcadia in 2013. The leaked codebase is a subset of all projects in Arcadia and we find several components in it related to the search engine in the \u201cKernel,\u201d \u201cLibrary,\u201d \u201cRobot,\u201d \u201cSearch,\u201d and \u201cExtSearch\u201d archives.\u00a0<\/p>\n<p>The move is wholly unprecedented. Not since the AOL search query data of 2006 has something so material related to a web search engine entered the public domain.\u00a0<\/p>\n<p>Although we are missing the data and many files that are referenced, this is the first instance of a tangible look at how a modern search engine works at the code level.\u00a0<\/p>\n<p>Personally, I can\u2019t get over how fantastic the timing is to be able to actually see the code as I finish my book \u201cThe Science of SEO\u201d where I\u2019m talking about Information Retrieval, how modern search engines actually work, and how to build a simple one yourself.\u00a0<\/p>\n<p>In any event, I\u2019ve been parsing through the code since last Thursday and any engineer will tell you that is not enough time to understand how everything works. So, I suspect there will be several more posts as I keep tinkering.<\/p>\n<p>Before we jump in, I want to give a shout-out to <a href=\"https:\/\/www.linkedin.com\/in\/benwills\/\" target=\"_blank\" rel=\"noopener\">Ben Wills<\/a> at Ontolo for sharing the code with me, pointing me in the initial direction of where the good stuff is, and going back and forth with me as we deciphered things. Feel free to <a href=\"http:\/\/ipullrank.com\/yandex-search-ranking-factor-insights\" target=\"_blank\" rel=\"noopener\">grab the spreadsheet with all the data we\u2019ve compiled about the ranking factors here<\/a>.<\/p>\n<p>Also, shout out to <a href=\"https:\/\/www.ryanmjones.com\/\" target=\"_blank\" rel=\"noopener\">Ryan Jones<\/a> for digging in and sharing some key findings with me over IM.\u00a0<\/p>\n<p>OK, let\u2019s get busy!<\/p>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_81 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#Its_not_Googles_code_so_why_do_we_care\" >It\u2019s not Google\u2019s code, so why do we care?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#Some_context_on_Yandexs_architecture\" >Some context on Yandex\u2019s architecture<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#There_are_17854_ranking_factors_in_the_codebase\" >There are 17,854 ranking factors in the codebase<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#The_initial_weighting_of_ranking_factors\" >The initial weighting of ranking factors\u00a0<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#Top_5_negatively_weighted_initial_ranking_factors\" >Top 5 negatively weighted initial ranking factors<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#Top_5_positively_weighted_initial_ranking_factors\" >Top 5 positively weighted initial ranking factors<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#There_are_plenty_of_unexpected_initial_ranking_factors\" >There are plenty of unexpected initial ranking factors\u00a0<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#Yandex_scrapes_Google_Bing_YouTube_and_TikTok\" >Yandex scrapes Google, Bing, YouTube and TikTok<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#Yandex_has_anti-SEO_upper_bounds_for_some_ranking_factors\" >Yandex has anti-SEO upper bounds for some ranking factors<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#Yandex_boosts_%E2%80%9CVital_Hosts%E2%80%9D\" >Yandex boosts \u201cVital Hosts\u201d<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#The_structure_of_the_document_server\" >The structure of the document server<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#Link_factors_and_prioritization\" >Link factors and prioritization<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/craighordlow.com\/index.php\/2023\/01\/30\/yandex-scrapes-google-and-other-seo-learnings-from-the-source-code-leak\/#What_can_we_apply_from_Yandex_to_what_we_know_about_Google\" >What can we apply from Yandex to what we know about Google?<\/a><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Its_not_Googles_code_so_why_do_we_care\"><\/span>It\u2019s not Google\u2019s code, so why do we care?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Some believe that reviewing this codebase is a distraction and that there is nothing that will impact how they make business decisions. I find that curious considering these are people from the same SEO community that used the CTR model from the 2006 AOL data as the industry standard for modeling across any search engine for many years to follow.\u00a0<\/p>\n<p>That said, Yandex is not Google. Yet the two are state-of-the-art web search engines that have continued to stay at the cutting edge of technology.<\/p>\n<p>Software engineers from both companies go to the same conferences (SIGIR, ECIR, etc) and <a href=\"https:\/\/research.yandex.com\/research-areas\/\" target=\"_blank\" rel=\"noopener\">share findings and innovations<\/a> in Information Retrieval, Natural Language Processing\/Understanding, and Machine Learning. Yandex also has a presence in Palo Alto and Google previously had a presence in Moscow.\u00a0<\/p>\n<p>A quick LinkedIn search uncovers a few hundred engineers that have worked at both companies, although we don\u2019t know how many of them have actually worked on Search at both companies.<\/p>\n<p>In a more direct overlap, Yandex also makes usage of Google\u2019s open source technologies that have been critical to innovations in Search like TensorFlow, BERT, MapReduce, and, to a much lesser extent, Protocol Buffers.\u00a0<\/p>\n<p>So, while Yandex is certainly not Google, it\u2019s also not some random research project that we\u2019re talking about here. There is a lot we can learn about how a modern search engine is built from reviewing this codebase.\u00a0<\/p>\n<p>At the very least, we can disabuse ourselves of some obsolete notions that still permeate SEO tools like text-to-code ratios and W3C compliance or the general belief that Google\u2019s 200 signals are simply 200 individual on and off-page features rather than classes of composite factors that potentially use thousands of individual measures.\u00a0\u00a0<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Some_context_on_Yandexs_architecture\"><\/span>Some context on Yandex\u2019s architecture<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Without context or the ability to successfully compile, run, and step through it, source code is very difficult to make sense of. <\/p>\n<p>Typically, new engineers get documentation, walk-throughs, and engage in pair programming to get onboarded to an existing codebase. And, there is some limited onboarding documentation related to setting up the build process in the docs archive. However, Yandex\u2019s code also references internal wikis throughout, but those have not leaked and the commenting in the code is also quite sparse.<\/p>\n<p>Luckily, Yandex does give some insights into its architecture in its <a href=\"https:\/\/yandex.com\/company\/technologies\/searcharch\/\" target=\"_blank\" rel=\"noopener\">public documentation<\/a>. There are also a couple of patents they\u2019ve published in the US that help shed a bit of light. Namely:<\/p>\n<p><a href=\"https:\/\/patents.google.com\/patent\/US20160162574\" target=\"_blank\" rel=\"noopener\">Computer-implemented method of and system for searching an inverted index having a plurality of posting lists<\/a> <\/p>\n<p><a href=\"https:\/\/patents.google.com\/patent\/US9501575\" target=\"_blank\" rel=\"noopener\">Search result ranker<\/a>\u00a0<\/p>\n<p>As I\u2019ve been researching Google for my book, I\u2019ve developed a much deeper understanding of the structure of its ranking systems through various whitepapers, patents, and talks from engineers couched against my SEO experience. I\u2019ve also spent a lot of time sharpening my grasp of general Information Retrieval best practices for web search engines. It comes as no surprise that there are indeed some best practices and similarities at play with Yandex.<\/p>\n<p>Yandex\u2019s documentation discusses a dual-distributed crawler system. One for real-time crawling called the \u201cOrange Crawler\u201d and another for general crawling.\u00a0<\/p>\n<p>Historically, Google is said to have had an index stratified into three buckets, one for housing real-time crawl, one for regularly crawled and one for rarely crawled. This approach is considered a best practice in IR.\u00a0<\/p>\n<p>Yandex and Google differ in this respect, but the general idea of segmented crawling driven by an understanding of update frequency holds.<\/p>\n<p>One thing worth calling out is that Yandex has no separate rendering system for JavaScript. <a href=\"https:\/\/yandex.com\/support\/webmaster\/recommendations\/changing-site-structure.html\" target=\"_blank\" rel=\"noopener\">They say this in their documentation<\/a> and, although they have Webdriver-based system for visual regression testing called Gemini, they limit themselves to text-based crawl.\u00a0<\/p>\n<p>The documentation also discusses a sharded database structure that breaks pages down into an inverted index and a document server. <\/p>\n<p>Just like most other web search engines the indexing process builds a dictionary, caches pages, and then places data into the inverted index such that bigrams and trigams and their placement in the document is represented. <\/p>\n<p>This differs from Google in that they moved to phrase-based indexing, meaning n-grams that can be much longer than trigrams a long time ago.<\/p>\n<p>However, the Yandex system uses <a href=\"https:\/\/searchengineland.com\/a-deep-dive-into-bert-how-bert-launched-a-rocket-into-natural-language-understanding-324522\" target=\"_blank\" rel=\"noopener\">BERT<\/a> in its pipeline as well, so at some point documents and queries are converted to <a href=\"https:\/\/developers.google.com\/machine-learning\/crash-course\/embeddings\/video-lecture\" target=\"_blank\" rel=\"noopener\">embeddings<\/a> and <a href=\"https:\/\/en.wikipedia.org\/wiki\/Nearest_neighbor_search\" target=\"_blank\" rel=\"noopener\">nearest neighbor search<\/a> techniques are employed for ranking.<\/p>\n<p>The ranking process is where things begin to get more interesting.\u00a0<\/p>\n<p>Yandex has a layer called <em>Metasearch<\/em> where cached popular search results are served after they process the query. If the results are not found there, then the search query is sent to a series of thousands of different machines in the <em>Basic Search <\/em>layer simultaneously. Each builds a <em>posting list <\/em>of relevant documents then returns it to MatrixNet, Yandex\u2019s neural network application for re-ranking, to build the SERP.<\/p>\n<p>Based on videos wherein Google engineers have talked about Search\u2019s infrastructure, that ranking process is quite similar to Google Search. They talk about Google\u2019s tech being in shared environments where various applications are on every machine and jobs are distributed across those machines based on the availability of computing power.\u00a0<\/p>\n<p>One of the use cases is exactly this, the distribution of queries to an assortment of machines to process the relevant index shards quickly. Computing the posting lists is the first place that we need to consider the ranking factors.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"There_are_17854_ranking_factors_in_the_codebase\"><\/span>There are 17,854 ranking factors in the codebase<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>On the Friday following the leak, the inimitable Martin MacDonald eagerly <a href=\"https:\/\/webmarketingschool.com\/complete-internal-list-of-yandex-ranking-factors\/\" target=\"_blank\" rel=\"noopener\">shared a file from the codebase<\/a> called web_factors_info\/factors_gen.in. The file comes from the \u201cKernel\u201d archive in the codebase leak and features 1,922 ranking factors.\u00a0<\/p>\n<p>Naturally, the SEO community has run with that number and that file to eagerly spread news of the insights therein. Many folks have translated the descriptions and built tools or Google Sheets and ChatGPT to make sense of the data. All of which are great examples of the power of the community. However, the 1,922 represents just one of many sets of ranking factors in the codebase.\u00a0<\/p>\n<p>A deeper dive into the codebase reveals that there are numerous ranking factor files for different subsets of Yandex\u2019s query processing and ranking systems.\u00a0<\/p>\n<p>Combing through those, we find that there are actually 17,854 ranking factors in total. Included in those ranking factors are a variety of metrics related to:<\/p>\n<p>Clicks.<\/p>\n<p>Dwell time.<\/p>\n<p>Leveraging Yandex\u2019s Google Analytics equivalent, Metrika.\u00a0<\/p>\n<p>There is also a series of Jupyter notebooks that have an additional 2,000 factors outside of those in the core code. Presumably, these Jupyter notebooks represent tests where engineers are considering additional factors to add to the codebase. Again, you can review all of these features with metadata that we collected from across the<a href=\"http:\/\/ipullrank.com\/yandex-search-ranking-factor-insights\" target=\"_blank\" rel=\"noopener\"> codebase at this link<\/a>.<\/p>\n<p>Yandex\u2019s documentation further clarifies that they have three classes of ranking factors: Static, Dynamic, and those related specifically to the user\u2019s search and how it was performed. In their own words:<\/p>\n<p>In the codebase these are indicated in the rank factors files with the tags TG_STATIC and TG_DYNAMIC. The search related factors have multiple tags such as TG_QUERY_ONLY, TG_QUERY, TG_USER_SEARCH, and TG_USER_SEARCH_ONLY.\u00a0<\/p>\n<p>While we have uncovered a potential 18k ranking factors to choose from, the documentation related to MatrixNet indicates that scoring is built from tens of thousands of factors and customized based on the search query.<\/p>\n<p>This indicates that the ranking environment is highly dynamic, similar to that of Google environment. According to Google\u2019s \u201c<a href=\"https:\/\/patents.google.com\/patent\/US8060497\" target=\"_blank\" rel=\"noopener\">Framework for evaluating scoring functions<\/a>\u201d patent, they have long had something similar where multiple functions are run and the best set of results are returned.\u00a0<\/p>\n<p>Finally, considering that the documentation references tens of thousands of ranking factors, we should also keep in mind that there are many other files referenced in the code that are missing from the archive. So, there is likely more going on that we are unable to see. This is further illustrated by reviewing the images in the onboarding documentation which shows other directories that are not present in the archive.<\/p>\n<p>For instance, I suspect there is more related to the DSSM in the \/semantic-search\/ directory.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"The_initial_weighting_of_ranking_factors\"><\/span>The initial weighting of ranking factors\u00a0<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>I first operated under the assumption that the codebase didn\u2019t have any weights for the ranking factors. Then I was shocked to see that the nav_linear.h file in the \/search\/relevance\/ directory features the initial coefficients (or weights) associated with ranking factors on full display. <\/p>\n<p>This section of the code highlights 257 of the 17,000+ ranking factors we\u2019ve identified. (<em>Hat tip to Ryan Jones for pulling these and lining them up with the ranking factor descriptions.)<\/em><\/p>\n<p>For clarity, when you think of a search engine algorithm, you\u2019re probably thinking of a long and complex mathematical equation by which every page is scored based on a series of factors. While that is an oversimplification, the following screenshot is an excerpt of such an equation. The coefficients represent how important each factor is and the resulting computed score is what would be used to score selecter pages for relevance.<\/p>\n<p>These values being hard-coded suggests that this is certainly not the only place that ranking happens. Instead, this function is most likely where the initial relevance scoring is done to generate a series of posting lists for each shard being considered for ranking. In the first patent listed above, they talk about this as a concept of query-independent relevance (QIR) which then limits documents prior to reviewing them for query-specific relevance (QSR).<\/p>\n<p>The resulting posting lists are then handed off to MatrixNet with query features to compare against. So while we don\u2019t know the specifics of the downstream operations (yet), these weights are still valuable to understand because they tell you the requirements for a page to be eligible for the consideration set.<\/p>\n<p>However, that brings up the next question: <em>what do we know about MatrixNet?<\/em><\/p>\n<p>There is neural ranking code in the Kernel archive and there are numerous references to MatrixNet and \u201cmxnet\u201d as well as many references to Deep Structured Semantic Models (DSSM) throughout the codebase.\u00a0<\/p>\n<p>The description of one of the FI_MATRIXNET ranking factor indicates that MatrixNet is applied to all factors.\u00a0<\/p>\n<p>Factor {<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0Index:\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 160<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0CppName:\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u201cFI_MATRIXNET\u201d<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0Name: \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u201cMatrixNet\u201d<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0Tags: \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 [TG_DOC, TG_DYNAMIC, TG_TRANS, TG_NOT_01, TG_REARR_USE, TG_L3_MODEL_VALUE, TG_FRESHNESS_FROZEN_POOL]<\/p>\n<p>\u00a0\u00a0\u00a0\u00a0Description:\u00a0 \u00a0 \u00a0 \u00a0 \u201cMatrixNet is applied to all factors \u2013 the formula\u201d<\/p>\n<p>}<\/p>\n<p>There\u2019s also a bunch of binary files that may be the pre-trained models themselves, but it\u2019s going to take me more time to unravel those aspects of the code.\u00a0<\/p>\n<p>What is immediately clear is that there are multiple levels to ranking (L1, L2, L3) and there is an assortment of ranking models that can be selected at each level.<\/p>\n<p>The selecting_rankings_model.cpp file suggests that different ranking models may be considered at each layer throughout the process. This is basically how neural networks work. Each level is an aspect that completes operations and their combined computations yield the re-ranked list of documents that ultimately appears as a SERP. I\u2019ll follow up with a deep dive on MatrixNet when I have more time. For those that need a sneak peek, check out the Search result ranker patent.<\/p>\n<p>For now, let\u2019s take a look at some interesting ranking factors.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Top_5_negatively_weighted_initial_ranking_factors\"><\/span>Top 5 negatively weighted initial ranking factors<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The following is a list of the highest negatively weighted initial ranking factors with their weights and a brief explanation based on their descriptions translated from Russian.<\/p>\n<p><strong>FI_ADV:<\/strong> -0.2509284637 -This factor determines that there is advertising of any kind on the page and issues the heaviest weighted penalty for a single ranking factor.<\/p>\n<p><strong>FI_DATER_AGE:<\/strong> -0.2074373667 \u2013 This factor is the difference between the current date and the date of the document determined by a dater function. The value is 1 if the document date is the same as today, 0 if the document is 10 years or older, or if the date is not defined. This indicates that Yandex has a preference for older content.<\/p>\n<p><strong>FI_QURL_STAT_POWER:<\/strong> -0.1943768768 \u2013 This factor is the number of URL impressions as it relates to the query. It seems as though they want to demote a URL that appears in many searches to promote diversity of results.\u00a0<\/p>\n<p><strong>FI_COMM_LINKS_SEO_HOSTS:<\/strong> -0.1809636391 \u2013 This factor is the percentage of inbound links with \u201ccommercial\u201d anchor text. The factor reverts to 0.1 if the proportion of such links is more than 50%, otherwise, it\u2019s set to 0.<\/p>\n<p><strong>FI_GEO_CITY_URL_REGION_COUNTRY:<\/strong> -0.168645758 \u2013 This factor is the geographical coincidence of the document and the country that the user searched from. This one doesn\u2019t quite make sense if 1 means that the document and the country match.<\/p>\n<p>In summary, these factors indicate that, for the best score, you should:<\/p>\n<p>Avoid ads.<\/p>\n<p>Update older content rather than make new pages.<\/p>\n<p>Make sure most of your links have branded anchor text.\u00a0<\/p>\n<p>Everything else in this list is beyond your control.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Top_5_positively_weighted_initial_ranking_factors\"><\/span>Top 5 positively weighted initial ranking factors<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>To follow up, here\u2019s a list of the highest weighted positive ranking factors.\u00a0<\/p>\n<p><strong>FI_URL_DOMAIN_FRACTION:<\/strong> +0.5640952971 \u2013 This factor is a strange masking overlap of the query versus the domain of the URL. The example given is Chelyabinsk lottery which abbreviated as chelloto. To compute this value, Yandex find three-letters that are covered (che, hel, lot, olo), see what proportion of all the three-letter combinations are in the domain name.<\/p>\n<p><strong>FI_QUERY_DOWNER_CLICKS_COMBO:<\/strong> +0.3690780393 \u2013 The description of this factor is that is \u201ccleverly combined of FRC and pseudo-CTR.\u201d There is no immediate indication of what FRC is.<\/p>\n<p><strong>FI_MAX_WORD_HOST_CLICKS:<\/strong> +0.3451158835 \u2013 This factor is the clickability of the most important word in the domain. For example, for all queries in which there is the word \u201cwikipedia\u201d click on wikipedia pages.<\/p>\n<p><strong>FI_MAX_WORD_HOST_YABAR:<\/strong> +0.3154394573 \u2013 The factor description says \u201cthe most characteristic query word corresponding to the site, according to the bar.\u201d\u00a0 I\u2019m assuming this means the keyword most searched for in Yandex Toolbar associated to the site.<\/p>\n<p><strong>FI_IS_COM:<\/strong> +0.2762504972 \u2013 The factor is that the domain is a .COM.\u00a0<\/p>\n<p>In other words:<\/p>\n<p>Play word games with your domain.<\/p>\n<p>Make sure it\u2019s a dot com.<\/p>\n<p>Encourage people to search for your target keywords in the Yandex Bar.<\/p>\n<p>Keep driving clicks.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"There_are_plenty_of_unexpected_initial_ranking_factors\"><\/span>There are plenty of unexpected initial ranking factors\u00a0<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>What\u2019s more interesting in the initial weighted ranking factors are the unexpected ones. The following is a list of seventeen factors that stood out.\u00a0<\/p>\n<p><strong>FI_PAGE_RANK:<\/strong> +0.1828678331 \u2013 PageRank is the 17th highest weighted factor in Yandex. They previously removed links from their ranking system entirely, so it\u2019s not too shocking how low it is on the list.<\/p>\n<p><strong>FI_SPAM_KARMA:<\/strong> +0.00842682963 \u2013 The Spam karma is named after \u201cantispammers\u201d and is the likelihood that the host is spam; based on Whois information<\/p>\n<p><strong>FI_SUBQUERY_THEME_MATCH_A:<\/strong> +0.1786465163 \u2013 How closely the query and the document match thematically. This is the 19th highest weighted factor.<\/p>\n<p><strong>FI_REG_HOST_RANK:<\/strong> +0.1567124399 \u2013 Yandex has a host (or domain) ranking factor.<\/p>\n<p><strong>FI_URL_LINK_PERCENT:<\/strong> +0.08940421124 \u2013 Ratio of links whose anchor text is a URL (rather than text) to the total number of links.<\/p>\n<p><strong>FI_PAGE_RANK_UKR:<\/strong> +0.08712279101 \u2013 There is a specific Ukranian PageRank<\/p>\n<p><strong>FI_IS_NOT_RU:<\/strong> +0.08128946612 \u2013 It\u2019s a positive thing if the domain is not a .RU. Apparently, the Russian search engine doesn\u2019t trust Russian sites.<\/p>\n<p><strong>FI_YABAR_HOST_AVG_TIME2:<\/strong> +0.07417219313 \u2013 This is the average dwell time as reported by YandexBar<\/p>\n<p><strong>FI_LERF_LR_LOG_RELEV:<\/strong> +0.06059448504 \u2013 This is link relevance based on the quality of each link<\/p>\n<p><strong>FI_NUM_SLASHES:<\/strong> +0.05057609417 \u2013 The number of slashes in the URL is a ranking factor.\u00a0<\/p>\n<p><strong>FI_ADV_PRONOUNS_PORTION:<\/strong> -0.001250755075 \u2013 The proportion of pronoun nouns on the page.\u00a0<\/p>\n<p><strong>FI_TEXT_HEAD_SYN:<\/strong>\u00a0 -0.01291908335 \u2013 The presence of [query] words in the header, taking into account synonyms<\/p>\n<p><strong>FI_PERCENT_FREQ_WORDS:<\/strong> -0.02021022114 \u2013 The percentage of the number of words, that are the 200 most frequent words of the language, from the number of all words of the text.<\/p>\n<p><strong>FI_YANDEX_ADV:<\/strong> -0.09426121965 \u2013 Getting more specific with the distaste towards ads, Yandex penalizes pages with Yandex ads.<\/p>\n<p><strong>FI_AURA_DOC_LOG_SHARED:<\/strong> -0.09768630485 \u2013 The logarithm of the number of shingles (areas of text) in the document that are not unique.<\/p>\n<p><strong>FI_AURA_DOC_LOG_AUTHOR:<\/strong> -0.09727752961 \u2013 The logarithm of the number of shingles on which this owner of the document is recognized as the author.<\/p>\n<p><strong>FI_CLASSIF_IS_SHOP:<\/strong> -0.1339319854 \u2013 Apparently, Yandex is going to give you less love if your page is a store.<\/p>\n<p>The primary takeaway from reviewing these odd rankings factors and the array of those available across the Yandex codebase is that there are many things that could be a ranking factor.\u00a0<\/p>\n<p>I suspect that Google\u2019s reported \u201c200 signals\u201d are actually 200 classes of signal where each signal is a composite built of many other components. In much the same way that Google Analytics has dimensions with many metrics associated, Google Search likely has classes of ranking signals composed of many features.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Yandex_scrapes_Google_Bing_YouTube_and_TikTok\"><\/span>Yandex scrapes Google, Bing, YouTube and TikTok<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The codebase also reveals that Yandex has many parsers for other websites and their respective services. To Westerners, the most notable of those are the ones I\u2019ve listed in the heading above. Additionally, Yandex has parsers for a variety of services that I was unfamiliar with as well as those for its own services.\u00a0<\/p>\n<p>What is immediately evident, is that the parsers are feature complete. Every meaningful component of the Google SERP is extracted. In fact, anyone that might be considering scraping any of these services might do well to review this code.<\/p>\n<p>There is other code that indicates Yandex is using some Google data as part of the DSSM calculations, but the 83 Google named ranking factors themselves make it clear that Yandex has leaned on the Google\u2019s results pretty heavily.<\/p>\n<p>Obviously, Google would never pull the <a href=\"https:\/\/searchengineland.com\/google-bing-is-cheating-copying-our-search-results-62914\" target=\"_blank\" rel=\"noopener\">Bing move of copying another search engine\u2019s results<\/a> nor be reliant on one for core ranking calculations.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Yandex_has_anti-SEO_upper_bounds_for_some_ranking_factors\"><\/span>Yandex has anti-SEO upper bounds for some ranking factors<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>315 ranking factors have thresholds at which any computed value beyond that indicates to the system that that feature of the page is over-optimized. 39 of these ranking factors are part of the initially weighted factors that may keep a page from being included in the initial postings list. You can find these in the spreadsheet I\u2019ve linked to above by filtering for the Rank Coefficient and the Anti-SEO column.<\/p>\n<p>It\u2019s not far-fetched conceptually to expect that all modern search engines set thresholds on certain factors that SEOs have historically abused such as anchor text, CTR, or keyword stuffing. For instance, Bing was said to leverage the abusive usage of the meta keywords as a negative factor.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Yandex_boosts_%E2%80%9CVital_Hosts%E2%80%9D\"><\/span>Yandex boosts \u201cVital Hosts\u201d<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Yandex has a series of boosting mechanisms throughout its codebase. These are artificial improvements to certain documents to ensure they score higher when being considered for ranking.\u00a0<\/p>\n<p>Below is a comment from the \u201cboosting wizard\u201d which suggests that smaller files benefit best from the boosting algorithm.<\/p>\n<p>There are several types of boosts; I\u2019ve seen one boost related to links and I\u2019ve also seen a series of \u201cHandJobBoosts\u201d which I can only assume is a weird translation of \u201cmanual\u201d changes.\u00a0<\/p>\n<p>One of these boosts I found particularly interesting is related to \u201cVital Hosts.\u201d Where a vital host can be any site specified. Specifically mentioned in the variables is NEWS_AGENCY_RATING which leads me to believe that Yandex gives a boost that biases its results to certain news organizations.<\/p>\n<p>Without getting into geopolitics, this is very different from Google in that they have been adamant about not introducing biases like this into their ranking systems.\u00a0<\/p>\n<h2><span class=\"ez-toc-section\" id=\"The_structure_of_the_document_server\"><\/span>The structure of the document server<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The codebase reveals how documents are stored in Yandex\u2019s document server. This is helpful in understanding that a search engine does not simply make a copy of the page and save it to its cache, it\u2019s capturing various features as metadata to then use in the downstream rankings process.\u00a0<\/p>\n<p>The screenshot below highlights a subset of those features that are particularly interesting. Other files with SQL queries suggest that the document server has closer to 200 columns including the DOM tree, sentence lengths, fetch time, a series of dates, and antispam score, redirect chain, and whether or not the document is translated. The most complete list I\u2019ve come across is in \/robot\/rthub\/yql\/protos\/web_page_item.proto.<\/p>\n<p>What\u2019s most interesting in the subset here is the number of <a href=\"https:\/\/en.wikipedia.org\/wiki\/SimHash\" target=\"_blank\" rel=\"noopener\">simhashes<\/a> that are employed. Simhashes are numeric representations of content and search engines use them for lightning fast comparison for the determination of duplicate content. There are various instances in the robot archive that indicate duplicate content is explicitly demoted.\u00a0<\/p>\n<p>Also, as part of the indexing process, the codebase features <a href=\"https:\/\/ipullrank.com\/ultimate-guide-to-tf-idf-content-optimization\" target=\"_blank\" rel=\"noopener\">TF-IDF<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Okapi_BM25\" target=\"_blank\" rel=\"noopener\">BM25<\/a>, and BERT in its text processing pipeline. It\u2019s not clear why all of these mechanisms exist in the code because there is some redundancy in using them all.\u00a0<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Link_factors_and_prioritization\"><\/span>Link factors and prioritization<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>How Yandex handles link factors is particularly interesting because they previously disabled their impact altogether. The codebase also reveals a lot of information about link factors and how links are prioritized.\u00a0<\/p>\n<p>Yandex\u2019s link spam calculator has 89 factors that it looks at. Anything marked as SF_RESERVED is deprecated. Where provided, you can find the descriptions of these factors in the Google Sheet linked above.<\/p>\n<p>Notably, Yandex has a host rank and some scores that appear to live on long term after a site or page develops a reputation for spam.\u00a0<\/p>\n<p>Another thing Yandex does is review copy across a domain and determine if there is duplicate content with those links. This can be sitewide link placements, links on duplicate pages, or simply links with the same anchor text coming from the same site.<\/p>\n<p>This illustrates how trivial it is to discount multiple links from the same source and clarifies how important it is to target more unique links from more diverse sources.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"What_can_we_apply_from_Yandex_to_what_we_know_about_Google\"><\/span>What can we apply from Yandex to what we know about Google?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Naturally, this is still the question on everyone\u2019s mind. While there are certainly many analogs between Yandex and Google, truthfully, only a Google Software Engineer working on Search could definitively answer that question.\u00a0<\/p>\n<p><strong>Yet, that is the wrong question.<\/strong><\/p>\n<p>Really, this code should help us expand our thinking about modern search. Much of the collective understanding of search is built from what the SEO community learned in the early 2000s through testing and from the mouths of search engineers when search was far less opaque. That unfortunately has not kept up with the rapid pace of innovation.\u00a0<\/p>\n<p>Insights from the many features and factors of the Yandex leak should yield more hypotheses of things to test and consider for ranking in Google. They should also introduce more things that can be parsed and measured by SEO crawling, link analysis, and ranking tools.\u00a0<\/p>\n<p>For instance, a measure of the cosine similarity between queries and documents using BERT embeddings could be valuable to understand versus competitor pages since it\u2019s something that modern search engines are themselves doing.<\/p>\n<p>Much in the way the AOL Search logs moved us from guessing the distribution of clicks on SERP, the Yandex codebase moves us away from the abstract to the concrete and our \u201cit depends\u201d statements can be better qualified.<\/p>\n<p>To that end, this codebase is a gift that will keep on giving. It\u2019s only been a weekend and we\u2019ve already gleaned some very compelling insights from this code.\u00a0<\/p>\n<p>I anticipate some ambitious SEO engineers with far more time on their hands will keep digging and maybe even fill in enough of what\u2019s missing to compile this thing and get it working. I also believe engineers at the different search engines are also going through and parsing out innovations that they can learn from and add to their systems.\u00a0<\/p>\n<p>Simultaneously, Google lawyers are probably drafting aggressive cease and desist letters related to all the scraping.<\/p>\n<p>I\u2019m eager to see the evolution of our space that\u2019s driven by the curious people who will maximize this opportunity.<\/p>\n<p>But, hey, if getting insights from actual code is not valuable to you, you\u2019re welcome to go back to doing something more important like arguing about subdomains versus subdirectories.\u00a0<\/p>\n<p>The post <a href=\"https:\/\/searchengineland.com\/yandex-leak-learnings-392393\" target=\"_blank\" rel=\"noopener\">Yandex scrapes Google and other SEO learnings from the source code leak<\/a> appeared first on <a href=\"https:\/\/searchengineland.com\/\" target=\"_blank\" rel=\"noopener\">Search Engine Land<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>\u201cFragments\u201d of Yandex\u2019s codebase leaked online last week. Much like Google, Yandex is a platform with many aspects such as email, maps, a taxi service, etc. The code leak featured chunks of all of it.\u00a0 According to the documentation therein, Yandex\u2019s codebase was folded into one large repository called Arcadia in 2013. The leaked codebase is a subset of all projects in Arcadia and we find several components in it related to the search engine in the \u201cKernel,\u201d \u201cLibrary,\u201d \u201cRobot,\u201d \u201cSearch,\u201d and \u201cExtSearch\u201d archives.\u00a0 The move [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"h5ap_radio_sources":[],"cybocfi_hide_featured_image":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-7930","post","type-post","status-publish","format-standard","hentry","category-best-seo-blogs"],"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":false,"author_link":"https:\/\/craighordlow.com\/author\/"},"_links":{"self":[{"href":"https:\/\/craighordlow.com\/index.php\/wp-json\/wp\/v2\/posts\/7930","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/craighordlow.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/craighordlow.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/craighordlow.com\/index.php\/wp-json\/wp\/v2\/comments?post=7930"}],"version-history":[{"count":0,"href":"https:\/\/craighordlow.com\/index.php\/wp-json\/wp\/v2\/posts\/7930\/revisions"}],"wp:attachment":[{"href":"https:\/\/craighordlow.com\/index.php\/wp-json\/wp\/v2\/media?parent=7930"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/craighordlow.com\/index.php\/wp-json\/wp\/v2\/categories?post=7930"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/craighordlow.com\/index.php\/wp-json\/wp\/v2\/tags?post=7930"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}