{"id":337302,"date":"2022-08-19T21:00:23","date_gmt":"2022-08-19T21:00:23","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=337302"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=337302","title":{"rendered":"<span>\u0427\u0430\u0441\u0442\u044c 4. \u0418\u0449\u0435\u043c \u043c\u0430\u0442\u0447\u0438 \u0432 Dota 2 \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c \u0440\u043e\u043b\u0438\u043a\u043e\u0432 \u043d\u0430 YouTube \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e BERT \u0438 OpenDota<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435, \u0447\u0442\u043e \u0441 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u0438\u0434\u0435\u043e \u043d\u0430 YouTube \u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c\u0438 \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438\u0437 \u043c\u0430\u0442\u0447\u0430 \u043f\u043e Dota 2. \u0410 \u0441 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u0441\u0435\u0445 \u043c\u0430\u0442\u0447\u0435\u0439 \u043f\u043e Dota 2. \u041a\u0430\u043a \u0434\u043b\u044f \u0432\u0438\u0434\u0435\u043e \u043d\u0430\u0439\u0442\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0411\u0414? \u042d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u043c\u044b \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0438 \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f.<\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0441\u0442\u0430\u0442\u0435\u0439 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u043e\u0438\u0441\u043a\u0430 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u043e\u0432 \u0432 \u043c\u0430\u0442\u0447\u0430\u0445 Dota 2. \u0414\u043b\u044f \u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0439 \u0434\u0430\u0442\u0430\u0441\u0435\u0442 \u0441 \u0442\u0430\u0439\u043c-\u043a\u043e\u0434\u0430\u043c\u0438. \u041d\u0430 YouTube \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043a\u0430\u043d\u0430\u043b\u043e\u0432, \u0433\u0434\u0435 \u043b\u044e\u0434\u0438 \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442 \u043d\u0430\u0440\u0435\u0437\u043a\u0438 \u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c\u0438 \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438\u0437 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439 \u043f\u043e Dota 2.<\/p>\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u044f\u0445:<\/p>\n<ol>\n<li>\n<p>\u0412\u00a0<a href=\"https:\/\/habr.com\/ru\/post\/672420\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a>\u00a0\u043c\u044b \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u043b\u0438 \u0440\u0435\u043f\u043b\u0435\u0439 \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0430\u0442\u0447\u0430 \u043f\u043e Dota 2 \u0438 \u043d\u0430\u0448\u043b\u0438 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u00a0<a href=\"https:\/\/habr.com\/ru\/post\/677200\/\" rel=\"noopener noreferrer nofollow\">\u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a>\u00a0\u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0440\u0435\u043f\u043b\u0435\u0435\u0432 \u043d\u0430 Celery \u0438 Flask.<\/p>\n<\/li>\n<li>\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/post\/679762\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e \u0441 \u043d\u0430\u0440\u0435\u0437\u043a\u0430\u043c\u0438 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u043e\u0432 \u0441 YouTube, \u0441\u0435\u043c\u043f\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0434\u0440\u044b \u0438 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u0442\u044c \u043d\u0430 \u043d\u0438\u0445 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<\/li>\n<\/ol>\n<h3>\u041f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c<\/h3>\n<ol>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0438 \u0432\u0440\u0435\u043c\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0438\u0434\u0435\u043e<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0445\u043e\u0434\u0438\u043c \u043c\u0430\u0442\u0447\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e API OpenDota<\/p>\n<\/li>\n<li>\n<p>\u041a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u0442\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e <code>BERT<\/code><\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u043e\u0438\u043c \u044d\u043c\u0431\u0435\u0434\u0438\u043d\u0433\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0438\u0441\u043a \u043c\u0430\u0442\u0447\u0430 \u043f\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0443 \u0432\u0438\u0434\u0435\u043e<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043a\u043e\u0434 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<\/li>\n<\/ol>\n<h2>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0438 \u0432\u0440\u0435\u043c\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0438\u0434\u0435\u043e<\/h2>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u043e\u0439 \u043d\u0430\u043c \u043f\u043e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <code>yt_dlp<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 URL \u0432\u0438\u0434\u0435\u043e, \u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435. <\/p>\n<pre><code class=\"python\">... import yt_dlp   @lru_cache def get_video_metadata(url: str, save: bool = False) -> Tuple[str | int, Dict]:     options = dict()     with yt_dlp.YoutubeDL(options) as ydl:         metadata = ydl.extract_info(url, download=False)     video_id = metadata.get('id')      if save:         metadata_file = f'{video_id}.json'         video_metadata_path = VIDEO_DIR \/ metadata_file         with open(video_metadata_path, 'w') as fout:             json.dump(metadata, fout, indent=4)     return video_id, metadata<\/code><\/pre>\n<p>\u0421\u043b\u043e\u0432\u0430\u0440\u044c <code>metadata<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0432\u0438\u0434\u0435\u043e, \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435. \u0412\u043e\u0437\u044c\u043c\u0435\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043c\u0430\u0442\u0447 Team Spirit \u043f\u0440\u043e\u0442\u0438\u0432 Team Secret.<\/p>\n<pre><code class=\"python\">url = 'https:\/\/www.youtube.com\/watch?v=cXA5Hw2boLA&amp;ab_channel=DotADigest' video_id, metadata = get_video_metadata(url) print(metadata)  > {     \"id\": \"cXA5Hw2boLA\",     \"title\": \"SECRET vs TEAM SPIRIT - RAMPAGE! SEMI FINAL - RIYADH MASTERS 2022 Dota 2 Highlights\",     \"thumbnail\": \"https:\/\/i.ytimg.com\/vi\/cXA5Hw2boLA\/hqdefault.jpg\",     \"description\": \"DOTA 2 TS SECRET vs TEAM SPIRIT - RAMPAGE! SEMI FINAL - RIYADH MASTERS 2022 by Gamers8 Dota 2 Highlights 2022 Tournament - Semi Final Playoff #dota2 #dpc  \\nWatch Live Riyadh Masters Dota 2: https:\/\/www.twitch.tv\/gamers8gg - Commentary by Gareth &amp; Lacoste\",     \"uploader\": \"DotA Digest\",     \"upload_date\": \"20220724\",     \"uploader_id\": \"RUDota2TV\",     \"uploader_url\": \"http:\/\/www.youtube.com\/user\/RUDota2TV\",     \"channel_id\": \"UCUqLL4VcEy4mXcQL0O_H_bg\",     \"channel_url\": \"https:\/\/www.youtube.com\/channel\/UCUqLL4VcEy4mXcQL0O_H_bg\",     \"duration\": 1648,     \"view_count\": 50716,     \"average_rating\": null,     \"age_limit\": 0,     \"webpage_url\": \"https:\/\/www.youtube.com\/watch?v=cXA5Hw2boLA\",  ...<\/code><\/pre>\n<h2>\u041d\u0430\u0445\u043e\u0434\u0438\u043c \u043c\u0430\u0442\u0447\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e API OpenDota<\/h2>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043c\u0441\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u043e\u043c \u043a\u0430\u043d\u0430\u043b\u0430 DotA Digest. \u041e\u0431\u044b\u0447\u043d\u043e \u0430\u0432\u0442\u043e\u0440 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434 \u0438 \u0442\u0443\u0440\u043d\u0438\u0440. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0437\u043d\u0430\u0435\u043c \u0434\u0430\u0442\u0443 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0438\u0434\u0435\u043e. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043d\u0430\u0439\u0442\u0438 <code>Replay<\/code>. <\/p>\n<p>\u0418\u0434\u0435\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f. \u0412\u0438\u0434\u0435\u043e \u0441 \u043d\u0430\u0440\u0435\u0437\u043a\u0430\u043c\u0438 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u043e\u0432 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u0430\u0442\u0447 \u0443\u0436\u0435 \u0441\u044b\u0433\u0440\u0430\u043d. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0430\u0432\u0442\u043e\u0440\u044b YouTube-\u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u0441\u0442\u0440\u0435\u043c\u044f\u0442\u0441\u044f \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0438\u0434\u0435\u043e \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u043d\u044c\u0448\u0435, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u043e\u0432. \u0417\u043d\u0430\u0447\u0438\u0442 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u0437\u044f\u0442\u044c \u0432\u0441\u0435 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0430\u0442\u0447\u0438 \u0437\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043d\u0435\u0439 \u0434\u043e \u0434\u0430\u0442\u044b \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0438\u0434\u0435\u043e \u0438 \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0438\u0441\u043a\u043e\u043c\u044b\u043c (\u0437\u0430\u043f\u0435\u0447\u0430\u0442\u043b\u0451\u043d\u043d\u044b\u043c \u043d\u0430 \u0432\u0438\u0434\u0435\u043e).<\/p>\n<p>\u0421\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0440\u0435\u043f\u043b\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u0437\u043d\u0430\u044f <code>match_id<\/code> \u2014 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043c\u0430\u0442\u0447\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0430\u043c\u0430 \u0438\u0433\u0440\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f API OpenDota.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 wrapper \u0434\u043b\u044f <code>\/explorer<\/code> endpoint, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 OpenDota.<\/p>\n<pre><code class=\"python\">import requests from tenacity import retry, stop_after_attempt, wait_fixed   @retry(stop=stop_after_attempt(7), wait=wait_fixed(10)) def query_opendota(sql: str, **kwargs: dict) -> List[Dict]:     query = sql.format(**kwargs)     logger.debug(query)  r = requests.get(         'https:\/\/api.opendota.com\/api\/explorer',          params=dict(sql=query)     )     r.raise_for_status()     result = r.json()     rows = result['rows']     return rows<\/code><\/pre>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0430\u0442\u0447\u0438 \u0437\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0434\u0432\u0430 \u0434\u043d\u044f \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u0434\u0430\u0442\u044b.<\/p>\n<pre><code class=\"python\">from datetime import datetime, timedelta   def get_nearest_matches(date: datetime) -> List[Dict]:     end_time = date + timedelta(days=1)     start_time = date - timedelta(days=2)     query = '''     SELECT         match_id,         start_time,         matches.leagueid,         leagues.name as league,         radiant_team_id,         radiant_team.name as radiant_name,         radiant_team.tag as radiant_tag,         dire_team_id,         dire_team.name as dire_name,         dire_team.tag as dire_tag     FROM         matches         join teams as dire_team on matches.dire_team_id = dire_team.team_id         join teams as radiant_team on              matches.radiant_team_id = radiant_team.team_id         join leagues on matches.leagueid = leagues.leagueid     WHERE         start_time >= extract(epoch from timestamp '{start_time}')         and start_time &lt; extract(epoch from timestamp '{end_time}')     ORDER BY         start_time desc     LIMIT       500     '''     matches = query_opendota(         query,         start_time=datetime.strftime(start_time, '%m-%d-%Y'),         end_time=datetime.strftime(end_time, '%m-%d-%Y')     )     return matches<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043d\u0430 \u0432\u0441\u0435 \u0442\u043e\u043c \u0436\u0435 \u043c\u0430\u0442\u0447\u0435 Team Spirit \u043f\u0440\u043e\u0442\u0438\u0432 Team Secret. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u043c \u0434\u0430\u0442\u0443 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0438\u0434\u0435\u043e \u0438\u0437 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u0439\u0434\u0435\u043c \u0432\u0441\u0435 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0430\u0442\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0441\u044b\u0433\u0440\u0430\u043d\u044b \u0432 \u0434\u0435\u043d\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0434\u0432\u0430 \u0434\u043d\u044f.<\/p>\n<pre><code class=\"python\">url = 'https:\/\/www.youtube.com\/watch?v=cXA5Hw2boLA&amp;ab_channel=DotADigest' video_id, metadata = get_video_metadata(url) upload_date = metadata['upload_date'] upload_date = datetime.strptime(upload_date, '%Y%m%d') matches = get_nearest_matches(upload_date) print(len(matches))  > 288<\/code><\/pre>\n<p>\u0412\u0441\u0435\u0433\u043e \u043c\u0430\u0442\u0447\u0435\u0439 288. \u0421\u0440\u0435\u0434\u0438 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c 12 \u043c\u0430\u0442\u0447\u0435\u0439 \u0441 \u0443\u0447\u0430\u0441\u0442\u0438\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u044b Team Spirit, 3 \u0437\u0430 Radiant \u0438 9 \u0437\u0430 Dire.<\/p>\n<pre><code class=\"python\">print([m for m in matches if m['radiant_name'] == 'Team Spirit'])  > [     {         \"match_id\": 6676488286,         \"start_time\": 1658692615,         \"leagueid\": 14391,         \"league\": \"Riyadh Masters by Gamers8\",         \"radiant_team_id\": 7119388,         \"radiant_name\": \"Team Spirit\",         \"radiant_tag\": \"TSpirit\",         \"dire_team_id\": 15,         \"dire_name\": \"PSG.LGD\",         \"dire_tag\": \"PSG.LGD\"     },     {         \"match_id\": 6676051545,         \"start_time\": 1658673115,         \"leagueid\": 14391,         \"league\": \"Riyadh Masters by Gamers8\",         \"radiant_team_id\": 7119388,         \"radiant_name\": \"Team Spirit\",         \"radiant_tag\": \"TSpirit\",         \"dire_team_id\": 1838315,         \"dire_name\": \"Team Secret\",         \"dire_tag\": \"Secret\"     },     {         \"match_id\": 6672690521,         \"start_time\": 1658491214,         \"leagueid\": 14391,         \"league\": \"Riyadh Masters by Gamers8\",         \"radiant_team_id\": 7119388,         \"radiant_name\": \"Team Spirit\",         \"radiant_tag\": \"TSpirit\",         \"dire_team_id\": 8291895,         \"dire_name\": \"Tundra Esports\",         \"dire_tag\": \"Tundra\"     } ]<\/code><\/pre>\n<p>\u041d\u044e\u0430\u043d\u0441 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e Spirit \u0438\u0433\u0440\u0430\u043b\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 Team Secret, \u043d\u043e \u0438 \u0441 PSG.LGD, \u0438 \u0441 Tundra Esports. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u0437 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u043e\u043d\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u043c\u0430\u0442\u0447\u0443 Secret &#8212; Spirit. <\/p>\n<pre><code class=\"python\">print(metadata['fulltitle']) > \"SECRET vs TEAM SPIRIT - RAMPAGE! SEMI FINAL - RIYADH MASTERS 2022 Dota 2 Highlights\"<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0436\u0435 \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0430\u0442\u0447\u0438 \u0432 \u0411\u0414, \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u043e\u0434 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0432\u0438\u0434\u0435\u043e? <\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u043c\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438. \u041d\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0432\u0438\u0434\u0435\u043e \u043f\u0438\u0448\u0435\u0442 \u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u0438 \u0442\u0443\u0440\u043d\u0438\u0440\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u043f\u0435\u0447\u0430\u0442\u043a\u0438 \u0438 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u043e\u0439\u0442\u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u041b\u0435\u0432\u0438\u043d\u0448\u0442\u0435\u0439\u043d\u0430, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043e\u0439\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043e\u043f\u0435\u0447\u0430\u0442\u043e\u043a \u0438 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0439. \u041d\u043e \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438 \u0432\u0438\u0434\u0435\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0438 \u043a\u043b\u0438\u043a\u0431\u0435\u0439\u0442\u043d\u044b\u0435 \u0441\u043b\u043e\u0432\u043e\u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u044f.<\/p>\n<p>\u041d\u043e \u044f \u0440\u0435\u0448\u0438\u043b \u0441\u0442\u0440\u0435\u043b\u044c\u043d\u0443\u0442\u044c \u0438\u0437 \u043f\u0443\u0448\u043a\u0438 \u043f\u043e \u0432\u043e\u0440\u043e\u0431\u044c\u044f\u043c. \u0411\u043b\u0430\u0433\u043e \u0432 \u043d\u0430\u0448\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u0441\u0435 \u0441\u0438\u043b\u044c\u043d\u0435\u0435 \u043d\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u044c \u043d\u043e\u0432\u043e\u0435, \u043c\u043e\u0434\u043d\u043e\u0435, \u043c\u043e\u043b\u043e\u0434\u0435\u0436\u043d\u043e\u0435 \u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u2014 \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u0438.<\/p>\n<h2>\u041a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u0442\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e BERT<\/h2>\n<p>\u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044c<code>DistillBERT<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e \u0441\u0443\u0442\u0438 \u0441\u0432\u043e\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043f\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0438 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 <code>BERT<\/code>. \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442 \u0432 &#171;\u0445\u043e\u0440\u043e\u0448\u0438\u0435&#187; \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c.<\/p>\n<p>BERT \u2014 \u043c\u043e\u0434\u0435\u043b\u044c, \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 (\u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b), \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0441\u0432\u044f\u0437\u0438 \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438. <\/p>\n<p>\u0421\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u0442\u043e\u043a\u0435\u043d\u0430\u0445. \u0421\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435 \u043e\u043d\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u043b\u043e\u0432\u0430\u043c\u0438 \u0438\u043b\u0438 \u043a\u0443\u0441\u043e\u0447\u043a\u0430\u043c\u0438 \u0441\u043b\u043e\u0432. \u0414\u043b\u044f \u0438\u0445 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c BPE (Byte Pair Encoding). \u0412\u0441\u0435\u0433\u043e \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 30 000 \u0442\u043e\u043a\u0435\u043d\u043e\u0432.<\/p>\n<p>\u0412 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430 \u0430\u0432\u0442\u043e\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0442\u0435\u043a\u0441\u0442\u044b \u0438\u0437 \u043a\u043d\u0438\u0433 \u0438 \u0432\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438, \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e \u0431\u043e\u043b\u0435\u0435 3 \u043c\u043b\u0440\u0434 \u0441\u043b\u043e\u0432. \u041f\u0440\u0438\u0447\u0435\u043c 15% \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0437\u0430\u043c\u0435\u043d\u044f\u043b\u0438\u0441\u044c \u043d\u0430 \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0439 \u2014 [MASK]. \u0417\u0430\u0434\u0430\u0447\u0430 \u043c\u043e\u0434\u0435\u043b\u0438 \u0431\u044b\u043b\u0430 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434 \u043c\u0430\u0441\u043a\u043e\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u043d\u0430 \u043c\u043e\u0433\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u043a\u0430\u043a \u0441\u043b\u0435\u0432\u0430, \u0442\u0430\u043a \u0438 \u0441\u043f\u0440\u0430\u0432\u0430. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440.<\/p>\n<blockquote>\n<p>[CLS] the man went to [MASK] store [SEP] he bought a gallon [MASK] milk [SEP] <\/p>\n<\/blockquote>\n<p>\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c, \u0447\u0442\u043e \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a<\/p>\n<blockquote>\n<p>The man went to asdf store. He bought a gallon dinosaur&#8217;s milk.<\/p>\n<\/blockquote>\n<p>\u041d\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u0432\u0434\u043e\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u043c \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442<\/p>\n<blockquote>\n<p>The men went to the store. He bought a gallon of milk.<\/p>\n<\/blockquote>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u044d\u0442\u0438\u043c \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044c \u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0430\u0441\u044c \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u043e\u0433\u043b\u0430 \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u0433\u0430\u043b\u043b\u043e\u043d \u043c\u043e\u043b\u043e\u043a\u0430 \u0434\u0438\u043d\u043e\u0437\u0430\u0432\u0440\u0430. \u041d\u043e \u0443 \u0434\u0438\u043d\u043e\u0437\u0430\u0432\u0440\u043e\u0432 \u043d\u0435\u0442 \u043c\u043e\u043b\u043e\u043a\u0430, \u0443 \u043d\u0438\u0445 \u0437\u0434\u043e\u0440\u043e\u0432\u0435\u043d\u043d\u044b\u0435 \u044f\u0439\u0446\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u043b\u0430 \u043e\u0442 \u043b\u043e\u0441\u0441\u0430 \u043f\u043e \u0432\u0435\u0441\u0430\u043c. \u0418 \u043f\u043e\u0442\u0438\u0445\u043e\u043d\u044c\u043a\u0443 \u0441\u0445\u043e\u0434\u0438\u043b\u0430\u0441\u044c \u043a \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u0432\u0434\u043e\u043f\u043e\u0431\u043d\u043e\u043c\u0443 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0443. \u0418 \u0442\u0430\u043a \u0434\u043b\u044f \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432.<\/p>\n<p>\u0421\u0445\u0435\u043c\u0430 \u043c\u043e\u0434\u0435\u043b\u0438:<\/p>\n<ol>\n<li>\n<p>\u0411\u0435\u0440\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0434\u043b\u0438\u043d\u044b<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u043c \u043d\u0430 \u0442\u043e\u043a\u0435\u043d\u044b<\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u0436\u0434\u043e\u043c\u0443 \u0442\u043e\u043a\u0435\u043d\u0443 \u0441\u0442\u0430\u0432\u0438\u043c \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 emdedding \u2014 768-\u043c\u0435\u0440\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Positional Encoding, \u0447\u0442\u043e\u0431\u044b \u0443\u0447\u0435\u0441\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043b\u043e\u0432 (\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u0435)<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0433\u043e\u043d\u044f\u0435\u043c \u0447\u0435\u0440\u0435\u0437 Transformer-\u0431\u043b\u043e\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0435 embedding&#8217;\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442 \u0441\u043b\u043e\u0432\u0430 \u0432 \u0442\u0435\u043a\u0441\u0442\u0435 \u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0441\u0432\u044f\u0437\u0438 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0441\u043b\u043e\u0432 \u043f\u043e\u0434 \u043c\u0430\u0441\u043a\u043e\u0439<\/p>\n<\/li>\n<\/ol>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0446\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043b\u044f \u043d\u0430\u0441 \u0432 \u043f.6 \u2014 \u0445\u043e\u0440\u043e\u0448\u0438\u0445 \u044d\u043c\u0431\u0435\u0434\u0438\u043d\u0433\u0430\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432.<\/p>\n<h2>\u0421\u0442\u0440\u043e\u0438\u043c \u044d\u043c\u0431\u0435\u0434\u0438\u043d\u0433\u0438<\/h2>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043c \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0443 \u0432\u0438\u0434\u0435\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 \u0432\u0435\u043a\u0442\u043e\u0440. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u044b \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0418\u0437\u043c\u0435\u0440\u0438\u043c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 \u0432\u0435\u043a\u0442\u043e\u0440\u0430-\u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u0434\u043e \u0432\u0441\u0435\u0445 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043c\u0430\u0442\u0447\u0435\u0439 \u0438 \u0432\u044b\u0431\u0435\u0440\u0435\u043c \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439. \u042d\u0442\u043e \u0438 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0448\u0438\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c \u043f\u043e\u0438\u0441\u043a\u0430. \u0410 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0445 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043f\u043e \u0442\u0435\u043a\u0441\u0442\u0443 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>DistillBERT<\/code>.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u0435\u0434\u043e\u0431\u0443\u0447\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0441 HuggingFace.<\/p>\n<pre><code class=\"python\">import transformers from transformers import DistilBertTokenizer, DistilBertModel   @lru_cache def load_text_model() -> tuple:     model_version = 'distilbert-base-uncased'     logger.info(f'Loading model: {model_version}')     transformers.logging.set_verbosity_error()     tokenizer = DistilBertTokenizer.from_pretrained(\"distilbert-base-uncased\")     model = DistilBertModel.from_pretrained(\"distilbert-base-uncased\")     return tokenizer, model<\/code><\/pre>\n<p>\u0418 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u043b\u043e\u044f \u0431\u043b\u043e\u043a\u0430 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440\u0430.<\/p>\n<pre><code class=\"python\">def get_distilbert_hidden_state(batch: List[str]) -> torch.Tensor:     \"\"\"     Hidden State from the last TransformerBlock of DistilBert.      Returns (B, T, H) Tensor, where      - B - Batch Size,     - T - Number of tokens in the longest string     - H - Hidden Vector Dim (768 for DistilBert)     \"\"\"     tokenizer, model = load_text_model()     inputs = tokenizer(batch, return_tensors='pt', padding=True)     outputs = model(**inputs)     hidden_state = outputs.last_hidden_state     return hidden_state<\/code><\/pre>\n<p>\u0420\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432\u044b\u0445\u043e\u0434 \u0441 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u043b\u043e\u044f \u0434\u043b\u044f \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u0432\u0438\u0434\u0435\u043e &#171;SECRET vs TEAM SPIRIT &#8212; RAMPAGE! SEMI FINAL &#8212; RIYADH MASTERS 2022 Dota 2 Highlights&#187;.<\/p>\n<pre><code class=\"python\">hidden_states = get_distilbert_hidden_state([     'SECRET vs TEAM SPIRIT - RAMPAGE! SEMI FINAL - RIYADH MASTERS 2022 Dota 2 Highlights', ])  type(hidden_state) > torch.Tensor  hidden_states.shape > torch.Size([1, 22, 768])<\/code><\/pre>\n<p>\u0418\u043c\u0435\u0435\u043c PyTorch Tensor \u0441 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c\u044e:<\/p>\n<ul>\n<li>\n<p>1 \u2014 \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u0430\u0442\u0447\u0430. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0437 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>22 \u2014 \u0447\u0438\u0441\u043b\u043e \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u044b\u043b\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e BPE tokenizer<\/p>\n<\/li>\n<li>\n<p>768 \u2014 \u0440\u0430\u0437\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u044c \u0441\u043a\u0440\u044b\u0442\u043e\u0433\u043e \u0441\u043b\u043e\u044f. \u0411\u044b\u043b\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u0430 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u0435\u0442\u0438, \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u043d\u0430 \u043d\u0435\u0451 \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u043c.<\/p>\n<\/li>\n<\/ul>\n<p>\u0411\u0430\u0442\u0447 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u043a \u0440\u0430\u0437\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b.<\/p>\n<pre><code class=\"python\">hidden_states = get_distilbert_hidden_state([     'SECRET vs TEAM SPIRIT - RAMPAGE! SEMI FINAL - RIYADH MASTERS 2022 Dota 2 Highlights',     'SECRET vs SPIRIT - RIYADH MASTERS 2022s', ])  hidden_states.shape > torch.Size([2, 22, 768])<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043a\u0430\u0436\u0434\u0430\u044f \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043c\u0430\u0442\u0440\u0438\u0446\u0435\u0439 \u0447\u0438\u0441\u0435\u043b <img loading=\"lazy\" decoding=\"async\" class=\"formula inline\" source=\" \\mathbb{R}^{22\u0445768}\" alt=\" \\mathbb{R}^{22\u0445768}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/071\/95b\/bc0\/07195bbc0c6b522024997f5ac8149170.svg\" width=\"57\" height=\"21\"\/>. \u041d\u043e \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u043d\u0435 \u0442\u0430\u043a \u0443\u0434\u043e\u0431\u043d\u043e \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u0435\u0437 \u0441\u0442\u0440\u0430\u0445\u0430, \u0431\u0435\u0437 \u0443\u0432\u0430\u0436\u0435\u043d\u0438\u044f \u0443\u0441\u0440\u0435\u0434\u043d\u0438\u043c \u043f\u043e \u043f\u0435\u0440\u0432\u043e\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 \u0442\u0435\u043d\u0437\u043e\u0440\u0430, \u0442.\u0435. \u043f\u043e \u0432\u0441\u0435\u043c \u0442\u043e\u043a\u0435\u043d\u0430\u043c.<\/p>\n<pre><code class=\"python\">def get_text_embeddings(batch: List[str]) -> torch.Tensor:     hidden_state = get_distilbert_hidden_state(batch)     embeddings = torch.mean(hidden_state, dim=1)     return embeddings<\/code><\/pre>\n<p>\u0422.\u0435. \u043c\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0435\u043a\u0441\u0442, \u043a\u0430\u043a \u043d\u0435\u0447\u0442\u043e \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u043e\u0442 \u0441\u043b\u043e\u0432 (\u0442\u043e\u043a\u0435\u043d\u043e\u0432) \u0432 \u043d\u0435\u043c. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440 \u0438\u0437 768 \u0447\u0438\u0441\u0435\u043b.<\/p>\n<pre><code class=\"python\">embedding = get_text_embeddings([     'Hello, World!', ])  embedding.shape > torch.Size([1, 768])  print(embedding) > tensor([[ 1.5433e-03, -3.2035e-01,  4.5550e-01,  6.7697e-03, -4.9975e-03,          -3.3267e-01,  5.5809e-01, -6.2899e-02,  4.8135e-03, -6.1892e-02,          -5.6701e-02, -3.2326e-01, -1.0381e-02,  4.1199e-01,  7.4125e-02,           7.1323e-02, -1.0036e-03,  9.4666e-03,  1.4607e-01,  3.1909e-01,          ...<\/code><\/pre>\n<h2>\u041f\u043e\u0438\u0441\u043a \u043c\u0430\u0442\u0447\u0430 \u043f\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0443 \u0432\u0438\u0434\u0435\u043e<\/h2>\n<p>\u041a\u0430\u043a \u043f\u043e\u043c\u0435\u0440\u0438\u0442\u044c \u0431\u043b\u0438\u0437\u043e\u0441\u0442\u044c \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432? \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u043a\u043e\u0441\u0438\u043d\u0443\u0441 \u0443\u0433\u043b\u0430 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438. \u0418\u0437 \u043a\u0443\u0440\u0441\u0430 \u043b\u0438\u043d\u0435\u0439\u043d\u043e\u0439 \u0430\u043b\u0433\u0435\u0431\u0440\u044b \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u043c \u043f\u0440\u043e \u0441\u043a\u0430\u043b\u044f\u0440\u043d\u043e\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"formula\" source=\"(A,B) = ||A| |\\cdot ||B|| \\cdot \\cos{\\theta}\" alt=\"(A,B) = ||A| |\\cdot ||B|| \\cdot \\cos{\\theta}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c7b\/871\/8a8\/c7b8718a8ebcdb079c0a644c661de47c.svg\" width=\"216\" height=\"22\"\/><img loading=\"lazy\" decoding=\"async\" class=\"formula\" source=\"\\cos{\\theta} = \\frac{(A,B)}{||A|| \\cdot ||B||} = \\frac{\\sum_{i}^{768}{a_ib_i}} {\\sqrt{\\sum{a^2_i}} \\cdot \\sqrt{\\sum{b^2_i}}}\" alt=\"\\cos{\\theta} = \\frac{(A,B)}{||A|| \\cdot ||B||} = \\frac{\\sum_{i}^{768}{a_ib_i}} {\\sqrt{\\sum{a^2_i}} \\cdot \\sqrt{\\sum{b^2_i}}}\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/43c\/b5a\/336\/43cb5a33638898871638ac171571362a.svg\" width=\"325\" height=\"72\"\/><\/p>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u043e\u0438\u0441\u043a\u0430. \u041d\u0430 \u0432\u0445\u043e\u0434 \u043e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u0435\u043a\u0441\u0442 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u0440\u043f\u0443\u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u0432 (\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b), \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043a\u0430\u0442\u044c. \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 Top-N \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043a \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u043e\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u0441\u0438\u043d\u0443\u0441\u043d\u043e\u0439 \u043c\u0435\u0440\u044b \u0431\u043b\u0438\u0437\u043e\u0441\u0442\u0438.<\/p>\n<pre><code class=\"python\">def search(text: str, corpus: List[str], top: int = 3) -> List[Tuple[int, str]]:     batch = [text] + corpus     with torch.no_grad():         embeddings = get_text_embeddings(batch)         similarities = F.cosine_similarity(embeddings[0:1], embeddings[1:], dim=1)         top_ids = torch.topk(similarities, k=top).indices     result = [         (int(idx), corpus[idx])         for idx in top_ids     ]     return result<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435.<\/p>\n<pre><code class=\"python\">search(     'SECRET vs TEAM SPIRIT - RAMPAGE! SEMI FINAL - RIYADH MASTERS 2022 Dota 2 Highlights',     [         'NAVI vs Aliance - The International 2013',         'LGD Pushat',         'SECRET vs SPIRIT - RIYADH MASTERS 2022',           'Net drug, ya ne opravdivaus',     ],     top=4 )  > [  (2, 'SECRET vs SPIRIT - RIYADH MASTERS 2022'),  (0, 'NAVI vs Aliance - The International 2013'),  (1, 'LGD Pushat'),  (3, 'Net drug, ya ne opravdivaus')]<\/code><\/pre>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0422\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0430\u043c\u044b\u0439 \u0431\u043b\u0438\u0437\u043a\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<pre><code class=\"python\">def search_top1(text: str, corpus: List[str]) -> str:     _, result = search(text, corpus, top=1)[0]     return result<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u043f\u0438\u0441\u043e\u043a <code>matches<\/code> \u2014 \u0432\u0441\u0435\u0445 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0441\u044b\u0433\u0440\u0430\u043d\u044b \u0437\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043d\u0435\u0439 \u0434\u043e \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0438\u0434\u0435\u043e. \u041e\u0434\u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434, \u0442\u0435\u0433\u0438 \u043a\u043e\u043c\u0430\u043d\u0434 \u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0443\u0440\u043d\u0438\u0440\u0430.<\/p>\n<pre><code class=\"json\">record = {     \"match_id\": 6676488286,     \"start_time\": 1658692615,     \"leagueid\": 14391,     \"league\": \"Riyadh Masters by Gamers8\",     \"radiant_team_id\": 7119388,     \"radiant_name\": \"Team Spirit\",     \"radiant_tag\": \"TSpirit\",     \"dire_team_id\": 15,     \"dire_name\": \"PSG.LGD\",     \"dire_tag\": \"PSG.LGD\" }<\/code><\/pre>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u043c\u0430\u0442\u0447\u0435\u0439. \u0411\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043c\u0435\u043d\u0430, \u043d\u043e \u0438 \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u0438 \u0441 \u0442\u0435\u0433\u0430\u043c\u0438 \u043a\u043e\u043c\u0430\u043d\u0434, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u043d\u0435 \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043b\u0443\u0447\u0448\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<pre><code class=\"python\">def generate_team_pairs(matches: List[Dict]) -> Dict:     pairs = dict()     for m in matches:         match_id = m['match_id']         radiant_tag = m['radiant_tag']         dire_tag = m['dire_tag']         radiant_name = m['radiant_name']         dire_name = m['dire_name']          name_pair_1 = f'{radiant_name} vs {dire_name}'         name_pair_2 = f'{dire_name} vs {radiant_name}'         tag_pair_1 = f'{radiant_tag} vs {dire_tag}'         tag_pair_2 = f'{dire_tag} vs {radiant_tag}'         for pair in (name_pair_1, name_pair_2, tag_pair_1, tag_pair_2):             pairs[pair] = match_id     return pairs<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u043d\u044f\u044f \u043a \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u0437 \u0411\u0414, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c<\/p>\n<pre><code class=\"python\">generate_team_pairs([record])  > {     \"Team Spirit vs PSG.LGD\": 6676488286,     \"PSG.LGD vs Team Spirit\": 6676488286,     \"TSpirit vs PSG.LGD\": 6676488286,     \"PSG.LGD vs TSpirit\": 6676488286 }<\/code><\/pre>\n<p>\u0413\u0434\u0435 <code>6676488286<\/code> \u2014 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043c\u0430\u0442\u0447\u0430 \u0432 \u0411\u0414.<\/p>\n<p>\u041d\u0435 \u0437\u0430\u0431\u0443\u0434\u0435\u043c \u0438 \u043f\u0440\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0442\u0443\u0440\u043d\u0438\u0440\u043e\u0432.<\/p>\n<pre><code class=\"python\">def generate_team_tournaments(matches: List[Dict]) -> Dict:     team_tournaments = dict()     pairs = generate_team_pairs(matches)     for m in matches:         match_id = m['match_id']         league = m['league']         for pair, pair_match_id in pairs.items():             if match_id == pair_match_id:                 team_tournament = f'{pair} | {league}'                 team_tournaments[team_tournament] = match_id     return team_tournaments<\/code><\/pre>\n<pre><code class=\"python\">generate_team_tournaments([record])  > {     \"Team Spirit vs PSG.LGD | Riyadh Masters by Gamers8\": 6676488286,     \"PSG.LGD vs Team Spirit | Riyadh Masters by Gamers8\": 6676488286,     \"TSpirit vs PSG.LGD | Riyadh Masters by Gamers8\": 6676488286,     \"PSG.LGD vs TSpirit | Riyadh Masters by Gamers8\": 6676488286 }<\/code><\/pre>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0438\u0448\u0435\u043d\u043a\u0438 \u043d\u0430 \u0442\u043e\u0440\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0435\u043c, \u0447\u0442\u043e \u043d\u0430 \u043a\u0430\u043d\u0430\u043b\u0435 DotA Digest, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u0435\u043c \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043b\u0438\u0441\u044c \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0432\u0438\u0434\u0435\u043e \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <\/p>\n<p><code>{Team1} vs {Team2} - {Clickbait comment} - {Tournament} Dota 2 Highlights<\/code><\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u043c \u0432\u0438\u0434\u0435\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<pre><code class=\"python\">title = 'SECRET vs TEAM SPIRIT - RAMPAGE! SEMI FINAL - RIYADH MASTERS 2022 Dota 2 Highlights' teams_pair, _, tournament = [t.strip() for t in title.split('-')] tournament = tournament.replace('Dota 2 Highlights', '') title = f'{teams_pair} | {tournament}' print(title) > 'SECRET vs TEAM SPIRIT | RIYADH MASTERS 2022 '<\/code><\/pre>\n<p>\u0418 \u0432\u043e\u0442 \u043e\u043d\u0430 \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043c\u0430\u0442\u0447\u0430, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0443 \u0440\u043e\u043b\u0438\u043a\u0430 \u043d\u0430 YouTube.<\/p>\n<pre><code class=\"python\">def search_team_tournament_pairs(video_title: str, matches: List[Dict]) -> int:     teams_pair, _, tournament = [t.strip() for t in video_title.split('-')]     tournament = tournament.replace('Dota 2 Highlights', '')     team_tournament = f'{teams_pair} | {tournament}'     team_tournaments = generate_team_tournaments(matches)     candidate = search_top1(team_tournament, list(team_tournaments))     match_id = team_tournaments[candidate]     return match_id<\/code><\/pre>\n<p>\u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0432\u0438\u0434\u0435\u043e \u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u043c\u0430\u0442\u0447\u0435\u0439 \u0438\u0437 \u0411\u0414. \u041f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u043a &#171;\u043f\u0440\u0430\u0432\u043e\u0441\u043b\u0430\u0432\u043d\u043e\u043c\u0443&#187; \u0432\u0438\u0434\u0443. \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0438 \u0441 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u043c \u043c\u0430\u0442\u0447\u0435\u0439 \u0438\u0437 \u0411\u0414. \u0421\u0442\u0440\u043e\u0438\u0442 \u044d\u043c\u0431\u0435\u0434\u0438\u043d\u0433\u0438 (\u0432\u0435\u043a\u0442\u043e\u0440\u043d\u044b\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f) \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0439. \u0421\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0438\u0445 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u043f\u043e \u043a\u043e\u0441\u0438\u043d\u0443\u0441\u043d\u043e\u0439 \u043c\u0435\u0440\u0435 \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0433\u043e \u043a\u0430\u043d\u0434\u0438\u0434\u0430\u0442\u0430. \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 match_id, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u043f\u043b\u0435\u0439.<\/p>\n<p>\u0412\u044b\u0432\u0435\u0434\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u0438\u0441\u043a\u0430.<\/p>\n<pre><code class=\"python\">match_id = search_team_tournament_pairs(teams_pair, tournament, matches) [m for m in matches if m['match_id'] == match_id] > [     {         \"match_id\": 6673204572,         \"start_time\": 1658513208,         \"leagueid\": 14391,         \"league\": \"Riyadh Masters by Gamers8\",         \"radiant_team_id\": 1838315,         \"radiant_name\": \"Team Secret\",         \"radiant_tag\": \"Secret\",         \"dire_team_id\": 7119388,         \"dire_name\": \"Team Spirit\",         \"dire_tag\": \"TSpirit\"     } ]<\/code><\/pre>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0438\u0441\u043a\u0430\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0438 \u0432 \u0411\u0414 \u043f\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u043c \u0432\u0438\u0434\u0435\u043e \u043d\u0430 YouTube. \u041f\u043e\u0438\u0433\u0440\u0430\u043b\u0438\u0441\u044c \u0441 \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044f\u043c\u0438. \u0418 \u0432\u043e\u043e\u0431\u0449\u0435 \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u043b\u0438 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043c \u0434\u0430\u0442\u0430\u0441\u0435\u0442 \u0438 \u0443\u043b\u0443\u0447\u0448\u0438\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u043e\u0432 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438.<\/p>\n<p>* \u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0438\u0441\u043a\u0430 \u043c\u043e\u0436\u043d\u043e \u0443\u0442\u043e\u0447\u043d\u0438\u0442\u044c, \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0432 \u0411\u0414. \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0435\u0441\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043d\u0430 GitHub.<\/p>\n<p>** \u0412\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c \u0437\u0430\u043c\u0435\u0442\u0438\u0442, \u0447\u0442\u043e \u0432\u0438\u0434\u0435\u043e \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u0435 \u043e\u0434\u0438\u043d \u043c\u0430\u0442\u0447, \u0430 \u0441\u0435\u0440\u0438\u044e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e \u0438\u0433\u0440\u0430\u044e\u0442 2 \u0438\u043b\u0438 3 \u043a\u0430\u0440\u0442\u044b. \u041c\u043d\u0435 \u0431\u044b\u043b\u043e \u043b\u0435\u043d\u044c \u0432\u043e\u0437\u0438\u0442\u044c\u0441\u044f, \u043d\u043e \u0432 \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u0435 \u044d\u0442\u043e \u0432\u0430\u0436\u043d\u043e \u0443\u0447\u0435\u0441\u0442\u044c.<\/p>\n<h2>\u0421\u0441\u044b\u043b\u043a\u0438<\/h2>\n<ul>\n<li>\n<p><a href=\"https:\/\/t.me\/savostyanov_dmitry\" rel=\"noopener noreferrer nofollow\">\u041c\u043e\u0439 Telegram-\u043a\u0430\u043d\u0430\u043b<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/arch1baald\/dota-highlights\/blob\/text\/src\/youtube.py#L251\" rel=\"noopener noreferrer nofollow\">\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 (\u0432\u0435\u0442\u043a\u0430 text)<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/docs.opendota.com\/#tag\/explorer\" rel=\"noopener noreferrer nofollow\">API OpenDota<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/github.com\/odota\/core\/blob\/master\/sql\/create_tables.sql\" rel=\"noopener noreferrer nofollow\">\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0411\u0414 OpenDota<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/arxiv.org\/pdf\/1810.04805.pdf\" rel=\"noopener noreferrer nofollow\">\u0421\u0442\u0430\u0442\u044c\u044f \u043f\u0440\u043e BERT<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/682480\/\"> https:\/\/habr.com\/ru\/post\/682480\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435, \u0447\u0442\u043e \u0441 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u0438\u0434\u0435\u043e \u043d\u0430 YouTube \u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c\u0438 \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438\u0437 \u043c\u0430\u0442\u0447\u0430 \u043f\u043e Dota 2. \u0410 \u0441 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u0441\u0435\u0445 \u043c\u0430\u0442\u0447\u0435\u0439 \u043f\u043e Dota 2. \u041a\u0430\u043a \u0434\u043b\u044f \u0432\u0438\u0434\u0435\u043e \u043d\u0430\u0439\u0442\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0411\u0414? \u042d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u043c\u044b \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0438 \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f.<\/p>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0441\u0442\u0430\u0442\u0435\u0439 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u043e\u0438\u0441\u043a\u0430 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u043e\u0432 \u0432 \u043c\u0430\u0442\u0447\u0430\u0445 Dota 2. \u0414\u043b\u044f \u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0430\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u0439 \u0434\u0430\u0442\u0430\u0441\u0435\u0442 \u0441 \u0442\u0430\u0439\u043c-\u043a\u043e\u0434\u0430\u043c\u0438. \u041d\u0430 YouTube \u0435\u0441\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043a\u0430\u043d\u0430\u043b\u043e\u0432, \u0433\u0434\u0435 \u043b\u044e\u0434\u0438 \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442 \u043d\u0430\u0440\u0435\u0437\u043a\u0438 \u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c\u0438 \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438\u0437 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0442\u0447\u0435\u0439 \u043f\u043e Dota 2.<\/p>\n<p>\u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u044f\u0445:<\/p>\n<ol>\n<li>\n<p>\u0412\u00a0<a href=\"https:\/\/habr.com\/ru\/post\/672420\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a>\u00a0\u043c\u044b \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u043b\u0438 \u0440\u0435\u043f\u043b\u0435\u0439 \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0430\u0442\u0447\u0430 \u043f\u043e Dota 2 \u0438 \u043d\u0430\u0448\u043b\u0438 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u00a0<a href=\"https:\/\/habr.com\/ru\/post\/677200\/\" rel=\"noopener noreferrer nofollow\">\u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a>\u00a0\u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0440\u0435\u043f\u043b\u0435\u0435\u0432 \u043d\u0430 Celery \u0438 Flask.<\/p>\n<\/li>\n<li>\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/post\/679762\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u043c\u044b \u043d\u0430\u0443\u0447\u0438\u043b\u0438\u0441\u044c \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e \u0441 \u043d\u0430\u0440\u0435\u0437\u043a\u0430\u043c\u0438 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u043e\u0432 \u0441 YouTube, \u0441\u0435\u043c\u043f\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0434\u0440\u044b \u0438 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u0442\u044c \u043d\u0430 \u043d\u0438\u0445 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<\/li>\n<\/ol>\n<h3>\u041f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c<\/h3>\n<ol>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0438 \u0432\u0440\u0435\u043c\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0438\u0434\u0435\u043e<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0445\u043e\u0434\u0438\u043c \u043c\u0430\u0442\u0447\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e API OpenDota<\/p>\n<\/li>\n<li>\n<p>\u041a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u0442\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e <code>BERT<\/code><\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u043e\u0438\u043c \u044d\u043c\u0431\u0435\u0434\u0438\u043d\u0433\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0438\u0441\u043a \u043c\u0430\u0442\u0447\u0430 \u043f\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0443 \u0432\u0438\u0434\u0435\u043e<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u043a\u043e\u0434 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<\/li>\n<\/ol>\n<h2>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0438 \u0432\u0440\u0435\u043c\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0438\u0434\u0435\u043e<\/h2>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u043e\u0439 \u043d\u0430\u043c \u043f\u043e \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 <code>yt_dlp<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 URL \u0432\u0438\u0434\u0435\u043e, \u0430 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435. <\/p>\n<pre><code class=\"python\">... import yt_dlp   @lru_cache def get_video_metadata(url: str, save: bool = False) -> Tuple[str | int, Dict]:     options = dict()     with yt_dlp.YoutubeDL(options) as ydl:         metadata = ydl.extract_info(url, download=False)     video_id = metadata.get('id')      if save:         metadata_file = f'{video_id}.json'         video_metadata_path = VIDEO_DIR \/ metadata_file         with open(video_metadata_path, 'w') as fout:             json.dump(metadata, fout, indent=4)     return video_id, metadata<\/code><\/pre>\n<p>\u0421\u043b\u043e\u0432\u0430\u0440\u044c <code>metadata<\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432 \u0441\u0435\u0431\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0432\u0438\u0434\u0435\u043e, \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435. \u0412\u043e\u0437\u044c\u043c\u0435\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043c\u0430\u0442\u0447 Team Spirit \u043f\u0440\u043e\u0442\u0438\u0432 Team Secret.<\/p>\n<pre><code class=\"python\">url = 'https:\/\/www.youtube.com\/watch?v=cXA5Hw2boLA&amp;ab_channel=DotADigest' video_id, metadata = get_video_metadata(url) print(metadata)  > {     \"id\": \"cXA5Hw2boLA\",     \"title\": \"SECRET vs TEAM SPIRIT - RAMPAGE! SEMI FINAL - RIYADH MASTERS 2022 Dota 2 Highlights\",     \"thumbnail\": \"https:\/\/i.ytimg.com\/vi\/cXA5Hw2boLA\/hqdefault.jpg\",     \"description\": \"DOTA 2 TS SECRET vs TEAM SPIRIT - RAMPAGE! SEMI FINAL - RIYADH MASTERS 2022 by Gamers8 Dota 2 Highlights 2022 Tournament - Semi Final Playoff #dota2 #dpc  \\nWatch Live Riyadh Masters Dota 2: https:\/\/www.twitch.tv\/gamers8gg - Commentary by Gareth &amp; Lacoste\",     \"uploader\": \"DotA Digest\",     \"upload_date\": \"20220724\",     \"uploader_id\": \"RUDota2TV\",     \"uploader_url\": \"http:\/\/www.youtube.com\/user\/RUDota2TV\",     \"channel_id\": \"UCUqLL4VcEy4mXcQL0O_H_bg\",     \"channel_url\": \"https:\/\/www.youtube.com\/channel\/UCUqLL4VcEy4mXcQL0O_H_bg\",     \"duration\": 1648,     \"view_count\": 50716,     \"average_rating\": null,     \"age_limit\": 0,     \"webpage_url\": \"https:\/\/www.youtube.com\/watch?v=cXA5Hw2boLA\",  ...<\/code><\/pre>\n<h2>\u041d\u0430\u0445\u043e\u0434\u0438\u043c \u043c\u0430\u0442\u0447\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e API OpenDota<\/h2>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043c\u0441\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u043e\u043c \u043a\u0430\u043d\u0430\u043b\u0430 DotA Digest. \u041e\u0431\u044b\u0447\u043d\u043e \u0430\u0432\u0442\u043e\u0440 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434 \u0438 \u0442\u0443\u0440\u043d\u0438\u0440. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0437\u043d\u0430\u0435\u043c \u0434\u0430\u0442\u0443 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0438\u0434\u0435\u043e. \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043d\u0430\u0439\u0442\u0438 <code>Replay<\/code>. <\/p>\n<p>\u0418\u0434\u0435\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f. \u0412\u0438\u0434\u0435\u043e \u0441 \u043d\u0430\u0440\u0435\u0437\u043a\u0430\u043c\u0438 \u0445\u0430\u0439\u043b\u0430\u0439\u0442\u043e\u0432 \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u0430\u0442\u0447 \u0443\u0436\u0435 \u0441\u044b\u0433\u0440\u0430\u043d. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0430\u0432\u0442\u043e\u0440\u044b YouTube-\u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u0441\u0442\u0440\u0435\u043c\u044f\u0442\u0441\u044f \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0438\u0434\u0435\u043e \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u043d\u044c\u0448\u0435, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u043e\u0432. \u0417\u043d\u0430\u0447\u0438\u0442 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u0437\u044f\u0442\u044c \u0432\u0441\u0435 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0430\u0442\u0447\u0438 \u0437\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043d\u0435\u0439 \u0434\u043e \u0434\u0430\u0442\u044b \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0438\u0434\u0435\u043e \u0438 \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0438\u0441\u043a\u043e\u043c\u044b\u043c (\u0437\u0430\u043f\u0435\u0447\u0430\u0442\u043b\u0451\u043d\u043d\u044b\u043c \u043d\u0430 \u0432\u0438\u0434\u0435\u043e).<\/p>\n<p>\u0421\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0440\u0435\u043f\u043b\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u0437\u043d\u0430\u044f <code>match_id<\/code> \u2014 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043c\u0430\u0442\u0447\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0430\u043c\u0430 \u0438\u0433\u0440\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f API OpenDota.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 wrapper \u0434\u043b\u044f <code>\/explorer<\/code> endpoint, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 OpenDota.<\/p>\n<pre><code class=\"python\">import requests from tenacity import retry, stop_after_attempt, wait_fixed   @retry(stop=stop_after_attempt(7), wait=wait_fixed(10)) def query_opendota(sql: str, **kwargs: dict) -> List[Dict]:     query = sql.format(**kwargs)     logger.debug(query)  r = requests.get(         'https:\/\/api.opendota.com\/api\/explorer',          params=dict(sql=query)     )     r.raise_for_status()     result = r.json()     rows = result['rows']     return rows<\/code><\/pre>\n<p>\u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0430\u0442\u0447\u0438 \u0437\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0434\u0432\u0430 \u0434\u043d\u044f \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0439 \u0434\u0430\u0442\u044b.<\/p>\n<pre><code class=\"python\">from datetime import datetime, timedelta   def get_nearest_matches(date: datetime) -> List[Dict]:     end_time = date + timedelta(days=1)     start_time = date - timedelta(days=2)     query = '''     SELECT         match_id,         start_time,         matches.leagueid,         leagues.name as league,         radiant_team_id,         radiant_team.name as radiant_name,         radiant_team.tag as radiant_tag,         dire_team_id,         dire_team.name as dire_name,         dire_team.tag as dire_tag     FROM         matches         join teams as dire_team on matches.dire_team_id = dire_team.team_id         join teams as radiant_team on              matches.radiant_team_id = radiant_team.team_id         join leagues on matches.leagueid = leagues.leagueid     WHERE         start_time >= extract(epoch from timestamp '{start_time}')         and start_time &lt; extract(epoch from timestamp '{end_time}')     ORDER BY         start_time desc     LIMIT       500     '''     matches = query_opendota(         query,         start_time=datetime.strftime(start_time, '%m-%d-%Y'),         end_time=datetime.strftime(end_time, '%m-%d-%Y')     )     return matches<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043d\u0430 \u0432\u0441\u0435 \u0442\u043e\u043c \u0436\u0435 \u043c\u0430\u0442\u0447\u0435 Team Spirit \u043f\u0440\u043e\u0442\u0438\u0432 Team Secret. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u043c \u0434\u0430\u0442\u0443 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u0438\u0434\u0435\u043e \u0438\u0437 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u0439\u0434\u0435\u043c \u0432\u0441\u0435 \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u043c\u0430\u0442\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0441\u044b\u0433\u0440\u0430\u043d\u044b \u0432 \u0434\u0435\u043d\u044c \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0434\u0432\u0430 \u0434\u043d\u044f.<\/p>\n<pre><code class=\"python\">url = 'https:\/\/www.youtube.com\/watch?v=cXA5Hw2boLA&amp;ab_channel=DotADigest' video_id, metadata = get_video_metadata(url) upload_date = metadata['upload_date'] upload_date = datetime.strptime(upload_date, '%Y%m%d') matches = get_nearest_matches(upload_date) print(len(matches))  > 288<\/code><\/pre>\n<p>\u0412\u0441\u0435\u0433\u043e \u043c\u0430\u0442\u0447\u0435\u0439 288. \u0421\u0440\u0435\u0434\u0438 \u043d\u0438\u0445 \u0435\u0441\u0442\u044c 12 \u043c\u0430\u0442\u0447\u0435\u0439 \u0441 \u0443\u0447\u0430\u0441\u0442\u0438\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u044b Team Spirit, 3 \u0437\u0430 Radiant \u0438 9 \u0437\u0430 Dire.<\/p>\n<pre><code class=\"python\">print([m for m in matches if m['radiant_name'] == 'Team Spirit'])  > [     {         \"match_id\": 6676488286,         \"start_time\": 1658692615,         \"leagueid\": 14391,         \"league\": \"Riyadh Masters by Gamers8\",         \"radiant_team_id\": 7119388,         \"radiant_name\": \"Team Spirit\",         \"radiant_tag\": \"TSpirit\",         \"dire_team_id\": 15,         \"dire_name\": \"PSG.LGD\",         \"dire_tag\": \"PSG.LGD\"     },     {         \"match_id\": 6676051545,         \"start_time\": 1658673115,         \"leagueid\": 14391,         \"league\": \"Riyadh Masters by Gamers8\",         \"radiant_team_id\": 7119388,         \"radiant_name\": \"Team Spirit\",         \"radiant_tag\": \"TSpirit\",         \"dire_team_id\": 1838315,         \"dire_name\": \"Team Secret\",         \"dire_tag\": \"Secret\"     },     {         \"match_id\": 6672690521,         \"start_time\": 1658491214,         \"leagueid\": 14391,         \"league\": \"Riyadh Masters by Gamers8\",         \"radiant_team_id\": 7119388,         \"radiant_name\": \"Team Spirit\",         \"radiant_tag\": \"TSpirit\",         \"dire_team_id\": 8291895,         \"dire_name\": \"Tundra Esports\",         \"dire_tag\": \"Tundra\"     } ]<\/code><\/pre>\n<p>\u041d\u044e\u0430\u043d\u0441 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e Spirit \u0438\u0433\u0440\u0430\u043b\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 Team Secret, \u043d\u043e \u0438 \u0441 PSG.LGD, \u0438 \u0441 Tundra Esports. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u0437 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u043e\u043d\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u043c\u0430\u0442\u0447\u0443 Secret &#8212; Spirit. <\/p>\n<pre><code class=\"python\">print(metadata['fulltitle']) > \"SECRET vs TEAM SPIRIT - RAMPAGE! SEMI FINAL - RIYADH MASTERS 2022 Dota 2 Highlights\"<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0436\u0435 \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0430\u0442\u0447\u0438 \u0432 \u0411\u0414, \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u043f\u043e\u0434 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0432\u0438\u0434\u0435\u043e? <\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u043c\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c\u0438. \u041d\u043e \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0432\u0438\u0434\u0435\u043e \u043f\u0438\u0448\u0435\u0442 \u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u0438 \u0442\u0443\u0440\u043d\u0438\u0440\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u043f\u0435\u0447\u0430\u0442\u043a\u0438 \u0438 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u043e\u0439\u0442\u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u041b\u0435\u0432\u0438\u043d\u0448\u0442\u0435\u0439\u043d\u0430, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043e\u0439\u0442\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043e\u043f\u0435\u0447\u0430\u0442\u043e\u043a \u0438 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0439. \u041d\u043e \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438 \u0432\u0438\u0434\u0435\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0438 \u043a\u043b\u0438\u043a\u0431\u0435\u0439\u0442\u043d\u044b\u0435 \u0441\u043b\u043e\u0432\u043e\u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u044f.<\/p>\n<p>\u041d\u043e \u044f \u0440\u0435\u0448\u0438\u043b \u0441\u0442\u0440\u0435\u043b\u044c\u043d\u0443\u0442\u044c \u0438\u0437 \u043f\u0443\u0448\u043a\u0438 \u043f\u043e \u0432\u043e\u0440\u043e\u0431\u044c\u044f\u043c. \u0411\u043b\u0430\u0433\u043e \u0432 \u043d\u0430\u0448\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u0441\u0435 \u0441\u0438\u043b\u044c\u043d\u0435\u0435 \u043d\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u043f\u043e\u043f\u0443\u043b\u044f\u0440\u043d\u043e\u0441\u0442\u044c \u043d\u043e\u0432\u043e\u0435, \u043c\u043e\u0434\u043d\u043e\u0435, \u043c\u043e\u043b\u043e\u0434\u0435\u0436\u043d\u043e\u0435 \u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u2014 \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u0438.<\/p>\n<h2>\u041a\u0440\u0430\u0442\u043a\u043e\u0435 \u043e\u0442\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u043e BERT<\/h2>\n<p>\u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044c<code>DistillBERT<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e \u0441\u0443\u0442\u0438 \u0441\u0432\u043e\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u043f\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0438 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432\u0435\u0440\u0441\u0438\u0435\u0439 <code>BERT<\/code>. \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442 \u0432 &#171;\u0445\u043e\u0440\u043e\u0448\u0438\u0435&#187; \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c.<\/p>\n<p>BERT \u2014 \u043c\u043e\u0434\u0435\u043b\u044c, \u043e\u0431\u0443\u0447\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 (\u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b), \u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0441\u0432\u044f\u0437\u0438 \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438. <\/p>\n<p>\u0421\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 \u043f\u0440\u043e\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0445 \u0442\u043e\u043a\u0435\u043d\u0430\u0445. \u0421\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435 \u043e\u043d\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u043b\u043e\u0432\u0430\u043c\u0438 \u0438\u043b\u0438 \u043a\u0443\u0441\u043e\u0447\u043a\u0430\u043c\u0438 \u0441\u043b\u043e\u0432. \u0414\u043b\u044f \u0438\u0445 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c BPE (Byte Pair Encoding). \u0412\u0441\u0435\u0433\u043e \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 30 000 \u0442\u043e\u043a\u0435\u043d\u043e\u0432.<\/p>\n<p>\u0412 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430 \u0430\u0432\u0442\u043e\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0442\u0435\u043a\u0441\u0442\u044b \u0438\u0437 \u043a\u043d\u0438\u0433 \u0438 \u0432\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438, \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e \u0431\u043e\u043b\u0435\u0435 3 \u043c\u043b\u0440\u0434 \u0441\u043b\u043e\u0432. \u041f\u0440\u0438\u0447\u0435\u043c 15% \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0437\u0430\u043c\u0435\u043d\u044f\u043b\u0438\u0441\u044c \u043d\u0430 \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0439 \u2014 [MASK]. \u0417\u0430\u0434\u0430\u0447\u0430 \u043c\u043e\u0434\u0435\u043b\u0438 \u0431\u044b\u043b\u0430 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434 \u043c\u0430\u0441\u043a\u043e\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u043d\u0430 \u043c\u043e\u0433\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0434\u043b\u0438\u043d\u044b \u043a\u0430\u043a \u0441\u043b\u0435\u0432\u0430, \u0442\u0430\u043a \u0438 \u0441\u043f\u0440\u0430\u0432\u0430. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440.<\/p>\n<blockquote>\n<p>[CLS] the man went to [MASK] store [SEP] he bought a gallon [MASK] milk [SEP] <\/p>\n<\/blockquote>\n<p>\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c, \u0447\u0442\u043e \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a<\/p>\n<blockquote>\n<p>The man went to asdf store. He bought a gallon dinosaur&#8217;s milk.<\/p>\n<\/blockquote>\n<p>\u041d\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u0432\u0434\u043e\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u043c \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442<\/p>\n<blockquote>\n<p>The men went to the store. He bought a gallon of milk.<\/p>\n<\/blockquote>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u044d\u0442\u0438\u043c \u043d\u0435\u0439\u0440\u043e\u0441\u0435\u0442\u044c \u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0430\u0441\u044c \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u043e\u0433\u043b\u0430 \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u0433\u0430\u043b\u043b\u043e\u043d \u043c\u043e\u043b\u043e\u043a\u0430 \u0434\u0438\u043d\u043e\u0437\u0430\u0432\u0440\u0430. \u041d\u043e \u0443 \u0434\u0438\u043d\u043e\u0437\u0430\u0432\u0440\u043e\u0432 \u043d\u0435\u0442 \u043c\u043e\u043b\u043e\u043a\u0430, \u0443 \u043d\u0438\u0445 \u0437\u0434\u043e\u0440\u043e\u0432\u0435\u043d\u043d\u044b\u0435 \u044f\u0439\u0446\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u043b\u0430 \u043e\u0442 \u043b\u043e\u0441\u0441\u0430 \u043f\u043e \u0432\u0435\u0441\u0430\u043c. \u0418 \u043f\u043e\u0442\u0438\u0445\u043e\u043d\u044c\u043a\u0443 \u0441\u0445\u043e\u0434\u0438\u043b\u0430\u0441\u044c \u043a \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0430\u0432\u0434\u043e\u043f\u043e\u0431\u043d\u043e\u043c\u0443 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0443. \u0418 \u0442\u0430\u043a \u0434\u043b\u044f \u043c\u0438\u043b\u043b\u0438\u043e\u043d\u043e\u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432.<\/p>\n<p>\u0421\u0445\u0435\u043c\u0430 \u043c\u043e\u0434\u0435\u043b\u0438:<\/p>\n<ol>\n<li>\n<p>\u0411\u0435\u0440\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0434\u043b\u0438\u043d\u044b<\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0437\u0431\u0438\u0432\u0430\u0435\u043c \u043d\u0430 \u0442\u043e\u043a\u0435\u043d\u044b<\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u0436\u0434\u043e\u043c\u0443 \u0442\u043e\u043a\u0435\u043d\u0443 \u0441\u0442\u0430\u0432\u0438\u043c \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 emdedding \u2014 768-\u043c\u0435\u0440\u043d\u044b\u0439 \u0432\u0435\u043a\u0442\u043e\u0440<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c Positional Encoding, \u0447\u0442\u043e\u0431\u044b \u0443\u0447\u0435\u0441\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0441\u043b\u043e\u0432 (\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 \u0441\u0442\u0430\u0442\u044c\u0435)<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0433\u043e\u043d\u044f\u0435\u043c<\/p>\n<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-337302","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/337302","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=337302"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/337302\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=337302"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=337302"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=337302"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}