Как работает ранжирование
Статьи оцениваются на основе количества апвотов, времени с момента публикации и различных штрафов по следующей формуле:

Поскольку время имеет больший показатель степени, чем голоса, рейтинг статьи в конечном итоге упадёт до нуля, поэтому ничего не остаётся на первой странице слишком долго. Этот показатель известен как гравитация.
Можно ожидать, что при каждом посещении Hacker News все статьи переоцениваются по этой формуле и переранжируются. Но в целях оптимизации статьи ранжируются повторно лишь изредка. Когда статья получает апвот, она переранжируется и перемещается на соответствующую позицию в списке, остальные статьи не меняются. Таким образом значительно снижается количество переранжирований. Однако существует вероятность того, что статья перестаёт получать голоса и застревает на высокой позиции. Чтобы избежать этого, каждые 30 секунд одна из топ-50 статей выбирается случайным образом и переранжируется. В результате статья может быть «неправильно» ранжирована в течение многих минут, если она не получает голосов. Кроме того, страницы могут кэшироваться в течение 90 секунд.
Сырые оценки и первое место в типичный день
На следующем изображении показаны сырые оценки (без штрафов) для топ-60 статей HN на протяжении дня 11 ноября. Каждая линия соответствует статье, цветом указана её позиция на странице. Красная линия показывает первую статью на HN. Обратите внимание, что из-за штрафов статья с наивысшей сырой оценкой часто не является первой.
Этот график показывает несколько интересных моментов. Оценка статьи быстро растёт, а затем медленно падает в течение многих часов. Формула оценивания объясняет большую часть этого: статья, получающая постоянный поток голосов, будет быстро подниматься, а затем постепенно падать. Но наблюдаемый пик ещё более резкий — это потому, что статьи получают много голосов в первый или два часа, а затем скорость голосования снижается. Комбинация этих двух факторов даёт крутые кривые, показанные на графике.
Есть несколько статей в день, которые набирают значительно больше, чем остальные, наряду со множеством статей в середине диапазона. Некоторые статьи набирают очень хорошие оценки, но не везёт застрять позади более популярной статьи. Другие статьи кратко занимают первое место, между падением одной и подъёмом другой.
Глядя на разницу между статьей с наивысшей сырой оценкой (вверху графика) и самой высокорейтинговой статьей (красная линия), можно увидеть, когда применены штрафы. Статья Getting website registration completely wrong заняла первое место рано утром, но была наказана за спорность и быстро упала на странице, позволив Linux ate my RAM ненадолго занять первое место перед тем, как Simpsons in CSS её обогнала. Немного позже штраф за спорность был применён к Apple Maps вскоре после достижения ею первого места, что привело к потере первой позиции и быстрому падению в рейтинге. Статья Snapchat достигла вершины HN, но была так сильно наказана в 8:22 утра, что вообще исчезла с графика. Why you should never use MongoDB была невероятно популярна и провела бы большую часть дня на первом месте, но была быстро наказана и застряла на седьмом месте. Severing ties with the NSA началась с штрафа за NSA, но была настолько популярна, что всё равно заняла первое место. Однако вскоре ей был применён ещё больший штраф, что вынудило её упасть на страницу. Наконец, в конце дня $4.1m goes missing была наказана. Как выяснилось, она бы вскоре потеряла первое место в пользу FTL даже без штрафа.
Зелёные треугольники и текст показывают, где применены штрафы за «спорность». Синие треугольники и текст показывают, где статьи были наказаны в забвение, исчезнув из топ-60. Более мягкие штрафы здесь не показаны.
Ясно, что контент на первом месте HN — это не «естественный» результат, а следствие постоянного применения штрафов ко многим статьям. Неясно, являются ли эти штрафы результатом действий администраторов HN или статей, отмеченных пользователями.
Отправки, которые получают автоматические штрафы
Некоторые отправки получают автоматические штрафы в зависимости от заголовка, а другие — в зависимости от домена. По-видимому, любая статья со словом NSA в заголовке получает автоматический штраф 0,4. Ищу другие слова, вызывающие автоматические штрафы, такие как awesome, bitcoin и bubble, но они, похоже, не штрафуются. Наблюдал, что много веб-сайтов получают автоматический штраф от 0,25 до 0,8:
arstechnica.com, businessinsider.com, easypost.com, github.com, imgur.com, medium.com, quora.com, qz.com, reddit.com, rt.com, stackexchange.com, theguardian.com, theregister.com, theverge.com, torrentfreak.com, youtube.com. Уверен, что фактический список длиннее. (Это отдельно от «заблокированных» сайтов, которые были указаны когда-то.)
Одна интересная теория eterm: новости из популярных источников отправляются параллельно несколькими людьми, что приводит к большему количеству апвотов, чем статья «заслуживает». Автоматическое штрафование популярных веб-сайтов помогает противодействовать этому эффекту.
Воздействие штрафов
Используя формулу оценивания, можно вычислить воздействие штрафа. Если статья получает множитель штрафа 0,4, это эквивалентно тому, что каждый голос считается только за 0,3 голоса. Или статья будет падать в рейтинге на 66% быстрее, чем обычно. Множитель штрафа 0,1 соответствует каждому голосу, считаемому за 0,05 голоса, или падению статьи в 3,6 раза быстрее нормы. Таким образом, множитель штрафа 0,4 имеет значительный эффект, а 0,1 очень суров.
Спорность
Чтобы предотвратить холивары на Hacker News, статьи с «слишком большим» количеством комментариев получают строгий штраф как «спорные». В опубликованном коде функция contro-factor срабатывает для любого поста с более чем 20 комментариями и большим количеством комментариев, чем апвотов. Такая статья масштабируется как (votes/comments)^2. Однако фактическая формула отличается — она активна для любого поста с большим количеством комментариев, чем апвотов, и по крайней мере 40 комментариями. На основе эмпирических данных я подозреваю, что показатель степени равен 3, а не 2, но не доказал это.
Штраф за спорность может иметь внезапный и катастрофический эффект на рейтинг статьи, заставляя её быть высокорейтинговой одну минуту и исчезнуть, когда достигнет 40 комментариев. Если вы когда-нибудь думали, почему популярная статья вдруг исчезла со первой страницы, спорность — вероятная причина. Например, Why the Chromebook pundits are out of touch with reality упала с 5-го на 22-е место в момент достижения 40 комментариев, и Show HN: Get your health records from any doctor была на 17-м месте, но полностью исчезла из топ-60 при достижении 40 комментариев.
Моя методология
Сканировал страницы /news и /news2 каждую минуту (оставаясь ниже лимита 2 страницы в минуту). Парсил (довольно некрасивый) HTML с помощью Beautiful Soup, обрабатывал результаты большим набором Python-скриптов и строил графики с помощью непостижимого, но мощного matplotlib. Основная идея анализа — генерировать сырые оценки, используя формулу, а затем искать аномалии. В определённый момент времени (например, 11/09 8:46) можно вычислить сырые оценки для топ-10 статей:
2.802 Pyret: A new programming language from the creators of Racket 1.407 The Big Data Brain Drain: Why Science is in Trouble 1.649 The NY Times endorsed a secretive trade agreement that the public can't read 0.785 S.F. programmers build alternative to HealthCare.gov (warning: autoplay video) 0.844 Marelle: logic programming for devops 0.738 Sprite Lamp 0.714 Why Teenagers Are Fleeing Facebook 0.659 NodeKnockout is in Full Tilt. Checkout some demos 0.805 ISO 1 0.483 Shopify accepts Bitcoin. 0.452 Show HN: Understand closures
Обратите внимание, что три из топ-10 статей ранжируются ниже ожидаемого по их оценке: The NY Times, Marelle и ISO 1. Поскольку The NY Times ранжируется между статьями с 1.407 и 0.785, её множитель штрафа можно рассчитать как между 0,47 и 0,85. Аналогично другие штрафы должны быть между 0,87-0,93 и 0,60-0,82.
Наблюдал, что большинство статей ранжируются в соответствии с их оценкой, и исключения постоянно ранжируются намного ниже, что указывает на штраф. Это свидетельствует о том, что используемая формула оценивания соответствует опубликованному коду. Если бы формула была другой, например, если бы показатель гравитации был больше, я бы ожидал увидеть статьи, выходящие из своего «ожидаемого» ранжирования по мере увеличения голосов или возраста, но никогда этого не видел.
Эта техника показывает существование штрафа и даёт диапазон для штрафа, но определение точного штрафа затруднено. Можно посмотреть на диапазон со временем и надеяться, что он сойдётся к единственному значению. Однако несколько источников ошибок мешают этому. Во-первых, соседние статьи могут также иметь применённые штрафы или быть оценены по-другому (например, вакансии). Во-вторых, поскольку статьи не постоянно переранжируются, статья может быть неправильно размещена временно. В-третьих, штраф на статью может меняться со временем. В-четвёртых, подсчитанное количество голосов может отличаться от фактического, потому что «плохие» голоса подавляются. В результате я смог определить приблизительные штрафы, но есть довольно много численной нестабильности.
Штрафы на протяжении дня
Следующий график показывает вычисленные штрафы на протяжении дня. Каждая линия показывает конкретную статью. Должна начинаться с 1 (без штрафа) и затем упасть на уровень штрафа при его применении. Линия заканчивается, когда статья выпадает из топ-60, что может произойти довольно скоро после применения штрафа. Похоже, есть штрафы 0,2 и 0,4, а также много в диапазоне 0,8-0,9. Похоже, что много штрафов применяются в 9 утра (когда приходят модераторы?), с дополнительными в течение дня. Экспериментирую с различными алгоритмами для улучшения графика, так как он довольно шумный.

В среднем около 20% статей на первой странице были наказаны, в то время как 38% статей на второй странице были наказаны. (Процент на первой странице ниже, поскольку наказанные статьи менее вероятно будут на первой странице, в определённом смысле по определению.) Происходит гораздо больше наказания, чем можно было бы ожидать.
Вот список статей на первой странице на 11/11, которые были наказаны. (Это исключает статьи, которые были бы там, если бы не были наказаны.) Этот список намного длиннее, чем я ожидал; прокручивайте для полного списка.
Why the Climate Corporation Sold Itself to Monsanto, Facebook Publications, Bill Gates: What I Learned in the Fight Against Polio, McCain says NSA chief Keith Alexander 'should resign or be fired', You are not a software engineer, What is a y-combinator?, Typhoon Haiyan kills 10,000 in Philippines, To Persuade People, Tell Them a Story, Tetris and The Power Of CSS, Microsoft Research Publications, Moscow subway sells free tickets for 30 sit-ups, The secret world of cargo ships, These weeks in Rust, Empty-Stomach Intelligence, Getting website registration completely wrong, The Six Most Common Species Of Code, Amazon to Begin Sunday Deliveries, With Post Office's Help, Linux ate my RAM, Simpsons in CSS, Apple maps: how Google lost when everyone thought it had won, Docker and Go: why did we decide to write Docker in Go?, Amazon Code Ninjas, Last Doolittle Raiders make final toast, Linux Voice - A new Linux magazine that gives back, Want to download anime? Just made a program for that, Commit 15 minutes to explain to a stranger why you love your job., Why You Should Never Use MongoDB, Show HN: SketchDeck - build slides faster, Zero to Peanut Butter Docker Time in 78 Seconds, NSA's Surveillance Powers Extend Far Beyond Counterterrorism, How Sentry's Open Source Service Was Born, Real World OCaml, Show HN: Get your health records from any doctor, Why the Chromebook pundits are out of touch with reality, Towards a More Modular Future for JavaScript Libraries, Why is virt-builder written in OCaml?, IOS: End of an Era, The craziest things you can plug into your iPhone's audio jack, RFC: Replace Java with Go in default languages, Show HN: Find your health plan on Health Sherpa, Web Latency Benchmark: A new kind of browser benchmark, Why are Amazon, Facebook and Yahoo copying Microsoft's stack ranking system?, Severing Ties with the NSA, Doctor performs surgery using Google Glass, Duplicity + S3: Easy, cheap, encrypted, automated full-disk backups, Bitcoin's UK future looks bleak, Amazon Redshift's New Features, You're only getting the nice feedback, Software is Easy, Hardware is of Medium Difficulty, Facebook Warns Users After Adobe Breach, International Space Station Infected With USB Stick Malware, Tidbit: Client-Side Bitcoin Mining, Go: "I have already used the name for *MY* programming language", Multi-Modal Drone: Fly, Swim & Drive, The Daily Go Programming Newspaper, "We have no food, we need water and other things to survive.", Introducing the Humble Store, The Six Most Common Species Of Code, $4.1m goes missing as Chinese bitcoin trading platform GBL vanishes, Could Bitcoin Be More Disruptive than the Internet?, Apple Store is updating.
Код формулы оценивания
Arc-исходный код версии сервера HN доступен, а также обновленная формула оценивания:
(= gravity* 1.8 timebase* 120 front-threshold* 1
nourl-factor* .4 lightweight-factor* .17 gag-factor* .1)
(def frontpage-rank (s (o scorefn realscore) (o gravity gravity*))
(* (/ (let base (- (scorefn s) 1)
(if (> base 0) (expt base .8) base))
(expt (/ (+ (item-age s) timebase*) 60) gravity))
(if (no (in s!type 'story 'poll)) .8
(blank s!url) nourl-factor*
(mem 'bury s!keys) .001
(* (contro-factor s)
(if (mem 'gag s!keys)
gag-factor*
(lightweight s)
lightweight-factor*
1)))))
На случай, если вы не читаете код Arc, приведённый выше фрагмент определяет несколько констант: gravity* = 1.8, timebase* = 120 (минут) и т. д. Затем определяет метод frontpage-rank, который ранжирует статью s на основе её апвотов (realscore) и возраста в минутах (item-age).
Множитель штрафа определяется условием if с несколькими случаями. Если статья не является 'story' или 'poll', множитель штрафа составляет 0,8. В противном случае, если поле URL пусто (Ask HN и т. д.), коэффициент составляет nourl-factor*. Если статья отмечена как 'bury', множитель масштабирования составляет 0,001, и статья ранжируется в забвение. Наконец, стандартный случай объединяет множитель спорности и множитель шутки/лёгкости.
Множитель спорности contro-factor предназначен для подавления статей, приводящих к холиварам, и обсуждается подробнее позже.
Следующий множитель поражает статью, отмеченную как шутка, с тяжёлым значением 0,1, и «лёгкую» статью с множителем 0,17. Фактическая система штрафов выглядит намного более сложной, чем то, что появляется в опубликованном коде.
Заключение
Позиция статьи на домашней странице Hacker News — это не демократия на основе апвотов, как можно ожидать. Тщательно изучая статьи, которые появляются на странице Hacker News, можно многое узнать об используемой формуле оценивания. В то время как апвоты — очевидный фактор, контролирующий рейтинги, существует также сложная система «штрафов», которая заставляет статьи ранжироваться ниже или исчезать полностью. Это не просто предотвращение спама, но затрагивает многие очень популярные статьи. И если в статье больше комментариев, чем голосов, не добавляйте свой комментарий, иначе можете её убить!
Обсуждение на Hacker News.
Обновление (11/18): статья о штрафах получила штраф
Иронично, что эта статья была наказана на Hacker News. Минуты спустя после попадания на первую страницу был применён тяжёлый штраф 0,2, вынудивший её со первой страницы. Чёрная линия на графике ниже показывает позицию этой статьи на Hacker News. Можно увидеть резкое падение при применении штрафа. Серая линия показывает, где была бы ранжирована статья без штрафа. Без штрафа статья была бы на 5-м месте, но со штрафом так и не вернулась на первую страницу (позиции 1-30). Нижняя зелёная линия показывает сырую оценку этой статьи. (11/26: Сообщили, что штраф был применён, потому что сработало «детектирование кольца голосования» по ошибке.)

