第 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: レビューのラベル分布の確認¶
入力 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のインストール¶
入力 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のインストール¶
入力 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))