CINXE.COM
クッキーの日記
<!DOCTYPE html> <html lang="ja" data-admin-domain="//blog.hatena.ne.jp" data-admin-origin="https://blog.hatena.ne.jp" data-author="cookie-box" data-avail-langs="ja en" data-blog="cookie-box.hatenablog.com" data-blog-host="cookie-box.hatenablog.com" data-blog-is-public="1" data-blog-name="クッキーの日記" data-blog-owner="cookie-box" data-blog-show-ads="1" data-blog-show-sleeping-ads="" data-blog-uri="https://cookie-box.hatenablog.com/" data-blog-uuid="6653586347145897172" data-blogs-uri-base="https://cookie-box.hatenablog.com" data-brand="hatenablog" data-data-layer="{"hatenablog":{"admin":{},"analytics":{"brand_property_id":"","measurement_id":"","non_sampling_property_id":"","property_id":"","separated_property_id":"UA-29716941-23"},"blog":{"blog_id":"6653586347145897172","content_seems_japanese":"true","disable_ads":"","enable_ads":"true","enable_keyword_link":"true","entry_show_footer_related_entries":"true","force_pc_view":"true","is_public":"true","is_responsive_view":"true","is_sleeping":"false","lang":"ja","name":"\u30af\u30c3\u30ad\u30fc\u306e\u65e5\u8a18","owner_name":"cookie-box","uri":"https://cookie-box.hatenablog.com/"},"brand":"hatenablog","page_id":"index","permalink_entry":null,"pro":"free","router_type":"blogs"}}" data-device="pc" data-dont-recommend-pro="false" data-global-domain="https://hatena.blog" data-globalheader-color="b" data-globalheader-type="pc" data-has-touch-view="1" data-help-url="https://help.hatenablog.com" data-no-suggest-touch-view="1" data-page="index" data-parts-domain="https://hatenablog-parts.com" data-plus-available="" data-pro="false" data-router-type="blogs" data-sentry-dsn="https://03a33e4781a24cf2885099fed222b56d@sentry.io/1195218" data-sentry-environment="production" data-sentry-sample-rate="0.1" data-static-domain="https://cdn.blog.st-hatena.com" data-version="4c841dff904291fd18670d1f8165c6" data-initial-state="{}" > <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#"> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="robots" content="max-image-preview:large" /> <meta charset="utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=7; IE=9; IE=10; IE=11" /> <title>クッキーの日記</title> <link rel="canonical" href="https://cookie-box.hatenablog.com/"/> <meta itemprop="name" content="クッキーの日記"/> <meta itemprop="image" content="https://cdn.user.blog.st-hatena.com/default_entry_og_image/57244776/1731406725676161"/> <meta property="og:title" content="クッキーの日記"/> <meta property="og:type" content="blog"/> <meta property="og:url" content="https://cookie-box.hatenablog.com/"/> <meta property="og:image" content="https://cdn.image.st-hatena.com/image/scale/300e623073f4e2041a76b6c0f4ff32cb58bc1c41/backend=imagemagick;enlarge=0;height=1000;version=1;width=1200/https%3A%2F%2Fcdn.user.blog.st-hatena.com%2Fdefault_entry_og_image%2F57244776%2F1731406725676161"/> <meta property="og:image:alt" content="クッキーの日記"/> <meta property="og:description" content="クッキーの日記" /> <meta property="og:site_name" content="クッキーの日記"/> <meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:image" content="https://cdn.user.blog.st-hatena.com/default_entry_og_image/57244776/1731406725676161" /> <meta name="twitter:title" content="クッキーの日記" /> <meta name="twitter:description" content="クッキーの日記" /> <meta name="twitter:app:name:iphone" content="はてなブログアプリ" /> <meta name="twitter:app:id:iphone" content="583299321" /> <meta name="twitter:app:url:iphone" content="hatenablog:///open?uri=https%3A%2F%2Fcookie-box.hatenablog.com%2F" /> <script id="embed-gtm-data-layer-loader" data-data-layer-page-specific="" > (function() { function loadDataLayer(elem, attrName) { if (!elem) { return {}; } var json = elem.getAttribute(attrName); if (!json) { return {}; } return JSON.parse(json); } var globalVariables = loadDataLayer( document.documentElement, 'data-data-layer' ); var pageSpecificVariables = loadDataLayer( document.getElementById('embed-gtm-data-layer-loader'), 'data-data-layer-page-specific' ); var variables = [globalVariables, pageSpecificVariables]; if (!window.dataLayer) { window.dataLayer = []; } for (var i = 0; i < variables.length; i++) { window.dataLayer.push(variables[i]); } })(); </script> <!-- Google Tag Manager --> <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-P4CXTW');</script> <!-- End Google Tag Manager --> <link rel="shortcut icon" href="https://cookie-box.hatenablog.com/icon/favicon"> <link rel="apple-touch-icon" href="https://cookie-box.hatenablog.com/icon/touch"> <link rel="icon" sizes="192x192" href="https://cookie-box.hatenablog.com/icon/link"> <link rel="alternate" type="application/atom+xml" title="Atom" href="https://cookie-box.hatenablog.com/feed"/> <link rel="alternate" type="application/rss+xml" title="RSS2.0" href="https://cookie-box.hatenablog.com/rss"/> <link rel="author" href="http://www.hatena.ne.jp/cookie-box/"> <link rel="stylesheet" type="text/css" href="https://cdn.blog.st-hatena.com/css/blog.css?version=4c841dff904291fd18670d1f8165c6"/> <link rel="stylesheet" type="text/css" href="https://usercss.blog.st-hatena.com/blog_style/6653586347145897172/192b3664c2c31bbdf1ae7d271403d776309f9b85"/> <script> </script> <style> div#google_afc_user, div.google-afc-user-container, div.google_afc_image, div.google_afc_blocklink { display: block !important; } </style> <script src="https://cdn.pool.st-hatena.com/valve/valve.js" async></script> <script id="test-valve-definition"> var valve = window.valve || []; valve.push(function(v) { v.config({ service: 'blog', content: { result: 'adtrust', documentIds: ["blog:entry:6802418398303423483","blog:entry:6801883189120915633","blog:entry:6801883189084381760","blog:entry:6801883189064800107","blog:entry:820878482969516668"] } }); v.defineDFPSlot({"lazy":1,"sizes":{"mappings":[[[320,568],[[336,280],[300,250],"fluid"]],[[0,0],[[300,250]]]]},"slotId":"ad-in-entry","unit":"/4374287/blog_pc_entry_sleep_in-article"}); v.defineDFPSlot({"lazy":"","sizes":[[300,250],[336,280],[468,60],"fluid"],"slotId":"google_afc_user_container_0","unit":"/4374287/blog_user"}); v.defineDFPSlot({"lazy":"","sizes":[[300,250],[336,280],[468,60],"fluid"],"slotId":"google_afc_user_container_1","unit":"/4374287/blog_user_2nd"}); v.defineDFPSlot({"lazy":"","sizes":[[300,250],[336,280],[468,60],"fluid"],"slotId":"google_afc_user_container_2","unit":"/4374287/blog_user_2nd"}); v.defineDFPSlot({"lazy":"1","sizes":[[300,250],[336,280],[468,60],"fluid"],"slotId":"google_afc_user_container_3","unit":"/4374287/blog_user_2nd"}); v.defineDFPSlot({"lazy":"1","sizes":[[300,250],[336,280],[468,60],"fluid"],"slotId":"google_afc_user_container_4","unit":"/4374287/blog_user_2nd"}); v.sealDFPSlots(); }); </script> <script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","name":"クッキーの日記","url":"https://cookie-box.hatenablog.com/"}</script> <link href="https://fonts.googleapis.com/earlyaccess/mplus1p.css" rel="stylesheet" /> <link href="https://fonts.googleapis.com/earlyaccess/roundedmplus1c.css" rel="stylesheet" /> <script> MathJax = { tex: { inlineMath: [['$', '$'], ['\\(', '\\)']] } }; </script> <script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"> </script> </head> <body class="page-index enable-top-editarea enable-bottom-editarea globalheader-ng-enabled"> <div id="globalheader-container" data-brand="hatenablog" > <iframe id="globalheader" height="37" frameborder="0" allowTransparency="true"></iframe> </div> <nav class=" blog-controlls "> <div class="blog-controlls-blog-icon"> <a href="https://cookie-box.hatenablog.com/"> <img src="https://cdn.blog.st-hatena.com/images/admin/blog-icon-noimage.png" alt="クッキーの日記"/> </a> </div> <div class="blog-controlls-title"> <a href="https://cookie-box.hatenablog.com/">クッキーの日記</a> </div> <a href="https://blog.hatena.ne.jp/cookie-box/cookie-box.hatenablog.com/subscribe?utm_campaign=subscribe_blog&utm_medium=button&utm_source=blogs_topright_button" class="blog-controlls-subscribe-btn test-blog-header-controlls-subscribe"> 読者になる </a> </nav> <div id="container"> <div id="container-inner"> <header id="blog-title" data-brand="hatenablog"> <div id="blog-title-inner" > <div id="blog-title-content"> <h1 id="title"><a href="https://cookie-box.hatenablog.com/">クッキーの日記</a></h1> </div> </div> </header> <div id="top-editarea"> <!--<span style="font-family: 'Lato', sans-serif;letter-spacing: 0.1em; font-size:105%;font-weight:bold;font-size:92%;color:#d0af4c">5TH ANNIVERSARY <i class="blogicon-star"></i> SINCE 2015</span>--> <table class="mytable" style="margin-top:0.0em;min-width: 280px;"> <tr><td style="border: 0px;padding-bottom:13px;"> </td></tr> <tr><td style="border: 0px;padding-bottom:5px;"> <div class="entry-categories categories2" style="float:left;"> <a style=" letter-spacing: 0.14em;" href="http://cookie-box.hatenablog.com/archive/category/DLM">DLM</a> </div> <div class="entry-categories categories2" style="float:left;"> <a href="http://cookie-box.hatenablog.com/archive/category/%E7%8A%B6%E6%85%8B%E7%A9%BA%E9%96%93%E3%83%A2%E3%83%87%E3%83%AB">状態空間モデル</a> </div> <div class="entry-categories categories2" style="float:left;"> <a href="http://cookie-box.hatenablog.com/archive/category/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92">機械学習</a> </div> <div class="entry-categories categories2" style="float:left;"> <a href="http://cookie-box.hatenablog.com/archive/category/%E5%BC%B7%E5%8C%96%E5%AD%A6%E7%BF%92">強化学習</a> </div> <div class="entry-categories categories2" style="float:left;"> <a href="http://cookie-box.hatenablog.com/archive/category/%E4%BD%8D%E7%9B%B8%E7%9A%84%E3%83%87%E3%83%BC%E3%82%BF%E8%A7%A3%E6%9E%90">位相的データ解析</a> </div> <div class="entry-categories categories2" style="float:left;"> <a href="http://cookie-box.hatenablog.com/archive/category/R">R</a> </div> <div class="entry-categories categories2" style="float:left;"> <a href="http://cookie-box.hatenablog.com/archive/category/%E6%95%B0%E7%90%86%E8%AB%96%E7%90%86%E5%AD%A6">数理論理学</a> </div> <div class="entry-categories categories2" style="float:left;"> <a href="http://cookie-box.hatenablog.com/archive/category/%E7%A2%BA%E7%8E%87%E8%AB%96">確率論</a> </div> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #b3b3b3;" href="http://cookie-box.hatenablog.com/entry/2016/01/01/000000">本読みまとめ</a> </div> <!--<div class="entry-categories categories2" style="float:left;"> <a style="background-color: #b3b3b3;" href="http://cookie-box.hatenablog.com/entry/2017/01/01/000000">論文読みまとめ</a> </div> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #b3b3b3;" href="http://cookie-box.hatenablog.com/entry/2017/01/01/030000">ライブラリまとめ</a> </div>--> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #b3b3b3;" href="http://cookie-box.hatenablog.com/entry/2016/01/01/030000">勉強会参加ログ</a> </div> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #b3b3b3;" href="http://cookie-box.hatenablog.com/entry/1970/01/01/000000">このブログについて</a> </div> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #4d4d4d; letter-spacing: 0.14em;" href="http://qiita.com/CookieBox26">Qiita</a> </div> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #4d4d4d; letter-spacing: 0.14em;" href="https://www.slideshare.net/ChihiroKusunoki">SlideShare</a> </div> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #4d4d4d; letter-spacing: 0.14em;" href="https://speakerdeck.com/cookiebox26">SpeakerDeck</a> </div> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #4d4d4d; letter-spacing: 0.14em;" href="https://gist.github.com/CookieBox26">GitHub Gist</a> </div> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #4d4d4d; letter-spacing: 0.14em;" href="https://github.com/CookieBox26/ToyBox/wiki/100%E6%97%A5%E5%BE%8C%E3%81%AB%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%82%92%E3%81%99%E3%82%8B%E3%82%AF%E3%83%83%E3%82%AD%E3%83%BC">100ML</a> </div> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #4d4d4d; letter-spacing: 0.14em;" href="https://github.com/CookieBox26/ML">github.com/CookieBox26/ML</a> </div> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #4d4d4d; letter-spacing: 0.14em;" href="https://zenn.dev/cookiebox26">Zenn</a> </div> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #4d4d4d; letter-spacing: 0.14em;" href="https://techbookfest.org/organization/5673028065165312">技術書典</a> </div> <div class="entry-categories categories2" style="float:left;"> <a style="background-color: #4d4d4d; letter-spacing: 0.14em;" href="https://cookiebox26.github.io/cookipedia/index.html">Cookipedia</a> </div> </td> </tr> <tr><td> <div class="sample-box-13"> 数式が崩れていたらその記事単体を表示すると解消するかもしれないです。 <!-- <ul class="recent-entries hatena-urllist "> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <span style="font-family: 'Lato', sans-serif;letter-spacing: 0.1em; font-size:105%;font-weight:bold">2021-04-19</span> <a href="https://cookie-box.hatenablog.com/entry/2021/04/19/235844">雑記</a>を更新しました </div> </li> </ul> --> </div> </td></tr> </table> </div> <div id="content" class="hfeed" > <div id="content-inner"> <div id="wrapper"> <div id="main"> <div id="main-inner"> <!-- google_ad_section_start --> <!-- rakuten_ad_target_begin --> <article class="entry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-4000 words-400 mode-hatena entry-odd" id="entry-6802418398303423483" data-keyword-campaign="" data-uuid="6802418398303423483" data-publication-type="entry"> <div class="entry-inner"> <header class="entry-header"> <div class="date entry-date first"> <a href="https://cookie-box.hatenablog.com/archive/2024/11/12" rel="nofollow"> <time datetime="2024-11-12T09:13:50Z" title="2024-11-12T09:13:50Z"> <span class="date-year">2024</span><span class="hyphen">-</span><span class="date-month">11</span><span class="hyphen">-</span><span class="date-day">12</span> </time> </a> </div> <h1 class="entry-title"> <a href="https://cookie-box.hatenablog.com/entry/2024/11/12/181350" class="entry-title-link bookmark">雑記</a> </h1> <div class="entry-categories categories"> <a href="https://cookie-box.hatenablog.com/archive/category/%E9%9B%91%E8%A8%98" class="entry-category-link category-雑記">雑記</a> </div> </header> <div class="entry-content hatenablog-entry"> <p>お気付きの点がありましたらご指摘いただけますと幸いです。<div class="matome-container"><b>まとめ</b><br /> このブログ記事の証明は<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%AF%A5%B9%A5%C8%A5%E9">ダイクストラ</a>法を【解釈1】のように捉えているが、【解釈2】のように「Q からコスト最小のノードを取り出したときもうそのノードのコストはそれにしかならない」という方針で示す方が吞み込みやすいかもしれないしあまり変わらないかもしれない。<ul> <li>【解釈1】<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%AF%A5%B9%A5%C8%A5%E9">ダイクストラ</a>法とは、安く行けるノードから収集していく方法である。</li> <li>【解釈2】<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%AF%A5%B9%A5%C8%A5%E9">ダイクストラ</a>法とは、到達コストが確定するノードから確定していく方法である。</li> </ul></div><div class="ref-container"><ol> <li><a href="https://nw.tsuda.ac.jp/lec/dijkstra/">Dijkstra's Algorithm</a>: このブログ記事を書く前に Qiita に以下の記事を書いたときに実装を参考にした。</li> <ul><li><a href="https://qiita.com/CookieBox26/items/9b9388783435e237579d">【Python】ダイクストラ法 + 可視化スクリプト #matplotlib - Qiita</a>: こちらに書いた「もしノード0以外からノード3に行くならば、必ず他の暫定コストを経由しなければならない」が【解釈2】に近い。なお、この記事にリンクした可視化<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B9%A5%AF%A5%EA%A5%D7%A5%C8">スクリプト</a>はこれ以上ノードが増えるとみづらいし汎用性が低い。</li></ul> <li><a href="https://manabitimes.jp/math/644#3">数学的帰納法をわかりやすく【例題3問、応用5パターン】 | 高校数学の美しい物語</a>: このブログ記事の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%E4%C2%EA">補題</a>アでパターン 3 の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B5%A2%C7%BC%CB%A1">帰納法</a>をつかっている。</li> </ol></div><div class="turn kazusa"><div></div><div>エッジの重みが非負の場合の単一始点最短経路問題を解く<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>に<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%AF%A5%B9%A5%C8%A5%E9">ダイクストラ</a>法なるものがあるのですね。なるほど<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>を実行してみると最短経路が出てくるようにみえますが、しかしなぜこの<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>で最短経路が出てくるといえるのでしょうか。</div></div></p> <figure class="figure-image figure-image-fotolife" title=""><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20241112/20241112082428.png" width="889" height="799" loading="lazy" title="" class="hatena-fotolife" style="width:640px" itemprop="image"></span><figcaption>ノード0からの最小コストを求めていく経過<br/>詳細:<a href="https://qiita.com/CookieBox26/items/9b9388783435e237579d">【Python】ダイクストラ法 + 可視化スクリプト #matplotlib - Qiita</a></figcaption></figure><p><div class="turn kazusa"><div></div><div><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%AF%A5%B9%A5%C8%A5%E9">ダイクストラ</a>法の主張を書き下すと以下でしょうか。いまは計算量を議論したいのではないので、Q を優先度付きキューにするとよいなどは置いておきます。また、目標ノードまでの最小コストが達成される経路を取り出したいなら Q には〈 コストいくらで, どのノードに行ける, どのノードのほうからきたとき 〉というタプルを格納するべきですがそれも置いておきます。<div class="prop"><div class="header">定理〈 <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%AF%A5%B9%A5%C8%A5%E9">ダイクストラ</a>法 〉</div>N 個のノード 0, 1, ..., N-1 と、それらの間に張られるいくつかのエッジからなるグラフがあるとする。各エッジには非負のコストが付いているものとする (コストは向きによって違ってもよい)。<br /> いま、ノード 0 からノード N-1 までの道が存在するものとするとき、ノード 0 からノード N-1 まで行く最小コストが以下の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>で求まる。</p><p><div class="prop algo"><div class="header"><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a></div>空の集合 Q を用意する。 #〈 コストいくらで, どのノードに行ける 〉というタプルを格納する。<br /> 空の辞書 D を用意する。 # 各ノードまでの最小コストがいくらに確定したかが格納される。<br /> 【手順0】Q に要素〈 コスト=0, ノード=0 〉を追加する。<br /> 【手順1】Q からコスト最小の要素〈 コスト=c, ノード=i 〉を取り出す。<br /> 【手順2】i が既に D のキーならば、【手順1】に戻る。<br /> 【手順3】i をキー、c を値として D に追加する。<br /> 【手順4】i=N-1 ならここで終了する。求める最小コストは c である。<br /> 【手順5】i からエッジがあるノード j のそれぞれに対して以下を実行し、【手順1】に戻る。<br /> j が D のキーでないならば、Q に〈 コスト=c+cost(i, j), ノード=j 〉 を追加する。 <br /> ただし cost(i, j) はノード i からノード j へエッジを通るときのコストである。</div></div>D には結果的に最小コストが確定したノードが溜まっていきます。対して Q は、D に確定ノードを追加するたびに「確定ノードから一歩でこのノードに行けるよ (それがそのノードまでの最小コストかはさておき)」といったいわば暫定ノードを溜める集合ですね。それで、とどのつまり<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%AF%A5%B9%A5%C8%A5%E9">ダイクストラ</a>法は Q からコスト最小の要素を取り出して D に追加していくというだけなのですが、明らかでないのはなぜこれで D に各ノードまでの確定最小コストが蓄積してくれるのかですね……。</div></div><div class="turn kazusa"><div></div><div>まあしかし、現実として D に安く行けるノードから蓄積されていくことがわかっていますので、直接以下の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%E4%C2%EA">補題</a>が<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B5%A2%C7%BC%CB%A1">帰納法</a>で示せるかやってみましょう。<div class="prop"><b><a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%E4%C2%EA">補題</a>ア.</b>【手順3】を n 回目に通るときには、D に「n 番目に安く行けるノード及びそのコスト」が格納される。</div><div class="prop algo"><b><a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%E4%C2%EA">補題</a>アの証明.</b><br /> <a class="keyword" href="https://d.hatena.ne.jp/keyword/%B5%A2%C7%BC%CB%A1">帰納法</a>で示す。まず、n=1 のとき、【手順3】を 1 回目に通るときには、D にノード 0 自身 (最も安く行けるノード) までのコスト 0 が格納されるので成り立つ。<br /> 次に、n=1, ..., k に対して、【手順3】を n 回目に通るときに、D に n 番目に安く行けるノード及びそのコストが格納されると仮定する。このとき、【手順3】を k+1 回目に通る直前の【手順1】の時点で、<ul> <li>Q に格納されているうちコスト最小のノードのコストが D に格納されている k 個のノードのうちの最大コストを下回ることはない (<b><a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%E4%C2%EA">補題</a>イ</b>)。</li> <li>D にも Q にも格納されていないノードであって Q 内の最安ノードより安く到達できるノードはない (∵ もしあるとすると、そのノードは D に格納されているノードから 2 歩以上先のはずだが、そこに至る 1 歩先のノードは必ず【手順5】で Q に格納されているはずなので、2 歩以上先により安く到達できることに矛盾する)。</li> </ul>が成り立つので、この【手順1】の時点の Q の最安ノードは k+1 番目に安く行けるノードとなり、【手順3】を k+1 回目に通るときには、D に「k+1 番目に安く行けるノード及びそのコスト」が格納される。<br /> よって<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B5%A2%C7%BC%CB%A1">帰納法</a>により、【手順3】を n 回目に通るときには、D に「n 番目に安く行けるノード及びそのコスト」が格納されることが示された。</div><b><a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%E4%C2%EA">補題</a>イ</b>は別途証明しましょう。といっても<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%EB%A5%B4%A5%EA%A5%BA%A5%E0">アルゴリズム</a>上明らかですが……。<div class="prop"><b><a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%E4%C2%EA">補題</a>イ.</b>n 回目の【手順5】を終えた時点で、Q に格納されているうちコスト最小のノードのコスト q_n が D に格納されているうちの最大コスト d_n を下回ることはない (d_n ≦ q_n)。</div><div class="prop algo"><b><a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%E4%C2%EA">補題</a>イの証明.</b><br /> <a class="keyword" href="https://d.hatena.ne.jp/keyword/%B5%A2%C7%BC%CB%A1">帰納法</a>で示す。n=1 のとき、1 回目の【手順3】で空の D に Q の唯一の要素であるノード 0 ( コスト 0 ) が移されて Q は空になり、その直後の 1 回目の【手順5】で Q にノード 0 からエッジがあるノードおよびそこまでのコストが格納されるが、任意のエッジのコストは非負なのでコスト最小エッジのコスト q_1 が d_1 = 0 を下回ることはない。<br /> 次に、n=k のとき、k 回目の【手順5】を終えた時点で、d_k ≦ q_k と仮定する。このとき、k+1 回目の【手順3】で D に Q から最小コスト q_k が移され、D の新しい最大コストが d_{k+1}=q_k となり、Q の新しい最小コストが q' ≧ q_k になり、その直後の【手順5】で Q にさっきのコスト最小のノードからエッジがあるノードおよびそこまでのコストが格納されるが、任意のエッジのコストは非負なのでコスト最小のエッジのコスト c' をとっても d_{k+1}=q_k≦min(q', q_k+c')=q_{k+1} である。<br /> よって<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B5%A2%C7%BC%CB%A1">帰納法</a>により、n 回目の【手順5】を終えた時点で、d_n ≦ q_n である。</div></div></div><div class="turn kazusa"><div></div><div>証明できたと思いますが、この証明は<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%AF%A5%B9%A5%C8%A5%E9">ダイクストラ</a>法を【解釈1】のように捉えていますね。【解釈2】のように捉えて、Q からコスト最小のノードを取り出したときもうそのノードのコストはそれにしかならない、という方針で示す方が吞み込みやすいでしょうか……あまり変わらないでしょうか……。<ul> <li>【解釈1】<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%AF%A5%B9%A5%C8%A5%E9">ダイクストラ</a>法とは、安く行けるノードから収集していく方法である。</li> <li>【解釈2】<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%AF%A5%B9%A5%C8%A5%E9">ダイクストラ</a>法とは、到達コストが確定するノードから確定していく方法である。</li> </ul></div></div><div class="turn takumi"><div></div><div>あれ、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%AF%A5%B9%A5%C8%A5%E9">ダイクストラ</a>法を勉強しているんだね。</div></div><div class="turn kazusa"><div></div><div>あ副部長、はい、最近<a href="https://www.mobius-games.co.jp/HansimGluck/rasenderoboter.htm">ハイパーロボット</a>という<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%DC%A1%BC%A5%C9%A5%B2%A1%BC%A5%E0">ボードゲーム</a>を購入したんですが、これは全員でいっせいに最短手数を考えるゲームなので、なんと任意の人数 (1~∞) で遊ぶことができるんです。これなら社員全員で遊べるので会社の親睦会にも最適ではないでしょうか。それで、最短手数を求めようと<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%A4%A5%AF%A5%B9%A5%C8%A5%E9">ダイクストラ</a>法を。</div></div><div class="turn takumi"><div></div><div>いやその輸入元サイトに好き嫌いのはっきりしたゲームってあるじゃないか……そもそも会話するようなゲームじゃないから親睦にもならなさそうだし……あと、ハイパーロボットは<a class="keyword" href="https://d.hatena.ne.jp/keyword/%C9%FD%CD%A5%C0%E8%C3%B5%BA%F7">幅優先探索</a>でいいんじゃないかな。あらゆる問題設定をすべて解きたいならまた別だけど。</div></div><div class="turn kazusa"><div></div><div>ええ。</div></div><div class="owari">終わり</div></p> </div> <footer class="entry-footer"> <div class="entry-tags-wrapper"> <div class="entry-tags"> </div> </div> <p class="entry-footer-section track-inview-by-gtm" data-gtm-track-json="{"area": "finish_reading"}"> <span class="author vcard"><span class="fn" data-load-nickname="1" data-user-name="cookie-box" >cookie-box</span></span> <span class="entry-footer-time"><a href="https://cookie-box.hatenablog.com/entry/2024/11/12/181350"><time data-relative datetime="2024-11-12T09:13:50Z" title="2024-11-12T09:13:50Z" class="updated">2024-11-12 18:13</time></a></span> <span class=" entry-footer-subscribe " data-test-blog-controlls-subscribe> <a href="https://blog.hatena.ne.jp/cookie-box/cookie-box.hatenablog.com/subscribe?utm_source=blogs_entry_footer&utm_medium=button&utm_campaign=subscribe_blog"> 読者になる </a> </span> </p> <div class="hatena-star-container" data-hatena-star-container data-hatena-star-url="https://cookie-box.hatenablog.com/entry/2024/11/12/181350" data-hatena-star-title="雑記" data-hatena-star-variant="profile-icon" data-hatena-star-profile-url-template="https://blog.hatena.ne.jp/{username}/" ></div> <div class="social-buttons"> <div class="social-button-item"> <a href="https://b.hatena.ne.jp/entry/s/cookie-box.hatenablog.com/entry/2024/11/12/181350" class="hatena-bookmark-button" data-hatena-bookmark-url="https://cookie-box.hatenablog.com/entry/2024/11/12/181350" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="この記事をはてなブックマークに追加"><img src="https://b.st-hatena.com/images/entry-button/button-only.gif" alt="この記事をはてなブックマークに追加" width="20" height="20" style="border: none;" /></a> </div> <div class="social-button-item"> <div class="fb-share-button" data-layout="box_count" data-href="https://cookie-box.hatenablog.com/entry/2024/11/12/181350"></div> </div> <div class="social-button-item"> <a class="entry-share-button entry-share-button-twitter test-share-button-twitter" href="https://x.com/intent/tweet?text=%E9%9B%91%E8%A8%98+-+%E3%82%AF%E3%83%83%E3%82%AD%E3%83%BC%E3%81%AE%E6%97%A5%E8%A8%98&url=https%3A%2F%2Fcookie-box.hatenablog.com%2Fentry%2F2024%2F11%2F12%2F181350" title="X(Twitter)で投稿する" ></a> </div> </div> <div class="google-afc-image test-google-rectangle-ads"> <div id="google_afc_user_container_0" class="google-afc-user-container google_afc_blocklink2_5 google_afc_boder" data-test-unit="/4374287/blog_user"></div> <a href="http://blog.hatena.ne.jp/guide/pro" class="open-pro-modal" data-guide-pro-modal-ad-url="https://hatena.blog/guide/pro/modal/ad">広告を非表示にする</a> </div> <div class="customized-footer"> </div> <div class="comment-box js-comment-box"> <ul class="comment js-comment"> <li class="read-more-comments" style="display: none;"><a>もっと読む</a></li> </ul> <a class="leave-comment-title js-leave-comment-title">コメントを書く</a> </div> </footer> </div> </article> <article class="entry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-10000 words-600 mode-hatena entry-even" id="entry-6801883189120915633" data-keyword-campaign="" data-uuid="6801883189120915633" data-publication-type="entry"> <div class="entry-inner"> <header class="entry-header"> <div class="date entry-date first"> <a href="https://cookie-box.hatenablog.com/archive/2024/07/18" rel="nofollow"> <time datetime="2024-07-18T14:58:43Z" title="2024-07-18T14:58:43Z"> <span class="date-year">2024</span><span class="hyphen">-</span><span class="date-month">07</span><span class="hyphen">-</span><span class="date-day">18</span> </time> </a> </div> <h1 class="entry-title"> <a href="https://cookie-box.hatenablog.com/entry/2024/07/18/235843" class="entry-title-link bookmark">雑記: Transformer で記事から回答文を選択するための継続事前学習方法の話</a> </h1> <div class="entry-categories categories"> <a href="https://cookie-box.hatenablog.com/archive/category/%E9%9B%91%E8%A8%98" class="entry-category-link category-雑記">雑記</a> </div> </header> <div class="entry-content hatenablog-entry"> <p>お気付きの点がありましたらご指摘いただけますと幸いです。<div style="background:#f0f0f0;padding: 1.0em;font-size:92%; margin: 0 0 2.0em 0;"><b>まとめ</b><ul> <li>[1] によると、Transformer に <span class="command">[CLS] 質問文 [SEP] 回答文候補 [SEP] 回答文を含む記事 [SEP]</span> を入力して質問文と回答文候補の適合度を出したいとき、ELECTRA や RoBERTa を直接 fine-tuning するよりも、同じ段落かどうか (<a class="keyword" href="https://d.hatena.ne.jp/keyword/SSP">SSP</a>: Sentences in Same Paragraph) を判定するタスクで継続事前学習するほうがよい。つまり、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A1%BC%A5%D1%A5%B9">コーパス</a>から <span class="command">[CLS] 文章A [SEP] 文章B [SEP] 文章Aが属する文書の1段落目 [SEP]</span> を大量に生成し、文章Bが文章Aと同一段落に属するかどうかを継続事前学習する (このとき同時に元の ELECTRA, RoBERTa の事前学習タスクも学習する)。</li> <ul> <li>[1] によると、同一段落予測タスクによって同じトピックを説明する文同士が関連付けられるようになり、質問文と回答文候補の関連付けも上手くいくようになるという説明がなされている。</li> <li>継続事前学習時に「文章Aが属する文書の1段落目」を取る他に、「文章Aが属する段落」「文章Aとその前後の文章」を取るやり方も合わせて提案されており、Table 1 をみるに ELECTRA には 1 つ目のやり方が、RoBERTa には 2 つ目のやり方が比較的マッチしていそうだがデー<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%BF%A5%BB%A5%C3%A5%C8">タセット</a>にもよる。</li> </ul> </ul></div><div class="ref-box" style="padding-left:0.5em;"><ol class="ref"> <li><a href="https://aclanthology.org/2023.acl-short.40/">Context-Aware Transformer Pre-Training for Answer Sentence Selection - ACL Anthology</a>: 回答を含む記事が与えられた上で質問文と回答文候補の適合度を出すのに、Transformer を事前学習方法 ELECTRA と RoBERTa で事前学習したものを直接 fine-tuning するよりも、提案手法で継続事前学習するほうがよいという研究である。なお、Transformer への入力形式は <span class="command">[CLS] 質問 [SEP] 回答 [SEP] 記事 [SEP]</span> (3つのセグメントの別があるのでセグメントエンベディングもあり) である。</li> <li><a href="https://arxiv.org/abs/1911.04118">[1911.04118] TANDA: Transfer and Adapt Pre-Trained Transformer Models for Answer Sentence Selection</a>: AS2 タスクの先行研究である ([1] の第 3 著者が第 3 著者である)。</li> <li><a href="https://arxiv.org/abs/1810.04805">[1810.04805] BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding</a>: Transformer の事前学習手法であって、単語列 <span class="command">[CLS] 文章A [SEP] 文章B [SEP]</span> (位置・セグメント両エンベディングあり) を入力とした事前学習をするものである。ただし、このとき以下の 1., 2. の予測を同時に行うものとし、事前学習の目的関数は 1. の尤度の平均と 2. の尤度の平均の和とする (1 つの入力に予測値 1. は 1 つしか出てこないのに平均という意味がわかりにくいが私はバッチ内平均と思っている)。なお、この事前学習時に因果マスキングは行わない (=双方向へのアテンションを許容する)。</li> <ol> <li><a class="keyword" href="https://d.hatena.ne.jp/keyword/MLM">MLM</a> タスク: 単語列内の各文章の添え字から 15% を選び、各添え字に対応する出力ベクトルの線形変換のソフトマックス変換によってこの添え字の単語が何であったかを予測する。このとき、添え字のうち 8 割は元の単語を [MASK] <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C8%A1%BC%A5%AF">トーク</a>ンに置き換え、1 割は元の単語をランダムな単語に置き換え、1 割は置き換えをしない ([MASK] 率が大きい分には割合の多寡の影響は小さいらしい)。</li> <ul><li>[4] によるとこの 15% の選び方は、各単語列に対して予め決めた 10 パターンを 40 エポック中で 4 回ずつ使用している。これに対し [4] ではモデルにフィードする度に動的にサンプリングする方がよいという実験結果を示している。</li></ul> <li>NSP タスク: 文章Aと文章Bは 50% の確率で<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A1%BC%A5%D1%A5%B9">コーパス</a>内で連続する文章ペアとし、50% の確率でそうでない文章ペアとする。[CLS] に対応する出力ベクトルの線形変換のシグモイド変換 (たぶん) によって、連続する文章ペアでありそうかを予測する。</li> <ul><li>ただし [4] によるとここでいう文章は厳密な文章ではなく複数の文章のつながりでありうる。[4] では厳密な文章とした実験結果もあるが、かえって性能が低下しており、これは入力単語列が短くなりすぎて長距離依存性を学習できなくなったものと考察されている。さらに [4] では NSP 損失自体を削除しても性能は変わらないかやや向上すると示されており、[3] でも NSP 損失を削除していたのではないかとすら書かれている。そのため、今日では学習済 BERT といっても NSP タスクはなされていないことが多い。</li></ul> </ol> <li><a href="https://arxiv.org/abs/1907.11692">[1907.11692] RoBERTa: A Robustly Optimized BERT Pretraining Approach</a>: [3] を改良した Transformer の事前学習手法であって、[3] からの差分は <a class="keyword" href="https://d.hatena.ne.jp/keyword/MLM">MLM</a> タスクの動的サンプリング化、NSP タスクの削除、バッチサイズの拡大 (256 -> 2K) などがある。NSP タスク削除に伴い、入力単語列は <span class="command">[CLS] 文章 [SEP]</span> (セグメントの区別がないのでセグメントエンベディングなし) となる。</li> <li><a href="https://arxiv.org/abs/2003.10555">[2003.10555] ELECTRA: Pre-training Text Encoders as Discriminators Rather Than Generators</a>: Transformer の事前学習手法であって、GAN を取り入れており、小規模モデルでも高い性能を実現できるといわれるが大規模モデルでは RoBERTa 等への優位性がないといわれる (要出典)。具体的に、入力文章のマスク箇所にジェネレータが単語を埋めてディスクリミネータを欺こうとし、ディスクリミネータとしての Transformer が文章中の全単語に対し偽物か本物かを識別しようとする。ジェネレータとして使用するモデルは何でもよいが典型的には小さな Transformer であるらしい。</li> <li><a href="https://aclanthology.org/2022.emnlp-main.810/">Pre-training Transformer Models with Sentence-Level Objectives for Answer Sentence Selection - ACL Anthology</a>: <a class="keyword" href="https://d.hatena.ne.jp/keyword/SSP">SSP</a> タスクの先行研究である ([1] の著者全員がこの論文の著者である)。</li> <li><a href="https://www.amazon.science/publications/answer-sentence-selection-using-local-and-global-context-in-transformer-models">Answer sentence selection using local and global context in Transformer models - Amazon Science</a>: Contextual AS2 タスクの先行研究である ([1] の第 3 著者が第 2 著者である)。この論文が [1] のベースラインとされているが、この論文でいう Local Triplet がそのベースライン ([1] の継続事前学習しない版) であるはずと思う。</li> </ol></div><div style="font-size:92%;"><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>文脈依存の回答文選択 (Contextual AS2: Contextual Answer Sentence Selection) ……文脈依存といいますと、「小麦粉の生地にあんこを入れて、丸く焼いたお菓子の名前は?」のような質問に対して適した回答を選択するという問題設定でしょうか。文脈からユーザがどこ出身かを読み取って「<a class="keyword" href="https://d.hatena.ne.jp/keyword/%C2%E7%C8%BD%BE%C6%A4%AD">大判焼き</a>」「<a class="keyword" href="https://d.hatena.ne.jp/keyword/%BA%A3%C0%EE%BE%C6%A4%AD">今川焼き</a>」……などから適した回答を選択しなければ、ユーザとロボットの間に禍根を残しかねません。</p></div></div></div><div class="balloon5 org02"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229162343.png" width="387" height="387" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>「地方による」でいいじゃないか……論文 [1] の 2 枚目をみるに、単なる AS2 はとんできた質問 <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20q" alt=" q"/> に対して回答候補 <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5C%7Bs_1%2C%20%5Ccdots%20s_n%5C%7D" alt=" \{s_1, \cdots s_n\}"/> から最も適合するであろう回答を返すために、質問-回答ペア <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%28q%2C%20s_i%29" alt=" (q, s_i)"/> が噛み合っているかのモデルを学習しようとする問題設定だね。他方、Contextual AS2 は質問-回答-文脈トリプレット <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%28q%2C%20s_i%2C%20c_i%29" alt=" (q, s_i, c_i)"/> が噛み合っているかのモデルを学習しようとするみたいだ。</p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p style="margin-bottom: 0.75em">その形式に合わせるのでしたら、ユーザの出身地域を文脈として与えて、以下でしょうか。最初のトリプレットのみ適合度が 1 で、後の 2 つの適合度は 0 です。愛知県出身の私が「おーばんやき」と認識して育ちましたので、間違いありません。</p></p> <pre class="code" data-lang="" data-unlink>1 ('小麦粉の生地にあんこを入れて丸く焼いたお菓子は?', '大判焼きです。', '愛知県出身です。') 0 ('小麦粉の生地にあんこを入れて丸く焼いたお菓子は?', '今川焼きです。', '愛知県出身です。') 0 ('小麦粉の生地にあんこを入れて丸く焼いたお菓子は?', 'おやきです。', '愛知県出身です。')</pre><p></div></div></div><div class="balloon5 org02"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229162343.png" width="387" height="387" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p style="margin-bottom: 0.75em">形式的にはそのようなトリプレットでもいいはずなんだけど、論文 [1] を読んでいくと、おそらくここでいう<span style="color: #00796b">「文脈」</span>は<span style="color: #00796b">「質問への回答を明示的に含む文章」</span>である気がするね。</p><p style="margin-bottom: 0.75em">というのも、[1] で評価されているデー<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%BF%A5%BB%A5%C3%A5%C8">タセット</a>の1つは ASNQ といって研究 [2] で構築されたものなんだけど ( [2] と [1] は第 3 著者が同一人物だね)、何でも元々 <a href="https://github.com/google-research-datasets/natural-questions">NQ</a> というデー<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%BF%A5%BB%A5%C3%A5%C8">タセット</a>があって、これは[質問, <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A6%A5%A3%A5%AD%A5%DA%A5%C7%A5%A3%A5%A2">ウィキペディア</a>記事, <span style="color: #1464b3">正解段落<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B6%E8%B4%D6">区間</a></span>, <span style="color: #d32f2f">正解段落中の正解句<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B6%E8%B4%D6">区間</a></span>]の集合みたい (厳密にはそもそも正解段落がない場合があるし、正解句も 2 箇所以上ある場合もあるみたいだけど)。</p><pre class="code">('フランスで最も高い山は?',<br/> '<span style="color: #d32f2f"><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a></span><span style="color: #1464b3">は西ヨーロッパの最高峰である。標高4808mを誇る。</span>山名は仏語で「白い山」の意。…')</pre><p style="margin-bottom: 0.75em">NQ はたぶん、ウェブ検索において「対象ページからユーザの知りたい情報が記述されている段落を特定して」「さらにその中の直接回答部分を抽出 / ハイライトしたい」という目的が強く意識されたデー<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%BF%A5%BB%A5%C3%A5%C8">タセット</a>だと思う。ただ、ウェブを検索したユーザ相手にはそのようなインターフェースでも違和感はないけど、チャットインターフェースなどでは文章で回答するのが自然だし、余計な中間タスクを経由せずに「記事から正解の文章を選びたい」となると思う。NQ をその用途に寄せて加工したのが ASNQ で、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A6%A5%A3%A5%AD%A5%DA%A5%C7%A5%A3%A5%A2">ウィキペディア</a>記事から<span style="color: #673ab7">正解句を含む文章が</span>正しく特定できるかというタスクになっているみたいだね。それ以外の文章は全て負例として扱う。今回扱うトリプレットとして書くなら以下のようになると思う。</p><pre class="code">1 ('フランスで最も高い山は?',<br/> '<span style="color: #673ab7"><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>は西ヨーロッパの最高峰である。'</span>,<br/> '<span style="color: #673ab7"><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>は西ヨーロッパの最高峰である。</span>標高4808mを誇る。山名は仏語で「白い山」の意。…')<br/>0 ('フランスで最も高い山は?',<br/> '<span style="color: #673ab7">標高4808mを誇る。'</span>,<br/> '<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>は西ヨーロッパの最高峰である。<span style="color: #673ab7">標高4808mを誇る。</span>山名は仏語で「白い山」の意。…')<br/>0 ('フランスで最も高い山は?',<br/> '<span style="color: #673ab7">山名は仏語で「白い山」の意。'</span>,<br/> '<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>は西ヨーロッパの最高峰である。標高4808mを誇る。<span style="color: #673ab7">山名は仏語で「白い山」の意。</span>…')</pre></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p style="margin-bottom: 0.75em">記事中から<span style="color: #d32f2f">正解句</span>ではなく<span style="color: #673ab7">正解句を含む文章</span>を選び取ることを目的とする、ですか。であれば、先の私の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%C2%E7%C8%BD%BE%C6%A4%AD">大判焼き</a>の例は異なりますね。あれはモデル自体に知識を問うていますが、その<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>の例ですと、知識を含む文章は外部から与えられるのですね。さながら小中高生の国語のテストの文章読解です。</p><p>そしてそのためにデー<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%BF%A5%BB%A5%C3%A5%C8">タセット</a> NQ を加工したのですか。文章で返答したいなら「<span style="color: #d32f2f">正解句</span>です」と返せばよい気もしますが……いえ、しかし、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>が山の名前であるという知識がある人には「フランスの最高峰は?」に「<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>です」とだけいわれて「<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>山がフランスの最高峰だったか」と理解できますが、そうでなければ「なんで急にケーキの話をしたの」となってしまいかねないですね。その点、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A6%A5%A3%A5%AD%A5%DA%A5%C7%A5%A3%A5%A2">ウィキペディア</a>記事の冒頭であれば「A は B である」の形式をもちますから、文章を丸ごと返せば誤り検出符号のような役割を果たしそうです。さらに、その例の場合は<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>がフランスどころか西ヨーロッパの最高峰であると前提条件をゆるめられることも教えてくれますね。</p></div></div></div><div class="balloon5 org02"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229162343.png" width="387" height="387" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>もちろん質問への直接回答だけほしい場合もあるだろうから、どのような人がどのような目的で質問する目的かにもよるだろうけどね。専門家が使う場合はシンプルな回答でよいだろうし、誤解が生じることがクリティカルであれば文章ごと返した方がよいかもしれない。1 つの文章を返すだけでは不十分な場合もあるかもしれない。</p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>確かにそうですね。回答文が 1 文とは限らないということも見据えるのでしたら柔軟に対応できる手法にしておかなければ……あれ? そもそも今回はどのような手法を用いて回答文選択をするのでしたっけ。</p></div></div></div><div class="balloon5 org02"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229162343.png" width="387" height="387" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>事前学習手法 ELECTRA と RoBERTa で事前学習した Transformer <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A1%BC%A5%AD%A5%C6%A5%AF%A5%C1%A5%E3">アーキテクチャ</a>を<span style="color: #dc4d01"> Contextual AS2 タスク向けに継続事前学習 (追加的な事前学習) をした上で</span> fine-tuning したもので最適な回答に最も高いスコアを割り当てようとするみたいだね。Transformer への入力は <span class="command">[CLS] 質問 [SEP] 回答 [SEP] 文脈 [SEP]</span> (3つのセグメントの別があるのでセグメントエンベディングもあり) で、出力は [CLS] に対応する出力ベクトルを線形変換で 1 次元にしてシグモイド変換して「適合度」としていると思う (適合するか否かの 2 値分類でなくても用途に応じて 3 値分類以上もできると先行研究 [2] にあるけど)。それで、研究 [1] の主眼になっているのはその<span style="color: #dc4d01">継続事前学習方法</span>だね。</p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A8%A5%EC%A5%AF%A5%C8%A5%E9">エレクトラ</a>にロベルタ? どちらも響きが高級化粧品ブランドっぽいですね。デパートの1階に店を構えていても違和感がないのでは? さておき、それらは Transformer の事前学習手法であるのですね。<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B8%C0%B8%EC%A5%E2%A5%C7%A5%EB">言語モデル</a>の事前学習というとやはり、文章を注ぎ込んで次の単語を予測させるのですか? 私は Transformer 出現前後の、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%BA%C6%B5%A2">再帰</a><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%CB%A5%E5%A1%BC%A5%E9%A5%EB%A5%CD%A5%C3%A5%C8">ニューラルネット</a>による言語処理が盛んであったときそう習いましたよ。</p></div></div></div><div class="balloon5 org02"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229162343.png" width="387" height="387" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>それはもう 7 年近く前だろう……何歳の設定なんだ……。そのように次の単語を予測することを含む Transformer 事前学習手法も GPT-3 などがあるけど、ELECTRA と RoBERTa は違う。RoBERTa から説明すると、これは入力文章の単語 (原論文においては単語ではなくバイトペア符号化によるサブワードだが) をランダムにマスクしてその単語が何かを予測する事前学習をする (<a class="keyword" href="https://d.hatena.ne.jp/keyword/MLM">MLM</a>: Masked Language Model)。マスクする割合は先行研究の BERT と同じ 15% かな。ちなみにこのとき self-attention の向きは制限しない。まあ意識しなければ制限しないと思うけど、GPT-3 などでは右向きに制限するから一応。</p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>穴埋め問題を解くのですか。向きを制限しないというのは、まあ人間は文章を聞いた先から (見た先から) 取り込んでいきますが、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%CB%A5%E5%A1%BC%A5%E9%A5%EB%A5%CD%A5%C3%A5%C8">ニューラルネット</a>が同様にする必要はないですものね。むしろ、人間であっても文章を最後まで聞いてから「ああ横須賀って神奈川県のほうの横須賀だったのか」と左向きに単語への理解を更新し得ますし。</p></div></div></div><div class="balloon5 org02"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229162343.png" width="387" height="387" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>ほとんどの日本人は横須賀と聞いて真っ先に愛知県<a class="keyword" href="https://d.hatena.ne.jp/keyword/%C5%EC%B3%A4%BB%D4">東海市</a>の横須賀町を思い浮かべないんだよなあ……。さておき、右向きの GPT-3 や後続手法は文章を生成するタスクに向くともいわれているし、何がしたいかによってどちら向きの self-attention に注力するとよいとかあるんじゃないか。</p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>今回したいことは、さながら小中高生の国語のテストの文章読解でしたね。次の単語を編んでいく作文ではありません。といって、穴埋め問題でもありません。文章列を読んで「主人公が悲しいと思ったのはなぜですか」などという問いの答えとなる文章を選び取るような問題であるはずです。穴埋め問題ばかり勉強して解けるようになるものでしょうか。</p></div></div></div><div class="balloon5 org02"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229162343.png" width="387" height="387" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>もちろん文章読解問題を解けるように fine-tuning するんだけど、研究 [1] ではいきなり fine-tuning するのではなく追加的な事前学習を施すことを提案している。部長が指摘するように、「(RoBERTa などの) 標準的な事前学習手法では文章列の中での文章の役割を学ぶことができない」と導入にあるね。</p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>追加的な事前学習をしようというのはよい提案のように聞こえますね。やはり、文章読解ドリルを購入して学習するのでしょうか。</p></div></div></div><div class="balloon5 org02"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229162343.png" width="387" height="387" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p style="margin-bottom: 0.75em">いや、そう簡単に大量の文章読解問題は手に入らない。そもそも想定分野の文章読解問題が大量にあったとして、それを学習するのはもはや fine-tuning だね……。</p><p style="margin-bottom: 0.75em">そうではなく、ここでは以下の 1. を正例、2. をハードな負例、3. を負例とした 2 値分類タスクを解く (厳密には文脈の取り方が 1 段落目を取る他にもう 2 種類提案されている) (なおこのときセグメントエンベディングはしないらしい)。要は<span style="color: #00796b">「同じ段落かどうか」(<a class="keyword" href="https://d.hatena.ne.jp/keyword/SSP">SSP</a>: Sentences in Same Paragraph) </span>の判定タスクだね。これなら質問文がなくても<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A1%BC%A5%D1%A5%B9">コーパス</a>から自動的につくれるよね。</p>1. <span class="command">[CLS] 文章A [SEP] 文章Aと同段落の他の文章(列) [SEP] 文章Aが属する文書の1段落目 [SEP]</span><br /> 2. <span class="command">[CLS] 文章A [SEP] 文章Aと別段落の他の文章(列) [SEP] 文章Aが属する文書の1段落目 [SEP]</span><br /> 3. <span class="command">[CLS] 文章A [SEP] 文章Aと別文書の文章(列) [SEP] 文章Aが属する文書の1段落目 [SEP]</span><br /> <p style="margin: 0.75em 0"><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>の例でいうと以下かな。最初のトリプレットだけが正例だね。ちなみに、正例 1 つにつきハードな負例を 2 つまで生成して、さらに負例が 4 個になるように普通の負例も生成するらしい (Appendix A.1)。ハードな負例と普通の負例で損失の重みを変えるという記述はなかったな。あと、この <a class="keyword" href="https://d.hatena.ne.jp/keyword/SSP">SSP</a> タスク (同一段落予測タスク) と同時に <a class="keyword" href="https://d.hatena.ne.jp/keyword/MLM">MLM</a> タスク (穴埋めタスク) も解くことに注意してね。同一段落予測とすべての穴埋め予測の交差<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A8%A5%F3%A5%C8%A5%ED%A5%D4%A1%BC">エントロピー</a>の和を継続事前学習の目的関数とするよ。</p><pre class="code">1 ('<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>は西ヨーロッパの最高峰である。',<br/> '標高4808mを誇る。',<br/> '<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>は西ヨーロッパの最高峰である。標高4808mを誇る。')<br/>0 ('<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>は西ヨーロッパの最高峰である。',<br/> '山名は仏語で「白い山」の意。',<br/> '<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>は西ヨーロッパの最高峰である。標高4808mを誇る。')<br/>0 ('<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>は西ヨーロッパの最高峰である。',<br/> '<a class="keyword" href="https://d.hatena.ne.jp/keyword/%BA%A3%C0%EE%BE%C6%A4%AD">今川焼き</a>とは、小麦粉からなる生地に餡を入れ<a class="keyword" href="https://d.hatena.ne.jp/keyword/%BE%C6%C0%AE">焼成</a>した和菓子である。',<br/> '<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>は西ヨーロッパの最高峰である。標高4808mを誇る。')</pre></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>なるほど……? まあその<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%E2%A5%F3%A5%D6%A5%E9%A5%F3">モンブラン</a>の例ですと、文章Aが1段落目に属していますから、[CLS] 位置からの self-attention が「文脈の中に質問文があり、かつ、回答文がある」ときに強く反応するよう学習されることが期待できるでしょうか……? 文脈から文章を探すことに目が向いたという点は穴埋めタスクよりも Contextual AS2 タスクに近づいたといえるでしょうが……しかし、実際のユーザ質問は必ずしも回答文と同一の段落に登場する文に近くないのではないでしょうか。近い場合もあるとは思いますが……。</p></div></div></div><div class="balloon5 org02"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229162343.png" width="387" height="387" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p style="margin-bottom: 0.75em">論文 [1] ではその点に対する説明として、<a class="keyword" href="https://d.hatena.ne.jp/keyword/SSP">SSP</a> タスクによってモデルが<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A5%E9%A5%D5%A5%EC%A1%BC%A5%BA">パラフレーズ</a>をも学び取ることができると説明しているんだよね (これについてはいっているだけで裏付ける実験結果があるわけではないと思う) (<a class="keyword" href="https://d.hatena.ne.jp/keyword/SSP">SSP</a> タスクの先行研究 [6] をちらっとみてもたぶんない)。</p><p style="margin-bottom: 0em">何でも、仮に「ロヴァートが登場したテレビ番組は?」という質問がきたとして、記事中にそっくり同じ言葉で「ロヴァートはテレビ番組『サニーwithチャンス』に登場した」とあった場合は、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B8%C0%B8%EC%A5%E2%A5%C7%A5%EB">言語モデル</a>がこの文を選ぶのは容易い。他方、もし記事中の表現が少し違って「彼女はドラマ『サニーwithチャンス』で演じた」であった場合は、この文を選ぶのは難しくなるらしい。<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B8%C0%B8%EC%A5%E2%A5%C7%A5%EB">言語モデル</a>が「演じる」から「登場する」への含意を学んでいないから (ちなみに原論文では acted in と appeared in だけど勝手に日本語に置き換えた)。でも、<a class="keyword" href="https://d.hatena.ne.jp/keyword/SSP">SSP</a> タスクで事前学習すれば、同じ段落に登場する文同士の関連付けを通じて、「登場する」に「演じる」が関連していると学べるらしい。</p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>うーん、穴埋めタスクでも、「演じる」も「登場する」もどちらも「ドラマ」と関連がありそうなどということは学べそうですが、<a class="keyword" href="https://d.hatena.ne.jp/keyword/SSP">SSP</a> タスクであれば直接的に [CLS] 位置からの self-attention が「演じる」と「登場する」が共存したときに強く反応するような学習が促進されるのでしょうか……?</p></div></div></div><div class="balloon5 org02"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229162343.png" width="387" height="387" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p style="margin-bottom: 0.75em">まあでも Table 1 をみると、クラブのマークが付いた、おそらく継続事前学習しない版 Contextual AS2 でもある程度の性能が出ているから、穴埋めタスクだけでは全然だめということでもないと思うんだけどね。デー<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%BF%A5%BB%A5%C3%A5%C8">タセット</a> ASNQ や NewsAS2 では継続事前学習をしたことによる改善幅が幾分小さくみえるし。他方、WikiQA の Precision@1 の改善幅は大きくもみえるんだよね。これらのデー<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%BF%A5%BB%A5%C3%A5%C8">タセット</a>の違いから今回の継続事前学習の意味を考察できるかもしれないね。</p><p>ちなみに、Appendix E. にある、継続事前学習によって正解できるようになった例が以下らしい (ELECTRA の例) (<span style="color: #d32f2f">赤</span>がこれまで選んでいた回答で不正解、<span style="color: #00796b">緑</span>が新たに選ぶようになった回答で正解)。</p><p style="margin: 0.75em 0"> <u>Q. <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%EF%A1%BC%A5%EB%A5%C9%A5%B7%A5%EA%A1%BC%A5%BA">ワールドシリーズ</a>で優勝するために勝利しなければならない試合数はいくつですか。</u><ol> <li><span style="color: #d32f2f">7 試合が行われ、ロサンゼルスで行われた第 7 試合で<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%B9%A5%C8%A5%ED%A5%BA">アストロズ</a>が勝利しました。</span></li> <li>1985 年に、7 試合 4 勝先取方式に変更されました。</li> <li>それ以降、2011、2014、2016年の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%EF%A1%BC%A5%EB%A5%C9%A5%B7%A5%EA%A1%BC%A5%BA">ワールドシリーズ</a>はすべて第 7 試合まで行われました。</li> <li><span style="color: #00796b"><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%EF%A1%BC%A5%EB%A5%C9%A5%B7%A5%EA%A1%BC%A5%BA">ワールドシリーズ</a>の優勝決定戦は 7 試合 4 勝先取方式の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D7%A5%EC%A1%BC%A5%AA%A5%D5">プレーオフ</a>で決定され、優勝チームには<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B3%A5%DF%A5%C3%A5%B7%A5%E7%A5%CA%A1%BC">コミッショナー</a>ズトロフィーが授与されます。</span></li> <li>2017年11月1日、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%B9%A5%C8%A5%ED%A5%BA">アストロズ</a>は第 7 試合で<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C9%A5%B8%A5%E3%A1%BC%A5%B9">ドジャース</a>を制し、1962年の創設以来初めて<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%EF%A1%BC%A5%EB%A5%C9%A5%B7%A5%EA%A1%BC%A5%BA">ワールドシリーズ</a>を制覇しました。</li> </ol></p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>2. も優勝に必要な試合数を示していますが、優勝の条件として書いていないからアウトなのですか。その質問を受けて、4. の冒頭の The winner of the World Series championship is determined through ... との強い関連を検出しなければならないのですね。</p></div></div></div>ELECTRA の話を全くしていないが長いので終わり</div></p> </div> <footer class="entry-footer"> <div class="entry-tags-wrapper"> <div class="entry-tags"> </div> </div> <p class="entry-footer-section track-inview-by-gtm" data-gtm-track-json="{"area": "finish_reading"}"> <span class="author vcard"><span class="fn" data-load-nickname="1" data-user-name="cookie-box" >cookie-box</span></span> <span class="entry-footer-time"><a href="https://cookie-box.hatenablog.com/entry/2024/07/18/235843"><time data-relative datetime="2024-07-18T14:58:43Z" title="2024-07-18T14:58:43Z" class="updated">2024-07-18 23:58</time></a></span> <span class=" entry-footer-subscribe " data-test-blog-controlls-subscribe> <a href="https://blog.hatena.ne.jp/cookie-box/cookie-box.hatenablog.com/subscribe?utm_medium=button&utm_source=blogs_entry_footer&utm_campaign=subscribe_blog"> 読者になる </a> </span> </p> <div class="hatena-star-container" data-hatena-star-container data-hatena-star-url="https://cookie-box.hatenablog.com/entry/2024/07/18/235843" data-hatena-star-title="雑記: Transformer で記事から回答文を選択するための継続事前学習方法の話" data-hatena-star-variant="profile-icon" data-hatena-star-profile-url-template="https://blog.hatena.ne.jp/{username}/" ></div> <div class="social-buttons"> <div class="social-button-item"> <a href="https://b.hatena.ne.jp/entry/s/cookie-box.hatenablog.com/entry/2024/07/18/235843" class="hatena-bookmark-button" data-hatena-bookmark-url="https://cookie-box.hatenablog.com/entry/2024/07/18/235843" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="この記事をはてなブックマークに追加"><img src="https://b.st-hatena.com/images/entry-button/button-only.gif" alt="この記事をはてなブックマークに追加" width="20" height="20" style="border: none;" /></a> </div> <div class="social-button-item"> <div class="fb-share-button" data-layout="box_count" data-href="https://cookie-box.hatenablog.com/entry/2024/07/18/235843"></div> </div> <div class="social-button-item"> <a class="entry-share-button entry-share-button-twitter test-share-button-twitter" href="https://x.com/intent/tweet?text=%E9%9B%91%E8%A8%98%EF%BC%9A+Transformer+%E3%81%A7%E8%A8%98%E4%BA%8B%E3%81%8B%E3%82%89%E5%9B%9E%E7%AD%94%E6%96%87%E3%82%92%E9%81%B8%E6%8A%9E%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE%E7%B6%99%E7%B6%9A%E4%BA%8B%E5%89%8D%E5%AD%A6%E7%BF%92%E6%96%B9%E6%B3%95%E3%81%AE%E8%A9%B1+-+%E3%82%AF%E3%83%83%E3%82%AD%E3%83%BC%E3%81%AE%E6%97%A5%E8%A8%98&url=https%3A%2F%2Fcookie-box.hatenablog.com%2Fentry%2F2024%2F07%2F18%2F235843" title="X(Twitter)で投稿する" ></a> </div> </div> <div class="google-afc-image test-google-rectangle-ads"> <div id="google_afc_user_container_1" class="google-afc-user-container google_afc_blocklink2_5 google_afc_boder" data-test-unit="/4374287/blog_user_2nd"></div> <a href="http://blog.hatena.ne.jp/guide/pro" class="open-pro-modal" data-guide-pro-modal-ad-url="https://hatena.blog/guide/pro/modal/ad">広告を非表示にする</a> </div> <div class="customized-footer"> </div> <div class="comment-box js-comment-box"> <ul class="comment js-comment"> <li class="read-more-comments" style="display: none;"><a>もっと読む</a></li> </ul> <a class="leave-comment-title js-leave-comment-title">コメントを書く</a> </div> </footer> </div> </article> <article class="entry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-2800 words-200 mode-hatena entry-odd" id="entry-6801883189084381760" data-keyword-campaign="" data-uuid="6801883189084381760" data-publication-type="entry"> <div class="entry-inner"> <header class="entry-header"> <div class="date entry-date first"> <a href="https://cookie-box.hatenablog.com/archive/2024/02/23" rel="nofollow"> <time datetime="2024-02-23T01:01:10Z" title="2024-02-23T01:01:10Z"> <span class="date-year">2024</span><span class="hyphen">-</span><span class="date-month">02</span><span class="hyphen">-</span><span class="date-day">23</span> </time> </a> </div> <h1 class="entry-title"> <a href="https://cookie-box.hatenablog.com/entry/2024/02/23/100110" class="entry-title-link bookmark">雑記:1つの一様乱数から2つの独立な一様乱数ができる</a> </h1> <div class="entry-categories categories"> <a href="https://cookie-box.hatenablog.com/archive/category/%E9%9B%91%E8%A8%98" class="entry-category-link category-雑記">雑記</a> </div> </header> <div class="entry-content hatenablog-entry"> <p><div style="font-size:100%;margin:0.3em 0;color: #4682b4;"><span style="font-family: 'Lato', sans-serif;font-weight:bold;">2024-03-11</span> この記事で示そうとしたことをまとめた PDF が以下です。<br/><a href="https://drive.google.com/file/d/1Gptoa2VT0o2JHbF2iWKU4nvet-J8sXgE/view?usp=sharing">20240309_asympstat.pdf - Google ドライブ</a></div><center><iframe src="https://drive.google.com/file/d/1Gptoa2VT0o2JHbF2iWKU4nvet-J8sXgE/preview" width="640" height="480"></iframe></center><br /> <hr style="border-top: 1px solid darkgray; margin: 0.5em 0; width: 100%;"/><br /> お気付きの点がありましたらご指摘いただけますと幸いです。<div class="ref-box" style="padding-left:0.5em;"><ol class="ref"> <li><a href="https://www.amazon.co.jp/Asymptotic-Statistics-Statistical-Probabilistic-Mathematics/dp/0521784506">https://www.amazon.co.jp/Asymptotic-Statistics-Statistical-Probabilistic-Mathematics/dp/0521784506</a></li> </ol></div><div style="font-size:92%;"><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>[1] の 99 ページに以下のようにありますね。<img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> は<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B6%E8%B4%D6">区間</a> <img src="https://chart.apis.google.com/chart?cht=tx&chl=%5B0%2C%201%5D" alt="[0, 1]"/> の値を取る一様乱数です。<div style="background: #fcfcfc;padding: 0.5em 1em; margin: 0.5em 0">It is possible to produce two independent uniform <img src="https://chart.apis.google.com/chart?cht=tx&chl=%5B0%2C%201%5D" alt="[0, 1]"/> variables <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1" alt="U_1"/> and <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_2" alt="U_2"/> from one given <img src="https://chart.apis.google.com/chart?cht=tx&chl=%5B0%2C%201%5D" alt="[0, 1]"/> variable <img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/>. (For instance, construct <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1" alt="U_1"/> and <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_2" alt="U_2"/> from the even and odd numbered digits in the decimal expansion of <img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/>.)</div>つまり、1つの一様乱数 <img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> から2つの独立な一様乱数 <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1%2C%20U_2" alt="U_1, U_2"/> がつくれると。つくり方の一例としては、 <img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> の小数点以下の奇数番目の数をとって詰めて <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1" alt="U_1"/> とし、同様に偶数番目をとって <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_2" alt="U_2"/> にするんですね。例えば以下でしょうか。<ul style="margin: 0.5em 0"><li><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20U%20%3D%200.12345678%20%5Ccdots" alt=" U = 0.12345678 \cdots"/> だったら、 <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1%2C%20U_2" alt="U_1, U_2"/> を以下のようにとる。</li> <ul><li><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20U_1%20%3D%200.1357%20%5Ccdots" alt=" U_1 = 0.1357 \cdots"/></li> <li><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20U_2%20%3D%200.2468%20%5Ccdots" alt=" U_2 = 0.2468 \cdots"/></li> </ul></ul>この <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1%2C%20U_2" alt="U_1, U_2"/> も一様乱数であり、互いに独立というのは直感的にはそうでしょう。元の <img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> が一様乱数である以上、「奇数番目はこの並びになりやすい」などということはないでしょうし、「奇数番目がこの並びなら偶数番目はこの並びになりやすい」ということもないでしょう。しかし、本当にそうなるのか、[1] には何も説明がありませんね。ここは私が証明してみましょう。</p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>いま示したいことは以下ですね。<div class="prop"><div style="font-weight:bold; margin-bottom: 0.5em"><a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%E4%C2%EA">補題</a>〈 1つの一様乱数から2つの独立な一様乱数ができる 〉</div> <img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> を <img src="https://chart.apis.google.com/chart?cht=tx&chl=%5B0%2C%201%5D" alt="[0, 1]"/> 上の一様分布にしたがう確率変数とする。いま、<img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> の小数点以下の奇数番目の数をつなげて詰めて <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1" alt="U_1"/> を、同様に偶数番目の数をつなげて詰めて <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_2" alt="U_2"/> をつくる。このとき、<img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1" alt="U_1"/> も <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_2" alt="U_2"/> も一様分布にしたがう確率変数であり、かつ、互いに独立である。</div>……まずは <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1%2C%20U_2" alt="U_1, U_2"/> の分布を知りたいですよね。<strong style="color: #fe2c54">例えば、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%5Cmathrm%7BP%7D%28U_1%20%3C%200.5%29" alt="\mathrm{P}(U_1 < 0.5)"/> がいくらになるのか考えてみましょう。</strong><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20U_1%20%3C%200.5" alt=" U_1 < 0.5"/> という事象を <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20U" alt=" U"/> についての事象に翻訳しないとわかりませんね。<img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> がどうあるべきかを知りたいので、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20U_1%20%3C%200.5" alt=" U_1 < 0.5"/> をどの桁の数字がどうあるべきかでいい直すと「<img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1%20%5C%2C" alt="U_1 \,"/>の小数第1位が5未満」ですね。逆に、これだけです。<img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1" alt="U_1"/> の他の桁への要請はありません。であれば……<img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1" alt="U_1"/> に小数第1位を供給するのは <img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> の小数第1位ですから、<img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> への要請も「<img src="https://chart.apis.google.com/chart?cht=tx&chl=U%20%5C%2C" alt="U \,"/>の小数第1位が5未満」だけです。そうなると<center style="margin: 0.7em 0"><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Cmathrm%7BP%7D%28U_1%20%3C%200.5%29%20%3D%20%5Cmathrm%7BP%7D%28%20U_1%20%5C%2C" alt=" \mathrm{P}(U_1 < 0.5) = \mathrm{P}( U_1 \,"/>の小数第1位が5未満<img src="https://chart.apis.google.com/chart?cht=tx&chl=%29%20%3D%20%5Cmathrm%7BP%7D%28%20U%20%5C%2C" alt=") = \mathrm{P}( U \,"/>の小数第1位が5未満<img src="https://chart.apis.google.com/chart?cht=tx&chl=%29%20%3D%20%5Cmathrm%7BP%7D%28U%20%3C%200.5%29%20%3D%200.5" alt=") = \mathrm{P}(U < 0.5) = 0.5"/></center>一様分布の確率になりますね。というか、同じ論理で以下までいえますね。<div style="border: 2px dotted #4d4d4d; margin: 0.7em 0"><center style="margin: 0.7em 0"><img src="https://chart.apis.google.com/chart?cht=tx&chl=%200%20%3C%20a%20%3C%201" alt=" 0 < a < 1"/> である <img src="https://chart.apis.google.com/chart?cht=tx&chl=a" alt="a"/> の小数点以下が1桁のとき、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Cmathrm%7BP%7D%28U_1%20%3C%20a%29%20%3D%20%20%5Cmathrm%7BP%7D%28U%20%3C%20a%29%20%3D%20a" alt=" \mathrm{P}(U_1 < a) = \mathrm{P}(U < a) = a"/></center></div></p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>では、<strong style="color: #fe2c54">小数点以下が2桁のとき</strong>はどうなるでしょうか。<img src="https://chart.apis.google.com/chart?cht=tx&chl=%5Cmathrm%7BP%7D%28U_1%20%3C%200.53%29" alt="\mathrm{P}(U_1 < 0.53)"/> を考えてみましょう。 さっきと同様に、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20U_1%20%3C%200.53" alt=" U_1 < 0.53"/> をどの桁の数字がどうあるべきかでいい直してみましょう。<p style="margin: 0.7em 0"><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Cquad%20%5Cmathrm%7BP%7D%28U_1%20%3C%200.53%29%20%3D%20%5Cmathrm%7BP%7D%28%20U_1%20%5C%2C" alt=" \quad \mathrm{P}(U_1 < 0.53) = \mathrm{P}( U_1 \,"/>の小数第1位が5未満、または、小数第1位が5かつ小数第2位が3未満<img src="https://chart.apis.google.com/chart?cht=tx&chl=%29" alt=")"/><br /> <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Cquad%20%20%5Cqquad%20%5Cqquad%20%5Cqquad%20%3D%20%5Cmathrm%7BP%7D%28%20U%20%5C%2C" alt=" \quad \qquad \qquad \qquad = \mathrm{P}( U \,"/>の小数第1位が5未満、または、小数第1位が5かつ小数第3位が3未満<img src="https://chart.apis.google.com/chart?cht=tx&chl=%29" alt=")"/><br /> <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Cquad%20%20%5Cqquad%20%5Cqquad%20%5Cqquad%20%3D%20%5Cmathrm%7BP%7D%28%20U%20%5C%2C" alt=" \quad \qquad \qquad \qquad = \mathrm{P}( U \,"/>の小数第1位が5未満<img src="https://chart.apis.google.com/chart?cht=tx&chl=%29%20%5C%2C%20%2B%20%5C%2C%20%5Cmathrm%7BP%7D%28%20U%20%5C%2C%20" alt=") \, + \, \mathrm{P}( U \, "/>の小数第1位が5かつ小数第3位が3未満<img src="https://chart.apis.google.com/chart?cht=tx&chl=%29%20%5Cquad%20%5Ctext%7B%E2%98%85%7D" alt=") \quad \text{★}"/><br /> <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Cbegin%7Bsplit%7D%20%5Cquad%20%5Cqquad%20%5Cqquad%20%5Cquad%20%5C%3B%20%5C%2C%20%5C%2C%20%26%3D%20%5Cmathrm%7BP%7D%28U%20%3C%200.5%29%20%5C%5C%20%26%20%5Cquad%20%2B%20%5Cmathrm%7BP%7D%280.500%20%5Cleqq%20U%20%3C%200.503%29%20%2B%20%5Cmathrm%7BP%7D%280.510%20%5Cleqq%20U%20%3C%200.513%29%20%5C%5C%20%26%20%5Cquad%20%2B%20%5Cmathrm%7BP%7D%280.520%20%5Cleqq%20U%20%3C%200.523%29%20%2B%20%5Cmathrm%7BP%7D%280.530%20%5Cleqq%20U%20%3C%200.533%29%20%5C%5C%20%26%20%5Cquad%20%2B%20%5Cmathrm%7BP%7D%280.540%20%5Cleqq%20U%20%3C%200.543%29%20%2B%20%5Cmathrm%7BP%7D%280.550%20%5Cleqq%20U%20%3C%200.553%29%20%5C%5C%20%26%20%5Cquad%20%2B%20%5Cmathrm%7BP%7D%280.560%20%5Cleqq%20U%20%3C%200.563%29%20%2B%20%5Cmathrm%7BP%7D%280.570%20%5Cleqq%20U%20%3C%200.573%29%20%5C%5C%20%26%20%5Cquad%20%2B%20%5Cmathrm%7BP%7D%280.580%20%5Cleqq%20U%20%3C%200.583%29%20%2B%20%5Cmathrm%7BP%7D%280.590%20%5Cleqq%20U%20%3C%200.593%29%20%20%5C%5C%20%26%3D%200.5%20%2B%2010%20%5Ctimes%200.003%20%20%5C%5C%20%26%3D%200.53%20%5Cend%7Bsplit%7D" alt=" \begin{split} \quad \qquad \qquad \quad \; \, \, &= \mathrm{P}(U < 0.5) \\ & \quad + \mathrm{P}(0.500 \leqq U < 0.503) + \mathrm{P}(0.510 \leqq U < 0.513) \\ & \quad + \mathrm{P}(0.520 \leqq U < 0.523) + \mathrm{P}(0.530 \leqq U < 0.533) \\ & \quad + \mathrm{P}(0.540 \leqq U < 0.543) + \mathrm{P}(0.550 \leqq U < 0.553) \\ & \quad + \mathrm{P}(0.560 \leqq U < 0.563) + \mathrm{P}(0.570 \leqq U < 0.573) \\ & \quad + \mathrm{P}(0.580 \leqq U < 0.583) + \mathrm{P}(0.590 \leqq U < 0.593) \\ &= 0.5 + 10 \times 0.003 \\ &= 0.53 \end{split}"/></p>やはり一様分布の確率になりました! 小数点以下が2桁になると、必然的にどの桁がどうあるべきかへの要請が「A または B」になりますね。そして、この「A または B」を <img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> についての事象に翻訳すると排反事象ですから確率の和となり (<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Ctext%7B%E2%98%85%7D" alt=" \text{★}"/>)、さらにこの第 2 項は <img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> 上の 10 個の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B6%E8%B4%D6">区間</a>に分裂しますね。なぜなら、「小数第1位が5かつ小数第3位が3未満」とは「小数第1位が5かつ<strong style="color: #fe2c54">小数第2位が0</strong>かつ小数第3位が3未満、または、小数第1位が5かつ<strong style="color: #fe2c54">小数第2位が1</strong>かつ小数第3位が3未満、または、……」であるからです。</p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>こうなると、小数点以下の桁数が3のときにも拡張できそうですね。つまり、以下です。<p style="margin: 0.7em 0"><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Cbegin%7Bsplit%7D%20%5Cquad%20%5Cmathrm%7BP%7D%28U_1%20%3C%200.534%29%20%26%3D%20%5Cmathrm%7BP%7D%28U%20%3C%200.5%29%20%5C%5C%20%26%20%5Cquad%20%2B%2010%20%5Ctimes%20%5Cmathrm%7BP%7D%280.500%20%5Cleqq%20U%20%3C%200.503%29%20%5Cquad%20%5Ctext%7B%E2%98%85%7D%20%5C%5C%20%26%20%5Cquad%20%2B%2010%5E2%20%5Ctimes%20%5Cmathrm%7BP%7D%280.50300%20%5Cleqq%20U%20%3C%200.50304%29%20%20%5Cquad%20%5Ctext%7B%E2%98%85%E2%98%85%7D%20%5C%5C%20%26%3D%200.5%20%2B%2010%20%5Ctimes%200.003%20%2B%2010%5E2%20%5Ctimes%200.00004%20%20%5C%5C%20%26%3D%200.534%20%5Cend%7Bsplit%7D" alt=" \begin{split} \quad \mathrm{P}(U_1 < 0.534) &= \mathrm{P}(U < 0.5) \\ & \quad + 10 \times \mathrm{P}(0.500 \leqq U < 0.503) \quad \text{★} \\ & \quad + 10^2 \times \mathrm{P}(0.50300 \leqq U < 0.50304) \quad \text{★★} \\ &= 0.5 + 10 \times 0.003 + 10^2 \times 0.00004 \\ &= 0.534 \end{split}"/></p><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Ctext%7B%E2%98%85%7D" alt=" \text{★}"/> では小数第2位が本当は10通りあるので係数 <img src="https://chart.apis.google.com/chart?cht=tx&chl=10" alt="10"/> が出てきて、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Ctext%7B%E2%98%85%E2%98%85%7D" alt=" \text{★★}"/> では小数第2位も小数第4位も10通りあるので係数 <img src="https://chart.apis.google.com/chart?cht=tx&chl=10%5E2" alt="10^2"/> が出てくるというわけです。<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B6%E8%B4%D6">区間</a>幅が同じなら確率が同じなので便宜<a class="keyword" href="https://d.hatena.ne.jp/keyword/%BE%E5%BE%AE">上小</a>数第2位や小数第4位が <img src="https://chart.apis.google.com/chart?cht=tx&chl=0" alt="0"/> のときの<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B6%E8%B4%D6">区間</a>を代表に書いてしまっていますが……。</p><p style="margin-top: 0.5em;">これはさらに一般化できそうですね。いま、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%200%20%3C%20a%20%3C%201" alt=" 0 < a < 1"/> である <img src="https://chart.apis.google.com/chart?cht=tx&chl=a" alt="a"/> の小数第 <img src="https://chart.apis.google.com/chart?cht=tx&chl=k" alt="k"/> 位の数を <img src="https://chart.apis.google.com/chart?cht=tx&chl=a_k" alt="a_k"/> とします。また便宜上 <img src="https://chart.apis.google.com/chart?cht=tx&chl=a_0%3D0" alt="a_0=0"/> とします。そうすると、<img src="https://chart.apis.google.com/chart?cht=tx&chl=a" alt="a"/> の小数点以下の桁数が有限の <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20n" alt=" n"/> ならば以下になります。<p style="margin: 0.7em 0"><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Cbegin%7Bsplit%7D%20%5Cquad%20%5Cdisplaystyle%20%5Cmathrm%7BP%7D%28U_1%20%3C%20a%29%20%26%3D%5Cmathrm%7BP%7D%20%5Cleft%28%20U_1%20%3C%20%5Csum_%7Bk%3D1%7D%5En%2010%5E%7B-k%7D%20a_k%20%5Cright%29%20%5C%5C%20%26%3D%20%5Csum_%7Bk%3D1%7D%5En%2010%5E%7Bk%20-%201%7D%20%5Cmathrm%7BP%7D%20%5Cleft%28%5Csum_%7Bk%27%3D0%7D%5E%7Bk-1%7D%2010%5E%7B-2k%27%2B1%7D%20a_%7Bk%27%7D%20%5Cleqq%20U%20%3C%20%5Csum_%7Bk%27%3D0%7D%5E%7Bk%7D%2010%5E%7B-2k%27%2B1%7D%20a_%7Bk%27%7D%20%5Cright%29%20%20%5Cquad%20%5Ctext%7B%E2%98%85%E2%98%85%E2%98%85%7D%20%5C%5C%20%26%3D%20%5Csum_%7Bk%3D1%7D%5En%2010%5E%7Bk%20-%201%7D%2010%5E%7B-2k%2B1%7D%20a_k%20%5C%5C%20%26%3D%20%5Csum_%7Bk%3D1%7D%5En%2010%5E%7B-k%7D%20a_k%20%5C%5C%20%26%3D%20a%20%5Cend%7Bsplit%7D" alt=" \begin{split} \quad \displaystyle \mathrm{P}(U_1 < a) &=\mathrm{P} \left( U_1 < \sum_{k=1}^n 10^{-k} a_k \right) \\ &= \sum_{k=1}^n 10^{k - 1} \mathrm{P} \left(\sum_{k'=0}^{k-1} 10^{-2k'+1} a_{k'} \leqq U < \sum_{k'=0}^{k} 10^{-2k'+1} a_{k'} \right) \quad \text{★★★} \\ &= \sum_{k=1}^n 10^{k - 1} 10^{-2k+1} a_k \\ &= \sum_{k=1}^n 10^{-k} a_k \\ &= a \end{split}"/></p>さらに、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Ctext%7B%E2%98%85%E2%98%85%E2%98%85%7D" alt=" \text{★★★}"/> にあらわれる <img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> 上の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B6%E8%B4%D6">区間</a>たちは本当は互いに共通部分をもちません。であれば、一様測度の可算加法性より、「互いに共通部分がない無数の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B6%E8%B4%D6">区間</a>の和の確率」は「各<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B6%E8%B4%D6">区間</a>の確率の和の極限」に等しいので、<img src="https://chart.apis.google.com/chart?cht=tx&chl=a" alt="a"/> の小数点以下の桁数が無限であっても以下が成り立ちます。<strong style="color: #fe2c54">よって <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1" alt="U_1"/> は一様乱数です。</strong><p style="margin: 0.7em 0"><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Cquad%20%5Cdisplaystyle%20%5Cmathrm%7BP%7D%28U_1%20%3C%20a%29%20%3D%5Cmathrm%7BP%7D%20%5Cleft%28%20U_1%20%3C%20%5Clim_%7Bn%20%5Cto%20%5Cinfty%7D%20%5Csum_%7Bk%3D1%7D%5En%2010%5E%7B-k%7D%20a_k%20%5Cright%29%20%3D%20%5Clim_%7Bn%20%5Cto%20%5Cinfty%7D%20%5Csum_%7Bk%3D1%7D%5En%2010%5E%7B-k%7D%20a_k%20%3D%20a" alt=" \quad \displaystyle \mathrm{P}(U_1 < a) =\mathrm{P} \left( U_1 < \lim_{n \to \infty} \sum_{k=1}^n 10^{-k} a_k \right) = \lim_{n \to \infty} \sum_{k=1}^n 10^{-k} a_k = a"/></p></p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>そして <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_2" alt="U_2"/> も一様乱数になりますね。<img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1" alt="U_1"/> とは <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Ctext%7B%E2%98%85%E2%98%85%E2%98%85%7D" alt=" \text{★★★}"/> の部分がやや異なりますが、一様分布にしたがうことが確認できます。<p style="margin: 0.7em 0"><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Cbegin%7Bsplit%7D%20%5Cquad%20%5Cdisplaystyle%20%5Cmathrm%7BP%7D%28U_2%20%3C%20a%29%20%26%3D%5Cmathrm%7BP%7D%20%5Cleft%28%20U_2%20%3C%20%5Csum_%7Bk%3D1%7D%5En%2010%5E%7B-k%7D%20a_k%20%5Cright%29%20%5C%5C%20%26%3D%20%5Csum_%7Bk%3D1%7D%5En%2010%5E%7Bk%7D%20%5Cmathrm%7BP%7D%20%5Cleft%28%5Csum_%7Bk%27%3D0%7D%5E%7Bk-1%7D%2010%5E%7B-2k%27%7D%20a_%7Bk%27%7D%20%5Cleqq%20U%20%3C%20%5Csum_%7Bk%27%3D0%7D%5E%7Bk%7D%2010%5E%7B-2k%27%7D%20a_%7Bk%27%7D%20%5Cright%29%20%20%5Cquad%20%5Ctext%7B%E2%98%85%E2%98%85%E2%98%85%27%7D%20%5C%5C%20%26%3D%20%5Csum_%7Bk%3D1%7D%5En%2010%5E%7Bk%7D%2010%5E%7B-2k%7D%20a_k%20%5C%5C%20%26%3D%20%5Csum_%7Bk%3D1%7D%5En%2010%5E%7B-k%7D%20a_k%20%5C%5C%20%26%3D%20a%20%5Cend%7Bsplit%7D" alt=" \begin{split} \quad \displaystyle \mathrm{P}(U_2 < a) &=\mathrm{P} \left( U_2 < \sum_{k=1}^n 10^{-k} a_k \right) \\ &= \sum_{k=1}^n 10^{k} \mathrm{P} \left(\sum_{k'=0}^{k-1} 10^{-2k'} a_{k'} \leqq U < \sum_{k'=0}^{k} 10^{-2k'} a_{k'} \right) \quad \text{★★★'} \\ &= \sum_{k=1}^n 10^{k} 10^{-2k} a_k \\ &= \sum_{k=1}^n 10^{-k} a_k \\ &= a \end{split}"/></p></p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p><img src="https://chart.apis.google.com/chart?cht=tx&chl=U_1" alt="U_1"/> も <img src="https://chart.apis.google.com/chart?cht=tx&chl=U_2" alt="U_2"/> も一様乱数であることは確認できたので、これらが互いに独立であることを示しましょう。つまり、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%200%20%3C%20a%2C%20b%20%3C%201" alt=" 0 < a, b < 1"/> であるどんな <img src="https://chart.apis.google.com/chart?cht=tx&chl=a%2C%20b" alt="a, b"/> についても、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%5Cmathrm%7BP%7D%28U_1%20%3C%20a%2C%20U_2%20%3C%20b%29%20%3D%5Cmathrm%7BP%7D%28U_1%20%3C%20a%29%20%5Cmathrm%7BP%7D%28U_2%20%3C%20b%29%20%3Dab" alt="\mathrm{P}(U_1 < a, U_2 < b) =\mathrm{P}(U_1 < a) \mathrm{P}(U_2 < b) =ab"/> であることを示しましょう。</p><p style="margin-top: 0.5em;">しかし、どうすればいいのやら。具体的な例から考えてみますか。<img src="https://chart.apis.google.com/chart?cht=tx&chl=%5Cmathrm%7BP%7D%28U_1%20%3C%200.34%2C%20%5C%2C%20U_2%20%3C%200.56%29" alt="\mathrm{P}(U_1 < 0.34, \, U_2 < 0.56)"/> を考えると、<img src="https://chart.apis.google.com/chart?cht=tx&chl=a" alt="a"/> も <img src="https://chart.apis.google.com/chart?cht=tx&chl=b" alt="b"/> も小数点以下が2桁なので、どちらも <img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> のどの桁がどうあるべきかに「A または B」というタイプの要請をしてきます。なので、<img src="https://chart.apis.google.com/chart?cht=tx&chl=U" alt="U"/> への要請は 4 つに分かれます。それでこの場合は結局、独立な 2 つの一様分布の同時分布になります。<div style="font-size: 92%; margin-top:1em"></p> <pre> P(U_1 < 0.34, U_2 < 0.56) = P(U_1 < 0.3, U_2 < 0.5) + P(U_1 < 0.3, 0.5 ≦ U_2 < 0.56) + P(0.3 ≦ U_1 < 0.34, U_2 < 0.5) + P(0.3 ≦ U_1 < 0.34, 0.5 ≦ U_2 < 0.56) = P(U の 小数第1位が3未満 かつ 小数第2位が5未満) + P(U の 小数第1が3未満 かつ 小数第2位が5 かつ 小数第4位が6未満) + P(U の 小数第1位が3 かつ 小数第2位が5未満 かつ 小数第3位が4未満) + P(U の 小数第1位が3 かつ 小数第2位が5 かつ 小数第3位が4未満 かつ 小数第4位が6未満) = P(0.00 ≦ U < 0.05) + P(0.10 ≦ U < 0.15) + P(0.20 ≦ U < 0.25) + 10 * ( P(0.0500 ≦ U < 0.0506) + P(0.1500 ≦ U < 0.1506) + P(0.2500 ≦ U < 0.2506) ) + P(0.300 ≦ U < 0.304) + P(0.310 ≦ U < 0.314) + P(0.320 ≦ U < 0.324) + P(0.330 ≦ U < 0.334) + P(0.340 ≦ U < 0.344) + P(0.3500 ≦ U < 0.3506) + P(0.3510 ≦ U < 0.3516) + P(0.3520 ≦ U < 0.3526) + P(0.3530 ≦ U < 0.3536) = 3 * 0.05 + 10 * 3 * 0.0006 + 5 * 0.004 + 4 * 0.0006 = 0.3 * 0.5 + 0.3 * 0.06 + 0.5 * 0.04 + 0.04 * 0.06 = 0.3 * 0.56 + 0.04 * 0.56 = 0.34 * 0.56 </pre><p></div></p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>ではこれを任意の桁数に一般化して……えっと……あれ……一般の場合も上の要領で導出しようとすると煩雑になりそうですね……。</p></div></div></div><div class="balloon5 org02"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229162343.png" width="387" height="387" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>こうしたら?<div style="border: 2px dotted #4d4d4d; margin: 0.5em 0; padding: 0.5em 1.0em;"><img src="https://chart.apis.google.com/chart?cht=tx&chl=0%20%5Cleqq%20a%2C%20b%20%5Cleqq%201" alt="0 \leqq a, b \leqq 1"/> を小数点以下の桁数が有限である小数とする。このとき、小数点以下の桁数が大きい方の桁数を <img src="https://chart.apis.google.com/chart?cht=tx&chl=N" alt="N"/> として <img src="https://chart.apis.google.com/chart?cht=tx&chl=d%20%3D%2010%5E%7B-N%7D" alt="d = 10^{-N}"/> とする。また、2つの引数の小数以下を交互につなぐ関数 <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20f%28x%2C%20y%29" alt=" f(x, y)"/> を定義する。例えば、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20f%280.1234%2C%200.56%29%20%3D%200.1526304" alt=" f(0.1234, 0.56) = 0.1526304"/> である。<br /> このとき、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Cmathrm%7BP%7D%28U_1%20%3C%20a%2C%20%5C%2C%20U_2%20%3C%20b%29" alt=" \mathrm{P}(U_1 < a, \, U_2 < b)"/> は以下となる。<br /> <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Cbegin%7Bsplit%7D%20%5Cmathrm%7BP%7D%28U_1%20%3C%20a%2C%20%5C%2C%20U_2%20%3C%20b%29%20%26%3D%20%5Cmathrm%7BP%7D%20%5Cleft%28%20%20%5Cbigcup_%7Bn%3D0%7D%5E%7Ba%2Fd-1%7D%20%5Cbigcup_%7Bm%3D0%7D%5E%7Bb%2Fd-1%7D%20%28%20nd%20%5Cleqq%20U_1%20%3C%20nd%20%2B%20d%2C%20%5C%2C%20md%20%5Cleqq%20U_2%20%3C%20md%20%2B%20d%20%29%20%5Cright%29%20%5C%5C%20%26%3D%20%5Cmathrm%7BP%7D%20%5Cleft%28%20%20%5Cbigcup_%7Bn%3D0%7D%5E%7Ba%2Fd-1%7D%20%5Cbigcup_%7Bm%3D0%7D%5E%7Bb%2Fd-1%7D%20%5Cbigl%28%20f%28nd%2C%20md%29%20%5Cleqq%20U%20%3C%20f%28nd%2C%20md%29%20%2B%20d%5E2%20%5Cbigr%29%20%5Cright%29%20%5C%5C%20%26%3D%20%5Csum_%7Bn%3D0%7D%5E%7Ba%2Fd-1%7D%20%5Csum_%7Bm%3D0%7D%5E%7Bb%2Fd-1%7D%20%5Cmathrm%7BP%7D%20%5Cbigl%28%20f%28nd%2C%20md%29%20%5Cleqq%20U%20%3C%20f%28nd%2C%20md%29%20%2B%20d%5E2%20%5Cbigr%29%20%5C%5C%20%26%3D%20%28a%2Fd%29%28b%2Fd%29d%5E2%20%5C%5C%20%26%3D%20ab%20%5Cend%7Bsplit%7D" alt=" \begin{split} \mathrm{P}(U_1 < a, \, U_2 < b) &= \mathrm{P} \left( \bigcup_{n=0}^{a/d-1} \bigcup_{m=0}^{b/d-1} ( nd \leqq U_1 < nd + d, \, md \leqq U_2 < md + d ) \right) \\ &= \mathrm{P} \left( \bigcup_{n=0}^{a/d-1} \bigcup_{m=0}^{b/d-1} \bigl( f(nd, md) \leqq U < f(nd, md) + d^2 \bigr) \right) \\ &= \sum_{n=0}^{a/d-1} \sum_{m=0}^{b/d-1} \mathrm{P} \bigl( f(nd, md) \leqq U < f(nd, md) + d^2 \bigr) \\ &= (a/d)(b/d)d^2 \\ &= ab \end{split}"/><br /> </div></p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>なんと。すっきりしましたね。ああ、そのように区切っておけば、相当する U 上の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B6%E8%B4%D6">区間</a>は小数点以下 2N 桁まで固定され、それより右の桁が任意であるような、幅 d^2 の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B6%E8%B4%D6">区間</a>に一律になりますね。そうか、私は、「U_1 の何桁目が何で U_2 の何桁目が何である」という境界で区切っていましたが、そのためにU上の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B6%E8%B4%D6">区間</a>の大きさはばらついたりあまつさえ分裂したりしていたので、できうる限り細かく区切っておいた方が扱いやすかったんですね。</p></div></div></div></p> <p>小数点以下の桁数が無限でも成り立つことを後でかく → PDF にかいたが副部長のアプローチでは結局かいていない</div></p> </div> <footer class="entry-footer"> <div class="entry-tags-wrapper"> <div class="entry-tags"> </div> </div> <p class="entry-footer-section track-inview-by-gtm" data-gtm-track-json="{"area": "finish_reading"}"> <span class="author vcard"><span class="fn" data-load-nickname="1" data-user-name="cookie-box" >cookie-box</span></span> <span class="entry-footer-time"><a href="https://cookie-box.hatenablog.com/entry/2024/02/23/100110"><time data-relative datetime="2024-02-23T01:01:10Z" title="2024-02-23T01:01:10Z" class="updated">2024-02-23 10:01</time></a></span> <span class=" entry-footer-subscribe " data-test-blog-controlls-subscribe> <a href="https://blog.hatena.ne.jp/cookie-box/cookie-box.hatenablog.com/subscribe?utm_source=blogs_entry_footer&utm_medium=button&utm_campaign=subscribe_blog"> 読者になる </a> </span> </p> <div class="hatena-star-container" data-hatena-star-container data-hatena-star-url="https://cookie-box.hatenablog.com/entry/2024/02/23/100110" data-hatena-star-title="雑記:1つの一様乱数から2つの独立な一様乱数ができる" data-hatena-star-variant="profile-icon" data-hatena-star-profile-url-template="https://blog.hatena.ne.jp/{username}/" ></div> <div class="social-buttons"> <div class="social-button-item"> <a href="https://b.hatena.ne.jp/entry/s/cookie-box.hatenablog.com/entry/2024/02/23/100110" class="hatena-bookmark-button" data-hatena-bookmark-url="https://cookie-box.hatenablog.com/entry/2024/02/23/100110" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="この記事をはてなブックマークに追加"><img src="https://b.st-hatena.com/images/entry-button/button-only.gif" alt="この記事をはてなブックマークに追加" width="20" height="20" style="border: none;" /></a> </div> <div class="social-button-item"> <div class="fb-share-button" data-layout="box_count" data-href="https://cookie-box.hatenablog.com/entry/2024/02/23/100110"></div> </div> <div class="social-button-item"> <a class="entry-share-button entry-share-button-twitter test-share-button-twitter" href="https://x.com/intent/tweet?text=%E9%9B%91%E8%A8%98%EF%BC%9A1%E3%81%A4%E3%81%AE%E4%B8%80%E6%A7%98%E4%B9%B1%E6%95%B0%E3%81%8B%E3%82%892%E3%81%A4%E3%81%AE%E7%8B%AC%E7%AB%8B%E3%81%AA%E4%B8%80%E6%A7%98%E4%B9%B1%E6%95%B0%E3%81%8C%E3%81%A7%E3%81%8D%E3%82%8B+-+%E3%82%AF%E3%83%83%E3%82%AD%E3%83%BC%E3%81%AE%E6%97%A5%E8%A8%98&url=https%3A%2F%2Fcookie-box.hatenablog.com%2Fentry%2F2024%2F02%2F23%2F100110" title="X(Twitter)で投稿する" ></a> </div> </div> <div class="google-afc-image test-google-rectangle-ads"> <div id="google_afc_user_container_2" class="google-afc-user-container google_afc_blocklink2_5 google_afc_boder" data-test-unit="/4374287/blog_user_2nd"></div> <a href="http://blog.hatena.ne.jp/guide/pro" class="open-pro-modal" data-guide-pro-modal-ad-url="https://hatena.blog/guide/pro/modal/ad">広告を非表示にする</a> </div> <div class="customized-footer"> </div> <div class="comment-box js-comment-box"> <ul class="comment js-comment"> <li class="read-more-comments" style="display: none;"><a>もっと読む</a></li> </ul> <a class="leave-comment-title js-leave-comment-title">コメントを書く</a> </div> </footer> </div> </article> <article class="entry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-6400 words-600 mode-hatena entry-even" id="entry-6801883189064800107" data-keyword-campaign="" data-uuid="6801883189064800107" data-publication-type="entry"> <div class="entry-inner"> <header class="entry-header"> <div class="date entry-date first"> <a href="https://cookie-box.hatenablog.com/archive/2023/12/07" rel="nofollow"> <time datetime="2023-12-06T15:00:00Z" title="2023-12-06T15:00:00Z"> <span class="date-year">2023</span><span class="hyphen">-</span><span class="date-month">12</span><span class="hyphen">-</span><span class="date-day">07</span> </time> </a> </div> <h1 class="entry-title"> <a href="https://cookie-box.hatenablog.com/entry/2023/12/07/000000" class="entry-title-link bookmark">雑記: ルーヴァン法とライデン法の話</a> </h1> <div class="entry-categories categories"> <a href="https://cookie-box.hatenablog.com/archive/category/%E9%9B%91%E8%A8%98" class="entry-category-link category-雑記">雑記</a> </div> </header> <div class="entry-content hatenablog-entry"> <p>お気付きの点がありましたらご指摘いただけますと幸いです。<div style="background:#f0f0f0;padding: 1.0em;font-size:92%;"><b>まとめ</b><ul> <li>グラフをコミュニティに分割する手法に、<strong>ルーヴァン法</strong>と、それを改良した<strong>ライデン法</strong>がある。</li> <li>ルーヴァン法もライデン法もコミュニティ分割のモジュラリティ (や Constant Potts Model の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%CF%A5%DF%A5%EB%A5%C8%A5%CB%A5%A2%A5%F3">ハミルトニアン</a>) を最大化しようとする。モジュラリティは同じコミュニティのノードがつながっていることに報酬、つながっていないことにペナルティを課す指標と解釈することもできる。ただし報酬やペナルティの度合いがノードの次数が大きさ (生えている枝の多さ) に依存する。</li> <li>ルーヴァン法はシングルトン<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>から開始し、ノードをランダムな順序で回っていってモジュラリティが大きくなるのであればノードを<a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%CC%A5%B3%A5%DF">別コミ</a>ュニティに移動していくことを周回し、それが終わったら1コミュニティが1ノードになるようにグラフを集約し、また同じことを繰り返す。</li> <li>ライデン法もシングルトン<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>から開始し、ノードをランダムな順序で回っていってモジュラリティが大きくなるのであればノードを<a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%CC%A5%B3%A5%DF">別コミ</a>ュニティに移動していき (ただし移動したら近隣の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%CA%CC%A5%B3%A5%DF">別コミ</a>ュニティのノードを必ず後で回るようにし、必ずすべてのノードを回すようにする)、それが一周したら先に<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>を「精製」してから1コミュニティが1ノードになるようにグラフを集約し、同じことを繰り返す。</li> </ul></div><div class="ref-box" style="padding-left:0.5em;"><ol class="ref"> <li><a href="https://en.wikipedia.org/wiki/Louvain_method">Louvain method - Wikipedia</a> (2023年12月7日参照).</li> <li><a href="https://arxiv.org/abs/0803.0476">[0803.0476] Fast unfolding of communities in large networks</a> (2023年12月7日参照).</li> <li><a href="https://en.wikipedia.org/wiki/Modularity_(networks)">Modularity (networks) - Wikipedia</a> (2023年12月7日参照).</li> <li><a href="https://python-louvain.readthedocs.io/en/latest/index.html">Community detection for NetworkX’s documentation — Community detection for NetworkX 2 documentation</a> (2023年12月7日参照).</li> <li><a href="https://arxiv.org/abs/1810.08473">[1810.08473] From Louvain to Leiden: guaranteeing well-connected communities</a> (2023年12月7日参照).</li> <li><a href="https://leidenalg.readthedocs.io/en/stable/intro.html">Introduction — leidenalg 0.10.2.dev0+g47b490f.d20230720 documentation</a> (2023年12月7日参照).</li> </ol></div><div style="font-size:92%;"><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>グラフのコミュニティ分割手法の一つである Louvain 法 [1] は、モジュラリティなる指標を最大化するようにグラフをコミュニティ分割するのですね。それでとても高速であると。ちなみに原論文 [2] の著者陣に Louvain さんという方はいらっしゃらなくて不思議に思ったのですが、著者陣の所属大学がベルギーのフランス語圏のルーヴァン・<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%AB%A5%C8%A5%EA%A5%C3%A5%AF">カトリック</a>大学であることが手<a class="keyword" href="https://d.hatena.ne.jp/keyword/%CB%A1%CC%BE">法名</a>の由来なのですね。であればカタカナ表記は「ルーヴァン法」とすべきですね。わたしは初見で「<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%EB%A1%BC%A5%F4%A5%A7%A5%F3">ルーヴェン</a>法」だと思いそうよんでしまっていたのですが、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%EB%A1%BC%A5%F4%A5%A7%A5%F3">ルーヴェン</a>・<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%AB%A5%C8%A5%EA%A5%C3%A5%AF">カトリック</a>大学と表記すると分割元である<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%AA%A5%E9%A5%F3%A5%C0%B8%EC">オランダ語</a>圏の方の大学を指すようですので。それにしても、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%AA%A5%E9%A5%F3%A5%C0%B8%EC">オランダ語</a>話者とフランス語話者との対立で大学が分割されるという歴史的経緯があったのですね……グラフだけでなく大学まで分割されていたとは……。</p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p style="margin-bottom: 0.5em"><a class="keyword" href="https://d.hatena.ne.jp/keyword/%B4%D7%CF%C3%B5%D9%C2%EA">閑話休題</a>、グラフのモジュラリティとは何なのでしょうか。ルーヴァン法が如何に高速であるといっても、モジュラリティがグラフの分割のよさを示す指標として納得できるものでなければ採用するわけにはいきません。モジュラリティの定義は [3] などにありますので、さしあたり適当なグラフの適当な分割を考えて計算してみましょう。例えば下図のようになりますね。</p><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20231206/20231206115053.png" width="1439" height="675" loading="lazy" title="" class="hatena-fotolife" itemprop="image"></span></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p style="margin-bottom: 1.0em">ルーヴァン法の <a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a> パッケージ [4] が出す値と合致するかどうかも確認してみましょう。上図と同じ 0~6 のノードを登録し、上図と同じ個所にエッジを張ると、最適な分割は上図の青とオレンジの分け方になりますね (ノード 0~2 がコミュニティ 0、ノード 3~6 がコミュニティ 1)。この分割のモジュラリティは……上図の値と一致していますね。</p><div class="code-title" data-title="ルーヴァン法によるコミュニティ分割"></p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synPreProc">import</span> networkx <span class="synStatement">as</span> nx <span class="synPreProc">import</span> community G = nx.Graph() G.add_nodes_from([<span class="synConstant">0</span>, <span class="synConstant">1</span>, <span class="synConstant">2</span>, <span class="synConstant">3</span>, <span class="synConstant">4</span>, <span class="synConstant">5</span>, <span class="synConstant">6</span>]) G.add_edges_from([ (<span class="synConstant">0</span>, <span class="synConstant">1</span>), (<span class="synConstant">0</span>, <span class="synConstant">2</span>), (<span class="synConstant">1</span>, <span class="synConstant">2</span>), (<span class="synConstant">2</span>, <span class="synConstant">3</span>), (<span class="synConstant">3</span>, <span class="synConstant">4</span>), (<span class="synConstant">3</span>, <span class="synConstant">5</span>), (<span class="synConstant">3</span>, <span class="synConstant">6</span>), (<span class="synConstant">4</span>, <span class="synConstant">5</span>), (<span class="synConstant">5</span>, <span class="synConstant">6</span>)]) partition = community.best_partition(G) <span class="synIdentifier">print</span>(partition) modularity = community.modularity(partition, G) <span class="synIdentifier">print</span>(modularity) <span class="synIdentifier">print</span>( <span class="synConstant">6.0</span> / <span class="synConstant">18.0</span> - (<span class="synConstant">7.0</span> / <span class="synConstant">18.0</span>) * (<span class="synConstant">7.0</span> / <span class="synConstant">18.0</span>) + <span class="synConstant">10.0</span> / <span class="synConstant">18.0</span> - (<span class="synConstant">11.0</span> / <span class="synConstant">18.0</span>) * (<span class="synConstant">11.0</span> / <span class="synConstant">18.0</span>) ) </pre><p></div></p> <pre>{0: 0, 1: 0, 2: 0, 3: 1, 4: 1, 5: 1, 6: 1} 0.3641975308641975 0.3641975308641974 </pre><p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>モジュラリティが一致したのはいいのですが、問題はこれがよい分割の指標かどうかです。モジュラリティは「コミュニティ内部の枝の本数の期待値 (枝が生える元を不変としてつながる先がランダムであった場合の期待値) からの差」といった指標になっていますが、この期待値の計算においては、自分自身への枝も、同じノード間の 2 本以上の枝も許容されるし、枝が枝毛になる (枝を張る先を選択するときに既にそこに枝が張られていることを考慮しないという意味) ことも許容されますよね。これでは基準である期待値がめちゃくちゃなような……ただまあ、[3] には in a large random network, the number of self-loops and multi-edges is vanishingly small. とあるのでそこは置いておきますか……。</p><p style="margin-top:0.5em;">しかし、やはり個人的には「期待値」を考えるのはわかりにくいです……つながる先のみがランダムである状態に意味を見出しづらいですし……。コミュニティ分割のよさはもっと素朴に「ノードどうしが同じコミュニティなら枝があってほしい (あったら加点、なかったら減点)」「ノードどうしが違うコミュニティなら枝があってほしくない (あったら減点、なかったら加点)」といったものであってほしいですが、モジュラリティの定義をそれっぽく書き下すと以下でしょうか。ここで、<img src="https://chart.apis.google.com/chart?cht=tx&chl=n" alt="n"/> はノード数、<img src="https://chart.apis.google.com/chart?cht=tx&chl=m" alt="m"/> はエッジ数 (両方向からカウントしたものではなく直感的な本数)、<img src="https://chart.apis.google.com/chart?cht=tx&chl=k_v" alt="k_v"/> はノード <img src="https://chart.apis.google.com/chart?cht=tx&chl=v" alt="v"/> につながっているエッジ数 (ノードの次数) です。<ul> <li>すべてのノード対 <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%28v%2C%20w%29" alt=" (v, w)"/> について以下を足して <img src="https://chart.apis.google.com/chart?cht=tx&chl=2m" alt="2m"/> で割ったものがモジュラリティです。</li> <ul> <li><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%28v%2C%20w%29" alt=" (v, w)"/> が同じコミュニティで、枝がないとき、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20-k_v%20k_w%2F%282m%29" alt=" -k_v k_w/(2m)"/> のペナルティです。</li> <li><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%28v%2C%20w%29" alt=" (v, w)"/> が同じコミュニティで、枝があるとき、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%201-k_v%20k_w%2F%282m%29" alt=" 1-k_v k_w/(2m)"/> の報酬です。</li> <li><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%28v%2C%20w%29" alt=" (v, w)"/> が違うコミュニティであるときは報酬もペナルティもありません。</li> </ul></ul>これだと対称でないので以下のようにかくこともできます (<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%5Csum_v%20k_v%20%3D%202m" alt=" \sum_v k_v = 2m"/> を利用します)。しかしかえってわかりにくいかもしれません。<ul> <li>すべてのノード対 <img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%28v%2C%20w%29" alt=" (v, w)"/> について以下を足して <img src="https://chart.apis.google.com/chart?cht=tx&chl=2m" alt="2m"/> で割ったものがモジュラリティです。</li> <ul> <li><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%28v%2C%20w%29" alt=" (v, w)"/> が同じコミュニティで、枝がないとき、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20-k_v%20k_w%2F%284m%29" alt=" -k_v k_w/(4m)"/> のペナルティです。</li> <li><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%28v%2C%20w%29" alt=" (v, w)"/> が同じコミュニティで、枝があるとき、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%201%2F2-k_v%20k_w%2F%284m%29" alt=" 1/2-k_v k_w/(4m)"/> の報酬です。</li> <li><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%28v%2C%20w%29" alt=" (v, w)"/> が違うコミュニティで、枝がないとき、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20k_v%20k_w%2F%284m%29" alt=" k_v k_w/(4m)"/> の報酬です。</li> <li><img src="https://chart.apis.google.com/chart?cht=tx&chl=%20%28v%2C%20w%29" alt=" (v, w)"/> が違うコミュニティで、枝があるとき、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20-1%2F2%2Bk_v%20k_w%2F%284m%29" alt=" -1/2+k_v k_w/(4m)"/> のペナルティです。</li> </ul></ul></p><p style="margin-bottom:1.0em">こうしてみると、例えば、もしある <a class="keyword" href="https://d.hatena.ne.jp/keyword/SNS">SNS</a> 上で友達関係にある人たちをコミュニティ分割したいのだとしたら、<img src="https://chart.apis.google.com/chart?cht=tx&chl=%20k_v" alt=" k_v"/> が大きい人はたくさんの友達がいる人なので、そんな友達が多い A さんと友達である B さんを同じコミュニティと判定しても報酬は少なめで、違うコミュニティと判定してもペナルティは控えめになりますね。そんなにたくさん友達がいたらどのコミュニティに所属していても不思議でないという感じでしょうか。逆に、友達が少ない人に対する判定は厳しくなりますね。どうも個々人の友達の人数=各ノードの次数への依存度が大きい指標である気がしますが……。</p><div class="code-title" data-title="モジュラリティの検算 (2通り)"></p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synStatement">def</span> <span class="synIdentifier">modularity</span>(partition, G): mo = <span class="synConstant">0.0</span> m = <span class="synIdentifier">float</span>(<span class="synIdentifier">len</span>(G.edges)) <span class="synStatement">for</span> v <span class="synStatement">in</span> G.nodes: <span class="synStatement">for</span> w <span class="synStatement">in</span> G.nodes: <span class="synStatement">if</span> partition[v] == partition[w]: <span class="synComment"># 同じコミュニティならペナルティか報酬</span> mo -= G.degree[v] * G.degree[w] / (<span class="synConstant">2.0</span> * m) <span class="synStatement">if</span> ((v, w) <span class="synStatement">in</span> G.edges) <span class="synStatement">or</span> ((w, v) <span class="synStatement">in</span> G.edges): mo += <span class="synConstant">1.0</span> <span class="synComment"># つながっていたら報酬</span> <span class="synStatement">return</span> mo / (<span class="synConstant">2.0</span> * m) <span class="synStatement">def</span> <span class="synIdentifier">modularity2</span>(partition, G): mo = <span class="synConstant">0.0</span> m = <span class="synIdentifier">float</span>(<span class="synIdentifier">len</span>(G.edges)) <span class="synStatement">for</span> v <span class="synStatement">in</span> G.nodes: <span class="synStatement">for</span> w <span class="synStatement">in</span> G.nodes: <span class="synStatement">if</span> partition[v] == partition[w]: <span class="synComment"># 同じコミュニティならペナルティか報酬</span> mo -= <span class="synConstant">0.5</span> * G.degree[v] * G.degree[w] / (<span class="synConstant">2.0</span> * m) <span class="synStatement">if</span> ((v, w) <span class="synStatement">in</span> G.edges) <span class="synStatement">or</span> ((w, v) <span class="synStatement">in</span> G.edges): mo += <span class="synConstant">0.5</span> <span class="synComment"># つながっていたら報酬</span> <span class="synStatement">else</span>: <span class="synComment"># 違うコミュニティでもペナルティか報酬</span> mo += <span class="synConstant">0.5</span> * G.degree[v] * G.degree[w] / (<span class="synConstant">2.0</span> * m) <span class="synStatement">if</span> ((v, w) <span class="synStatement">in</span> G.edges) <span class="synStatement">or</span> ((w, v) <span class="synStatement">in</span> G.edges): mo -= <span class="synConstant">0.5</span> <span class="synComment"># つながっていたらペナルティ</span> <span class="synStatement">return</span> mo / (<span class="synConstant">2.0</span> * m) <span class="synIdentifier">print</span>(modularity(partition, G)) <span class="synIdentifier">print</span>(modularity2(partition, G)) </pre><p></div></p> <pre>0.3641975308641976 0.36419753086419754 </pre><p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>案の定 [3] をみると、グラフが大きい場合、各コミュニティ内が密にエッジで結束している場合でも、コミュニティどうしが統合されてしまうという問題点が指摘されていますね。これは例えば、ある漫画が好きな人たちの密なコミュニティと、あるゲームが好きな人たちの密なコミュニティが形成されているにもかかわらず、前者に所属する C さんと後者に所属する D さんが友達どうしであり、かつ両者ともに友達が少なめであるせいで両者を同じコミュニティにしないことのペナルティが相対的に大きくなり、コミュニティを統合してしまうといった状況でしょうか。</p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>しかし、ルーヴァン法の記事 [1] をみると、Leiden 法ではこれが解消されているというような記述がありますね。Leiden 法もモジュラリティベースのコミュニティ分割手法らしいですが、Leiden 法は純粋なモジュラリティ最大化をしないのでしょうか? モジュラリティ最大化の範囲で<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>がよくなるのでしょうか? Leiden 法の原論文は [5] ですね。ルーヴァン法と同じ<a class="keyword" href="https://d.hatena.ne.jp/keyword/%CC%BF%CC%BE">命名</a>則で著者陣の所属が Leiden 大学なんですね。であれば以降ライデン法と表記しましょう。しかし、ルーヴァン法に代わるライデン法がオランダの大学発とは、「From Louvain to Leiden:」といった挑戦的にもみえるタイトルといい、因縁を感じるような……どうか分割するのはグラフだけにして……。</p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p style="margin-bottom:1.0em">とりあえずライデン法の <a class="keyword" href="https://d.hatena.ne.jp/keyword/Python">Python</a> パッケージ [6] を使用してみると、グラフを igraph 形式に変換すればコミュニティ分割してくれますね。簡単な例なので結果も変わりません。</p><div class="code-title" data-title="ライデン法によるコミュニティ分割"></p> <pre class="code lang-python" data-lang="python" data-unlink><span class="synPreProc">import</span> networkx <span class="synStatement">as</span> nx <span class="synPreProc">import</span> igraph <span class="synStatement">as</span> ig <span class="synPreProc">import</span> leidenalg <span class="synStatement">as</span> la ig_graph = ig.Graph.TupleList(G.edges(), directed=<span class="synIdentifier">False</span>) partition = la.find_partition(ig_graph, la.ModularityVertexPartition) <span class="synIdentifier">print</span>(partition) </pre><p></div></p> <pre>Clustering with 7 elements and 2 clusters [0] 3, 4, 5, 6 [1] 0, 1, 2 </pre><p></div></div></div><div class="balloon5 org01"><div class="faceicon"><span itemscope itemtype="http://schema.org/Photograph"><img src="https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookie-box/20211229/20211229151958.png" width="378" height="378" loading="lazy" title="" class="hatena-fotolife" style="width:60px" itemprop="image"></span></div><div class="chatting"><div class="says"><p>それで肝心のライデン法がどうよいのかですが……ライデン法の原論文 [5] をみていくとそもそもルーヴァン法の疑似コードもありますね。これをまとめると以下でしょうか。なるほどシンプルですね。<ol> <li>まず初期状態の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>はグラフ内のノード1つ1つを1コミュニティにします (シングルトン<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>)。</li> <li>ノードをランダムな順に回って「ノードを別のコミュニティに移動したらモジュラリティが大きくなるか」を調べ、大きくなるようなら<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>を変更します。モジュラリティが大きくなったら次の周回に進み、大きくならなければ終わります。</li> <li>2. の移動結果に基づき、1コミュニティが1ノードになるようにグラフを集約し、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>をシングルトン<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>にし、2. に戻ります。2. で<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>の変更が発生していなければこれで終わります。</li> </ol>対してライデン法では以下ですね。refinement が理解し切れていません。ただここは色々な実装がありえてそれによってコミュニティ分割に理想的な性質をもたせられるような感じにみえますが……?<ol> <li>まず初期状態の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>はグラフ内のノード1つ1つを1コミュニティにします (シングルトン<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>)。</li> <li>ノードをランダムな順にキューに入れてキュー内のノードを回って「ノードを別のコミュニティに移動したらモジュラリティが大きくなるか」を調べ、大きくなるようなら<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>を変更します。ただしこのとき変更が発生したら、その隣接ノードであって異なるコミュニティであるノードをキューに追加して後で必ず回るようにします。キュー内のノードを回り切ったらこの手順を終わります。</li> <li><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>の「精製 (refinement)」をします。2. の結果のコミュニティをそのまま採用するのではなく、そのコミュニティの中でよくつながりあっているところがコミュニティとして採用されます。なので 2. の結果のコミュニティはここで分割され得ます。</li> <li>ここまでの結果に基づき、1コミュニティが1ノードになるようにグラフを集約し、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>をシングルトン<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>にし、2. に戻ります。2. と 3. で<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D1%A1%BC%A5%C6%A5%A3%A5%B7%A5%E7%A5%F3">パーティション</a>の変更が発生していなければ終わります。</li> </ol></p></div></div></div>終わり</div></p> </div> <footer class="entry-footer"> <div class="entry-tags-wrapper"> <div class="entry-tags"> </div> </div> <p class="entry-footer-section track-inview-by-gtm" data-gtm-track-json="{"area": "finish_reading"}"> <span class="author vcard"><span class="fn" data-load-nickname="1" data-user-name="cookie-box" >cookie-box</span></span> <span class="entry-footer-time"><a href="https://cookie-box.hatenablog.com/entry/2023/12/07/000000"><time data-relative datetime="2023-12-06T15:00:00Z" title="2023-12-06T15:00:00Z" class="updated">2023-12-07 00:00</time></a></span> <span class=" entry-footer-subscribe " data-test-blog-controlls-subscribe> <a href="https://blog.hatena.ne.jp/cookie-box/cookie-box.hatenablog.com/subscribe?utm_campaign=subscribe_blog&utm_source=blogs_entry_footer&utm_medium=button"> 読者になる </a> </span> </p> <div class="hatena-star-container" data-hatena-star-container data-hatena-star-url="https://cookie-box.hatenablog.com/entry/2023/12/07/000000" data-hatena-star-title="雑記: ルーヴァン法とライデン法の話" data-hatena-star-variant="profile-icon" data-hatena-star-profile-url-template="https://blog.hatena.ne.jp/{username}/" ></div> <div class="social-buttons"> <div class="social-button-item"> <a href="https://b.hatena.ne.jp/entry/s/cookie-box.hatenablog.com/entry/2023/12/07/000000" class="hatena-bookmark-button" data-hatena-bookmark-url="https://cookie-box.hatenablog.com/entry/2023/12/07/000000" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="この記事をはてなブックマークに追加"><img src="https://b.st-hatena.com/images/entry-button/button-only.gif" alt="この記事をはてなブックマークに追加" width="20" height="20" style="border: none;" /></a> </div> <div class="social-button-item"> <div class="fb-share-button" data-layout="box_count" data-href="https://cookie-box.hatenablog.com/entry/2023/12/07/000000"></div> </div> <div class="social-button-item"> <a class="entry-share-button entry-share-button-twitter test-share-button-twitter" href="https://x.com/intent/tweet?text=%E9%9B%91%E8%A8%98%EF%BC%9A+%E3%83%AB%E3%83%BC%E3%83%B4%E3%82%A1%E3%83%B3%E6%B3%95%E3%81%A8%E3%83%A9%E3%82%A4%E3%83%87%E3%83%B3%E6%B3%95%E3%81%AE%E8%A9%B1+-+%E3%82%AF%E3%83%83%E3%82%AD%E3%83%BC%E3%81%AE%E6%97%A5%E8%A8%98&url=https%3A%2F%2Fcookie-box.hatenablog.com%2Fentry%2F2023%2F12%2F07%2F000000" title="X(Twitter)で投稿する" ></a> </div> </div> <div class="google-afc-image test-google-rectangle-ads"> <script> (valve = window.valve || []).push(function(v) { v.displayDFPSlot('google_afc_user_container_3'); }); </script> <div id="google_afc_user_container_3" class="google-afc-user-container google_afc_blocklink2_5 google_afc_boder" data-test-unit="/4374287/blog_user_2nd"></div> <a href="http://blog.hatena.ne.jp/guide/pro" class="open-pro-modal" data-guide-pro-modal-ad-url="https://hatena.blog/guide/pro/modal/ad">広告を非表示にする</a> </div> <div class="customized-footer"> </div> <div class="comment-box js-comment-box"> <ul class="comment js-comment"> <li class="read-more-comments" style="display: none;"><a>もっと読む</a></li> </ul> <a class="leave-comment-title js-leave-comment-title">コメントを書く</a> </div> </footer> </div> </article> <article class="entry hentry test-hentry js-entry-article date-first autopagerize_page_element chars-7600 words-400 mode-hatena entry-odd" id="entry-820878482969516668" data-keyword-campaign="" data-uuid="820878482969516668" data-publication-type="entry"> <div class="entry-inner"> <header class="entry-header"> <div class="date entry-date first"> <a href="https://cookie-box.hatenablog.com/archive/2023/09/21" rel="nofollow"> <time datetime="2023-09-21T14:58:15Z" title="2023-09-21T14:58:15Z"> <span class="date-year">2023</span><span class="hyphen">-</span><span class="date-month">09</span><span class="hyphen">-</span><span class="date-day">21</span> </time> </a> </div> <h1 class="entry-title"> <a href="https://cookie-box.hatenablog.com/entry/2023/09/21/235815" class="entry-title-link bookmark">雑記: AWS にカフェ (アプリケーション) を開店準備するまで</a> </h1> <div class="entry-categories categories"> <a href="https://cookie-box.hatenablog.com/archive/category/%E9%9B%91%E8%A8%98" class="entry-category-link category-雑記">雑記</a> </div> </header> <div class="entry-content hatenablog-entry"> <p><div style="font-size:94%">人生で、新しく配属された組織が <a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> の知識を前提にしていることがあると思います。でも用語が多いと思います。なので同じ境遇の方のためにカフェに喩えました。お気づきの点がありましたらご指摘いただけますと幸いです。<br /> なお、長くなってしまったのでパブリックサブネットの NAT <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B2%A1%BC%A5%C8%A5%A6%A5%A7%A5%A4">ゲートウェイ</a>やロードバランサの話はないです。</p><p><h5 id="まとめ">まとめ</h5></p> <ul> <li><strong><a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a></strong>: あなたが初めて <a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> 国にカフェ (アプリケーション) を建設するとき、まずつくる町です (つくらなくてもデフォルトでつくられますが)。16~65536 区画 (IP アドレス数) の広さの町をつくることができます。 <ul> <li><strong>サブネット</strong>: 町の中の丁目です。なお、各丁目の 2 区画目には自動的にタクシー乗り場 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> ルータ) が建設されます。</li> <li><strong>ルートテーブル</strong>: 各タクシー乗り場に設置されている、「そこからある目的地 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/%C1%F7%BF%AE%C0%E8">送信先</a>) に行くとき、次の経由地 (ターゲット) はどこか」を示すガイドブックです。ここに登録がない目的地には行けません。</li> </ul></li> <li><strong>EC2 <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a></strong>: カフェの建物 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/%B2%BE%C1%DB%A5%DE%A5%B7%A5%F3">仮想マシン</a>) です。建てたい丁目 (サブネット) に、建てたい構造・広さ (<a class="keyword" href="https://d.hatena.ne.jp/keyword/Amazon">Amazon</a> マシンイメージ・<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>タイプ) の建物を建設します。 <ul> <li><strong>セキュリティグループ</strong>: 建物のセキュリティシステムに登録するルールです。 <ul> <li><strong>インバウンドルール</strong>: 建物外から建物内に入ってくる人の通行許可です。</li> <li><strong>アウトバウンドルール</strong>: 建物内から建物外に出張に行く人の出張許可です。</li> </ul></li> <li><strong>IAM ロール</strong>: その建物から <a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> 国の公共機関を利用してよいかの許可です。</li> </ul></li> <li><strong>SSM Agent</strong>: <a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> 国の公共サービスとして、建設した建物についてくる管理人ロボです。建設したカフェの内装工事 (開発作業) をするとき、インバウンドルールに自分を追加して自分で建物に入ってやる方法 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/SSH">SSH</a> 接続など) も、建物にいる管理人ロボに代わりにやらせる方法 (セッションマネージャー経由の接続) もあります (通常後者の方法を取ります)。</li> <li><strong>Systems Manager (SSM)</strong>: 管理人ロボを派遣している <a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> 国の公共機関です。あなたがこの機関の受付窓口 (<strong>セッションマネージャー</strong>) に内装工事の指示を送り、他方、管理人ロボが定期的にカフェがある丁目の支所から秘密の地下通路でこの機関に指示を確認しに出張することで (ポーリング)、便利で安全に内装工事ができます。</li> <li><strong><a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> エンドポイント</strong>: その丁目で <a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> 国の公共機関を利用したいとき、その丁目内に誘致する支所です。なんと秘密の地下通路 (PrivateLink) で本部とつながっています (<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%BF%A1%BC%A5%D5%A5%A7%A5%A4%A5%B9">インターフェイス</a>型の場合)。</li> </ul><p><div class="ref-box"><ol><li><a href="https://qiita.com/TakanoriVega/items/f567d71c9f400d45db28">IPアドレスとCIDR表記の理解:AWSでのネットワーキング - Qiita</a>:人はまず <a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> を作成しようとして「10.0.0.0/16 って何」となると思います。このページをみて事なきを得ました。</li> <li><a href="https://mtrad-blog.com/2022/09/14/post-3430/">【VPC/サブネット】AWSによる予約IPアドレスについて - エムトラッドブログ</a>:1. の記事に「最初の4つと最後の1つの<a class="keyword" href="https://d.hatena.ne.jp/keyword/IP%A5%A2%A5%C9%A5%EC%A5%B9">IPアドレス</a>は<a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a>によって予約されています」とあってとても気になると思います。このページをみて事なきを得ました。</li> <li><a href="https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/setup-create-vpc.html">ステップ 2: VPC エンドポイントを作成する - AWS Systems Manager</a>:最初プライベートサブネットをルートテーブルでインターネット<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B2%A1%BC%A5%C8%A5%A6%A5%A7%A5%A4">ゲートウェイ</a>につないでしまっていたので (台無し)、たぶんそのせいでこの設定をしなくてもセッションマネージャーに接続できていました。わかりません。正しくはこの設定をするはずです。この設定をしてセッションマネージャーで接続できるようになるのに少しタイムラグがあって焦りました。</li> <li><a href="https://qiita.com/miyuki_samitani/items/9d9f7a0c417cb75a6c85">VPCエンドポイント ってなんのこと? - Qiita</a>:本当になんのことなので助かりました。</li> <li><a href="https://dev.classmethod.jp/articles/ssh-through-session-manager/">セッションマネージャー越しにSSHアクセスすると何が嬉しいのか | DevelopersIO</a>:セッションマネージャー経由時にどうなっているのかわからなかったので参考にしました。</li></ol></div><div class="con-box"></p> <ul class="table-of-contents"> <li><a href="#まとめ">まとめ</a></li> <li><a href="#町-VPC-をつくる">町 (VPC) をつくる</a></li> <li><a href="#建物-EC2-インスタンス-を建てる">建物 (EC2 インスタンス) を建てる</a></li> <li><a href="#建物の管理人ロボ-SSM-Agent-に内装工事指示を出す">建物の管理人ロボ (SSM Agent) に内装工事指示を出す</a></li> <li><a href="#町の外部-インターネット-から資材を搬入できるようにする">町の外部 (インターネット) から資材を搬入できるようにする</a></li> <li><a href="#完成したカフェに訪問してみる">完成したカフェに訪問してみる</a></li> </ul><p></div></p><p>以下、ストーリー本編です。</p><p><h5 id="町-VPC-をつくる">町 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a>) をつくる</h5>あなたは <a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> 国の入国ビザ (アカウント) を得ました。あなたは <a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> 国にカフェを開業したい (アプリケーションをたてたい) です。そのためには、まず町 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a>) をつくります。<a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%C3%A5%B7%A5%E5">ダッシュ</a>ボードに移動し、「<a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> を作成」を押下します。</p> <ul> <li>「作成するリソース」で「<a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> など」を選択します。 <ul> <li>本当にただ町をつくるだけなら「<a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> のみ」でよいですが、町をつくるときにその中に何丁目をつくるかと、各丁目のタクシー乗り場から出るタクシーはどこに行けるのか書き込むガイドブックもつくっておくと便利だと思います。</li> </ul></li> <li>「<a class="keyword" href="https://d.hatena.ne.jp/keyword/IPv4">IPv4</a> CIDR ブロック」で<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A4%A2%A4%CA%A4%BF%A4%CE%C4%AE">あなたの町</a>の大きさを指定します。ただし、以下の決まりがあります。 <ul> <li>町の大きさは 16 区画~ 65536 区画 (10.0.0.0/28 ~ 10.0.0.0/16) の広さを指定することになっています。この区画ごとに住所 (IP アドレス) があります。なお、10.0.0.0/n という表記は 2 の 32-n 乗の区画数を表します。</li> <li>ただし、町の中をさらに丁目 (サブネット) に分ける場合は、1 つの丁目が最低 16 区画必要です。町全体が 1 つの丁目でも構いませんが、以下のような場合には丁目を分けます。 <ul> <li>例えば、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A4%A2%A4%CA%A4%BF%A4%CE%C4%AE">あなたの町</a>の中に「町の外から直接入ってこれる丁目 (パブリックサブネット)」と「そうでない丁目 (プライベートサブネット)」があるような設計にしたいならば、そこで丁目を分けます。</li> <li>例えば、停電でカフェが全く営業できなくなるリスクに備えて地域ごとに依存する<a class="keyword" href="https://d.hatena.ne.jp/keyword/%C8%AF%C5%C5%BD%EA">発電所</a>を分けてカフェを分散したい (複数データセンターにアプリケーションをデプロイしたい) ならば、ある一つの<a class="keyword" href="https://d.hatena.ne.jp/keyword/%C8%AF%C5%C5%BD%EA">発電所</a>に依存する丁目 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%D9%A5%A4%A5%E9%A5%D3%A5%EA%A5%C6%A5%A3">アベイラビリティ</a>ゾーン) ごとに丁目を分けます。これは設計思想というか仕組み上分けざるをえません。</li> </ul></li> </ul></li> <li>つまり、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A4%A2%A4%CA%A4%BF%A4%CE%C4%AE">あなたの町</a>を、<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A2%A5%D9%A5%A4%A5%E9%A5%D3%A5%EA%A5%C6%A5%A3">アベイラビリティ</a>ゾーン数が 2 で、それぞれにパブリックサブネットとプライベートサブネットがあるようにしたいなら、丁目の数は 4 になり、ゆえに町全体の大きさは最低 64 区画必要です。</li> <li>あなたは防犯上町の外から直接入れない丁目にカフェを建設したく、また停電時にまで営業を続行したい事情はなかったので、町の大きさを 32 区画 (10.0.0.0/27) とし、最初の 16 区画 (10.0.0.0/28) を 1 丁目とし、次の 16 区画 (10.0.0.16/28) を 2 丁目とし、それぞれパブリックサブネット、プライベートサブネットとして運用することにしようとしました。 <ul> <li>なお、各丁目の最初の 4 区画と最後の 1 区画には <a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> 国の決まりで自動的に公共施設が建てられるなどします (以下)。なので、それらの区画にはあなたのカフェは建設できません。 <ul> <li>最初の区画は、そこの住所 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/IP%A5%A2%A5%C9%A5%EC%A5%B9">IPアドレス</a>) が特別な意味をもつ (その丁目の識別に利用される) ので (ネットワークアドレス)、そこには慣例的に施設を建設しません。</li> <li>2 番目の区画には、タクシー乗り場 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> ルータ) が建設されます。なお、<a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> 国で移動するときは必ずタクシー乗り場からタクシーに乗らなければならず、タクシー乗り場に設置されているガイドブック (ルートテーブル) にない目的地には行けません。ルートテーブルについてはこの記事の最後の方が再度触れます。</li> <li>3 番目の区画には、<a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> 国の各種公共サービス機関 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> リソース) の住所を調べられる案内所 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/Amazon">Amazon</a> <a class="keyword" href="https://d.hatena.ne.jp/keyword/DNS">DNS</a> サーバ) が建設されます。</li> <li>4 番目の区画はなんか念のため施設を建設することが禁止されています。</li> <li>最後の区画は、そこの住所がその丁目内のすべての区画の住所の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A8%A5%A4%A5%EA%A5%A2%A5%B9">エイリアス</a>になるという特殊な意味をもつので (ブロードキャストアドレス)、施設は建設できません。</li> </ul></li> </ul></li> </ul><p><h5 id="建物-EC2-インスタンス-を建てる">建物 (EC2 <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>) を建てる</h5><a class="keyword" href="https://d.hatena.ne.jp/keyword/%A4%A2%A4%CA%A4%BF%A4%CE%C4%AE">あなたの町</a>ができたらそこにカフェの建物 (EC2 <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>) を建てます。EC2 <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%C3%A5%B7%A5%E5">ダッシュ</a>ボードに移動し、「<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>を起動」を押下します。</p> <ul> <li>「<a class="keyword" href="https://d.hatena.ne.jp/keyword/Amazon">Amazon</a> マシンイメージ」「<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>タイプ」は建物の構造と広さのようなものです。あなたのカフェで利用したい設備が導入できる or 既に備わっている構造を選び、その設備に期待する価値を発揮できるくらいの広さを選ぶと思います。これはあなたのカフェで提供したいサービスや、見込んでいる来店客数に依存します。</li> <li>「ネットワーク設定」の「<a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a>」「サブネット」は建物を建てる町・丁目です。先ほどつくった <a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> とその中のプライベートサブネットを選びます。</li> <li>「ネットワーク設定」の「セキュリティグループ」は建物のセキュリティシステムに登録するルールです。後からでも変更できます。 <ul> <li>「インバウンドルール」は「建物外から建物内に入ってくる人の通行許可」です。「お店のこの入口に (ポート) 、この住所からやって来た (ソース)、こんな作法 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%D7%A5%ED%A5%C8%A5%B3%A5%EB">プロトコル</a>) の人なら通してよいです」というようなルールを複数登録できます。 <ul> <li>例えば、カフェの内装工事 (開発作業) のために自分も建物に入りたい場合、自分 (の IP アドレス) が作業員として (<a class="keyword" href="https://d.hatena.ne.jp/keyword/TCP">TCP</a> 接続で) 作業員入口 (22 番ポート) から入ってくることを許可するルールを追加します。<span style="color: #ff5252">ただし、実際には設計思想上プライベートサブネットにこのようなルールは追加せず、建物に公共サービスとして派遣されている管理人ロボ (SSM Agent) に代わりに作業させます。</span></li> <li>また、カフェの開店前に自分がお客様としてお店のサービスを確認したい場合、自分 (の IP アドレス) がお客様入口 (例えば 5000 番ポートへの <a class="keyword" href="https://d.hatena.ne.jp/keyword/TCP">TCP</a> 接続) から入ってくることを許可するルールも追加しておきます。<span style="color: #ff5252">ただし、実際には設計思想上プライベートサブネットにこのようなルールは追加せず、同じ町内のパブリックサブネットのロードバランサを通って来た人だけを許可します。</span></li> </ul></li> <li>「アウトバウンドルール」は「建物内から建物外に出張に行く人の出張許可」です。 <ul> <li>デフォルトではどこにでも出張に行けます。あなたがカフェに必要な資材をあらゆる場所から調達したいなら、どこにでも出張に行けるようにした方がよいと思います。そうでなく、「この工場のコーヒー豆の<a class="keyword" href="https://d.hatena.ne.jp/keyword/%BB%C5%C6%FE">仕入</a>れのみ許可する」などとしたいときはそのようなルールを追加すると思います。</li> </ul></li> </ul></li> <li>「高度な詳細」内にある「IAM <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>プロフィール」には「IAM ロール」を設定します (両者の違いはここでは割愛します)。後からでも変更できます。「IAM ロール」とは、その建物から <a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> 国の公共機関を利用してよいかの許可です。 <ul> <li>例えば、その建物の管理人ロボ (SSM Agent) に代わりに内装工事をさせる場合、管理人ロボが派遣元の公共機関 (SSM) に工事指示を確認しに行くことを許可する IAM ロール (AmazonEC2RoleforSSM) を設定する必要があります。</li> </ul></li> </ul><p><h5 id="建物の管理人ロボ-SSM-Agent-に内装工事指示を出す">建物の管理人ロボ (SSM Agent) に内装工事指示を出す</h5>建物が建ったら早速内装工事 (開発作業) をしたいと思います。例えば、インバウンドルールに自分を追加して自分で建物に入って工事することができます。ただ、この方法だとルールや鍵 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/SSH">SSH</a>キー) の管理が面倒だし、もしあなたのカフェに共同運営者が加わったらルールを追加したり鍵を渡したりがやっぱり面倒だし、そもそも、「カフェがある丁目は町の外から直接入れないようにしよう」としていたのに自分が直接入っていては設計思想と反しています。</p><p>なので、往々にして建設した建物に常駐している管理人ロボ (SSM Agent) に作業してもらいます。<a class="keyword" href="https://d.hatena.ne.jp/keyword/AWS">AWS</a> 国で建てた建物にはなんと公共サービスとして勝手にこのロボが付いてきます。このロボはあなたの身代わりとしてあなたそっくりに動いてくれます。</p><p>しかし、疑問があると思います。このロボにどうやって指示を送るのでしょうか。あなたがロボに会いに行くならば、「カフェがある丁目は町の外から直接入れない」に反すると思います。ロボに会いに来てもらうにせよ、ロボは指示通りに動くのだから、実質「直接入れない」に反しています。</p><p>しかし、ロボは公共機関 (SSM) から派遣されているので、特別で安全な経路で町の外に情報を取りに行くことができます。具体的に、ロボに作業してもらうためには、あなたのカフェがある丁目内に SSM の支所 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> エンドポイント) を誘致します。その支所はなんと秘密の地下通路 (PrivateLink) で本部でつながっています。ロボはここを通って、あなたが本部の窓口 (セッションマネージャー) に出した指示を定期的に確認しに来ることができます。</p> <ul> <li>再び <a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%C0%A5%C3%A5%B7%A5%E5">ダッシュ</a>ボードに移動します。やりたいことは公共機関の支所 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> エンドポイント) を誘致することなのですが、支所のセキュリティシステムにも、あなたのカフェからロボが指示を確認しにやって来ることを許可させないといけません。そこで、先にセキュリティシステムに登録するルール (セキュリティグループ) を作成します。サイドバーから「セキュリティグループ」を選択、「セキュリティグループを作成」を押下し、インバウンドルールに、「タイプ=<a class="keyword" href="https://d.hatena.ne.jp/keyword/HTTPS">HTTPS</a>、 ソース=あなたのカフェのセキュリティグループ (あなたのカフェの IP アドレスでもよいがセキュリティグループによる指定が推奨されている)」を追加します。</li> <li>いよいよ支所を追加します。サイドバーから「エンドポイント」を選択します。画面右上の「エンドポイントを作成」を押下し、サービスの検索フォームに .ssm と入力することで com.amazonaws.[リージョン名].ssm を探し当て選択します。続けてあなたのカフェの <a class="keyword" href="https://d.hatena.ne.jp/keyword/VPC">VPC</a> とサブネットを選択し、最後に「セキュリティグループ」でさっきつくったセキュリティグループを選択してエンドポイントを作成します。</li> <li>com.amazonaws.[リージョン名].ssmmessages, com.amazonaws.[リージョン名].ec2, com.amazonaws.[リージョン名].ec2messages に対しても同様に作成する必要があります。個々の支所の役割は割愛します。</li> </ul><p>ここまで作業して、EC2 <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の IAM <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>プロフィールに AmazonEC2RoleforSSM が含まれていれば、EC2 <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>の「接続」を押下しセッションマネージャータブから接続できるようになっています (接続できない場合はエンドポイント作成からタイムラグがあるので少し待ってみます)。接続したコンソールでカフェの内装工事 (開発) をします。カフェに直接入って工事をしているような感覚ですが、ストーリーの都合上、これは機関の窓口でロボに指示を送っているのだと思います。</p><p><h5 id="町の外部-インターネット-から資材を搬入できるようにする">町の外部 (インターネット) から資材を搬入できるようにする</h5></p><p>(あなたがまだサブネットのルートテーブルを適切に設定していない場合) 工事を始めてすぐに、外部から資材を搬入できない (パッケージをインストールできない) ことに気づきます。アウトバウンドルール上はどこにでも出張しに行けるようになっているのにです。それは、「この住所に資材を取りに行こう」として丁目のタクシー乗り場に行っても「そこの住所に向かう方法が登録されていないです」となっているためです。タクシー乗り場にあるガイドブックに目的地を登録する必要があります。</p> <ul> <li>ルートテーブル: 各丁目のタクシー乗り場に設置されている、「その丁目からある目的地 (<a class="keyword" href="https://d.hatena.ne.jp/keyword/%C1%F7%BF%AE%C0%E8">送信先</a>) に行くとき、次の経由地 (ターゲット) はどこか」を示すガイドブックです。ガイドブックに登録されていない目的地には行けません。その町内の住所については「町内なので直接向かってください (local)」と必ず登録されています (削除することはできません)。町外の住所にも行けるようにしたい場合は、例えば町外のすべての住所 (0.0.0.0/0) について「次は『インターネット<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B2%A1%BC%A5%C8%A5%A6%A5%A7%A5%A4">ゲートウェイ</a>』タクシー乗り場に向かってください」と登録します。そうすると、そこからまた町の外へ向かう道路 (<strong>インターネット</strong>) にガイドされることになります。 <ul> <li>ただし、プライベートサブネットのルートテーブルでは、直接インターネット<a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B2%A1%BC%A5%C8%A5%A6%A5%A7%A5%A4">ゲートウェイ</a>に向かわせるのは設計思想に反するので、NAT <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%B2%A1%BC%A5%C8%A5%A6%A5%A7%A5%A4">ゲートウェイ</a>に向かうようにします。</li> </ul></li> </ul><p><h5 id="完成したカフェに訪問してみる">完成したカフェに訪問してみる</h5></p><p>Elastic IP アドレスを EC2 <a class="keyword" href="https://d.hatena.ne.jp/keyword/%A5%A4%A5%F3%A5%B9%A5%BF%A5%F3%A5%B9">インスタンス</a>に紐づけ、インバウンドルールでアプリケーションがたっているポートへの自分の IP のアクセスを許可すれば仕上がりを確認できます。ただ、プライベートサブネットにパブリックな Elastic IP アドレスを紐づけるのはもう台無しです。実際には、パブリックサブネットにロードバランサを設置してそこを通ってアプリケーションにアクセスするようにします。</div></p> </div> <footer class="entry-footer"> <div class="entry-tags-wrapper"> <div class="entry-tags"> </div> </div> <p class="entry-footer-section track-inview-by-gtm" data-gtm-track-json="{"area": "finish_reading"}"> <span class="author vcard"><span class="fn" data-load-nickname="1" data-user-name="cookie-box" >cookie-box</span></span> <span class="entry-footer-time"><a href="https://cookie-box.hatenablog.com/entry/2023/09/21/235815"><time data-relative datetime="2023-09-21T14:58:15Z" title="2023-09-21T14:58:15Z" class="updated">2023-09-21 23:58</time></a></span> <span class=" entry-footer-subscribe " data-test-blog-controlls-subscribe> <a href="https://blog.hatena.ne.jp/cookie-box/cookie-box.hatenablog.com/subscribe?utm_medium=button&utm_source=blogs_entry_footer&utm_campaign=subscribe_blog"> 読者になる </a> </span> </p> <div class="hatena-star-container" data-hatena-star-container data-hatena-star-url="https://cookie-box.hatenablog.com/entry/2023/09/21/235815" data-hatena-star-title="雑記: AWS にカフェ (アプリケーション) を開店準備するまで" data-hatena-star-variant="profile-icon" data-hatena-star-profile-url-template="https://blog.hatena.ne.jp/{username}/" ></div> <div class="social-buttons"> <div class="social-button-item"> <a href="https://b.hatena.ne.jp/entry/s/cookie-box.hatenablog.com/entry/2023/09/21/235815" class="hatena-bookmark-button" data-hatena-bookmark-url="https://cookie-box.hatenablog.com/entry/2023/09/21/235815" data-hatena-bookmark-layout="vertical-balloon" data-hatena-bookmark-lang="ja" title="この記事をはてなブックマークに追加"><img src="https://b.st-hatena.com/images/entry-button/button-only.gif" alt="この記事をはてなブックマークに追加" width="20" height="20" style="border: none;" /></a> </div> <div class="social-button-item"> <div class="fb-share-button" data-layout="box_count" data-href="https://cookie-box.hatenablog.com/entry/2023/09/21/235815"></div> </div> <div class="social-button-item"> <a class="entry-share-button entry-share-button-twitter test-share-button-twitter" href="https://x.com/intent/tweet?text=%E9%9B%91%E8%A8%98%EF%BC%9A+AWS+%E3%81%AB%E3%82%AB%E3%83%95%E3%82%A7+(%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)+%E3%82%92%E9%96%8B%E5%BA%97%E6%BA%96%E5%82%99%E3%81%99%E3%82%8B%E3%81%BE%E3%81%A7+-+%E3%82%AF%E3%83%83%E3%82%AD%E3%83%BC%E3%81%AE%E6%97%A5%E8%A8%98&url=https%3A%2F%2Fcookie-box.hatenablog.com%2Fentry%2F2023%2F09%2F21%2F235815" title="X(Twitter)で投稿する" ></a> </div> </div> <div class="google-afc-image test-google-rectangle-ads"> <script> (valve = window.valve || []).push(function(v) { v.displayDFPSlot('google_afc_user_container_4'); }); </script> <div id="google_afc_user_container_4" class="google-afc-user-container google_afc_blocklink2_5 google_afc_boder" data-test-unit="/4374287/blog_user_2nd"></div> <a href="http://blog.hatena.ne.jp/guide/pro" class="open-pro-modal" data-guide-pro-modal-ad-url="https://hatena.blog/guide/pro/modal/ad">広告を非表示にする</a> </div> <div class="customized-footer"> </div> <div class="comment-box js-comment-box"> <ul class="comment js-comment"> <li class="read-more-comments" style="display: none;"><a>もっと読む</a></li> </ul> <a class="leave-comment-title js-leave-comment-title">コメントを書く</a> </div> </footer> </div> </article> <!-- rakuten_ad_target_end --> <!-- google_ad_section_end --> <div class="pager autopagerize_insert_before"> <span class="pager-next"> <a href="https://cookie-box.hatenablog.com/?page=1695308295" rel="next">次のページ</a> </span> </div> </div> </div> <aside id="box1"> <div id="box1-inner"> </div> </aside> </div><!-- #wrapper --> <aside id="box2"> <div id="box2-inner"> <div class="hatena-module hatena-module-category"> <div class="hatena-module-title"> カテゴリー </div> <div class="hatena-module-body"> <ul class="hatena-urllist"> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E9%9B%91%E8%A8%98" class="category-雑記"> 雑記 (209) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E6%BC%B8%E8%BF%91%E7%90%86%E8%AB%96" class="category-漸近理論"> 漸近理論 (13) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/Python" class="category-Python"> Python (9) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/Windows" class="category-Windows"> Windows (1) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E7%B5%B1%E8%A8%88%E7%9A%84%E5%9B%A0%E6%9E%9C%E6%8E%A8%E8%AB%96" class="category-統計的因果推論"> 統計的因果推論 (2) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/WSL2" class="category-WSL2"> WSL2 (2) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/PyTorch" class="category-PyTorch"> PyTorch (4) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/transformer" class="category-transformer"> transformer (6) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E7%B5%B1%E8%A8%88%E5%AD%A6" class="category-統計学"> 統計学 (4) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/Spring%20Boot" class="category-Spring-Boot"> Spring Boot (5) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/TeX" class="category-TeX"> TeX (3) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB%E6%B3%95" class="category-カーネル法"> カーネル法 (1) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92" class="category-機械学習"> 機械学習 (32) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E6%9C%AC%E8%AA%AD%E3%81%BF" class="category-本読み"> 本読み (97) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E8%AB%96%E6%96%87%E8%AA%AD%E3%81%BF" class="category-論文読み"> 論文読み (42) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E7%B5%B1%E8%A8%88%E7%9A%84%E4%BB%AE%E8%AA%AC%E6%A4%9C%E5%AE%9A" class="category-統計的仮説検定"> 統計的仮説検定 (2) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E7%B5%B1%E8%A8%88%E7%9A%84%E5%9B%A0%E6%9E%9C%E6%8E%A2%E7%B4%A2" class="category-統計的因果探索"> 統計的因果探索 (3) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E5%BC%B7%E5%8C%96%E5%AD%A6%E7%BF%92" class="category-強化学習"> 強化学習 (31) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/R" class="category-R"> R (14) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/MCMC" class="category-MCMC"> MCMC (8) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/Keras" class="category-Keras"> Keras (15) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/DLM" class="category-DLM"> DLM (14) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E6%B7%B1%E5%B1%A4%E5%AD%A6%E7%BF%92" class="category-深層学習"> 深層学習 (9) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E5%8B%89%E5%BC%B7%E4%BC%9A" class="category-勉強会"> 勉強会 (41) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E6%95%99%E5%B8%AB%E3%81%AA%E3%81%97%E5%AD%A6%E7%BF%92" class="category-教師なし学習"> 教師なし学習 (2) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E7%A2%BA%E7%8E%87%E8%AB%96" class="category-確率論"> 確率論 (22) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E6%95%B0%E7%90%86%E8%AB%96%E7%90%86%E5%AD%A6" class="category-数理論理学"> 数理論理学 (4) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E4%BD%8D%E7%9B%B8%E7%9A%84%E3%83%87%E3%83%BC%E3%82%BF%E8%A7%A3%E6%9E%90" class="category-位相的データ解析"> 位相的データ解析 (2) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E7%8A%B6%E6%85%8B%E7%A9%BA%E9%96%93%E3%83%A2%E3%83%87%E3%83%AB" class="category-状態空間モデル"> 状態空間モデル (2) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E3%82%B0%E3%83%A9%E3%83%95%E3%82%A3%E3%82%AB%E3%83%AB%E3%83%A2%E3%83%87%E3%83%AB" class="category-グラフィカルモデル"> グラフィカルモデル (1) </a> </li> <li> <a href="https://cookie-box.hatenablog.com/archive/category/%E8%A8%BC%E5%88%B8%E3%82%A2%E3%83%8A%E3%83%AA%E3%82%B9%E3%83%88" class="category-証券アナリスト"> 証券アナリスト (6) </a> </li> </ul> </div> </div> <div class="hatena-module hatena-module-profile"> <div class="hatena-module-title"> プロフィール </div> <div class="hatena-module-body"> <a href="https://cookie-box.hatenablog.com/about" class="profile-icon-link"> <img src="https://cdn.profile-image.st-hatena.com/users/cookie-box/profile.png?1578876096" alt="id:cookie-box" class="profile-icon" /> </a> <span class="id"> <a href="https://cookie-box.hatenablog.com/about" class="hatena-id-link"><span data-load-nickname="1" data-user-name="cookie-box">id:cookie-box</span></a> </span> <div class="profile-activities"> 最終更新: <time datetime="2024-11-12T09:13:50Z" data-relative data-epoch="1731402830000" class="updated">2024-11-12 18:13</time> </div> <div class="hatena-follow-button-box btn-subscribe js-hatena-follow-button-box" > <a href="#" class="hatena-follow-button js-hatena-follow-button"> <span class="subscribing"> <span class="foreground">読者です</span> <span class="background">読者をやめる</span> </span> <span class="unsubscribing" data-track-name="profile-widget-subscribe-button" data-track-once> <span class="foreground">読者になる</span> <span class="background">読者になる</span> </span> </a> <div class="subscription-count-box js-subscription-count-box"> <i></i> <u></u> <span class="subscription-count js-subscription-count"> </span> </div> </div> <div class="profile-about"> <a href="https://cookie-box.hatenablog.com/about">このブログについて</a> </div> </div> </div> <div class="hatena-module hatena-module-search-box"> <div class="hatena-module-title"> 検索 </div> <div class="hatena-module-body"> <form class="search-form" role="search" action="https://cookie-box.hatenablog.com/search" method="get"> <input type="text" name="q" class="search-module-input" value="" placeholder="記事を検索" required> <input type="submit" value="検索" class="search-module-button" /> </form> </div> </div> <div class="hatena-module hatena-module-recent-entries "> <div class="hatena-module-title"> <a href="https://cookie-box.hatenablog.com/archive"> 最新記事 </a> </div> <div class="hatena-module-body"> <ul class="recent-entries hatena-urllist "> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <span style="font-family: 'Lato', sans-serif;letter-spacing: 0.1em; font-size:105%;font-weight:bold">2024-11-12</span> <a href="https://cookie-box.hatenablog.com/entry/2024/11/12/181350">雑記</a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <span style="font-family: 'Lato', sans-serif;letter-spacing: 0.1em; font-size:105%;font-weight:bold">2024-07-18</span> <a href="https://cookie-box.hatenablog.com/entry/2024/07/18/235843">雑記: Transformer で記事から回答文を選択するための継続事前学習方法の話</a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <span style="font-family: 'Lato', sans-serif;letter-spacing: 0.1em; font-size:105%;font-weight:bold">2024-02-23</span> <a href="https://cookie-box.hatenablog.com/entry/2024/02/23/100110">雑記:1つの一様乱数から2つの独立な一様乱数ができる</a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <span style="font-family: 'Lato', sans-serif;letter-spacing: 0.1em; font-size:105%;font-weight:bold">2023-12-07</span> <a href="https://cookie-box.hatenablog.com/entry/2023/12/07/000000">雑記: ルーヴァン法とライデン法の話</a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <span style="font-family: 'Lato', sans-serif;letter-spacing: 0.1em; font-size:105%;font-weight:bold">2023-09-21</span> <a href="https://cookie-box.hatenablog.com/entry/2023/09/21/235815">雑記: AWS にカフェ (アプリケーション) を開店準備するまで</a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <span style="font-family: 'Lato', sans-serif;letter-spacing: 0.1em; font-size:105%;font-weight:bold">2023-07-27</span> <a href="https://cookie-box.hatenablog.com/entry/2023/07/27/141714">雑記: 自分のパッケージに Sphinx + Read the Docs によるドキュメントを用意する</a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <span style="font-family: 'Lato', sans-serif;letter-spacing: 0.1em; font-size:105%;font-weight:bold">2023-07-26</span> <a href="https://cookie-box.hatenablog.com/entry/2023/07/26/015309">雑記: 自分のパッケージを TestPyPI(PyPI のテスト環境)に登録するまで―外部パッケージに依存する場合</a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <span style="font-family: 'Lato', sans-serif;letter-spacing: 0.1em; font-size:105%;font-weight:bold">2023-07-25</span> <a href="https://cookie-box.hatenablog.com/entry/2023/07/25/102058">雑記: 自分のパッケージを TestPyPI(PyPI のテスト環境)に登録するまで</a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <span style="font-family: 'Lato', sans-serif;letter-spacing: 0.1em; font-size:105%;font-weight:bold">2023-07-19</span> <a href="https://cookie-box.hatenablog.com/entry/2023/07/19/203301">雑記: Windows 11 上の CUDA と PyTorch のアップグレード</a> </div> </li> <li class="urllist-item recent-entries-item"> <div class="urllist-item-inner recent-entries-item-inner"> <span style="font-family: 'Lato', sans-serif;letter-spacing: 0.1em; font-size:105%;font-weight:bold">2023-07-05</span> <a href="https://cookie-box.hatenablog.com/entry/2023/07/05/235534">雑記</a> </div> </li> </ul> </div> </div> <div class="hatena-module hatena-module-entries-access-ranking" data-count="10" data-source="access" data-enable_customize_format="0" data-display_entry_image_size_width="100" data-display_entry_image_size_height="100" data-display_entry_category="0" data-display_entry_image="0" data-display_entry_image_size_width="100" data-display_entry_image_size_height="100" data-display_entry_body_length="0" data-display_entry_date="0" data-display_entry_title_length="20" data-restrict_entry_title_length="0" data-display_bookmark_count="0" > <div class="hatena-module-title"> 注目記事 </div> <div class="hatena-module-body"> </div> </div> <div class="hatena-module hatena-module-archive" data-archive-type="default" data-archive-url="https://cookie-box.hatenablog.com/archive"> <div class="hatena-module-title"> <a href="https://cookie-box.hatenablog.com/archive">月別アーカイブ</a> </div> <div class="hatena-module-body"> <ul class="hatena-urllist"> <li class="archive-module-year archive-module-year-hidden" data-year="2024"> <div class="archive-module-button"> <span class="archive-module-hide-button">▼</span> <span class="archive-module-show-button">▶</span> </div> <a href="https://cookie-box.hatenablog.com/archive/2024" class="archive-module-year-title archive-module-year-2024"> 2024 </a> <ul class="archive-module-months"> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2024/11" class="archive-module-month-title archive-module-month-2024-11"> 2024 / 11 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2024/07" class="archive-module-month-title archive-module-month-2024-7"> 2024 / 7 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2024/02" class="archive-module-month-title archive-module-month-2024-2"> 2024 / 2 </a> </li> </ul> </li> <li class="archive-module-year archive-module-year-hidden" data-year="2023"> <div class="archive-module-button"> <span class="archive-module-hide-button">▼</span> <span class="archive-module-show-button">▶</span> </div> <a href="https://cookie-box.hatenablog.com/archive/2023" class="archive-module-year-title archive-module-year-2023"> 2023 </a> <ul class="archive-module-months"> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2023/12" class="archive-module-month-title archive-module-month-2023-12"> 2023 / 12 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2023/09" class="archive-module-month-title archive-module-month-2023-9"> 2023 / 9 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2023/07" class="archive-module-month-title archive-module-month-2023-7"> 2023 / 7 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2023/06" class="archive-module-month-title archive-module-month-2023-6"> 2023 / 6 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2023/02" class="archive-module-month-title archive-module-month-2023-2"> 2023 / 2 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2023/01" class="archive-module-month-title archive-module-month-2023-1"> 2023 / 1 </a> </li> </ul> </li> <li class="archive-module-year archive-module-year-hidden" data-year="2022"> <div class="archive-module-button"> <span class="archive-module-hide-button">▼</span> <span class="archive-module-show-button">▶</span> </div> <a href="https://cookie-box.hatenablog.com/archive/2022" class="archive-module-year-title archive-module-year-2022"> 2022 </a> <ul class="archive-module-months"> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2022/11" class="archive-module-month-title archive-module-month-2022-11"> 2022 / 11 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2022/08" class="archive-module-month-title archive-module-month-2022-8"> 2022 / 8 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2022/06" class="archive-module-month-title archive-module-month-2022-6"> 2022 / 6 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2022/05" class="archive-module-month-title archive-module-month-2022-5"> 2022 / 5 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2022/04" class="archive-module-month-title archive-module-month-2022-4"> 2022 / 4 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2022/03" class="archive-module-month-title archive-module-month-2022-3"> 2022 / 3 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2022/01" class="archive-module-month-title archive-module-month-2022-1"> 2022 / 1 </a> </li> </ul> </li> <li class="archive-module-year archive-module-year-hidden" data-year="2021"> <div class="archive-module-button"> <span class="archive-module-hide-button">▼</span> <span class="archive-module-show-button">▶</span> </div> <a href="https://cookie-box.hatenablog.com/archive/2021" class="archive-module-year-title archive-module-year-2021"> 2021 </a> <ul class="archive-module-months"> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2021/12" class="archive-module-month-title archive-module-month-2021-12"> 2021 / 12 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2021/11" class="archive-module-month-title archive-module-month-2021-11"> 2021 / 11 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2021/10" class="archive-module-month-title archive-module-month-2021-10"> 2021 / 10 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2021/09" class="archive-module-month-title archive-module-month-2021-9"> 2021 / 9 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2021/06" class="archive-module-month-title archive-module-month-2021-6"> 2021 / 6 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2021/05" class="archive-module-month-title archive-module-month-2021-5"> 2021 / 5 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2021/04" class="archive-module-month-title archive-module-month-2021-4"> 2021 / 4 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2021/03" class="archive-module-month-title archive-module-month-2021-3"> 2021 / 3 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2021/02" class="archive-module-month-title archive-module-month-2021-2"> 2021 / 2 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2021/01" class="archive-module-month-title archive-module-month-2021-1"> 2021 / 1 </a> </li> </ul> </li> <li class="archive-module-year archive-module-year-hidden" data-year="2020"> <div class="archive-module-button"> <span class="archive-module-hide-button">▼</span> <span class="archive-module-show-button">▶</span> </div> <a href="https://cookie-box.hatenablog.com/archive/2020" class="archive-module-year-title archive-module-year-2020"> 2020 </a> <ul class="archive-module-months"> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2020/12" class="archive-module-month-title archive-module-month-2020-12"> 2020 / 12 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2020/11" class="archive-module-month-title archive-module-month-2020-11"> 2020 / 11 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2020/10" class="archive-module-month-title archive-module-month-2020-10"> 2020 / 10 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2020/09" class="archive-module-month-title archive-module-month-2020-9"> 2020 / 9 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2020/08" class="archive-module-month-title archive-module-month-2020-8"> 2020 / 8 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2020/07" class="archive-module-month-title archive-module-month-2020-7"> 2020 / 7 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2020/06" class="archive-module-month-title archive-module-month-2020-6"> 2020 / 6 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2020/05" class="archive-module-month-title archive-module-month-2020-5"> 2020 / 5 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2020/04" class="archive-module-month-title archive-module-month-2020-4"> 2020 / 4 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2020/03" class="archive-module-month-title archive-module-month-2020-3"> 2020 / 3 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2020/02" class="archive-module-month-title archive-module-month-2020-2"> 2020 / 2 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2020/01" class="archive-module-month-title archive-module-month-2020-1"> 2020 / 1 </a> </li> </ul> </li> <li class="archive-module-year archive-module-year-hidden" data-year="2019"> <div class="archive-module-button"> <span class="archive-module-hide-button">▼</span> <span class="archive-module-show-button">▶</span> </div> <a href="https://cookie-box.hatenablog.com/archive/2019" class="archive-module-year-title archive-module-year-2019"> 2019 </a> <ul class="archive-module-months"> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2019/12" class="archive-module-month-title archive-module-month-2019-12"> 2019 / 12 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2019/11" class="archive-module-month-title archive-module-month-2019-11"> 2019 / 11 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2019/10" class="archive-module-month-title archive-module-month-2019-10"> 2019 / 10 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2019/09" class="archive-module-month-title archive-module-month-2019-9"> 2019 / 9 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2019/08" class="archive-module-month-title archive-module-month-2019-8"> 2019 / 8 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2019/07" class="archive-module-month-title archive-module-month-2019-7"> 2019 / 7 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2019/06" class="archive-module-month-title archive-module-month-2019-6"> 2019 / 6 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2019/05" class="archive-module-month-title archive-module-month-2019-5"> 2019 / 5 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2019/04" class="archive-module-month-title archive-module-month-2019-4"> 2019 / 4 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2019/03" class="archive-module-month-title archive-module-month-2019-3"> 2019 / 3 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2019/02" class="archive-module-month-title archive-module-month-2019-2"> 2019 / 2 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2019/01" class="archive-module-month-title archive-module-month-2019-1"> 2019 / 1 </a> </li> </ul> </li> <li class="archive-module-year archive-module-year-hidden" data-year="2018"> <div class="archive-module-button"> <span class="archive-module-hide-button">▼</span> <span class="archive-module-show-button">▶</span> </div> <a href="https://cookie-box.hatenablog.com/archive/2018" class="archive-module-year-title archive-module-year-2018"> 2018 </a> <ul class="archive-module-months"> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2018/12" class="archive-module-month-title archive-module-month-2018-12"> 2018 / 12 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2018/11" class="archive-module-month-title archive-module-month-2018-11"> 2018 / 11 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2018/10" class="archive-module-month-title archive-module-month-2018-10"> 2018 / 10 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2018/09" class="archive-module-month-title archive-module-month-2018-9"> 2018 / 9 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2018/08" class="archive-module-month-title archive-module-month-2018-8"> 2018 / 8 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2018/07" class="archive-module-month-title archive-module-month-2018-7"> 2018 / 7 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2018/06" class="archive-module-month-title archive-module-month-2018-6"> 2018 / 6 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2018/05" class="archive-module-month-title archive-module-month-2018-5"> 2018 / 5 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2018/04" class="archive-module-month-title archive-module-month-2018-4"> 2018 / 4 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2018/03" class="archive-module-month-title archive-module-month-2018-3"> 2018 / 3 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2018/02" class="archive-module-month-title archive-module-month-2018-2"> 2018 / 2 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2018/01" class="archive-module-month-title archive-module-month-2018-1"> 2018 / 1 </a> </li> </ul> </li> <li class="archive-module-year archive-module-year-hidden" data-year="2017"> <div class="archive-module-button"> <span class="archive-module-hide-button">▼</span> <span class="archive-module-show-button">▶</span> </div> <a href="https://cookie-box.hatenablog.com/archive/2017" class="archive-module-year-title archive-module-year-2017"> 2017 </a> <ul class="archive-module-months"> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2017/12" class="archive-module-month-title archive-module-month-2017-12"> 2017 / 12 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2017/10" class="archive-module-month-title archive-module-month-2017-10"> 2017 / 10 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2017/08" class="archive-module-month-title archive-module-month-2017-8"> 2017 / 8 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2017/07" class="archive-module-month-title archive-module-month-2017-7"> 2017 / 7 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2017/06" class="archive-module-month-title archive-module-month-2017-6"> 2017 / 6 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2017/05" class="archive-module-month-title archive-module-month-2017-5"> 2017 / 5 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2017/04" class="archive-module-month-title archive-module-month-2017-4"> 2017 / 4 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2017/03" class="archive-module-month-title archive-module-month-2017-3"> 2017 / 3 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2017/02" class="archive-module-month-title archive-module-month-2017-2"> 2017 / 2 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2017/01" class="archive-module-month-title archive-module-month-2017-1"> 2017 / 1 </a> </li> </ul> </li> <li class="archive-module-year archive-module-year-hidden" data-year="2016"> <div class="archive-module-button"> <span class="archive-module-hide-button">▼</span> <span class="archive-module-show-button">▶</span> </div> <a href="https://cookie-box.hatenablog.com/archive/2016" class="archive-module-year-title archive-module-year-2016"> 2016 </a> <ul class="archive-module-months"> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2016/12" class="archive-module-month-title archive-module-month-2016-12"> 2016 / 12 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2016/11" class="archive-module-month-title archive-module-month-2016-11"> 2016 / 11 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2016/10" class="archive-module-month-title archive-module-month-2016-10"> 2016 / 10 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2016/09" class="archive-module-month-title archive-module-month-2016-9"> 2016 / 9 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2016/08" class="archive-module-month-title archive-module-month-2016-8"> 2016 / 8 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2016/07" class="archive-module-month-title archive-module-month-2016-7"> 2016 / 7 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2016/06" class="archive-module-month-title archive-module-month-2016-6"> 2016 / 6 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2016/05" class="archive-module-month-title archive-module-month-2016-5"> 2016 / 5 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2016/04" class="archive-module-month-title archive-module-month-2016-4"> 2016 / 4 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2016/03" class="archive-module-month-title archive-module-month-2016-3"> 2016 / 3 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2016/02" class="archive-module-month-title archive-module-month-2016-2"> 2016 / 2 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2016/01" class="archive-module-month-title archive-module-month-2016-1"> 2016 / 1 </a> </li> </ul> </li> <li class="archive-module-year archive-module-year-hidden" data-year="2015"> <div class="archive-module-button"> <span class="archive-module-hide-button">▼</span> <span class="archive-module-show-button">▶</span> </div> <a href="https://cookie-box.hatenablog.com/archive/2015" class="archive-module-year-title archive-module-year-2015"> 2015 </a> <ul class="archive-module-months"> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2015/12" class="archive-module-month-title archive-module-month-2015-12"> 2015 / 12 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2015/11" class="archive-module-month-title archive-module-month-2015-11"> 2015 / 11 </a> </li> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/2015/04" class="archive-module-month-title archive-module-month-2015-4"> 2015 / 4 </a> </li> </ul> </li> <li class="archive-module-year archive-module-year-hidden" data-year="1970"> <div class="archive-module-button"> <span class="archive-module-hide-button">▼</span> <span class="archive-module-show-button">▶</span> </div> <a href="https://cookie-box.hatenablog.com/archive/1970" class="archive-module-year-title archive-module-year-1970"> 1970 </a> <ul class="archive-module-months"> <li class="archive-module-month"> <a href="https://cookie-box.hatenablog.com/archive/1970/01" class="archive-module-month-title archive-module-month-1970-1"> 1970 / 1 </a> </li> </ul> </li> </ul> </div> </div> </div> </aside> </div> </div> <div id="bottom-editarea"> <script> $(window).on("DOMContentLoaded", function(){ var $title = $(".acodion-title"); var $content = $(".acodion-content"); $title.on("click", function(){ var indx = $title.index($(this)); $content.eq(indx).slideToggle(300); }); }); </script> </div> </div> </div> <footer id="footer" data-brand="hatenablog"> <div id="footer-inner"> <address class="footer-address"> <a href="https://cookie-box.hatenablog.com/"> <img src="https://cdn.blog.st-hatena.com/images/admin/blog-icon-noimage.png" width="16" height="16" alt="クッキーの日記"/> <span class="footer-address-name">クッキーの日記</span> </a> </address> <p class="services"> Powered by <a href="https://hatena.blog/">Hatena Blog</a> | <a href="https://blog.hatena.ne.jp/-/abuse_report?target_url=https%3A%2F%2Fcookie-box.hatenablog.com%2F" class="report-abuse-link test-report-abuse-link" target="_blank">ブログを報告する</a> </p> </div> </footer> <script async src="https://s.hatena.ne.jp/js/widget/star.js"></script> <script> if (typeof window.Hatena === 'undefined') { window.Hatena = {}; } if (!Hatena.hasOwnProperty('Star')) { Hatena.Star = { VERSION: 2, }; } </script> <div id="fb-root"></div> <script>(function(d, s, id) { var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)) return; js = d.createElement(s); js.id = id; js.src = "//connect.facebook.net/ja_JP/sdk.js#xfbml=1&appId=719729204785177&version=v17.0"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk'));</script> <div class="quote-box"> <div class="tooltip-quote tooltip-quote-stock"> <i class="blogicon-quote" title="引用をストック"></i> </div> <div class="tooltip-quote tooltip-quote-tweet js-tooltip-quote-tweet"> <a class="js-tweet-quote" target="_blank" data-track-name="quote-tweet" data-track-once> <img src="https://cdn.blog.st-hatena.com/images/admin/quote/quote-x-icon.svg?version=4c841dff904291fd18670d1f8165c6" title="引用して投稿する" > </a> </div> </div> <div class="quote-stock-panel" id="quote-stock-message-box" style="position: absolute; z-index: 3000"> <div class="message-box" id="quote-stock-succeeded-message" style="display: none"> <p>引用をストックしました</p> <button class="btn btn-primary" id="quote-stock-show-editor-button" data-track-name="curation-quote-edit-button">ストック一覧を見る</button> <button class="btn quote-stock-close-message-button">閉じる</button> </div> <div class="message-box" id="quote-login-required-message" style="display: none"> <p>引用するにはまずログインしてください</p> <button class="btn btn-primary" id="quote-login-button">ログイン</button> <button class="btn quote-stock-close-message-button">閉じる</button> </div> <div class="error-box" id="quote-stock-failed-message" style="display: none"> <p>引用をストックできませんでした。再度お試しください</p> <button class="btn quote-stock-close-message-button">閉じる</button> </div> <div class="error-box" id="unstockable-quote-message-box" style="display: none; position: absolute; z-index: 3000;"> <p>限定公開記事のため引用できません。</p> </div> </div> <script type="x-underscore-template" id="js-requote-button-template"> <div class="requote-button js-requote-button"> <button class="requote-button-btn tipsy-top" title="引用する"><i class="blogicon-quote"></i></button> </div> </script> <div id="hidden-subscribe-button" style="display: none;"> <div class="hatena-follow-button-box btn-subscribe js-hatena-follow-button-box" > <a href="#" class="hatena-follow-button js-hatena-follow-button"> <span class="subscribing"> <span class="foreground">読者です</span> <span class="background">読者をやめる</span> </span> <span class="unsubscribing" data-track-name="profile-widget-subscribe-button" data-track-once> <span class="foreground">読者になる</span> <span class="background">読者になる</span> </span> </a> <div class="subscription-count-box js-subscription-count-box"> <i></i> <u></u> <span class="subscription-count js-subscription-count"> </span> </div> </div> </div> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> <script src="https://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script> <script type="text/javascript" src="https://cdn.blog.st-hatena.com/js/external/jquery.min.js?v=1.12.4&version=4c841dff904291fd18670d1f8165c6"></script> <script src="https://cdn.blog.st-hatena.com/js/texts-ja.js?version=4c841dff904291fd18670d1f8165c6"></script> <script id="vendors-js" data-env="production" src="https://cdn.blog.st-hatena.com/js/vendors.js?version=4c841dff904291fd18670d1f8165c6" crossorigin="anonymous"></script> <script id="hatenablog-js" data-env="production" src="https://cdn.blog.st-hatena.com/js/hatenablog.js?version=4c841dff904291fd18670d1f8165c6" crossorigin="anonymous" data-page-id="index"></script> <script>Hatena.Diary.GlobalHeader.init()</script> <script id="valve-dmp" data-service="blog" src="https://cdn.pool.st-hatena.com/valve/dmp.js" data-test-id="dmpjs" async></script> </body> </html>