[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article:cookpad-recipe-search-ranking":3},{"meta":4,"markdown":117},{"type":5,"articleId":6,"slug":7,"title":8,"titleEn":9,"category":10,"summary":11,"publishedAt":12,"image":13,"vocabulary":14},"article","tech-cookpad-recipe-search","cookpad-recipe-search-ranking","Cookpadのレシピ検索 — 学習to-rank実装","Cookpad's Recipe Search — Learning-to-Rank Implementation","tech","Cookpad's recipe search ranking — features (ingredient match, popularity, season, user history), learning-to-rank model architecture, A\u002FB testing infrastructure, and Japanese morphological analysis with mecab\u002Fkuromoji including seasonal and regional variation.\n","2026-04-27T00:00:00Z","https:\u002F\u002Fimages.yamiyomi.com\u002Ftech-cookpad-recipe-search.png",[15,20,25,29,33,38,42,46,50,54,58,62,66,70,74,78,82,86,90,94,98,102,106,109,113],{"word":16,"reading":17,"meaning":18,"level":19},"検索","けんさく","search","N2",{"word":21,"reading":22,"meaning":23,"level":24},"順位付け","じゅんいづけ","ranking","N1",{"word":26,"reading":27,"meaning":28,"level":19},"食材","しょくざい","ingredients",{"word":30,"reading":31,"meaning":32,"level":19},"一致","いっち","match",{"word":34,"reading":35,"meaning":36,"level":37},"人気","にんき","popularity","N3",{"word":39,"reading":40,"meaning":41,"level":37},"季節","きせつ","season",{"word":43,"reading":44,"meaning":45,"level":24},"履歴","りれき","history",{"word":47,"reading":48,"meaning":49,"level":37},"学習","がくしゅう","learning",{"word":51,"reading":52,"meaning":53,"level":24},"形態素","けいたいそ","morpheme",{"word":55,"reading":56,"meaning":57,"level":19},"解析","かいせき","analysis",{"word":59,"reading":60,"meaning":61,"level":19},"地域","ちいき","region",{"word":63,"reading":64,"meaning":65,"level":24},"変動","へんどう","variation",{"word":67,"reading":68,"meaning":69,"level":24},"旬","しゅん","peak season",{"word":71,"reading":72,"meaning":73,"level":24},"特徴量","とくちょうりょう","feature",{"word":75,"reading":76,"meaning":77,"level":24},"推薦","すいせん","recommendation",{"word":79,"reading":80,"meaning":81,"level":24},"嗜好","しこう","preference",{"word":83,"reading":84,"meaning":85,"level":24},"個人化","こじんか","personalization",{"word":87,"reading":88,"meaning":89,"level":19},"評価","ひょうか","evaluation",{"word":91,"reading":92,"meaning":93,"level":24},"指標","しひょう","metric",{"word":95,"reading":96,"meaning":97,"level":19},"検証","けんしょう","verification",{"word":99,"reading":100,"meaning":101,"level":19},"改善","かいぜん","improvement",{"word":103,"reading":104,"meaning":105,"level":19},"索引","さくいん","index",{"word":107,"reading":108,"meaning":65,"level":19},"揺れ","ゆれ",{"word":110,"reading":111,"meaning":112,"level":19},"表記","ひょうき","notation",{"word":114,"reading":115,"meaning":116,"level":24},"同義語","どうぎご","synonym","\n::para\n[クックパッド]{くっくぱっど:Cookpad}は[日本]{にほん:Japan:N5}[最大級]{さいだいきゅう:largest-class:N1}のレシピ[投稿]{とうこう:posting:N1}サービスとして、[一日]{いちにち:one day:N5}に[数]{すう:several:N3}[百万]{ひゃくまん:million:N5}[件]{けん:cases:N3}のレシピ[検索]{けんさく:search:N1}を[処理]{しょり:process:N3}しています。「[今夜]{こんや:tonight:N4}の[献立]{こんだて:menu:N1}」を[考える]{かんがえる:to think:N4}[利用者]{りようしゃ:user:N3}が[最も]{もっとも:most:N3}[満足]{まんぞく:satisfied:N3}するレシピを[上位]{じょうい:top:N3}に[並べる]{ならべる:to line up:N2}ためには、[単純な]{たんじゅんな:simple:N2}キーワード[一致]{いっち:match:N1}だけでは[不十分]{ふじゅうぶん:insufficient:N4}です。[本]{ほん:this:N5}[記事]{きじ:article:N3}では[クックパッド]{くっくぱっど:Cookpad}の[検索]{けんさく:search:N1}[順位付け]{じゅんいづけ:ranking:N2}の[全体]{ぜんたい:overall:N3}[像]{ぞう:picture:N2}を[整理]{せいり:organize:N1}します。\n\n#en\nCookpad, as one of Japan's largest-class recipe posting services, processes several million recipe searches per day. To rank the recipes that most satisfy users thinking about \"tonight's menu\" at the top, simple keyword matching alone is insufficient. This article organizes the overall picture of Cookpad's search ranking.\n::\n\n::heading\n[特徴量]{とくちょうりょう:features:N1}の[設計]{せっけい:design:N2}\n\n#en\nFeature Design\n::\n\n::para\n[順位付け]{じゅんいづけ:ranking:N2}モデルに[入力]{にゅうりょく:input:N4}される[特徴量]{とくちょうりょう:features:N1}は[多]{た:many:N4}[岐]{き:branches:N1}にわたります。[食材]{しょくざい:ingredient:N2}の[一致]{いっち:match:N1}[度]{ど:degree:N4}、レシピの[人気]{にんき:popularity:N5}（[つくれぽ]{つくれぽ:tsukurepo (cooked report) count}[数]{すう:count:N3}や[保存]{ほぞん:save:N1}[数]{すう:count:N3}）、[季節]{きせつ:season:N1}との[相性]{あいしょう:compatibility:N3}、[利用者]{りようしゃ:user:N3}の[過去]{かこ:past:N3}[閲覧]{えつらん:browsing:N1}[履歴]{りれき:history:N1}、[作者]{さくしゃ:author:N4}の[信頼]{しんらい:trust:N3}[度]{ど:degree:N4}、[投稿]{とうこう:posted:N1}からの[経過]{けいか:elapsed:N3}[時間]{じかん:time:N5}など、[数十]{すうじゅう:dozens:N3}から[数百]{すうひゃく:hundreds:N3}に[及ぶ]{およぶ:reaching:N1}[特徴量]{とくちょうりょう:features:N1}を[組み合わせ]{くみあわせ:combine:N3}ます。\n\n#en\nThe features fed into the ranking model are diverse — ingredient match degree, recipe popularity (number of tsukurepo \"cooked reports\" and saves), seasonal compatibility, the user's past browsing history, author trust level, time elapsed since posting, and more. Dozens to hundreds of features are combined.\n::\n\n::callout\n[良い]{よい:good:N3}[特徴量]{とくちょうりょう:features:N1}が[全て]{すべて:all:N3}を[決める]{きめる:to decide:N3}。モデルが[凝った]{こった:elaborate:N1}ものでも[特徴量]{とくちょうりょう:features:N1}が[貧弱]{ひんじゃく:poor:N2}なら[精度]{せいど:accuracy:N3}は[出ない]{でない:does not appear:N5}。\n\n#en\nGood features decide everything. Even with an elaborate model, if features are poor, accuracy will not appear.\n::\n\n::heading\n[形態素]{けいたいそ:morpheme:N1}[解析]{かいせき:analysis:N1}と[日本語]{にほんご:Japanese:N5}[特有]{とくゆう:specific:N4}の[難しさ]{むずかしさ:difficulty:N3}\n\n#en\nMorphological Analysis and Japanese-Specific Difficulties\n::\n\n::para\n[日本語]{にほんご:Japanese:N5}の[検索]{けんさく:search:N1}クエリは[英語]{えいご:English:N4}のように[空白]{くうはく:space:N4}で[単語]{たんご:word:N3}が[区切られて]{くぎられて:separated:N2}いません。「[豚肉]{ぶたにく:pork:N1}キャベツ[簡単]{かんたん:easy:N2}」というクエリを[処理]{しょり:process:N3}するためには、[形態素]{けいたいそ:morpheme:N1}[解析]{かいせき:analysis:N1}[器]{き:tool:N1}（[mecab]{めかぶ:mecab}や[kuromoji]{くろもじ:kuromoji}）で[単語]{たんご:word:N3}に[分解]{ぶんかい:break down:N3}する[必要]{ひつよう:necessity:N3}があります。[クックパッド]{くっくぱっど:Cookpad}は[料理]{りょうり:cooking:N4}[ドメイン]{どめいん:domain}に[特化]{とっか:specialized:N3}した[辞書]{じしょ:dictionary:N3}を[整備]{せいび:maintain:N1}し、[食材]{しょくざい:ingredient:N2}[名]{めい:name:N5}や[料理]{りょうり:cooking:N4}[用語]{ようご:term:N4}を[正しく]{ただしく:correctly:N4}[切り出せる]{きりだせる:can extract:N4}ようにしています。\n\n#en\nJapanese search queries are not separated by spaces between words like English. To process the query \"pork cabbage easy,\" it must be decomposed into words by a morphological analyzer (mecab or kuromoji). Cookpad maintains a dictionary specialized for the cooking domain so that ingredient names and cooking terms can be correctly extracted.\n::\n\n::heading\n[表記]{ひょうき:notation:N3}[揺れ]{ゆれ:variation:N1}と[同義語]{どうぎご:synonym:N1}の[吸収]{きゅうしゅう:absorbing:N3}\n\n#en\nAbsorbing Notation Variations and Synonyms\n::\n\n::para\n「[人参]{にんじん:carrot:N3}」「ニンジン」「にんじん」、「[豚]{ぶた:pork:N1}バラ」「[豚]{ぶた:pork:N1}ばら[肉]{にく:meat:N4}」など[同じ]{おなじ:same:N4}[食材]{しょくざい:ingredient:N2}でも[表記]{ひょうき:notation:N3}の[揺れ]{ゆれ:variation:N1}が[豊富]{ほうふ:abundant:N2}にあります。[索引]{さくいん:index:N1}[時]{じ:time:N5}にこれらを[正規]{せいき:normalized:N3}[化]{か:-ize:N3}し、クエリ[側]{がわ:side:N3}でも[同義語]{どうぎご:synonym:N1}[展開]{てんかい:expansion:N1}を[行う]{おこなう:perform:N5}ことで、ユーザーが[どの]{どの:which}[書き方]{かきかた:way of writing:N4}をしても[同じ]{おなじ:same:N4}レシピが[ヒット]{ひっと:hit}するようになります。\n\n#en\nThe same ingredient has abundant notation variations — \"人参 \u002F ニンジン \u002F にんじん\" for carrot, \"豚バラ \u002F 豚ばら肉\" for pork belly. By normalizing these at indexing time and performing synonym expansion on the query side, the same recipes will hit regardless of how the user writes them.\n::\n\n::heading\n[学習]{がくしゅう:learning:N4}to-rankモデル\n\n#en\nLearning-to-Rank Model\n::\n\n::para\n[特徴量]{とくちょうりょう:features:N1}を[人手]{ひとで:manually:N4}で[重み]{おもみ:weight:N4}[付け]{つけ:add:N3}するのではなく、[利用者]{りようしゃ:user:N3}のクリックや[つくれぽ]{つくれぽ:tsukurepo}[投稿]{とうこう:posting:N1}を[正解]{せいかい:correct answer:N3}データとして[学習]{がくしゅう:learning:N4}するモデルが[使われ]{つかわれ:used:N4}ます。LambdaMARTやXGBoostといった[勾配]{こうばい:gradient:N1}[ブースティング]{ぶーすてぃんぐ:boosting}[木]{き:tree:N5}モデルが[代表的]{だいひょうてき:representative:N3}で、[各]{かく:each:N2}[特徴量]{とくちょうりょう:features:N1}の[重要]{じゅうよう:importance:N3}[度]{ど:degree:N4}を[自動的]{じどうてき:automatically:N4}に[学習]{がくしゅう:learn:N4}します。「[人気]{にんき:popularity:N5}が[高ければ]{たかければ:if high:N5}よい」という[単純]{たんじゅん:simple:N2}な[線形]{せんけい:linear:N2}[関係]{かんけい:relationship:N3}ではなく、[食材]{しょくざい:ingredient:N2}[一致]{いっち:match:N1}との[組み合わせ]{くみあわせ:combination:N3}で[非]{ひ:non-:N3}[線形]{せんけい:linear:N2}に[評価]{ひょうか:evaluate:N1}できる[点]{てん:point:N3}が[強み]{つよみ:strength:N4}です。\n\n#en\nRather than weighting features manually, models that learn from user clicks and tsukurepo postings as ground truth are used. Gradient boosting tree models like LambdaMART and XGBoost are representative, automatically learning the importance of each feature. The strength is that they can evaluate non-linearly through combinations with ingredient match, rather than as a simple linear relationship like \"high popularity is good.\"\n::\n\n::heading\n[季節]{きせつ:season:N1}と[地域]{ちいき:regional:N2}[変動]{へんどう:variation:N3}\n\n#en\nSeasonal and Regional Variation\n::\n\n::para\n[日本]{にほん:Japan:N5}の[食]{しょく:food:N5}[文化]{ぶんか:culture:N3}は[季節]{きせつ:season:N1}と[強く]{つよく:strongly:N4}[結びついて]{むすびついて:tied:N1}おり、[夏]{なつ:summer:N4}は[冷]{ひや:chilled:N3}やし[中華]{ちゅうか:Chinese:N1}や[素麺]{そうめん:somen noodles:N1}、[冬]{ふゆ:winter:N4}は[鍋]{なべ:hot pot:N1}や[煮込み]{にこみ:stews:N1}が[人気]{にんき:popular:N5}です。[クックパッド]{くっくぱっど:Cookpad}は[食材]{しょくざい:ingredient:N2}の[旬]{しゅん:peak season:N1}や[気温]{きおん:temperature:N2}と[連動]{れんどう:linked:N3}した[特徴量]{とくちょうりょう:features:N1}を[加え]{くわえ:add:N3}、[同じ]{おなじ:same:N4}「[簡単]{かんたん:easy:N2}レシピ」というクエリでも[時期]{じき:time period:N3}によって[結果]{けっか:result:N1}が[変わる]{かわる:to change:N3}ように[設計]{せっけい:design:N2}しています。[地域]{ちいき:regional:N2}[差]{さ:difference:N3}（[関西]{かんさい:Kansai:N3}と[関東]{かんとう:Kanto:N3}の[味付け]{あじつけ:seasoning:N3}など）も[考慮]{こうりょ:consider:N1}に[入れ]{いれ:put in:N5}ます。\n\n#en\nJapanese food culture is strongly tied to seasons — chilled Chinese noodles and somen are popular in summer, hot pots and stews in winter. Cookpad adds features linked to ingredient peak seasons and temperature, designed so that even the same \"easy recipe\" query yields different results by time period. Regional differences (such as Kansai vs Kanto seasoning) are also taken into consideration.\n::\n\n::heading\nA\u002FBテスト[基盤]{きばん:infrastructure:N1}\n\n#en\nA\u002FB Testing Infrastructure\n::\n\n::para\n[新しい]{あたらしい:new:N4}モデルや[特徴量]{とくちょうりょう:features:N1}を[本番]{ほんばん:production:N3}に[投入]{とうにゅう:deploy:N3}する[前]{まえ:before:N5}に、[必ず]{かならず:always:N3}A\u002FBテストで[既存]{きそん:existing:N1}モデルとの[差]{さ:difference:N3}を[計測]{けいそく:measure:N2}します。[評価]{ひょうか:evaluation:N1}[指標]{しひょう:metric:N1}は[クリック]{くりっく:click}[率]{りつ:rate:N1}だけでなく、「[つくれぽ]{つくれぽ:tsukurepo}が[投稿]{とうこう:posted:N1}されたか」「[保存]{ほぞん:save:N1}されたか」など[料理]{りょうり:cooking:N4}が[実際に]{じっさいに:actually:N3}[作られた]{つくられた:cooked:N4}ことを[示す]{しめす:indicate:N3}[後段]{こうだん:downstream:N3}の[行動]{こうどう:action:N4}を[重視]{じゅうし:emphasize:N1}します。クリックされても[作られ]{つくられ:cooked:N4}なければ[本当の]{ほんとうの:true:N3}[満足]{まんぞく:satisfaction:N3}とは[言えない]{いえない:cannot say:N4}からです。\n\n#en\nBefore deploying a new model or feature to production, the difference from the existing model is always measured via A\u002FB test. Evaluation metrics emphasize not only click rate but also downstream actions that show the dish was actually cooked — \"was a tsukurepo posted?\" \"was it saved?\" — because clicking without cooking cannot be called true satisfaction.\n::\n\n::heading\n[個人化]{こじんか:personalization:N2}と[嗜好]{しこう:preference:N1}[履歴]{りれき:history:N1}\n\n#en\nPersonalization and Preference History\n::\n\n::para\n[同じ]{おなじ:same:N4}「カレー」というクエリでも、[肉]{にく:meat:N4}[食]{しょく:eater:N5}の[利用者]{りようしゃ:user:N3}にはチキンカレー、[野菜]{やさい:vegetable:N2}[中心]{ちゅうしん:centric:N4}の[利用者]{りようしゃ:user:N3}にはベジタブルカレーが[上位]{じょうい:top:N3}に[来る]{くる:to come:N5}ように、[個人]{こじん:individual:N2}の[過去]{かこ:past:N3}[行動]{こうどう:behavior:N4}を[考慮]{こうりょ:considering:N1}した[個人化]{こじんか:personalization:N2}が[行われ]{おこなわれ:performed:N5}ます。[ただし]{ただし:however}、[強すぎる]{つよすぎる:too strong:N4}[個人化]{こじんか:personalization:N2}は「[いつも]{いつも:always}[同じ]{おなじ:same:N4}レシピしか[出ない]{でない:does not appear:N5}」フィルターバブルを[生む]{うむ:to create:N5}ため、[一定]{いってい:certain:N3}の[割合]{わりあい:ratio:N3}で[新しい]{あたらしい:new:N4}レシピを[混ぜ込む]{まぜこむ:mix in:N2}[工夫]{くふう:device:N3}が[必要]{ひつよう:needed:N3}です。\n\n#en\nEven with the same query \"curry,\" personalization considering an individual's past behavior is performed so that meat-eating users see chicken curry on top, and vegetable-centric users see vegetable curry on top. However, overly strong personalization creates a filter bubble where \"only the same recipes ever appear,\" so a device for mixing in new recipes at a certain ratio is needed.\n::\n\n::heading\n[低]{てい:low:N2}レイテンシでの[応答]{おうとう:response:N1}\n\n#en\nLow-Latency Response\n::\n\n::para\n[数]{すう:millions of:N3}[百万]{ひゃくまん:millions of:N5}レシピから[数十]{すうじゅう:dozens:N3}を[即座]{そくざ:immediately:N1}に[返す]{かえす:to return:N3}ためには、[二]{ふた:two:N5}[段階]{だんかい:stage:N2}[検索]{けんさく:search:N1}が[基本]{きほん:basic:N1}です。[第]{だい:nth:N1}[一]{いち:first:N5}[段階]{だんかい:stage:N2}は[転置]{てんち:inverted:N3}インデックスで[候補]{こうほ:candidates:N2}を[数百]{すうひゃく:hundreds:N3}に[絞り]{しぼり:narrow down:N1}、[第]{だい:nth:N1}[二]{に:second:N5}[段階]{だんかい:stage:N2}で[重い]{おもい:heavy:N4}[学習]{がくしゅう:learning:N4}to-rankモデルを[適用]{てきよう:apply:N3}して[最終]{さいしゅう:final:N3}の[順位付け]{じゅんいづけ:ranking:N2}を[行い]{おこない:perform:N5}ます。[全件]{ぜんけん:all items:N3}にモデルを[掛ける]{かける:to apply:N3}と[応答]{おうとう:response:N1}[時間]{じかん:time:N5}が[爆発]{ばくはつ:explode:N2}するため、[現実的]{げんじつてき:realistic:N3}な[計算]{けいさん:computation:N2}コストで[精度]{せいど:accuracy:N3}を[出す]{だす:to produce:N5}[工夫]{くふう:device:N3}が[施されて]{ほどこされて:applied:N1}います。\n\n#en\nTo instantly return dozens of results from millions of recipes, two-stage search is the basic approach. The first stage narrows candidates down to hundreds via an inverted index, and the second stage applies a heavy learning-to-rank model for final ranking. Applying the model to all items would explode response time, so devices for producing accuracy at realistic computational cost are applied.\n::\n\n::heading\nおわりに\n\n#en\nConclusion\n::\n\n::para\n[クックパッド]{くっくぱっど:Cookpad}の[検索]{けんさく:search:N1}は「[食材]{しょくざい:ingredient:N2}が[一致]{いっち:match:N1}している」「[人気]{にんき:popular:N5}が[高い]{たかい:high:N5}」という[基本]{きほん:basic:N1}に[加え]{くわえ:add:N3}、[日本語]{にほんご:Japanese:N5}[特有]{とくゆう:specific:N4}の[表記]{ひょうき:notation:N3}[揺れ]{ゆれ:variation:N1}、[季節]{きせつ:seasonal:N1}・[地域]{ちいき:regional:N2}[変動]{へんどう:variation:N3}、[個人]{こじん:individual:N2}[嗜好]{しこう:preference:N1}を[組み合わせて]{くみあわせて:to combine:N3}「[今夜]{こんや:tonight:N4}[作りたい]{つくりたい:want to cook:N4}レシピ」を[届ける]{とどける:to deliver:N2}[仕組み]{しくみ:mechanism:N3}です。[機械]{きかい:machine:N2}[学習]{がくしゅう:learning:N4}と[料理]{りょうり:cooking:N4}[ドメイン]{どめいん:domain}[知識]{ちしき:knowledge:N3}の[両方]{りょうほう:both:N3}が[揃って]{そろって:together:N1}[初めて]{はじめて:for the first time:N3}[満足]{まんぞく:satisfying:N3}する[体験]{たいけん:experience:N4}が[実現]{じつげん:realized:N3}します。\n\n#en\nCookpad's search is a mechanism that, in addition to the basics of \"ingredient matches\" and \"high popularity,\" combines Japanese-specific notation variations, seasonal and regional variation, and individual preferences to deliver \"the recipe I want to cook tonight.\" Only when both machine learning and cooking domain knowledge come together is a satisfying experience realized.\n::\n"]