Skip to content

第 13 章 ソースコード一覧

書籍第 13 章「テキストデータを用いた機械学習」に掲載しているソースコードの一覧です。番号は書籍の「入力」番号と対応しています。上のバッジから、この章のコードをまとめた Google Colab ノートブックを開けます。

入力 13.1: 映画レビューデータの読み込みと確認

import pandas as pd
from urllib.request import urlretrieve

# データのダウンロードと読み込み
url = "https://ml.kano.ac/chapters/data/movie_reviews.csv"
urlretrieve(url, "movie_reviews.csv")
df = pd.read_csv("movie_reviews.csv")

# 長文のテキストは30文字で省略して表示
pd.set_option("display.max_colwidth", 30)
print(df.shape)

# 肯定的・否定的なレビューを3件ずつ表示
print(df.groupby("label").head(3))

入力 13.2: レビューのラベル分布の確認

print(df["label"].value_counts())

入力 13.3: TF-IDFとナイーブベイズによる文書分類

import MeCab
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report

# MeCabの準備(分かち書きモード)
tagger = MeCab.Tagger("-Owakati")

# MeCabで分かち書きを行い、単語のリストを返す関数を定義
def tokenize(text):
    result = tagger.parse(text)
    return result.strip().split()

# テキストとラベルの取得
texts = df["text"].values
labels = df["label"].values

# テキストを先に訓練用・テスト用に分割
train_texts, test_texts, y_train, y_test = train_test_split(
    texts, labels, test_size=0.2, random_state=42
)

# TF-IDFベクトル化(語彙とIDFは訓練テキストだけから学習)
vectorizer = TfidfVectorizer(tokenizer=tokenize, token_pattern=None)
X_train = vectorizer.fit_transform(train_texts)
X_test = vectorizer.transform(test_texts)

# ナイーブベイズで学習
model_nb = MultinomialNB()
model_nb.fit(X_train, y_train)

# テストデータで評価
y_pred = model_nb.predict(X_test)
print("【ナイーブベイズ(TF-IDF)】")
print(classification_report(y_test, y_pred))

入力 13.4: 線形SVMによる文書分類

from sklearn.svm import LinearSVC
from sklearn.metrics import classification_report

# SVMで学習
model_svm = LinearSVC(max_iter=1000)
model_svm.fit(X_train, y_train)

# テストデータで評価
y_pred_svm = model_svm.predict(X_test)
print("【SVM(TF-IDF)】")
print(classification_report(y_test, y_pred_svm))

入力 13.5: 新しいレビューのカテゴリ予測

# 新しいレビューを用意
new_reviews = [
    "最高の映画でした!感動して涙が出ました。",
    "つまらない映画でした。お金の無駄です。",
    "普通の映画でした。可もなく不可もなく。"
]

# TF-IDFベクトルに変換(学習時と同じvectorizerを使用)
X_new = vectorizer.transform(new_reviews)

# SVMで予測
predictions = model_svm.predict(X_new)

for review, pred in zip(new_reviews, predictions):
    print(f"レビュー: {review}")
    print(f"  予測: {pred}\n")

入力 13.6: 学習済みモデルによる商品レビューの感情判定

# 入力13.4の学習済みモデルで商品レビューの感情を判定
product_reviews = [
    "この商品はとても使いやすくて満足しています",
    "期待外れの商品でした。残念です",
]
X_product = vectorizer.transform(product_reviews)
predictions = model_svm.predict(X_product)

for review, pred in zip(product_reviews, predictions):
    print(f"{review} → {pred}")

入力 13.7: Gensimのインストール

# Google Colabでの実行
!pip install gensim

入力 13.8: Word2Vecモデルの学習

import MeCab
from gensim.models import Word2Vec

# サンプルの文書コーパス
corpus = [
    "機械学習はデータからパターンを学習する技術です",
    "深層学習はニューラルネットワークを用いた機械学習の手法です",
    "自然言語処理はテキストデータを分析する技術です",
    "画像認識は写真や動画から物体を検出する技術です",
    "機械学習を使ってテキストを分類することができます",
    "自然言語処理は人工知能の重要な分野です",
    "深層学習により画像認識の精度が大幅に向上しました",
    "テキストデータの分析には自然言語処理の技術が必要です",
]

# 内容語(名詞・動詞・形容詞)のみを抽出して分かち書き
tagger = MeCab.Tagger()

def tokenize_content(text):
    target_pos = ["名詞", "動詞", "形容詞"]
    words = []
    node = tagger.parseToNode(text)
    while node:
        if (
            node.surface != ""
            and node.feature.split(",")[0] in target_pos
        ):
            words.append(node.surface)
        node = node.next
    return words

tokenized_corpus = [tokenize_content(doc) for doc in corpus]

# Word2Vecモデルの学習
model_w2v = Word2Vec(
    sentences=tokenized_corpus,
    vector_size=20,    # ベクトルの次元数
    window=5,          # 文脈の窓幅
    min_count=1,       # 最低出現回数
    epochs=500,        # 学習回数
    sg=1,              # 1: Skip-gram, 0: CBOW
    seed=42,           # 乱数シードの固定
    workers=1,         # 再現性のため単一スレッドで学習
)

# 学習結果の確認
print(f"語彙数: {len(model_w2v.wv)}")
print(f"「学習」のベクトル(先頭5要素): {model_w2v.wv['学習'][:5]}")

入力 13.9: 「言語」に類似する単語の検索

# 「言語」に類似する単語を検索
similar_words = model_w2v.wv.most_similar("言語", topn=5)
print("「言語」に類似する単語:")
for word, score in similar_words:
    print(f"  {word}: {score:.4f}")

入力 13.10: Doc2Vecモデルの学習

from gensim.models.doc2vec import Doc2Vec, TaggedDocument

# TaggedDocumentの作成(文書IDと分かち書きしたテキスト)
tagged_docs = [
    TaggedDocument(words=tokens, tags=[f"doc_{i}"])
    for i, tokens in enumerate(tokenized_corpus)
]

# Doc2Vecモデルの学習
model_d2v = Doc2Vec(
    documents=tagged_docs,
    vector_size=20,    # ベクトルの次元数
    window=5,          # 文脈の窓幅
    min_count=1,       # 最低出現回数
    epochs=500,        # 学習回数
    dm=1,              # 1: PV-DM(分散記憶モデル), 0: PV-DBOW
    seed=42,           # 乱数シードの固定
    workers=1,         # 再現性のため単一スレッドで学習
)

# 文書ベクトルの確認
print(f"文書数: {len(tagged_docs)}")
print(f"doc_0 のベクトル(先頭5要素): {model_d2v.dv['doc_0'][:5]}")

入力 13.11: 文書間の類似度の確認

# 文書間の類似度
similar_docs = model_d2v.dv.most_similar("doc_0", topn=3)
print(f"元の文書: {corpus[0]}\n")
print("類似する文書:")
for doc_id, score in similar_docs:
    idx = int(doc_id.split("_")[1])
    print(f"  {doc_id} (類似度: {score:.4f}): {corpus[idx]}")

入力 13.12: 新しい文書のベクトル推論と類似文書検索

# 新しい文書のベクトルを推論
new_doc = "データ分析に機械学習を活用する"
new_tokens = tokenize_content(new_doc)
new_vector = model_d2v.infer_vector(new_tokens)

# 類似文書の検索
similar = model_d2v.dv.most_similar([new_vector], topn=3)
print(f"クエリ: {new_doc}\n")
print("類似する文書:")
for doc_id, score in similar:
    idx = int(doc_id.split("_")[1])
    print(f"  {doc_id} (類似度: {score:.4f}): {corpus[idx]}")

入力 13.13: Sentence Transformersのインストール

# Google Colabでの実行
!pip install sentence-transformers

入力 13.14: 文のEmbeddingへの変換

from sentence_transformers import SentenceTransformer

# モデルの読み込み
model_st = SentenceTransformer("paraphrase-multilingual-MiniLM-L12-v2")

# テキストをEmbeddingに変換
sentences = [
    "この映画は素晴らしかった",
    "この映画は最高だった",
    "今日の天気は晴れです"
]

embeddings = model_st.encode(sentences)

print(f"文の数: {len(embeddings)}")
print(f"各ベクトルの次元数: {embeddings.shape[1]}")
print(f"最初の文のベクトル(先頭5要素): {embeddings[0][:5]}")

入力 13.15: Embeddingを特徴量とした文書分類

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report

# 映画レビューデータを使用
texts = df["text"].values.tolist()
labels = df["label"].values

# 前項で読み込んだモデルでEmbeddingを生成
embeddings = model_st.encode(texts)

print(f"Embeddingの形状: {embeddings.shape}")

# 訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(
    embeddings, labels, test_size=0.2, random_state=42
)

# ロジスティック回帰で学習
model_lr = LogisticRegression(max_iter=1000)
model_lr.fit(X_train, y_train)

# テストデータで評価
y_pred = model_lr.predict(X_test)
print(classification_report(y_test, y_pred))