<jupyter_start><jupyter_text>第3章<jupyter_code>import codecs

import matplotlib.pyplot as plt
import seaborn as sns
plt.style.use('ggplot')
import numpy as np
import pandas as pd
from pandas import DataFrame
from sklearn.model_selection import train_test_split

from mf import MatrixFactorization<jupyter_output><empty_output><jupyter_text>Yahoo! R3データの読み込みと前処理<jupyter_code># オリジナルのトレーニングデータを読み込む
with codecs.open("./data/train.txt", "r", "utf-8") as f:
    train = pd.read_csv(f, delimiter="\t", header=None).values
    train[:, 0], train[:, 1] = train[:, 0] - 1, train[:, 1] - 1

# オリジナルのテストデータを読み込む
with codecs.open("./data/test.txt", "r", "utf-8") as f:
    test = pd.read_csv(f, delimiter="\t", header=None).values
    test[:, 0], test[:, 1] = test[:, 0] - 1, test[:, 1] - 1

# トレーニングデータのうち, 30%を無作為にバリデーションデータとする
train, val = train_test_split(train, test_size=0.30, random_state=12345)
# テストデータのうち, 1%を無作為に抽出し傾向スコアの推定に用いる
random, test = train_test_split(test, test_size=0.99, random_state=12345)

# 少量の完全ランダムな嗜好度合いデータを用いて傾向スコアを推定する [Schnabel16]
numerator = np.unique(train[:, 2], return_counts=True)[1]
numerator = numerator / numerator.sum() # P(R=r | O=1)の推定
denominator = np.unique(random[:, 2], return_counts=True)[1]
denominator = denominator / denominator.sum()  # P(R=r)の推定
pscore = numerator / denominator
# 図3.11で確認した通り、トレーニングデータとテストデータのレーティング分布は大きく乖離している
plt.subplots(1, figsize=(8,6))
train_df = DataFrame(train)
train_df["data"] = "train"
test_df = DataFrame(test)
test_df["data"] = "test"
data_df = pd.concat([train_df, test_df])
data_df.rename(columns={0: "user_id", 1: "item_id", 2: "rating"}, inplace=True)
sns.histplot(data_df, x="rating", hue="data", stat="probability", discrete=True, multiple="dodge", shrink=.8)
   
plt.xlabel("Rating Values", fontdict=dict(size=20))
plt.ylabel("Probability Mass", fontdict=dict(size=20))
plt.tight_layout()
plt.show()<jupyter_output><empty_output><jupyter_text>ナイーブ推定量に基づくMatrix Factorizationの学習<jupyter_code>mf_naive = MatrixFactorization(
    k=10,
    learning_rate=0.0001,
    reg_param=0.0001,
    random_state=12345,
)
val_loss_naive, test_loss_naive = mf_naive.fit(
    train=train, val=val, test=test, n_epochs=100
)<jupyter_output>100%|████████████████████████████████████████████| 100/100 [14:10<00:00,  8.50s/it]<jupyter_text>IPS推定量に基づくMatrix Factorizationの学習<jupyter_code>mf_ips = MatrixFactorization(
    k=10,
    learning_rate=0.0001,
    reg_param=0.0001,
    random_state=12345,
)
val_loss_ips, test_loss_ips = mf_ips.fit(
    train=train, val=val, test=test, pscore=pscore, n_epochs=100
)<jupyter_output>100%|████████████████████████████████████████████| 100/100 [14:20<00:00,  8.61s/it]<jupyter_text>学習曲線の描画  ナイーブ推定量に基づくMatrix Factorizationのバリデーションデータに対する誤差とテストデータに対する誤差の比較（図3.13）<jupyter_code>plt.subplots(1, figsize=(8,6))
plt.plot(np.arange(len(val_loss_naive)), val_loss_naive, label="Validation MSE", linewidth=3, linestyle="dashed")
plt.plot(np.arange(len(test_loss_naive)), test_loss_naive, label="Test MSE", linewidth=3)
   
plt.title("Validation/Test Curves: Naive", fontdict=dict(size=20))
plt.xlabel("Number of Epochs", fontdict=dict(size=20))
plt.ylabel("Mean Squared Error", fontdict=dict(size=20))
plt.ylim([1.0, 3.0])
plt.tight_layout()
plt.legend(loc="best", fontsize=20)
plt.show()<jupyter_output><empty_output><jupyter_text>IPS推定量に基づくMatrix Factorizationのバリデーションデータに対する誤差とテストデータに対する誤差の比較<jupyter_code>plt.subplots(1, figsize=(8,6))
plt.plot(np.arange(len(val_loss_ips)), val_loss_ips, label="Validation MSE", linewidth=3, linestyle="dashed")
plt.plot(np.arange(len(test_loss_ips)), test_loss_ips, label="Test MSE", linewidth=3)
 
plt.title("Validation/Test Curves: IPS", fontdict=dict(size=20))
plt.xlabel("Number of Epochs", fontdict=dict(size=20))
plt.ylabel("Mean Squared Error", fontdict=dict(size=20))
plt.ylim([0.5, 3.0])
plt.tight_layout()
plt.legend(loc="best", fontsize=20)
plt.show()<jupyter_output><empty_output><jupyter_text>ナイーブ推定量とIPS推定量を用いたときのそれぞれのテストデータに対する誤差の比較（図3.12）<jupyter_code>plt.subplots(1, figsize=(8,6))
plt.plot(np.arange(len(test_loss_naive)), test_loss_naive, label="Naive", linewidth=3, linestyle="dashed")
plt.plot(np.arange(len(test_loss_ips)), test_loss_ips, label="IPS", linewidth=3)
   
plt.title("Test MSE: Naive vs IPS", fontdict=dict(size=20))
plt.xlabel("Number of Epochs", fontdict=dict(size=20))
plt.ylabel("Mean Squared Error", fontdict=dict(size=20))
plt.ylim([1.0, 3.0])
plt.tight_layout()
plt.legend(loc="best", fontsize=20)
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17786648924373474, 'fraction_numerical': 0.04280328232424041, 'mean_word_length': 8.148073022312373, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '167659', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 2275, 'n_tokens_neox': 2075, 'n_words': 274, 'path': 'ch03/naive-vs-ips.ipynb', 'repo_name': 'masakiaota/ml_design_book', 'size': '4509'}