主要モデル・タスク・指標・前処理用語を一覧で。 各チップから関連セクションへジャンプできます。
論文記事から各用語のリンクをクリックすると、 該当箇所が開きます:
🍰 まずはやさしく
言葉をコンピュータで扱う技術です。
機械に言葉を理解させるために使います。
スマホの翻訳や対話アプリで使われています。
処理の流れと最新の仕組みを学びます。
人間の言語をコンピュータで処理する分野。 困難要因:
テキストを処理単位(トークン)に分割。 多くの NLP の最初のステップ。
英語は空白で分かち書き → 日本語は文字列。 形態素解析器で分割:
1 2 3 4 | import fugashi tagger = fugashi.Tagger() for word in tagger("日本の首都は東京都です。"): print(word.surface, word.feature.pos1, word.feature.lemma) |
Transformer 系は語彙の固定化のためサブワード(語の一部)に分割:
1 2 3 4 | from transformers import AutoTokenizer tok = AutoTokenizer.from_pretrained('cl-tohoku/bert-base-japanese-v3') ids = tok.encode('東京は日本の首都です') print(tok.convert_ids_to_tokens(ids)) |
「は」「が」「の」など、 内容語でない単語を除く。 古典的 NLP の前処理。 BERT 系では通常不要。
古典的だが今も強力なベースライン特徴化手法。
文書 = 単語の出現数ベクトル。 順序情報は捨てる。
$$\mathrm{TF}\text{-}\mathrm{IDF}(t, d) = \mathrm{TF}(t, d) \cdot \log\frac{N}{\mathrm{DF}(t)}$$
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # ── 分析対象の文書。説明用の合成データ(実在の投稿ではない)── documents = [ '広島の観光地は人が多いが景色がとても良い', '新しい統計データが公開されたので分析してみた', '今日の天気は雨で、外出には向かない', '人口減少と高齢化が地域経済に影響している', 'このカメラは写りが良く、価格も手頃だった', ] from sklearn.feature_extraction.text import TfidfVectorizer import fugashi tagger = fugashi.Tagger() def tokenize_ja(text): return [w.surface for w in tagger(text)] vec = TfidfVectorizer(tokenizer=tokenize_ja, token_pattern=None, max_features=5000) X = vec.fit_transform(documents) |
連続 n 単語を 1 特徴に。 文脈の一部を表現。 n=1(unigram)、 n=2(bigram)、 n=3(trigram)が標準。
「単語の意味は周囲に現れる単語で決まる」(分布仮説)に基づき、 文脈ウィンドウから単語を予測(Skip-gram)または逆(CBOW)。
1 2 3 4 5 | from gensim.models import Word2Vec sentences = [['東京', 'は', '日本', 'の', '首都'], ['大阪', 'は', '関西', 'の', '中心']] model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4) print(model.wv['東京']) print(model.wv.most_similar('東京')) |
Stanford 2014。 単語共起行列の対数を直接フィット。 Word2Vec と同等の性能。
Facebook 2016。 サブワード単位の埋め込み。 未知語にも対応。
同じ単語でも文脈で異なるベクトル:「銀行に預金」と「川の銀行」の「銀行」は別ベクトル。
双方向 Transformer Encoder。 大規模コーパスで Masked LM 事前学習。 分類・抽出系タスクで圧倒的精度。
1 2 3 4 5 6 7 8 9 | from transformers import AutoTokenizer, AutoModel import torch tok = AutoTokenizer.from_pretrained('cl-tohoku/bert-base-japanese-v3') model = AutoModel.from_pretrained('cl-tohoku/bert-base-japanese-v3') ids = tok('東京は日本の首都です', return_tensors='pt') with torch.no_grad(): out = model(**ids) embedding = out.last_hidden_state.mean(dim=1) # 文ベクトル print(embedding.shape) |
文単位の意味類似度を測れるよう、 contrastive learning でファインチューン。 検索・クラスタリングに使う。
感情極性(positive/negative)、 カテゴリ、 トピック等。
1 2 3 | from transformers import pipeline clf = pipeline('sentiment-analysis', model='koheiduck/bert-japanese-finetuned-sentiment') print(clf('このサービスはとても便利です')) |
テキストから人名・地名・組織名等を抽出。 BIO タグ付け。
1 2 3 | from transformers import pipeline ner = pipeline('ner', model='Davlan/bert-base-multilingual-cased-ner-hrl') print(ner('オバマは2009年にアメリカ大統領になった')) |
文ベクトル間のコサイン類似度。 RAG・FAQ 検索の基盤。
Encoder-Decoder Transformer が標準。 NMT (Neural MT)。
1 2 3 4 | from transformers import pipeline trans = pipeline('translation', model='Helsinki-NLP/opus-mt-ja-en') print(trans('東京は美しい都市です')) |
タスク指向 / オープンドメイン。 現代は ChatGPT 系 LLM が主流。
🍰 まずはやさしく
言葉の処理をまとめて解説するページです。
日本語特有の難しさを知るために使います。
地域の紹介文などのデータを扱います。
基本の用語から日本語の課題まで読みます。
本ページでは、 自然言語処理 (NLP) を統合的に解説します。 トークン化・形態素解析・BoW/TF-IDF・Word2Vec・BERT・埋め込み・主要 NLP タスクを一気通貫で扱います。
日本語は分かち書きが必要・敬語や文脈依存が強い・複雑なエンコーディング等、 英語にはない難しさがあります。 本ページは日本語固有の課題も扱います。
SSDSE は本来統計データセットだが、 NLP 教材として「数値 ↔ テキスト」変換タスクの素材になる。 既存日本語コーパスと組み合わせると更に拡張可能。
| コーパス | 規模 | SSDSE との組合せ案 |
|---|---|---|
| Wikipedia ja | 1.4M 記事 | 「47 都道府県 Wikipedia 記事」+ SSDSE 統計 → 統計値抽出タスク |
| 青空文庫 | 17K 作品 | 作品中の地名出現頻度 vs SSDSE 人口 |
| Livedoor ニュース | 7K 記事 | 分類タスク + 地域情報の付与 |
| 日本語 SNLI | 550K ペア | SSDSE 統計から含意判定問題生成 |
| JGLUE | 複数タスク | 統計データを別ドメインとして fine-tune |
「数値 ↔ テキスト」「地域 ↔ 文書」の橋渡しが、 SSDSE を NLP 教材として独自にしている点。 統計教育者が NLP に踏み出す際の好材料になる。
🍰 まずはやさしく
学習の地図のようなガイドです。
迷わずに勉強を進めるために使います。
県の名前を切り出すなどの演習で学びます。
5つの段階に分かれた学習パスを読みます。
自然言語処理 (NLP) を独学・授業で学ぶとき、 用語が散逸して「結局どれから始めればいいの?」となりがち。 このグループ教材は、 SSDSE-B-2026 のような 実データに基づいたテキスト演習を軸に、 5 つのレイヤーで段階的に学ぶ設計。
| L | 主要用語ページ | SSDSE 演習例 | 目標時間 |
|---|---|---|---|
| L1 | トークン化, ストップワード, ステミング | 都道府県名を janome で分かち書き | 2h |
| L2 | TF-IDF, BoW, コサイン類似度 | 県紹介文の類似度行列 | 3h |
| L3 | word2vec, FastText, 埋め込み | 統計指標による県クラスタリング | 4h |
| L4 | BERT, Transformer, Attention | 県紹介文の感情分類 | 6h |
| L5 | GPT, T5, RAG | 統計から県紹介文を生成 | 8h |
合計 23h で「現代 NLP の全レイヤーを SSDSE で体験」できる設計。
🍰 まずはやさしく
計算のルールをまとめたページです。
モデルがどう動くか正確に知るために使います。
単語の似ている度合いなどを計算します。
各モデルで使う重要な数式を読みます。
グループ教材を横断する主要な数式を 1 ページに集約。 詳細は個別ページへ。
$$ \mathrm{tfidf}(t, d) = \mathrm{tf}(t, d) \cdot \log\frac{N}{1 + \mathrm{df}(t)} $$
$$ \mathcal{L} = -\sum_{t=1}^{T} \sum_{-c \leq j \leq c, j \neq 0} \log p(w_{t+j} \mid w_t), \quad p(w_O \mid w_I) = \frac{\exp(v'_{w_O} \cdot v_{w_I})}{\sum_{w=1}^{V} \exp(v'_w \cdot v_{w_I})} $$
$$ \mathrm{Attention}(Q, K, V) = \mathrm{softmax}\!\left(\frac{Q K^\top}{\sqrt{d_k}}\right) V $$
$$ \mathcal{L}_{\text{GPT}} = -\sum_{t=1}^{T} \log p_\theta(w_t \mid w_{<t}) $$
NLP は「正解が一意ではない」タスクが多いため、 評価指標は多様。 グループ教材を学ぶ際に必ず通る評価指標を分類整理する。
| タスク | 代表指標 | 数式 (要点) | SSDSE 演習 |
|---|---|---|---|
| 分類 | F1, Macro-F1 | $2PR/(P+R)$ | 県紹介文の感情分類 |
| 機械翻訳 | BLEU, chrF, COMET | n-gram precision × BP | 県紹介文 ja→en |
| 要約 | ROUGE-L, BERTScore | 最長共通部分列 / 埋め込み類似 | 県統計の長文要約 |
| 言語モデル | Perplexity | $\exp(-\frac{1}{T}\sum \log p)$ | GPT2 を県紹介文で fine-tune |
| 対話 | 人手評価, LLM-as-judge | 主観 / GPT-4 採点 | 統計クイズ対話 |
| 情報検索 | MRR, nDCG, Recall@k | $\frac{1}{|Q|}\sum 1/\mathrm{rank}_q$ | 県名から統計検索 |
$$ \mathrm{BLEU} = \mathrm{BP} \cdot \exp\!\left(\sum_{n=1}^{N} w_n \log p_n\right), \quad \mathrm{BP} = \min(1, \exp(1 - r/c)) $$
BLEU は古典だが、 「意味的に合っているけど語順が違う」を罰してしまう。 現代は COMET や BERTScore など埋め込み系評価との併用が必須。
日本語 NLP は、 英語など空白で単語が区切られる言語とは根本的に異なる前処理が必要である。 日本語の文「東京の人口は約 1400 万人である」を解析するには、 まず「東京 / の / 人口 / は / 約 / 1400 / 万 / 人 / で / ある」のように 形態素(意味を持つ最小単位)に分割する必要がある。 この処理を 形態素解析(morphological analysis)と呼び、 日本語 NLP の出発点となる。 代表的なツールに MeCab、 Janome、 SudachiPy、 GiNZA があり、 それぞれ辞書、 速度、 機能の特性が異なる。
MeCab は C++ で実装された高速な解析器で、 IPADIC や UniDic などの辞書と組み合わせて使う。 Janome は純 Python 実装で、 インストールが容易で初学者向けに適している。 SudachiPy は新語や複合語に強く、 「東京特許許可局」のような長い固有名詞も適切に処理する。 GiNZA は spaCy ベースで、 形態素解析と依存構造解析を統合的に扱える。 SSDSE-B-2026 のような統計データに付随する説明文(メタデータ)を解析する場合、 「都道府県名」「人口」「総生産」等の専門用語を正しく認識できる辞書選定が重要である。
辞書の選定は精度を左右する。 IPADIC は基本辞書で多くのツールのデフォルトだが、 新語への対応が弱い。 mecab-ipadic-NEologd は Web 上の新語(流行語、 企業名等)を継続的に追加した拡張辞書で、 「SNS テキスト」や「ニュース記事」の処理で精度が向上する。 UniDic は国立国語研究所が公開する学術的辞書で、 教育・研究用途で標準的に使われる。 SSDSE-B-2026 のような統計データ解説の処理には IPADIC で十分だが、 自治体の議事録や住民の声を分析する場合は NEologd の使用を検討すべきである。
| ツール | 特徴 | 速度 | 推奨用途 |
|---|---|---|---|
| MeCab | C++ 実装、 高速 | ★★★★★ | 大量処理・本番 |
| Janome | Pure Python | ★★★ | 学習・小規模 |
| SudachiPy | 分割粒度可変 | ★★★★ | 新語・固有名詞重視 |
| GiNZA | spaCy 統合 | ★★★ | 構文解析と統合 |
| Kuromoji | Java 実装 | ★★★★ | JVM 環境 |
日本語特有の課題として「表記揺れ」がある。 「東京都」「東京」「Tokyo」「とうきょう」「トウキョウ」が同じ概念を指すケース、 「2026 年」「令和 8 年」「2026」のように年号表記が混在するケース、 半角と全角の差(「1400 万人」と「1400万人」)など、 機械的な処理では区別されない揺れが多発する。 NLP の前処理段階で、 これらを 正規化(normalization) することが、 後続のベクトル化や類似度計算の精度に大きく影響する。 SSDSE-B-2026 の都道府県名は標準化された形式で記録されているが、 自由記述のメタデータを処理する際は正規化が必須である。
もう一つの日本語特有の難しさが「曖昧性」である。 「東京の中心は新宿」という文は、 「東京(都)の中心は新宿(区)」とも「東京(駅)の中心は新宿(駅)」とも解釈できる。 また「人口の減少」と「減少の人口」は意味が逆になるが、 形態素解析だけでは違いを捉えにくい。 こうした曖昧性を解消するには、 文脈情報を考慮した 係り受け解析 や、 大規模言語モデル(LLM)を活用した文脈理解が必要となる。 SSDSE-B-2026 の解析でも、 「都道府県別の傾向」と「傾向別の都道府県」のように、 言い回しの違いが分析意図を変えるため、 自然言語クエリの設計には注意を要する。
最後に、 形態素解析の出力をどう活用するかが NLP パイプライン設計の核心である。 シンプルな用途では「名詞だけを抽出して頻度集計」「動詞だけを抽出して行動分析」のように品詞でフィルタリングする。 高度な用途では、 形態素ベクトルを Word2Vec や fastText で埋め込み、 文書間の意味的類似度を計算する。 さらに最先端では、 BERT や日本語 LLM が形態素解析を内包した形で文脈理解を行うため、 「形態素解析を明示的に行わない」アプローチも増えている。 用途と要求精度に応じてアプローチを選択することが、 NLP 実装の腕の見せどころである。
NLP の歴史で 2013 年に登場した Word2Vec は革命的だった。 「単語を高次元のベクトルに変換し、 ベクトル間の演算で意味関係を捉える」という発想は、 それ以前の「単語 = 離散的なシンボル」という常識を覆した。 有名な例として「king - man + woman = queen」のようなベクトル演算が、 単語の意味的関係を表現することが示された。 この基盤の上に、 GloVe(2014)、 fastText(2016)といった改良版が登場し、 NLP の精度が飛躍的に向上した。 SSDSE-B-2026 のような統計データ解説文を Word2Vec で処理すれば、 「人口 - 増加 + 減少 ≈ 過疎」のような関係性を抽出できる可能性がある。
しかし Word2Vec には根本的な制約があった。 「同じ単語は文脈に関わらず同じベクトル」になることである。 例えば「銀行」という単語は「金融機関」と「川岸」の両方の意味があるが、 Word2Vec ではどちらも同じベクトルになる。 この課題に対応するため、 2018 年に BERT(Bidirectional Encoder Representations from Transformers)が登場した。 BERT は「文脈に応じて単語ベクトルを動的に変化させる」ことで、 「銀行口座」と「川の銀行(岸)」を別のベクトルとして扱える。 この進化により、 NLP タスクの精度が大幅に向上した。
BERT の革新の核心は Transformer アーキテクチャと 自己注意機構(self-attention) である。 自己注意機構は「文中の各単語が、 他のどの単語に注目すべきか」を学習する仕組みで、 文脈情報を双方向(左右両方)から取り込める。 例えば「太郎が花子にプレゼントを渡した」という文で、 「渡した」という動詞を解釈する際、 「太郎(主語)」「花子(受け手)」「プレゼント(目的語)」すべてに同時に注目できる。 この能力により、 BERT は係り受け解析、 質問応答、 感情分析など多様な NLP タスクで人間に近い精度を達成した。
| モデル | 発表年 | 特徴 | 代表的応用 |
|---|---|---|---|
| Word2Vec | 2013 | 静的ベクトル | 類義語検索 |
| GloVe | 2014 | 共起行列ベース | 類義語検索 |
| fastText | 2016 | サブワード対応 | 未知語処理 |
| ELMo | 2018 | 双方向 LSTM | 文脈依存ベクトル |
| BERT | 2018 | Transformer | QA・感情分析 |
| GPT-3/4 | 2020/2023 | 大規模生成 | 対話・要約・生成 |
BERT 以降の発展として、 GPT-3(2020)と GPT-4(2023)に代表される 大規模言語モデル(LLM) が登場した。 これらは数千億パラメータを持ち、 「事前学習 + プロンプト」という新しいパラダイムを確立した。 BERT が「特定タスク向けにファインチューニング」する設計だったのに対し、 LLM は「自然言語の指示(プロンプト)だけでタスクを切り替える」柔軟性を持つ。 SSDSE-B-2026 の解析でも、 「人口減少と年収水準の関係を要約せよ」のようなプロンプトで、 専用モデルを訓練することなく分析できるようになった。
日本語 NLP の文脈では、 東北大 BERT、 京都大 BERT、 NICT BERT など、 日本語特化型の BERT モデルが多数公開されている。 これらは Wikipedia 日本語版や日本語ニュース記事で事前学習されており、 日本語特有の表現を理解できる。 また、 サイバーエージェントの OpenCALM や rinna の nekomata など、 日本語 LLM の開発も活発である。 SSDSE-B-2026 のような国内データの分析や行政・教育目的の自然言語処理では、 日本語特化モデルを使うことで精度と表現の自然さが大きく向上する。
意味ベクトルの応用範囲は広い。 文書検索では、 クエリと文書をベクトル化し、 コサイン類似度で類似文書を抽出する(セマンティック検索)。 クラスタリングでは、 大量の文書を意味的に類似したグループに分類する。 分類では、 ニュース記事のカテゴリ分けや、 顧客の問い合わせ自動分類を行う。 要約では、 長文の要点を自動抽出する。 SSDSE-B-2026 の都道府県別解説文をベクトル化すれば、 「人口減少が深刻な県」「産業構造が類似する県」のような意味的グルーピングが可能になる。 このような意味ベースの分析は、 単純な統計分析を補完する強力なツールとなる。
本セクションでは、自然言語処理(Natural Language Processing, NLP)のグループ教材で扱う中核概念について、数式・記号の意味を一つずつ言葉で読み解く。文字列を「数値ベクトル」に変換し、それを「文脈」とともに解釈し、最終的に「タスク出力」に写像するという NLP の根本的な発想の流れを、トークナイザ・埋め込み・自己注意・Transformer の 4 段階に分けて説明する。
テキスト $T$ を入力として、トークン列 $(t_1, t_2, \ldots, t_n)$ を返す関数 $\mathrm{Tok}: T \to V^n$ を考える。ここで $V$ は語彙集合(vocabulary)、$n$ は分割後のトークン数である。記号の意味を 1 つずつ読み解くと次のようになる。
つまり「文字列を、辞書 $V$ に登録された最小単位の並びに区切る」関数である。日本語では SentencePiece、英語では BPE が標準的に用いられる。
トークン $t_i$ を $d$ 次元の連続ベクトル $\mathbf{e}_i \in \mathbb{R}^d$ に写す関数 $E: V \to \mathbb{R}^d$ を定義する。記号の意味は次のとおり。
具体的には「東京」「大阪」「福岡」のような都市名は近い座標に配置され、「東京 - 日本 + フランス ≒ パリ」というようなベクトル演算が成り立つ。これは Mikolov らの Word2Vec で示された性質で、現代 NLP の基礎となっている。
Transformer の中核である自己注意は、入力ベクトル列 $X \in \mathbb{R}^{n \times d}$ から「Query」「Key」「Value」の 3 種類の行列を作り、トークン間の関連度を内積で測る仕組みである。
$$\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\left(\frac{Q K^\top}{\sqrt{d_k}}\right) V$$
たとえば「彼は銀行に行った。そこで彼はお金を引き出した」という文では、2 文目の「そこで」は 1 文目の「銀行」と高い注意重みで結ばれる。これにより代名詞解決や長距離依存が学習可能になる。
Transformer ブロックは「Multi-Head Self-Attention」と「Feed-Forward Network (FFN)」を残差接続と層正規化で繋いだ構造である。1 ブロックの式は次のとおり。
$$\begin{aligned} Y &= \mathrm{LayerNorm}(X + \mathrm{MHA}(X)) \\ Z &= \mathrm{LayerNorm}(Y + \mathrm{FFN}(Y)) \end{aligned}$$
このブロックを $L$ 層積み重ねたものが Transformer Encoder(BERT 系)または Decoder(GPT 系)である。BERT-base は 12 層、GPT-3 は 96 層に達する。
NLP 単独では SSDSE-B(数値統計データ)を直接扱わないが、たとえば「都道府県名」と「人口・消費支出・新規求職申込件数」(いずれも SSDSE-B に実在する列)を組み合わせて以下のような応用が考えられる。
| タスク | 入力(テキスト) | 出力 | 使う技術 |
|---|---|---|---|
| 都道府県分類 | 「人口が多く、失業率が低い」 | 「東京都」 | BERT 系分類 |
| 統計記事要約 | SSDSE 解説記事 2,000 字 | 200 字要約 | T5 / GPT |
| 数値質問応答 | 「2026 年の北海道の人口は?」 | 「約 511 万人」 | RAG + LLM |
| テーブル抽出 | 統計局 PDF | 構造化 CSV | LayoutLM / Donut |
SSDSE-B-2026 自体は数値データですが、 都道府県名と都道府県の特徴量を「擬似的なテキストドキュメント」として扱う実例を示します(教育目的)。
各都道府県の県庁所在地名や地理キーワードを文字列として連結し、 TF-IDF 行列を作成して類似都道府県を求めます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import pandas as pd from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True) # 各都道府県の特徴を「テキスト化」(数値→文字列の擬似ドキュメント) docs = [] for _, row in df.iterrows(): pref = str(row['Prefecture']) # 各列を「項目名_値帯」の形式に変換(例:'人口_多', '高齢化率_高') tokens = [pref] docs.append(' '.join(tokens)) # 実テキスト例:県庁所在地と地域情報 labels = df['Prefecture'].tolist() texts = [f"{name} 県庁 地方 統計 経済 人口" for name in labels] vectorizer = TfidfVectorizer(analyzer='char_wb', ngram_range=(2,3)) X = vectorizer.fit_transform(texts) print('TF-IDF 行列の形:', X.shape) # コサイン類似度で似た県を探す sim = cosine_similarity(X) print(f'東京と大阪の類似度: {sim[12, 26]:.3f}') |
SSDSE-B-2026 の都道府県名と統計指標を組み合わせて、 47 件の「県紹介文コーパス」を生成し、 NLP 演習素材として使う。
📥 入力データ (SSDSE-B-2026 一部):
🎯 このコードでやること: SSDSE の統計値からテンプレ文を生成、 janome で分かち書き、 TF-IDF をベクトル化、 県同士の類似度を計算する。
📥 入力: 上記 SSDSE-B-2026 (47 県の人口・新規求職申込件数・消費支出・高齢人口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import pandas as pd from janome.tokenizer import Tokenizer from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import cosine_similarity df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True) # 県紹介文をテンプレで生成 def make_doc(row): pop = '人口が多い' if row['A1101'] > 3000000 else '人口が少ない' inc = '消費支出が多い' if row['L3221'] > 300000 else '消費支出が標準的' unemp = '求職者が少ない' if row['F3101'] < 40000 else '求職者が多い' return f"{row['Prefecture']}は{pop}地域である。住民の{inc}。経済面では{unemp}。" df['doc'] = df.apply(make_doc, axis=1) # janome 分かち書き t = Tokenizer() df['tok'] = df['doc'].apply(lambda s: ' '.join([w.surface for w in t.tokenize(s)])) # TF-IDF vec = TfidfVectorizer(token_pattern=r"[^\s]+") M = vec.fit_transform(df['tok']) print('matrix shape:', M.shape) # 北海道との類似度 top 5 sim = cosine_similarity(M[0:1], M)[0] top = sim.argsort()[::-1][1:6] for i in top: print(f'{df.loc[i, "Prefecture"]:6s} sim={sim[i]:.3f}') |
📤 実行例:
💬 北海道とテンプレ語が最も一致するのは兵庫県(人口・消費支出・求職の 3 軸すべて同カテゴリ)。 テンプレが揃っている分、 TF-IDF は語の有無で素直に類似度を出す。 続く青森・岩手・群馬・鹿児島は 3 軸のうち 2 軸が一致するグループとして並ぶ。
グループ教材を通して、 自分がどのレベルに到達したかを 5 段階で測れるルーブリックを用意した。 SSDSE 演習の合格点と合わせて掲示する。
| Lv | 到達目標 | SSDSE 合格課題 | 目安時間 |
|---|---|---|---|
| ★1 | 基本用語が説明できる | 「TF-IDF とは何か」を 3 行で書ける | 1h |
| ★2 | 既存ライブラリで実装できる | 県紹介文の TF-IDF を sklearn で計算 | 3h |
| ★3 | 複数手法を比較できる | TF-IDF vs word2vec vs BERT で類似度を比較 | 8h |
| ★4 | 評価実験を設計できる | 交差検証 + 統計検定で 3 手法を比較 | 15h |
| ★5 | 独自手法を提案できる | SSDSE 専用ドメイン適応 BERT を作る | 30h+ |
大学 1 年生は ★2 まで、 卒論レベルは ★3、 修論レベルは ★4、 学会発表は ★5、 という目安。 各レベルで「SSDSE 合格課題」を達成することが用語理解の証になる。
SSDSE-B-2026 を NLP 演習に活用するときの代表ツール。 すべて Python から呼べ、 教育用途では無償で十分。
| 層 | ツール | 用途 | SSDSE 連携 |
|---|---|---|---|
| L1 | janome / fugashi / sudachi | 分かち書き | 県名・統計テンプレ |
| L2 | sklearn TfidfVectorizer | BoW/TF-IDF | 47 文書の類似度 |
| L3 | gensim word2vec / fasttext | 分散表現 | 県統計コーパス学習 |
| L4 | transformers / sentence-transformers | BERT 系 | 県紹介文の埋め込み |
| L5 | transformers (GPT2 系) | 生成 | 統計値からの作文 |
合成データで NLP 7 タスクの精度を集計する。
| タスク | 精度 |
|---|---|
| 形態素解析 | 0.98 |
| 構文解析 | 0.92 |
| 固有表現抽出 | 0.88 |
| 感情分析 | 0.85 |
| 機械翻訳 | 0.78 |
| 要約 | 0.65 |
| 質問応答 | 0.72 |
1 2 3 4 | import numpy as np acc = np.array([0.98, 0.92, 0.88, 0.85, 0.78, 0.65, 0.72]) print(f"平均: {acc.mean():.3f}") print(f"最低 index: {acc.argmin()} ({acc.min()})") |
💬 手計算 (Step 2) 0.826 と Python 出力が完全一致。
| 用途 | パッケージ |
|---|---|
| 日本語形態素解析 | fugashi, mecab-python3, sudachipy, janome |
| 解析パイプ | spacy, ginza, stanza |
| 古典NLP | sklearn.feature_extraction.text, nltk |
| 単語埋め込み | gensim, fasttext |
| 事前学習モデル | transformers, sentence-transformers |
| トークナイザ | tokenizers, sentencepiece, tiktoken |
| トピック | gensim, bertopic, top2vec |
| ベクトル検索 | faiss, chromadb, qdrant, weaviate |
| LLMフレーム | langchain, llamaindex, dspy |
| 評価 | seqeval, sacrebleu, evaluate (HuggingFace) |
日本語は文脈で省略される情報が多い。 BERT 系は文脈学習で対応するが、 完璧ではない。 敬語レベル(タメ口・丁寧語・尊敬語・謙譲語)は文体識別の特徴。
漢字・ひらがな・カタカナ・英数字が同一文に混在。 サブワード分割が破綻しやすい。 SentencePiece が標準的に使われる理由の一つ。
古典文書・Web テキストではメタ情報除去が必要。
A. ノー。 (1) 小規模・高速・確定的処理ではルール / 線形が依然有用、 (2) LLM の前処理として古典手法が使われる、 (3) コスト・遅延・プライバシー要件で LLM が使えない場面が多い。
A. 2026 時点では cl-tohoku/bert-base-japanese-v3、 LINE LDLM、 rinna が主要。 ドメイン特化なら継続事前学習を検討。
A. 知識更新性が高い・出典が必要 → RAG。 文体・スタイル変更 → Fine-tune。 多くは両者の併用。
A. 完全に防ぐのは困難。 (1) RAG で根拠付け、 (2) Self-Consistency や別モデルでの検証、 (3) 出力の確信度を測定、 (4) 重要な決定では人間がレビュー。
$$\mathrm{BLEU} = \mathrm{BP} \cdot \exp\left(\sum_{n=1}^N w_n \log p_n\right)$$
$p_n$ は n-gram 精度、 $\mathrm{BP}$ は短さペナルティ。 0-1 で大きいほど良い。 単一文では信頼性が低い。
BERT 埋め込みのコサイン類似度ベース。 BLEU/ROUGE より人手評価との相関が高い。
$$\mathrm{BERTScore} = \frac{1}{|x|}\sum_{x_i} \max_{\hat{x}_j} \cos(\mathbf{e}_{x_i}, \mathbf{e}_{\hat{x}_j})$$
$$\mathrm{PPL} = \exp\left(-\frac{1}{N}\sum_i \log p(x_i \mid x_{<i})\right)$$
「次の単語をどれくらい予測しにくいか」。 小さいほど良い言語モデル。
エンティティ単位の P/R/F1(部分一致でなく完全一致)。 seqeval ライブラリが標準。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | from sentence_transformers import SentenceTransformer import faiss import numpy as np # 1. インデックス構築 embedder = SentenceTransformer('intfloat/multilingual-e5-base') docs = ['文書1...', '文書2...', ...] embeddings = embedder.encode([f'passage: {d}' for d in docs]) index = faiss.IndexFlatIP(embeddings.shape[1]) faiss.normalize_L2(embeddings) index.add(embeddings) # 2. クエリ → 検索 query = '東京の人口は?' q_emb = embedder.encode([f'query: {query}']) faiss.normalize_L2(q_emb) scores, idx = index.search(q_emb, k=5) retrieved = [docs[i] for i in idx[0]] # 3. LLM に注入 prompt = f"""以下の文書を参考に質問に答えてください。 文書: {chr(10).join(retrieved)} 質問: {query} 回答:""" |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import LogisticRegression from sklearn.pipeline import Pipeline from sklearn.model_selection import cross_val_score texts = ['東京は首都です', '大阪は商業の街', '京都は古い都', '横浜は港町'] labels = [1, 0, 1, 0] pipe = Pipeline([ ('tfidf', TfidfVectorizer(analyzer='char_wb', ngram_range=(2,3))), ('clf', LogisticRegression(max_iter=1000)) ]) scores = cross_val_score(pipe, texts, labels, cv=2) print(f'CV 平均: {scores.mean():.3f}') |
🎯 このコードでやること: 多言語 BERT ベースの sentence-transformers を使って県紹介文を埋め込み、 TF-IDF とは異なる「意味的類似度」を観察する。
📥 入力: 上のセルで生成した df['doc'] (47 行のテンプレ文)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import pandas as pd from sentence_transformers import SentenceTransformer from sklearn.metrics.pairwise import cosine_similarity df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True) # 同じテンプレ文 def make_doc(row): pop = '人口が多い' if row['A1101'] > 3000000 else '人口が少ない' inc = '消費支出が多い' if row['L3221'] > 300000 else '消費支出が標準的' unemp = '求職者が少ない' if row['F3101'] < 40000 else '求職者が多い' return f"{row['Prefecture']}は{pop}地域である。住民の{inc}。経済面では{unemp}。" df['doc'] = df.apply(make_doc, axis=1) # 多言語 BERT model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2') emb = model.encode(df['doc'].tolist(), normalize_embeddings=True) print('embedding shape:', emb.shape) # 北海道と意味的に近い top 5 sim = cosine_similarity(emb[0:1], emb)[0] top = sim.argsort()[::-1][1:6] for i in top: print(f'{df.loc[i, "Prefecture"]:6s} sim={sim[i]:.3f}') |
📤 実行例 (埋め込み値はモデル・バージョン依存で変動する):
💬 TF-IDF とは違い、 BERT 系は「人口が多い・消費支出が標準的・求職者が多い」という文全体の意味が近い県を拾う。 北海道の隣人として千葉・東京・大阪など大規模県が上位に来る。 テンプレ文でも語順や文脈表現の違いを反映するため、 同じ「都道府県紹介」でも L2 (TF-IDF) と特徴の出方が異なるのを体感できる。
🎯 このコードでやること: SSDSE の数値を Few-shot プロンプトに埋めて、 ローカル LLM (例: rinna-1.6B) に県紹介文を生成させる演習の最小例。 API キー不要なオフライン版。
📥 入力: SSDSE-B-2026 から 47 県統計を取得
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import pandas as pd from transformers import AutoTokenizer, AutoModelForCausalLM import torch df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True) # 小規模日本語 LLM tok = AutoTokenizer.from_pretrained('rinna/japanese-gpt2-small') mdl = AutoModelForCausalLM.from_pretrained('rinna/japanese-gpt2-small') def gen_for(pref): row = df[df['Prefecture']==pref].iloc[0] prompt = f"{pref}は人口{int(row['A1101']/1000)}千人、消費支出{int(row['L3221'])}円、新規求職申込{int(row['F3101'])}件である。この県を一言で表すと、" inp = tok.encode(prompt, return_tensors='pt') out = mdl.generate(inp, max_length=80, do_sample=True, top_p=0.9, temperature=0.8) return tok.decode(out[0], skip_special_tokens=True) for p in ['北海道', '東京都', '沖縄県']: print(gen_for(p)) print('---') |
📤 実行例 (生成は確率的なので毎回変わる):
💬 数値をプロンプトに入れるだけで文章生成 (zero/few-shot) ができる。 ハルシネーション (数値と矛盾する文) が出やすいので、 評価時は BLEU/ROUGE や事実性チェックを入れる。 L5 では RAG で実データに根拠を持たせる手法へ進む。
🎯 このコードでやること: SSDSE 県名 + 県紹介テンプレ文を、 日本語前処理 (正規化 → 分かち書き → 品詞フィルタ → 原形化 → ストップワード除去) のパイプラインで整える。
📥 入力: SSDSE-B-2026 から 47 県のテンプレ文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import pandas as pd import unicodedata, re from janome.tokenizer import Tokenizer df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True) df['doc'] = df.apply(lambda r: f"{r['Prefecture']}は人口が{int(r['A1101']/1000)}千人で、雇用が活発である。", axis=1) # Step 1: Unicode 正規化 def normalize(s): s = unicodedata.normalize('NFKC', s) # 全角→半角、 異字体統合 s = s.lower() s = re.sub(r'\s+', ' ', s).strip() return s # Step 2: 分かち書き + 品詞フィルタ + 原形化 t = Tokenizer() STOP = set(['は','の','が','を','に','て','で','と','も','し','する','いる','ある','こと','する','れる','られる']) ALLOW = {'名詞','動詞','形容詞','副詞'} def preprocess(s): s = normalize(s) out = [] for tok in t.tokenize(s): pos = tok.part_of_speech.split(',')[0] if pos not in ALLOW: continue base = tok.base_form if tok.base_form != '*' else tok.surface if base in STOP: continue out.append(base) return out df['tokens'] = df['doc'].apply(preprocess) print(df[['Prefecture','tokens']].head(3).to_string()) |
📤 実行例:
💬 ユニコード正規化で全角・半角揺れを除去、 品詞フィルタで助詞・接続詞を捨てた結果、 「県名・統計用語・属性語」だけが残った。 この状態が L2 (TF-IDF) 以降への入力としてベスト。
| 落とし穴 | 対処 |
|---|---|
| 日本語に英語向けトークナイザ | 日本語事前学習モデルとセットで使う。 fugashi/sudachi を活用。 |
| 前処理を過剰に | BERT 系は素のテキストで OK。 古典手法のときだけ前処理。 |
| 小データで巨大 LLM fine-tune | LoRA・プロンプト・Few-shot で対応。 |
| クラス不均衡 | Macro-F1 で評価、 weighted loss、 リサンプリング。 |
| 時系列リーク | 時系列分割。 訓練に未来データを混ぜない。 |
| BLEU だけで翻訳評価 | 最新は COMET・BERTScore。 人手評価も併用。 |
| LLM 出力をそのまま信用 | ハルシネーション対策に RAG・根拠検証。 |
SSDSE-B はテキストデータではないため、 wikipedia 日本語コーパス・口コミデータ・ニュース等を併用してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # ── 学習・評価用のテキストとラベル。説明用の合成データ ── texts_train = [ '景色が良くて満足した', '価格が手頃で助かった', '対応が丁寧だった', '待ち時間が長くて疲れた', '説明が分かりにくかった', '値段の割に内容が薄い', ] labels_train = ['positive', 'positive', 'positive', 'negative', 'negative', 'negative'] texts_test = ['接客がとても良かった', '案内が不親切で困った'] labels_test = ['positive', 'negative'] from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.linear_model import LogisticRegression from sklearn.pipeline import Pipeline import fugashi tagger = fugashi.Tagger() def tok(text): return [w.surface for w in tagger(text)] pipe = Pipeline([ ('tfidf', TfidfVectorizer(tokenizer=tok, token_pattern=None)), ('lr', LogisticRegression(max_iter=1000)), ]) pipe.fit(texts_train, labels_train) print(pipe.score(texts_test, labels_test)) |
Hugging Face Trainer を使い、 bert-base-japanese-v3 を 3 エポック程度学習。 GPU が必要。
1 2 3 4 5 | from sentence_transformers import SentenceTransformer from sklearn.cluster import KMeans model = SentenceTransformer('intfloat/multilingual-e5-base') emb = model.encode(texts) clusters = KMeans(n_clusters=10, n_init=10).fit_predict(emb) |
「BERT で文書分類しました。」
「ネット口コミ 8,000 件(5 段階評価、 不均衡 [40%/25%/15%/12%/8%])を 3 クラス(高/中/低)に集約し、 cl-tohoku/bert-base-japanese-v3 を batch=16, lr=2e-5, 3epoch で fine-tune。 Stratified 5-fold CV で Macro-F1 = 0.78 ± 0.02。 ベースラインの TF-IDF+ロジスティック (Macro-F1 = 0.63) より大幅改善。 アテンション可視化で『否定形』『極性語』に強い注目を確認。 ハイパラ選定は内側 CV で実施した。」
関連概念を視覚的に整理した概念マップ。
概念マップは「形態素解析 → 単語埋め込み → 系列モデル / Transformer → 応用 (QA / 要約 / チャット)」の NLP スタックを示す。 SSDSE-B-2026 自体はテキストではないが、 都道府県の「特産品名・産業名」を MeCab で形態素解析し、 word2vec で類似県をクラスタリングする教材は応用しやすい。
NLP グループ教材は、 入力 (テキスト) から出力 (分類・生成・抽出) までの長いパイプラインで隣接領域と接続する。
「データ収集 → 形態素解析 → ベクトル化 → 系列モデル → 評価」が NLP の標準ワークフロー。 SSDSE-B-2026 の地域記述テキストを題材にすれば、 47 件規模で各段階を体験できる。
NLP タスクの選び方は「入出力の対応」で決まる。
少ラベル環境では事前学習モデルの few-shot / zero-shot から始め、 必要に応じて fine-tune に移行する段階的アプローチが効率的。
SSDSE 単体ではテキスト分析の練習が難しいため、 以下のような外部公的テキストデータと組み合わせることを推奨:
1 2 3 4 5 6 7 8 9 10 11 12 13 | from transformers import AutoTokenizer, AutoModel import torch tokenizer = AutoTokenizer.from_pretrained('cl-tohoku/bert-base-japanese-v3') model = AutoModel.from_pretrained('cl-tohoku/bert-base-japanese-v3') texts = ['東京は日本の首都です', '大阪は商業の中心地'] inputs = tokenizer(texts, padding=True, return_tensors='pt') with torch.no_grad(): outputs = model(**inputs) # [CLS] トークンの出力を文ベクトルとして使う sent_vec = outputs.last_hidden_state[:, 0, :] print('文ベクトル形:', sent_vec.shape) |
1 2 3 4 5 6 7 8 | from sentence_transformers import SentenceTransformer from sklearn.metrics.pairwise import cosine_similarity model = SentenceTransformer('intfloat/multilingual-e5-small') sentences = ['今日は天気が良い', '本日は晴天です', '株価が下落した'] embs = model.encode(sentences) sim = cosine_similarity(embs) print(sim) |
1 2 3 4 5 6 7 8 9 10 11 12 13 | from gensim.models import Word2Vec, LdaModel from gensim.corpora import Dictionary # tokens は分かち書き済みの list of list tokens = [['東京', 'は', '日本', 'の', '首都'], ['大阪', 'は', '商業', 'の', '街']] w2v = Word2Vec(tokens, vector_size=50, min_count=1, window=3, epochs=10) print('東京の近傍:', w2v.wv.most_similar('東京', topn=3)) dic = Dictionary(tokens) corpus = [dic.doc2bow(t) for t in tokens] lda = LdaModel(corpus, num_topics=2, id2word=dic, passes=5) for tid, w in lda.print_topics(): print(tid, w) |
1 2 3 4 5 6 7 8 9 10 11 12 | import spacy nlp = spacy.load('ja_ginza') doc = nlp('東京は日本の首都です。大阪は商業の中心地です。') for sent in doc.sents: for tok in sent: print(tok.text, tok.lemma_, tok.pos_, tok.dep_) # 固有表現抽出 for ent in doc.ents: print(ent.text, ent.label_) |