1:HL["/_next/static/media/e4af272ccee01ff0-s.p.woff2","font",{"crossOrigin":"","type":"font/woff2"}] 2:HL["/_next/static/css/97132489b96da1d5.css","style",{"crossOrigin":""}] 0:["Y_TW_5cOL4VPb7FuqRz3I",[[["",{"children":[["slug","blog30","d"],{"children":["__PAGE__?{\"slug\":\"blog30\"}",{}]}]},"$undefined","$undefined",true],"$L3",[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/97132489b96da1d5.css","precedence":"next","crossOrigin":""}]],"$L4"]]]] 5:HL["/_next/static/css/5b2728e81018a7be.css","style",{"crossOrigin":""}] 6:I[8326,["326","static/chunks/326-ead410bae2047633.js","986","static/chunks/986-f27c5a2c4d841870.js","42","static/chunks/app/%5Bslug%5D/page-419f452b4066bb25.js"],""] 7:I[6954,[],""] 8:I[7264,[],""] 3:[null,["$","html",null,{"lang":"ja","children":["$","body",null,{"className":"__className_f367f3 flex flex-col min-h-screen","children":[["$","header",null,{"className":"blog-header py-5","children":["$","div",null,{"className":"container mx-auto px-4","children":["$","div",null,{"className":"flex flex-col items-start","children":[["$","$L6",null,{"href":"/","className":"hover:no-underline","children":["$","h1",null,{"className":"text-6xl font-serif text-gray-800 mb-2 font-normal","children":"Shingoの数学ノート"}]}],["$","p",null,{"className":"text-xl text-gray-400 font-normal","children":"プログラミングと機械学習のメモ"}]]}]}]}],["$","main",null,{"className":"flex-grow","children":["$","$L7",null,{"parallelRouterKey":"children","segmentPath":["children"],"loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","template":["$","$L8",null,{}],"templateStyles":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[],"childProp":{"current":["$","$L7",null,{"parallelRouterKey":"children","segmentPath":["children",["slug","blog30","d"],"children"],"loading":"$undefined","loadingStyles":"$undefined","hasLoading":false,"error":"$undefined","errorStyles":"$undefined","template":["$","$L8",null,{}],"templateStyles":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined","childProp":{"current":["$L9","$La",null],"segment":"__PAGE__?{\"slug\":\"blog30\"}"},"styles":[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/5b2728e81018a7be.css","precedence":"next","crossOrigin":""}]]}],"segment":["slug","blog30","d"]},"styles":[]}]}],["$","footer",null,{"className":"bg-[#DDDDDD] text-[#999999] py-8 mt-12 text-center border-t border-[#e5e5e5]","children":["$","div",null,{"className":"container mx-auto px-4","children":[["$","p",null,{"className":"mb-2","children":"© All rights reserved by Shingo Sekine."}],["$","p",null,{"children":["$","a",null,{"href":"#","className":"hover:text-blue-500 transition-colors","children":"Back to top"}]}]]}]}]]}]}],null] 4:[["$","meta","0",{"charSet":"utf-8"}],["$","title","1",{"children":"Shingoの数学ノート"}],["$","meta","2",{"name":"description","content":"プログラミング言語と機械学習のメモ"}],["$","meta","3",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","link","4",{"rel":"icon","href":"/favicon.ico","type":"image/x-icon","sizes":"256x256"}],["$","meta","5",{"name":"next-size-adjust"}]] b:I[6180,["326","static/chunks/326-ead410bae2047633.js","986","static/chunks/986-f27c5a2c4d841870.js","42","static/chunks/app/%5Bslug%5D/page-419f452b4066bb25.js"],""] d:I[9703,["326","static/chunks/326-ead410bae2047633.js","986","static/chunks/986-f27c5a2c4d841870.js","42","static/chunks/app/%5Bslug%5D/page-419f452b4066bb25.js"],""] c:Tb53a,/*@jsxRuntime automatic @jsxImportSource react*/ const {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0]; const {useMDXComponents: _provideComponents} = arguments[0]; function _createMdxContent(props) { const _components = Object.assign({ p: "p", a: "a", h3: "h3", img: "img", pre: "pre", code: "code", span: "span", blockquote: "blockquote", h2: "h2", ul: "ul", li: "li" }, _provideComponents(), props.components); return _jsxs(_Fragment, { children: [_jsx(_components.p, { children: "前回と今回で、BERTの理論と実装について紹介したいと思います。" }), "\n", _jsx(_components.p, { children: "今回は、BERTの実装について説明していきます。" }), "\n", _jsxs(_components.p, { children: ["BERTの理論を知りたい方は", _jsx(_components.a, { href: "./blog29.html", children: "前回のブログ" }), "を参照してください。"] }), "\n", _jsxs(_components.p, { children: ["実際のコードは", _jsx(_components.a, { href: "https://github.com/Shingo425/NLP/blob/main/src/BERT_tutorial.ipynb", children: "github" }), "に上げてありますので、そちらも参考にしてください。"] }), "\n", _jsx(_components.h3, { children: "実行環境の準備" }), "\n", _jsx(_components.p, { children: "ローカルにNVIDIAのGPUを載せている人は多くはないと思うので、 実行環境はgoogle colaboratoryを想定しています。" }), "\n", _jsx(_components.p, { children: "その場合ランタイムはGPUにしてください。" }), "\n", _jsxs(_components.p, { children: ["また、trainingには以前紹介したyahoo locoのレビューデータを使用します。 まだ取得していない方は", _jsx(_components.a, { href: "./blog28.html", children: "こちらの記事" }), "を参考に取得してください"] }), "\n", _jsx(_components.p, { children: "この記事では、東京のレビューデータ「review_df_yahoo_tokyo.csv」を使用しています。" }), "\n", _jsx(_components.p, { children: "以下のようにファイルをアップロードしてください。" }), "\n", _jsx(_components.p, { children: _jsx(_components.img, { src: "/images/blog30/image1.png", alt: "" }) }), "\n", _jsx(_components.h3, { children: "モジュールのインポート" }), "\n", _jsx(_components.p, { children: "以下をインポートします。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: [_jsx(_components.span, { className: "hljs-keyword", children: "import" }), " numpy ", _jsx(_components.span, { className: "hljs-keyword", children: "as" }), " np\n\n\n", _jsx(_components.span, { className: "hljs-keyword", children: "import" }), " pandas ", _jsx(_components.span, { className: "hljs-keyword", children: "as" }), " pd\n", _jsx(_components.span, { className: "hljs-keyword", children: "from" }), " tqdm.notebook\n", _jsx(_components.span, { className: "hljs-keyword", children: "import" }), " tqdm\n", _jsx(_components.span, { className: "hljs-keyword", children: "import" }), " torch\n", _jsx(_components.span, { className: "hljs-keyword", children: "from" }), " sklearn.model_selection\n", _jsx(_components.span, { className: "hljs-keyword", children: "import" }), " train_test_split\n", _jsx(_components.span, { className: "hljs-keyword", children: "import" }), " torch.optim ", _jsx(_components.span, { className: "hljs-keyword", children: "as" }), " optim\n", _jsx(_components.span, { className: "hljs-keyword", children: "import" }), " torch.nn ", _jsx(_components.span, { className: "hljs-keyword", children: "as" }), " nn\n", _jsx(_components.span, { className: "hljs-keyword", children: "import" }), " torch.nn.functional ", _jsx(_components.span, { className: "hljs-keyword", children: "as" }), " F\n"] }) }), "\n", _jsx(_components.p, { children: "haggingfaceのtransformersモジュールを使用します" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: [_jsx(_components.span, { className: "hljs-comment", children: "# transformersをインストール !pip install transformers !pip install mecab-python3==0.996.2 fugashi ipadic" }), "\n", _jsx(_components.span, { className: "hljs-keyword", children: "from" }), " transformers\n", _jsx(_components.span, { className: "hljs-keyword", children: "import" }), " BertJapaneseTokenizer, BertModel\n"] }) }), "\n", _jsx(_components.p, { children: "準備で上げたデータセットを加工して使用します。" }), "\n", _jsx(_components.p, { children: "今回はlabelをRating > 3ならpositive、Rating < 3ならnegativeとしています。Rating==3は使用しません。" }), "\n", _jsx(_components.p, { children: _jsx(_components.img, { src: "/images/blog30/image3.png", alt: "" }) }), "\n", _jsx(_components.p, { children: "これを用いて、BERTのポジネガ分析をしてみましょう。" }), "\n", _jsx(_components.h3, { children: "tokenizer" }), "\n", _jsx(_components.p, { children: "まずは、tokenizerを定義します。学習済みモデルは、 'cl-tohoku/bert-base-japanese'を使用します。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: [_jsx(_components.span, { className: "hljs-comment", children: "# tokenizerの定義とvocabの辞書 model_name = 'cl-tohoku/bert-base-japanese' tokenizer = BertJapaneseTokenizer.from_pretrained(model_name)" }), "\n"] }) }), "\n", _jsx(_components.p, { children: "実際に分割例を見てみます。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: [_jsx(_components.span, { className: "hljs-comment", children: "# tokenizerの分割例 text = \"カーネーションが綺麗だった\" tokenizer.tokenize(text)" }), "\n"] }) }), "\n", _jsx(_components.p, { children: _jsx(_components.img, { src: "/images/blog30/image6.png", alt: "" }) }), "\n", _jsx(_components.h3, { children: "Input Embedding" }), "\n", _jsx(_components.p, { children: "次に入力をみていきましょう。" }), "\n", _jsx(_components.p, { children: "入力に必要なのは、Token Embedding(input_id), Segment Embedding(segment_id), attention_maskです。" }), "\n", _jsx(_components.p, { children: "Positional Embeddingは内部でやってくれるので作成する必要はありません。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: [_jsx(_components.span, { className: "hljs-comment", children: "# pad_tokenとmax_lengthの設定 " }), "\npad = tokenizer.vocab[", _jsx(_components.span, { className: "hljs-string", children: "\"[PAD]\"" }), "] \nmax_lengths=", _jsx(_components.span, { className: "hljs-number", children: "512" }), " \n\n", _jsx(_components.span, { className: "hljs-comment", children: "# tokenをid化 " }), "\ntoken = [", _jsx(_components.span, { className: "hljs-string", children: "\"[CLS]\"" }), "]+tokenizer.tokenize(text)[:max_lengths-", _jsx(_components.span, { className: "hljs-number", children: "2" }), "]+[", _jsx(_components.span, { className: "hljs-string", children: "\"[SEP]\"" }), "] \ninput_id = tokenizer.convert_tokens_to_ids(token) \n\n", _jsx(_components.span, { className: "hljs-comment", children: "# 1文のみなのでsegment_idは全て0 " }), "\nsegment_id = [", _jsx(_components.span, { className: "hljs-number", children: "0" }), "]*max_lengths \n\n", _jsx(_components.span, { className: "hljs-comment", children: "# input_idが存在する箇所に1を立てる " }), "\nattention_mask = [", _jsx(_components.span, { className: "hljs-number", children: "1" }), "]*", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(input_id)+[", _jsx(_components.span, { className: "hljs-number", children: "0" }), "]*(max_lengths - ", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(input_id)) \ninput_id = input_id+[pad]*(max_lengths-", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(input_id))\n"] }) }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: [_jsx(_components.span, { className: "hljs-built_in", children: "print" }), "(", _jsx(_components.span, { className: "hljs-string", children: "\"text:\"" }), ", text)\n", _jsx(_components.span, { className: "hljs-built_in", children: "print" }), "(", _jsx(_components.span, { className: "hljs-string", children: "\"token:\"" }), ", token)\n", _jsx(_components.span, { className: "hljs-built_in", children: "print" }), "(", _jsx(_components.span, { className: "hljs-string", children: "\"input_id:\"" }), ", input_id[:", _jsx(_components.span, { className: "hljs-number", children: "15" }), "], ", _jsx(_components.span, { className: "hljs-string", children: "\"len:\"" }), ", ", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(input_id))\n", _jsx(_components.span, { className: "hljs-built_in", children: "print" }), "(", _jsx(_components.span, { className: "hljs-string", children: "\"segment_id:\"" }), ", segment_id[:", _jsx(_components.span, { className: "hljs-number", children: "15" }), "], ", _jsx(_components.span, { className: "hljs-string", children: "\"len:\"" }), ", ", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(segment_id))\n", _jsx(_components.span, { className: "hljs-built_in", children: "print" }), "(", _jsx(_components.span, { className: "hljs-string", children: "\"attention_mask:\"" }), ", attention_mask[:", _jsx(_components.span, { className: "hljs-number", children: "15" }), "], ", _jsx(_components.span, { className: "hljs-string", children: "\"len:\"" }), ", ", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(attention_mask))\n"] }) }), "\n", _jsx(_components.p, { children: _jsx(_components.img, { src: "/images/blog30/image2.png", alt: "" }) }), "\n", _jsx(_components.h3, { children: "Data Loader作成" }), "\n", _jsx(_components.p, { children: "上記のinput Embeddingを元に、Datasetクラスを作成します。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: [_jsx(_components.span, { className: "hljs-comment", children: "# 上記のinput_dataの作成方法をもとにdataset化" }), "\n", _jsx(_components.span, { className: "hljs-keyword", children: "class" }), " ", _jsx(_components.span, { className: "hljs-title class_", children: "ReviewDataset" }), "(torch.utils.data.Dataset):\n ", _jsx(_components.span, { className: "hljs-keyword", children: "def" }), " ", _jsx(_components.span, { className: "hljs-title function_", children: "__init__" }), "(", _jsx(_components.span, { className: "hljs-params", children: "self, texts, labels=[]" }), "): \n ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".input_ids, ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".segment_ids, ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".attention_masks = [],[],[]\n ", _jsx(_components.span, { className: "hljs-keyword", children: "for" }), " text ", _jsx(_components.span, { className: "hljs-keyword", children: "in" }), " tqdm(texts): \n token = [", _jsx(_components.span, { className: "hljs-string", children: "\"[CLS]\"" }), "]+tokenizer.tokenize(text)[:max_lengths-", _jsx(_components.span, { className: "hljs-number", children: "2" }), "]+[", _jsx(_components.span, { className: "hljs-string", children: "\"[SEP]\"" }), "] \n input_id = tokenizer.convert_tokens_to_ids(token) \n segment_id = [", _jsx(_components.span, { className: "hljs-number", children: "0" }), "]*max_lengths \n attention_mask = [", _jsx(_components.span, { className: "hljs-number", children: "1" }), "]*", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(input_id)+[", _jsx(_components.span, { className: "hljs-number", children: "0" }), "]*(max_lengths - ", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(input_id)) \n input_id = input_id+[pad]*(max_lengths-", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(input_id)) \n ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".input_ids.append(input_id) \n ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".segment_ids.append(segment_id) \n ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".attention_masks.append(attention_mask) \n \n ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".input_ids = np.array(", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".input_ids) \n ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".segment_ids = np.array(", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".segment_ids) \n ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".attention_masks = np.array(", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".attention_masks) \n ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".labels = labels\n\n ", _jsx(_components.span, { className: "hljs-keyword", children: "def" }), " ", _jsx(_components.span, { className: "hljs-title function_", children: "__len__" }), "(", _jsx(_components.span, { className: "hljs-params", children: "self" }), "):\n ", _jsx(_components.span, { className: "hljs-keyword", children: "return" }), " ", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".input_ids)\n\n ", _jsx(_components.span, { className: "hljs-keyword", children: "def" }), " ", _jsx(_components.span, { className: "hljs-title function_", children: "__getitem__" }), "(", _jsx(_components.span, { className: "hljs-params", children: "self, idx" }), "):\n ", _jsx(_components.span, { className: "hljs-keyword", children: "if" }), " ", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".labels):\n ", _jsx(_components.span, { className: "hljs-keyword", children: "return" }), " ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".input_ids[idx], ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".segment_ids[idx], ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".attention_masks[idx], ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".labels[idx]\n ", _jsx(_components.span, { className: "hljs-keyword", children: "else" }), ":\n ", _jsx(_components.span, { className: "hljs-keyword", children: "return" }), " ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".input_ids[idx], ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".segment_ids[idx], ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".attention_masks[idx]\n"] }) }), "\n", _jsx(_components.p, { children: "上記クラスを使って、train_dataloaderとvalid_dataloaderを作成します。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: [_jsx(_components.span, { className: "hljs-comment", children: "# datasetとdataloaderの作成" }), "\n", _jsx(_components.span, { className: "hljs-keyword", children: "from" }), " sklearn.model_selection ", _jsx(_components.span, { className: "hljs-keyword", children: "import" }), " train_test_split \n\nbatch_size=", _jsx(_components.span, { className: "hljs-number", children: "8" }), " \nX,y = train_df[", _jsx(_components.span, { className: "hljs-string", children: "\"text\"" }), "].values, train_df[", _jsx(_components.span, { className: "hljs-string", children: "\"label\"" }), "].values \nX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=", _jsx(_components.span, { className: "hljs-number", children: "0.3" }), ", random_state=", _jsx(_components.span, { className: "hljs-number", children: "100" }), ",stratify=y) \ntrain_ds = ReviewDataset(texts=X_train, labels=y_train) \ntrain_dl = torch.utils.data.DataLoader(train_ds, batch_size=batch_size, shuffle=", _jsx(_components.span, { className: "hljs-literal", children: "True" }), ") \n\nval_ds = ReviewDataset(texts=X_val, labels=y_val) \nval_dl = torch.utils.data.DataLoader(val_ds, batch_size=batch_size, shuffle=", _jsx(_components.span, { className: "hljs-literal", children: "False" }), ")\n"] }) }), "\n", _jsx(_components.h3, { children: "modelの作成" }), "\n", _jsx(_components.p, { children: "BERTの2値分類モデルを作成します。" }), "\n", _jsx(_components.p, { children: "[CLS]トークンの特徴量を用いて全結合で2つの値を出力します。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: [_jsx(_components.span, { className: "hljs-comment", children: "# Bertの事前学習済みエンコーダーを使用して2値クラス分類器を作成" }), "\n", _jsx(_components.span, { className: "hljs-keyword", children: "class" }), " ", _jsx(_components.span, { className: "hljs-title class_", children: "BertClassification" }), "(nn.Module):\n ", _jsx(_components.span, { className: "hljs-keyword", children: "def" }), " ", _jsx(_components.span, { className: "hljs-title function_", children: "__init__" }), "(", _jsx(_components.span, { className: "hljs-params", children: "self, bert" }), "): \n ", _jsx(_components.span, { className: "hljs-built_in", children: "super" }), "(BertClassification, ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ").__init__() \n ", _jsx(_components.span, { className: "hljs-comment", children: "# BERTモジュール " }), "\n ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".bert = bert \n ", _jsx(_components.span, { className: "hljs-comment", children: "# BERTモデル " }), "\n ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".cls = nn.Linear(in_features=", _jsx(_components.span, { className: "hljs-number", children: "768" }), ", out_features=", _jsx(_components.span, { className: "hljs-number", children: "2" }), ") \n ", _jsx(_components.span, { className: "hljs-comment", children: "# 重み初期化処理 " }), "\n nn.init.normal_(", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".cls.weight, std=", _jsx(_components.span, { className: "hljs-number", children: "0.02" }), ") \n nn.init.normal_(", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".cls.bias, ", _jsx(_components.span, { className: "hljs-number", children: "0" }), ")\n\n ", _jsx(_components.span, { className: "hljs-keyword", children: "def" }), " ", _jsx(_components.span, { className: "hljs-title function_", children: "forward" }), "(", _jsxs(_components.span, { className: "hljs-params", children: ["self, input_ids, token_type_ids=", _jsx(_components.span, { className: "hljs-literal", children: "None" }), ", attention_mask=", _jsx(_components.span, { className: "hljs-literal", children: "None" })] }), "): \n ", _jsx(_components.span, { className: "hljs-comment", children: "# BERTの基本モデル部分の順伝搬 " }), "\n output = ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".bert(input_ids, token_type_ids, attention_mask) \n ", _jsx(_components.span, { className: "hljs-comment", children: "# [CLS]に対応する特徴量を取得します。 " }), "\n pooled_output = output[", _jsx(_components.span, { className: "hljs-number", children: "1" }), "] \n ", _jsx(_components.span, { className: "hljs-comment", children: "# 入力文章の1単語目[CLS]の特徴量を使用して、ポジ・ネガを分類します " }), "\n pooled_output = pooled_output.view(-", _jsx(_components.span, { className: "hljs-number", children: "1" }), ", ", _jsx(_components.span, { className: "hljs-number", children: "768" }), ") ", _jsx(_components.span, { className: "hljs-comment", children: "# sizeを[batch_size, hidden_size]に変換 " }), "\n out = ", _jsx(_components.span, { className: "hljs-variable language_", children: "self" }), ".cls(pooled_output)\n ", _jsx(_components.span, { className: "hljs-keyword", children: "return" }), " out\n"] }) }), "\n", _jsx(_components.p, { children: "「pooled_output=output[1]」の部分がわかりづらいので解説すると、 bertの公式では以下のように記述されています。" }), "\n", _jsxs(_components.blockquote, { children: ["\n", _jsx(_components.p, { children: "A BaseModelOutputWithPoolingAndCrossAttentions (if return_dict=True is passed or when config.return_dict=True) or a tuple of torch.FloatTensor comprising various elements depending on the configuration (BertConfig) and inputs. last_hidden_state (torch.FloatTensor of shape (batch_size, sequence_length, hidden_size)) – Sequence of hidden-states at the output of the last layer of the model. pooler_output (torch.FloatTensor of shape (batch_size, hidden_size)) – Last layer hidden-state of the first token of the sequence (classification token) further processed by a Linear layer and a Tanh activation function. The Linear layer weights are trained from the next sentence prediction (classification) objective during pretraining." }), "\n"] }), "\n", _jsx(_components.p, { children: "つまり、bertのoutputは以下のようになっています。" }), "\n", _jsx(_components.pre, { children: _jsx(_components.code, { className: "hljs language-python", children: "output=(last_layerの全てのtoken,last_layerの最初のToken(=[CLS]Token))\n" }) }), "\n", _jsx(_components.p, { children: "ということで、output[1]は[CLS]Tokenの特徴量を抽出していることになるわけですね。" }), "\n", _jsx(_components.p, { children: "ちなみに、attentionを可視化したいとか、最終層以外の特徴量も取り出したい等あれば、そういうオプションもあるので、以下を参考にしてください。" }), "\n", _jsx(_components.p, { children: _jsx(_components.a, { href: "https://huggingface.co/transformers/model_doc/bert.html", children: "公式ドキュメント" }) }), "\n", _jsx(_components.h3, { children: "Optimizer等の設定" }), "\n", _jsx(_components.p, { children: "次にOptimizerや、損失関数、gpuを使用するか等の設定を行います。" }), "\n", _jsx(_components.p, { children: "今回は、AdamとCross Entropyを使用します。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: ["cuda = torch.cuda.is_available()\n\n", _jsx(_components.span, { className: "hljs-comment", children: "# 学習済みモデルをダウンロード " }), "\nbert = BertModel.from_pretrained(model_name) \nmodel = BertClassification(bert) \n\n", _jsx(_components.span, { className: "hljs-comment", children: "# 高速化 " }), "\ntorch.backends.cudnn.benchmark = ", _jsx(_components.span, { className: "hljs-literal", children: "True" }), "\n\n", _jsx(_components.span, { className: "hljs-keyword", children: "if" }), " cuda:\n model.cuda() \n\n", _jsx(_components.span, { className: "hljs-comment", children: "# optimizerの設定 " }), "\noptimizer = optim.Adam(model.parameters(),lr = ", _jsx(_components.span, { className: "hljs-number", children: "4e-4" }), " ,betas=(", _jsx(_components.span, { className: "hljs-number", children: "0.9" }), ", ", _jsx(_components.span, { className: "hljs-number", children: "0.999" }), ")) \n\n", _jsx(_components.span, { className: "hljs-comment", children: "# 損失関数の設定 " }), "\ncriterion = nn.CrossEntropyLoss()\n"] }) }), "\n", _jsx(_components.p, { children: "また、今回は学習時間を短縮するため、最終層以外のパラメータを固定します。" }), "\n", _jsx(_components.p, { children: "実際のタスクでは、全てのパラメータを学習することも多いです。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: [_jsx(_components.span, { className: "hljs-comment", children: "# 最後以外のBertLayerモジュールのパラメータを固定(実際のタスクでは固定させないことも多い)" }), "\n", _jsx(_components.span, { className: "hljs-keyword", children: "for" }), " param ", _jsx(_components.span, { className: "hljs-keyword", children: "in" }), " model.bert.encoder.layer[:-", _jsx(_components.span, { className: "hljs-number", children: "1" }), "].parameters():\n param.requires_grad = ", _jsx(_components.span, { className: "hljs-literal", children: "False" }), "\n"] }) }), "\n", _jsx(_components.h3, { children: "学習" }), "\n", _jsx(_components.p, { children: "ここで学習フェーズです。" }), "\n", _jsx(_components.p, { children: "Pytorchは先ほど作ったdata_loaderを使って、for文でtrainingしていきます。" }), "\n", _jsx(_components.p, { children: "train, validともに1イテレーションごとに記述できるのが良いですね。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: [_jsx(_components.span, { className: "hljs-comment", children: "## 学習します。1epochあたり約8分です。 " }), "\nepochs = ", _jsx(_components.span, { className: "hljs-number", children: "2" }), "\n", _jsx(_components.span, { className: "hljs-keyword", children: "for" }), " epoch ", _jsx(_components.span, { className: "hljs-keyword", children: "in" }), " ", _jsx(_components.span, { className: "hljs-built_in", children: "range" }), "(epochs): \n total_loss = ", _jsx(_components.span, { className: "hljs-number", children: "0" }), " \n accuracy = ", _jsx(_components.span, { className: "hljs-number", children: "0" }), " \n model.train()\n ", _jsx(_components.span, { className: "hljs-built_in", children: "print" }), "(", _jsx(_components.span, { className: "hljs-string", children: "\"epoch {} start!\"" }), ".", _jsx(_components.span, { className: "hljs-built_in", children: "format" }), "(epoch+", _jsx(_components.span, { className: "hljs-number", children: "1" }), ")) \n \n ", _jsx(_components.span, { className: "hljs-comment", children: "# train" }), "\n ", _jsx(_components.span, { className: "hljs-keyword", children: "for" }), " iter_num, (input_ids, segment_ids, attention_masks, labels) ", _jsx(_components.span, { className: "hljs-keyword", children: "in" }), " tqdm(", _jsx(_components.span, { className: "hljs-built_in", children: "enumerate" }), "(train_dl),total = ", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(train_dl)): \n optimizer.zero_grad()\n ", _jsx(_components.span, { className: "hljs-keyword", children: "if" }), " cuda: \n input_ids, segment_ids, attention_masks, labels = input_ids.cuda(), segment_ids.cuda(), attention_masks.cuda(), labels.cuda() \n \n ", _jsx(_components.span, { className: "hljs-comment", children: "# forward(順伝搬) " }), "\n outputs = model(input_ids = input_ids, token_type_ids = segment_ids, attention_mask = attention_masks) \n pred_proba = outputs.softmax(dim=", _jsx(_components.span, { className: "hljs-number", children: "1" }), ")[:,", _jsx(_components.span, { className: "hljs-number", children: "1" }), "] \n pred = (pred_proba>=", _jsx(_components.span, { className: "hljs-number", children: "0.5" }), ").", _jsx(_components.span, { className: "hljs-built_in", children: "type" }), "(torch.", _jsx(_components.span, { className: "hljs-built_in", children: "int" }), ") \n loss = criterion(outputs,labels) \n \n ", _jsx(_components.span, { className: "hljs-comment", children: "# backward(逆伝搬) " }), "\n loss.backward() \n optimizer.step() \n total_loss += loss.item() \n accuracy += (pred==labels).", _jsx(_components.span, { className: "hljs-built_in", children: "sum" }), "().item() \n \n ", _jsx(_components.span, { className: "hljs-comment", children: "#50 iterごとにlossとaccuracyを表示" }), "\n ", _jsx(_components.span, { className: "hljs-keyword", children: "if" }), " (iter_num+", _jsx(_components.span, { className: "hljs-number", children: "1" }), ") % ", _jsx(_components.span, { className: "hljs-number", children: "50" }), " == ", _jsx(_components.span, { className: "hljs-number", children: "0" }), ": \n size = batch_size*(iter_num+", _jsx(_components.span, { className: "hljs-number", children: "1" }), ")\n ", _jsx(_components.span, { className: "hljs-built_in", children: "print" }), "(", _jsx(_components.span, { className: "hljs-string", children: "\"{} iter loss:{:.4f} accuracy:{:.4f}\"" }), ".", _jsx(_components.span, { className: "hljs-built_in", children: "format" }), "(iter_num+", _jsx(_components.span, { className: "hljs-number", children: "1" }), ", total_loss/(iter_num+", _jsx(_components.span, { className: "hljs-number", children: "1" }), "), accuracy/size)) \n \n total_loss /= ", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(train_dl) \n accuracy /= ", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(train_ds) \n \n ", _jsx(_components.span, { className: "hljs-comment", children: "# validation " }), "\n val_total_loss = ", _jsx(_components.span, { className: "hljs-number", children: "0" }), " \n val_accuracy = ", _jsx(_components.span, { className: "hljs-number", children: "0" }), " \n model.", _jsx(_components.span, { className: "hljs-built_in", children: "eval" }), "()\n ", _jsx(_components.span, { className: "hljs-keyword", children: "for" }), " input_ids, segment_ids, attention_masks, labels ", _jsx(_components.span, { className: "hljs-keyword", children: "in" }), " tqdm(val_dl):\n ", _jsx(_components.span, { className: "hljs-keyword", children: "if" }), " cuda: \n input_ids, segment_ids, attention_masks, labels = input_ids.cuda(), segment_ids.cuda(), attention_masks.cuda(), labels.cuda() \n ", _jsx(_components.span, { className: "hljs-keyword", children: "with" }), " torch.no_grad(): \n outputs = model(input_ids = input_ids, token_type_ids = segment_ids, attention_mask = attention_masks) \n pred_proba = outputs.softmax(dim=", _jsx(_components.span, { className: "hljs-number", children: "1" }), ")[:,", _jsx(_components.span, { className: "hljs-number", children: "1" }), "] \n pred = (pred_proba>=", _jsx(_components.span, { className: "hljs-number", children: "0.5" }), ").", _jsx(_components.span, { className: "hljs-built_in", children: "type" }), "(torch.", _jsx(_components.span, { className: "hljs-built_in", children: "int" }), ") \n loss = criterion(outputs,labels) \n val_total_loss += loss.item() \n val_accuracy += (pred==labels).", _jsx(_components.span, { className: "hljs-built_in", children: "sum" }), "().item() \n \n val_total_loss /= ", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(val_dl) \n val_accuracy /= ", _jsx(_components.span, { className: "hljs-built_in", children: "len" }), "(val_ds)\n ", _jsx(_components.span, { className: "hljs-built_in", children: "print" }), "(", _jsx(_components.span, { className: "hljs-string", children: "\"epoch{} total loss:{:.4f}, accuracy:{:.4f}, val_total loss:{:.4f}, val_accuracy:{:.4f}\"" }), ".", _jsx(_components.span, { className: "hljs-built_in", children: "format" }), "(epoch+", _jsx(_components.span, { className: "hljs-number", children: "1" }), ",total_loss,accuracy,val_total_loss,val_accuracy)) \n \ntorch.save(model.state_dict(), ", _jsx(_components.span, { className: "hljs-string", children: "'./model.hdf5'" }), ")\n"] }) }), "\n", _jsx(_components.h3, { children: "予測" }), "\n", _jsx(_components.p, { children: "最後に、本当にできたか予測してみましょう。" }), "\n", _jsx(_components.p, { children: "まずは出来上がったモデルをロードします。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: ["model.load_state_dict(torch.load(", _jsx(_components.span, { className: "hljs-string", children: "\"./model.hdf5\"" }), "))\n"] }) }), "\n", _jsx(_components.p, { children: "実際に予測してみます。" }), "\n", _jsx(_components.p, { children: "\"今日のランチは最高だった!\"を予測してみます。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: ["X_test = [", _jsx(_components.span, { className: "hljs-string", children: "\"今日のランチは最高だった!\"" }), "] \ntest_ds = ReviewDataset(texts=X_test) \ntest_dl = torch.utils.data.DataLoader(test_ds, batch_size=", _jsx(_components.span, { className: "hljs-number", children: "1" }), ", shuffle=", _jsx(_components.span, { className: "hljs-literal", children: "False" }), ")\n\n", _jsx(_components.span, { className: "hljs-keyword", children: "for" }), " input_ids, segment_ids, attention_masks ", _jsx(_components.span, { className: "hljs-keyword", children: "in" }), " test_dl:\n ", _jsx(_components.span, { className: "hljs-keyword", children: "if" }), " cuda: \n input_ids, segment_ids, attention_masks = input_ids.cuda(), segment_ids.cuda(), attention_masks.cuda() \n outputs = model(input_ids = input_ids, token_type_ids = segment_ids, attention_mask = attention_masks) \n pred_proba = outputs.softmax(dim=", _jsx(_components.span, { className: "hljs-number", children: "1" }), ")[:,", _jsx(_components.span, { className: "hljs-number", children: "1" }), "]\n ", _jsx(_components.span, { className: "hljs-built_in", children: "print" }), "(", _jsx(_components.span, { className: "hljs-string", children: "\"入力テキストのポジティブ度: {:.4f}\"" }), ".", _jsx(_components.span, { className: "hljs-built_in", children: "format" }), "(pred_proba.item()))\n"] }) }), "\n", _jsx(_components.p, { children: _jsx(_components.img, { src: "/images/blog30/image4.png", alt: "" }) }), "\n", _jsx(_components.p, { children: "もう一つ予測してみましょう。" }), "\n", _jsx(_components.p, { children: "\"今日のランチは微妙だった。\"を予測してみます。" }), "\n", _jsx(_components.pre, { children: _jsxs(_components.code, { className: "hljs language-python", children: ["X_test = [", _jsx(_components.span, { className: "hljs-string", children: "\"今日のランチは微妙だった。\"" }), "] \ntest_ds = ReviewDataset(texts=X_test) \ntest_dl = torch.utils.data.DataLoader(test_ds, batch_size=", _jsx(_components.span, { className: "hljs-number", children: "1" }), ", shuffle=", _jsx(_components.span, { className: "hljs-literal", children: "False" }), ")\n\n", _jsx(_components.span, { className: "hljs-keyword", children: "for" }), " input_ids, segment_ids, attention_masks ", _jsx(_components.span, { className: "hljs-keyword", children: "in" }), " test_dl:\n ", _jsx(_components.span, { className: "hljs-keyword", children: "if" }), " cuda: \n input_ids, segment_ids, attention_masks = input_ids.cuda(), segment_ids.cuda(), attention_masks.cuda() \n outputs = model(input_ids = input_ids, token_type_ids = segment_ids, attention_mask = attention_masks) \n pred_proba = outputs.softmax(dim=", _jsx(_components.span, { className: "hljs-number", children: "1" }), ")[:,", _jsx(_components.span, { className: "hljs-number", children: "1" }), "]\n ", _jsx(_components.span, { className: "hljs-built_in", children: "print" }), "(", _jsx(_components.span, { className: "hljs-string", children: "\"入力テキストのポジティブ度: {:.4f}\"" }), ".", _jsx(_components.span, { className: "hljs-built_in", children: "format" }), "(pred_proba.item()))\n"] }) }), "\n", _jsx(_components.p, { children: _jsx(_components.img, { src: "/images/blog30/image5.png", alt: "" }) }), "\n", _jsx(_components.p, { children: "うまく予想できてそうですね。" }), "\n", _jsx(_components.h3, { children: "まとめ" }), "\n", _jsx(_components.p, { children: "今回は実際のコードを紹介しました。" }), "\n", _jsx(_components.p, { children: "BERTはoutput layerを変えるだけでclassificationだけでなく、 さまざまなタスクが実行可能なのでぜひ試してみてください!" }), "\n", _jsx(_components.h2, { children: "参考文献" }), "\n", _jsxs(_components.ul, { children: ["\n", _jsx(_components.li, { children: "つくりながら学ぶ! PyTorchによる発展ディープラーニング 小川雄太郎 著" }), "\n"] })] }); } function MDXContent(props = {}) { const {wrapper: MDXLayout} = Object.assign({}, _provideComponents(), props.components); return MDXLayout ? _jsx(MDXLayout, Object.assign({}, props, { children: _jsx(_createMdxContent, props) })) : _createMdxContent(props); } return { default: MDXContent }; a:["$","div",null,{"className":"container mx-auto px-4 py-8 max-w-7xl","children":["$","div",null,{"className":"flex flex-col md:flex-row gap-8","children":[["$","article",null,{"className":"w-full md:w-[70%] bg-white shadow-lg rounded-lg p-8","children":[["$","header",null,{"className":"mb-8 border-b pb-4","children":[["$","div",null,{"className":"flex items-center gap-2 mb-2","children":[["$","$L6",null,{"href":"/","className":"text-gray-500 hover:text-orange-500","children":"Home"}],["$","span",null,{"className":"text-gray-300","children":">"}],["$","span",null,{"className":"text-gray-500","children":"$undefined"}]]}],["$","h1",null,{"className":"text-3xl font-bold mb-4","children":"BERTを使ってみよう2"}],["$","div",null,{"className":"text-gray-500 flex flex-wrap gap-4 items-center mb-6","children":[["$","time",null,{"className":"flex items-center gap-1 text-sm","children":[["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","height":"18px","viewBox":"0 0 24 24","width":"18px","fill":"#666666","className":"mr-1","children":[["$","path",null,{"d":"M0 0h24v24H0V0z","fill":"none"}],["$","path",null,{"d":"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z"}]]}],"日付: ","2021-04-23"]}],["$","div",null,{"className":"flex flex-wrap gap-2","children":[["$","$L6","自然言語処理",{"href":"/tags/自然言語処理","className":"bg-gray-100 hover:bg-blue-100 px-2 py-1 rounded text-sm text-gray-600 hover:text-blue-600 transition-colors","children":["#","自然言語処理"]}]]}]]}]]}],["$","div",null,{"className":"prose max-w-none prose-headings:border-b prose-headings:pb-2 prose-a:text-orange-600","children":["$","$Lb",null,{"compiledSource":"$c","frontmatter":{},"scope":{}}]}],["$","div",null,{"className":"flex justify-between items-center mt-12","children":[["$","div",null,{"className":"flex-1","children":["$","$L6",null,{"href":"/blog29","className":"group flex flex-col items-start p-4 rounded-lg border border-gray-100 hover:border-orange-200 hover:bg-orange-50 transition-all","children":[["$","span",null,{"className":"text-sm text-gray-500 mb-1 group-hover:text-orange-600 flex items-center","children":[["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","className":"h-4 w-4 mr-1","fill":"none","viewBox":"0 0 24 24","stroke":"currentColor","children":["$","path",null,{"strokeLinecap":"round","strokeLinejoin":"round","strokeWidth":2,"d":"M15 19l-7-7 7-7"}]}],"Previous"]}],["$","span",null,{"className":"font-medium text-gray-800 dark:text-gray-200 line-clamp-2","children":"BERTを使ってみよう1"}]]}]}],["$","div",null,{"className":"w-8"}],["$","div",null,{"className":"flex-1 text-right","children":["$","$L6",null,{"href":"/blog31","className":"group flex flex-col items-end p-4 rounded-lg border border-gray-100 hover:border-orange-200 hover:bg-orange-50 transition-all","children":[["$","span",null,{"className":"text-sm text-gray-500 mb-1 group-hover:text-orange-600 flex items-center","children":["Next",["$","svg",null,{"xmlns":"http://www.w3.org/2000/svg","className":"h-4 w-4 ml-1","fill":"none","viewBox":"0 0 24 24","stroke":"currentColor","children":["$","path",null,{"strokeLinecap":"round","strokeLinejoin":"round","strokeWidth":2,"d":"M9 5l7 7-7 7"}]}]]}],["$","span",null,{"className":"font-medium text-gray-800 dark:text-gray-200 line-clamp-2","children":"アプリ「ldadash」を公開しました!"}]]}]}]]}],["$","$Ld",null,{}]]}],["$","div",null,{"className":"w-full md:w-[30%]","children":"$Le"}]]}]}] 9:null f:I[9009,["326","static/chunks/326-ead410bae2047633.js","986","static/chunks/986-f27c5a2c4d841870.js","42","static/chunks/app/%5Bslug%5D/page-419f452b4066bb25.js"],""] e:["$","aside",null,{"className":"w-full flex flex-col gap-6","children":[["$","div",null,{"className":"bg-white p-6 rounded shadow-sm border","children":[["$","h3",null,{"className":"font-bold text-lg mb-4 text-[#494949] border-b pb-2","children":"プロフィール"}],["$","div",null,{"className":"flex items-center mb-4","children":[["$","$Lf",null,{}],["$","span",null,{"className":"font-bold","children":"Shingo.S"}]]}],["$","p",null,{"className":"mb-4 text-base leading-relaxed text-gray-600","children":["データサイエンティストとして働いています。仕事では主にPythonやSAS、Rを用いて分析しています。",["$","br",null,{}],["$","br",null,{}],"統計検定1級、Kaggle Expert。",["$","br",null,{}],"自然言語処理に興味があります。"]}],["$","div",null,{"className":"mt-4 flex items-center","children":["$","a",null,{"href":"https://x.com/shingo97358922","target":"_blank","rel":"noopener noreferrer","className":"flex items-center gap-2 text-gray-600 hover:text-black transition-colors","children":[["$","svg",null,{"className":"w-5 h-5","fill":"currentColor","viewBox":"0 0 24 24","aria-hidden":"true","children":["$","path",null,{"d":"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"}]}],["$","span",null,{"className":"text-sm font-medium","children":"@shingo97358922"}]]}]}]]}],["$","div",null,{"className":"bg-white p-6 rounded shadow-sm border","children":[["$","h3",null,{"className":"font-bold text-lg mb-4 text-[#494949] border-b pb-2","children":"アクセスカウンター"}],["$","div",null,{"className":"flex flex-col gap-2 text-gray-600 pl-2","children":[["$","div",null,{"className":"flex items-center gap-4","children":[["$","span",null,{"className":"w-12 text-right","children":"累計"}],["$","span",null,{"children":":"}],["$","span",null,{"className":"font-mono text-lg font-bold","children":"72320"}]]}],["$","div",null,{"className":"flex items-center gap-4","children":[["$","span",null,{"className":"w-12 text-right","children":"本日"}],["$","span",null,{"children":":"}],["$","span",null,{"className":"font-mono text-lg font-bold","children":"17"}]]}],["$","div",null,{"className":"flex items-center gap-4","children":[["$","span",null,{"className":"w-12 text-right","children":"昨日"}],["$","span",null,{"children":":"}],["$","span",null,{"className":"font-mono text-lg font-bold","children":"33"}]]}]]}]]}],["$","div",null,{"className":"bg-white p-6 rounded shadow-sm border","children":[["$","h3",null,{"className":"font-bold text-lg mb-4 text-[#494949] border-b pb-2","children":"月別アーカイブ"}],["$","ul",null,{"className":"text-base text-gray-600","children":[["$","li","2026年2月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2026-02","className":"hover:text-blue-500 transition-colors block","children":["2026年2月"," (",1,")"]}]}],["$","li","2025年2月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2025-02","className":"hover:text-blue-500 transition-colors block","children":["2025年2月"," (",1,")"]}]}],["$","li","2024年10月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2024-10","className":"hover:text-blue-500 transition-colors block","children":["2024年10月"," (",1,")"]}]}],["$","li","2024年7月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2024-07","className":"hover:text-blue-500 transition-colors block","children":["2024年7月"," (",1,")"]}]}],["$","li","2024年2月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2024-02","className":"hover:text-blue-500 transition-colors block","children":["2024年2月"," (",1,")"]}]}],["$","li","2023年6月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2023-06","className":"hover:text-blue-500 transition-colors block","children":["2023年6月"," (",1,")"]}]}],["$","li","2023年5月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2023-05","className":"hover:text-blue-500 transition-colors block","children":["2023年5月"," (",1,")"]}]}],["$","li","2023年3月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2023-03","className":"hover:text-blue-500 transition-colors block","children":["2023年3月"," (",2,")"]}]}],["$","li","2022年10月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2022-10","className":"hover:text-blue-500 transition-colors block","children":["2022年10月"," (",2,")"]}]}],["$","li","2022年9月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2022-09","className":"hover:text-blue-500 transition-colors block","children":["2022年9月"," (",2,")"]}]}],["$","li","2022年7月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2022-07","className":"hover:text-blue-500 transition-colors block","children":["2022年7月"," (",1,")"]}]}],["$","li","2022年3月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2022-03","className":"hover:text-blue-500 transition-colors block","children":["2022年3月"," (",1,")"]}]}],["$","li","2021年11月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2021-11","className":"hover:text-blue-500 transition-colors block","children":["2021年11月"," (",1,")"]}]}],["$","li","2021年10月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2021-10","className":"hover:text-blue-500 transition-colors block","children":["2021年10月"," (",2,")"]}]}],["$","li","2021年7月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2021-07","className":"hover:text-blue-500 transition-colors block","children":["2021年7月"," (",2,")"]}]}],["$","li","2021年5月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2021-05","className":"hover:text-blue-500 transition-colors block","children":["2021年5月"," (",2,")"]}]}],["$","li","2021年4月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2021-04","className":"hover:text-blue-500 transition-colors block","children":["2021年4月"," (",2,")"]}]}],["$","li","2021年2月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2021-02","className":"hover:text-blue-500 transition-colors block","children":["2021年2月"," (",1,")"]}]}],["$","li","2020年10月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2020-10","className":"hover:text-blue-500 transition-colors block","children":["2020年10月"," (",1,")"]}]}],["$","li","2020年9月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2020-09","className":"hover:text-blue-500 transition-colors block","children":["2020年9月"," (",1,")"]}]}],["$","li","2020年7月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2020-07","className":"hover:text-blue-500 transition-colors block","children":["2020年7月"," (",1,")"]}]}],["$","li","2020年6月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2020-06","className":"hover:text-blue-500 transition-colors block","children":["2020年6月"," (",1,")"]}]}],["$","li","2020年5月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2020-05","className":"hover:text-blue-500 transition-colors block","children":["2020年5月"," (",1,")"]}]}],["$","li","2020年4月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2020-04","className":"hover:text-blue-500 transition-colors block","children":["2020年4月"," (",1,")"]}]}],["$","li","2020年3月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2020-03","className":"hover:text-blue-500 transition-colors block","children":["2020年3月"," (",1,")"]}]}],["$","li","2020年2月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2020-02","className":"hover:text-blue-500 transition-colors block","children":["2020年2月"," (",1,")"]}]}],["$","li","2020年1月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2020-01","className":"hover:text-blue-500 transition-colors block","children":["2020年1月"," (",1,")"]}]}],["$","li","2019年12月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2019-12","className":"hover:text-blue-500 transition-colors block","children":["2019年12月"," (",1,")"]}]}],["$","li","2019年11月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2019-11","className":"hover:text-blue-500 transition-colors block","children":["2019年11月"," (",2,")"]}]}],["$","li","2019年10月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2019-10","className":"hover:text-blue-500 transition-colors block","children":["2019年10月"," (",2,")"]}]}],["$","li","2019年9月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2019-09","className":"hover:text-blue-500 transition-colors block","children":["2019年9月"," (",1,")"]}]}],["$","li","2019年8月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2019-08","className":"hover:text-blue-500 transition-colors block","children":["2019年8月"," (",8,")"]}]}],["$","li","2019年7月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2019-07","className":"hover:text-blue-500 transition-colors block","children":["2019年7月"," (",1,")"]}]}],["$","li","2019年6月",{"className":"mb-2 border-b border-dashed border-gray-200 pb-1 last:border-none","children":["$","$L6",null,{"href":"/archives/2019-06","className":"hover:text-blue-500 transition-colors block","children":["2019年6月"," (",2,")"]}]}]]}]]}],["$","div",null,{"className":"bg-white p-6 rounded shadow-sm border","children":[["$","h3",null,{"className":"font-bold text-lg mb-4 text-[#494949] border-b pb-2","children":"タグ一覧"}],["$","div",null,{"className":"flex flex-wrap gap-2","children":[["$","$L6","データ分析",{"href":"/tags/データ分析","className":"bg-gray-100 hover:bg-blue-500 hover:text-white rounded px-2 py-1 text-sm transition-colors duration-200 text-gray-600","children":["データ分析"," (",18,")"]}],["$","$L6","自然言語処理",{"href":"/tags/自然言語処理","className":"bg-gray-100 hover:bg-blue-500 hover:text-white rounded px-2 py-1 text-sm transition-colors duration-200 text-gray-600","children":["自然言語処理"," (",16,")"]}],["$","$L6","SAS",{"href":"/tags/SAS","className":"bg-gray-100 hover:bg-blue-500 hover:text-white rounded px-2 py-1 text-sm transition-colors duration-200 text-gray-600","children":["SAS"," (",12,")"]}],["$","$L6","Kaggle",{"href":"/tags/Kaggle","className":"bg-gray-100 hover:bg-blue-500 hover:text-white rounded px-2 py-1 text-sm transition-colors duration-200 text-gray-600","children":["Kaggle"," (",3,")"]}],["$","$L6","雑談",{"href":"/tags/雑談","className":"bg-gray-100 hover:bg-blue-500 hover:text-white rounded px-2 py-1 text-sm transition-colors duration-200 text-gray-600","children":["雑談"," (",2,")"]}]]}]]}],["$","div",null,{"className":"bg-white p-6 rounded shadow-sm border","children":[["$","h3",null,{"className":"font-bold text-lg mb-4 text-[#494949] border-b pb-2","children":"広告枠"}],["$","div",null,{"className":"flex justify-center items-center","children":[["$","a",null,{"href":"https://px.a8.net/svt/ejp?a8mat=4AXI0F+CULTTE+348+6CWQP","rel":"nofollow","target":"_blank","children":["$","img",null,{"style":{"border":0},"width":"250","height":"250","alt":"","src":"https://www25.a8.net/svt/bgt?aid=260223855777&wid=001&eno=01&mid=s00000000404001068000&mc=1"}]}],["$","img",null,{"style":{"border":0},"width":"1","height":"1","src":"https://www17.a8.net/0.gif?a8mat=4AXI0F+CULTTE+348+6CWQP","alt":""}]]}]]}]]}]