第2章 評価値行列
準備
次のコードを書きなさい。
import pprint
import numpy as np
np.set_printoptions(precision=3)
評価値行列
次の行列\(\boldsymbol{R}\)は評価値行列である。
\[\boldsymbol{R} = \left[ \begin{array}{rrrrrr} ? & 4 & 3 & 1 & 2 & ? \\ 5 & 5 & 4 & ? & 3 & 3 \\ 4 & ? & 5 & 3 & 2 & ? \\ ? & 3 & ? & 2 & 1 & 1 \\ 2 & 1 & 2 & 4 & ? & 3 \\ \end{array} \right]\]\(\boldsymbol{R}\)の\(u\)行目はユーザ\(u \in U\)を表し、\(i\)列目はアイテム\(i \in I\)を表す。ここで、\(\boldsymbol{R}\)におけるユーザ数は\(\mid U \mid = 5\)、アイテム数は\(\mid I \mid = 6\)となる。\(\boldsymbol{R}\)の\((u, i)\)成分はユーザ\(u\)がアイテム\(i\)に与えた評価値\(r_{u,i}\)を表す。ただし、\(?\)は欠損値であることを表す。このとき、次の問いに答えなさい。
01 評価値行列の生成
評価値行列\(\boldsymbol{R}\)をndarray
として生成するコードを書きなさい。得られたndarray
をR
とすること。
コード
【 問01 】
print('R = \n{}'.format(R))
結果
R =
[[nan 4. 3. 1. 2. nan]
[ 5. 5. 4. nan 3. 3.]
[ 4. nan 5. 3. 2. nan]
[nan 3. nan 2. 1. 1.]
[ 2. 1. 2. 4. nan 3.]]
★
numpy.array()
を使う。numpy.nan
を使う。
02 ユーザ集合
R
の各行のインデックスu
は各ユーザ\(u\)のユーザIDに対応する。R
からユーザ集合\(U\)(ユーザIDを要素としたベクトル)をndarray
として生成するコードを書きなさい。得られたndarray
をU
とすること。
コード
【 問02 】
print('U = {}'.format(U))
結果
U = [0 1 2 3 4]
★
numpy.arange()
を使う。ndarray.shape
を使う。
03 アイテム集合
R
の各列のインデックスi
は各アイテム\(i\)のアイテムIDに対応する。R
からアイテム集合\(I\)(アイテムIDを要素としたベクトル)をndarray
として生成するコードを書きなさい。得られたndarray
をI
とすること。
コード
【 問03 】
print('I = {}'.format(I))
結果
I = [0 1 2 3 4 5]
★
numpy.arange()
を使う。ndarray.shape
を使う。
04 ユーザ数
U
からユーザ数\(\mid U \mid\)を取得するコードを書きなさい。
コード
print('|U| = {}'.format(【 問04 】))
結果
|U| = 5
★
ndarray.size
を使う。
05 アイテム数
I
からアイテム数\(\mid I \mid\)を取得するコードを書きなさい。
コード
print('|I| = {}'.format(【 問05 】))
結果
|I| = 6
★
ndarray.size
を使う。
06 評価値
R
からユーザ\(u\)のアイテム\(i\)に対する評価値\(r_{u,i}\)を取得するコードを書きなさい。
コード
u = 0
i = 1
print('r{}{} = {}'.format(u, i, 【 問06 】))
結果
r01 = 4.0
★
- インデキシングを使う。
評価値行列の疎性
評価値行列\(\boldsymbol{R}\)の疎性\(\mathrm{sparsity}\)は次式で求められる。
\[\mathrm{sparsity} = 1 - \frac{\mid R \mid}{\mid U \mid \mid I \mid}\]ここで、\(\mid R \mid\)は評価値が与えられた成分の数、すなわち観測値数(欠損値でない要素数)を表す。このとき、次の問いに答えなさい。
07 評価値行列の全要素数
R
の全要素数を取得するコードを書きなさい。ただし、欠損値も含む。
コード
print('Rの全要素数 = {}'.format(【 問07 】))
結果
Rの全要素数 = 30
★
ndarray.size
を使う。
08 観測されているか否かの判定
R
において、観測値の要素にはTrue
を、欠損値の要素にはFalse
を入れたブール値配列を生成するコードを書きなさい。
コード
print('観測値 = \n{}'.format(【 問08 】))
結果
観測値 =
[[False True True True True False]
[ True True True False True True]
[ True False True True True False]
[False True False True True True]
[ True True True True False True]]
★
numpy.isnan()
を使う。~
演算子を使う。
09 評価値行列の観測値数
R
における観測値数\(\mid R \mid\)を取得するコードを書きなさい。
コード
print('|R| = {}'.format(【 問09 】))
結果
|R| = 22
★★
numpy.isnan()
を使う。~
演算子を使う。numpy.count_nonzero()
を使う。
★★
numpy.isnan()
を使う。~
演算子を使う。numpy.size
を使う。- ブール値インデキシングを使う。
10 評価値行列の疎性
評価値行列\(\boldsymbol{R}\)の疎性\(\mathrm{sparsity}\)を求めるコードを書きなさい。得られた値をsparsity
とすること。
コード
【 問10 】
print('sparsity = {:.3f}'.format(sparsity))
結果
sparsity = 0.267
★★
numpy.isnan()
を使う。~
演算子を使う。numpy.count_nonzero()
を使う。numpy.size
を使う。
評価済みアイテム集合
アイテム集合\(I\)のうちユーザ\(u\)が評価済みのアイテム集合を\(I_{u} \subseteq I\)、ユーザ\(v\)が評価済みのアイテム集合を\(I_{v} \subseteq I\)とすると、ユーザ\(u\)とユーザ\(v\)の共通の評価済みアイテム集合は\(I_{u,v} = I_{u} \cap I_{v}\)と表される。また、ユーザ集合\(U\)のうちアイテム\(i\)を評価済みのユーザ集合を\(U_{i} \subseteq U\)、アイテム\(j\)を評価済みのユーザ集合を\(U_{j} \subseteq U\)とすると、アイテム\(i\)とアイテム\(j\)の両方を評価済みのユーザ集合は\(U_{i,j} = U_{i} \cap U_{j}\)と表される。このとき、次の問いに答えなさい。
11 ユーザuが評価済みのアイテム集合
I
からユーザ\(u\)が評価済みのアイテム集合\(I_{u}\)をndarray
として生成するコードを書きなさい。
コード
u = 0
print('I{} = {}'.format(u, 【 問11 】))
結果
I0 = [1 2 3 4]
★★
numpy.isnan()
を使う。~
演算子を使う。- ブール値インデキシングを使う。
12 各ユーザの評価済みアイテム集合
I
から各ユーザの評価済みのアイテム集合をndarray
のリストとしてまとめて生成するコードを書きなさい。得られたリストをIu
とすること。
コード
【 問12 】
print('Iu = ')
pprint.pprint(Iu)
結果
Iu =
[array([1, 2, 3, 4]),
array([0, 1, 2, 4, 5]),
array([0, 2, 3, 4]),
array([1, 3, 4, 5]),
array([0, 1, 2, 3, 5])]
★★
for
ループを使う。numpy.isnan()
を使う。~
演算子を使う。- ブール値インデキシングを使う。
list.append()
を使う。
★★★
- リスト内包表記を使う。
numpy.isnan()
を使う。~
演算子を使う。- ブール値インデキシングを使う。
13 ユーザuとユーザvの共通の評価済みアイテム集合
Iu
からユーザ\(u\)とユーザ\(v\)の共通の評価済みアイテム集合\(I_{u,v}\)をndarray
として生成するコードを書きなさい。得られたndarray
をIuv
とすること。
コード
u = 0
v = 1
【 問13 】
print('I{}{} = {}'.format(u, v, Iuv))
結果
I01 = [1 2 4]
★
numpy.intersect1d
を使う。
14 アイテムiを評価済みのユーザ集合
U
からアイテム\(i\)を評価済みのユーザ集合\(U_{i}\)をndarray
として生成するコードを書きなさい。
コード
i = 0
print('U{} = {}'.format(i, 【 問14 】))
結果
U0 = [1 2 4]
★★
numpy.isnan()
を使う。~
演算子を使う。- ブール値インデキシングを使う。
15 各アイテムの評価済みユーザ集合
U
から各アイテムの評価済みユーザ集合\(U_{i}\)をndarray
のリストとしてまとめて生成するコードを書きなさい。得られたリストをUi
とすること。
コード
【 問15 】
print('Ui = ')
pprint.pprint(Ui)
結果
Ui =
[array([1, 2, 4]),
array([0, 1, 3, 4]),
array([0, 1, 2, 4]),
array([0, 2, 3, 4]),
array([0, 1, 2, 3]),
array([1, 3, 4])]
★★
for
ループを使う。numpy.isnan()
を使う。~
演算子を使う。- ブール値インデキシングを使う。
list.append()
を使う。
★★★
- リスト内包表記を使う。
numpy.isnan()
を使う。~
演算子を使う。- ブール値インデキシングを使う。
16 アイテムiとアイテムjの両方を評価済みのユーザ集合
Ui
からアイテム\(i\)とアイテム\(j\)の両方を評価済みのユーザ集合\(U_{i,j}\)をndarray
として生成するコードを書きなさい。得られたndarray
をUij
とすること。
コード
i = 0
j = 4
【 問16 】
print('U{}{} = {}'.format(i, j, Uij))
結果
U04 = [1 2]
★
numpy.intersect1d
を使う。
平均中心化評価値行列
ユーザ\(u\)の平均評価値\(\overline{r}_{u}\)は次式で求められる。
\[\overline{r}_{u} = \frac{\sum_{i \in I_{u}} r_{u,i}}{\mid I_{u} \mid}\]ユーザ\(u\)のアイテム\(i\)に対する評価値\(r_{u,i}\)からユーザ\(u\)の平均評価値\(\overline{r}_{u}\)を引いた評価値を平均中心化評価値\(r_{u,i}^{'}\)とよび、次式で表される。
\[r_{u,i}^{'} = r_{u,i} - \overline{r}_{u}\]評価値行列\(\boldsymbol{R}\)の評価値\(r_{u,i}\)を平均中心化評価値\(r_{u,i}^{'}\)に置き換えた評価値行列を平均中心化評価値行列\(\boldsymbol{R}^{'}\)とよび、次式のようになる。
\[\boldsymbol{R}^{'} = \left[ \begin{array}{rrrrrr} & 1.5 & 0.5 & -1.5 & -0.5 & \\ 1 & 1 & 0 & & -1 & -1 \\ 0.5 & & 1.5 & -0.5 & -1.5 & \\ & 1.25 & & 0.25 & -0.75 & -0.75 \\ -0.4 & -1.4 & -0.4 & 1.6 & & 0.6 \end{array} \right]\]このとき、次の問いに答えなさい。
17 評価値行列全体の平均評価値
R
全体の平均評価値を求めるコードを書きなさい。ただし、欠損値は無視する。
コード
print('R全体の平均評価値 = {:.3f}'.format(【 問17 】))
結果
R全体の平均評価値 = 2.864
★
numpy.nanmean()
を使う。
18 各アイテムの平均評価値
R
において各アイテムの平均評価値\(\overline{r}_{i}\)をndarray
としてまとめて求めるコードを書きなさい。ただし、欠損値は無視する。得られたndarray
をri_mean
とすること。
コード
【 問18 】
print('ri_mean = {}'.format(ri_mean))
結果
ri_mean = [3.667 3.25 3.5 2.5 2. 2.333]
★★
numpy.nanmean()
を使う。
19 各ユーザの平均評価値
R
において各ユーザの平均評価値\(\overline{r}_{u}\)をndarray
としてまとめて求めるコードを書きなさい。ただし、欠損値は無視する。得られたndarray
をru_mean
とすること。
コード
【 問19 】
print('ru_mean = {}'.format(ru_mean))
結果
ru_mean = [2.5 4. 3.5 1.75 2.4 ]
★★
numpy.nanmean()
を使う。
★★★
- 二重のリスト内包表記を使う。
numpy.sum()
を使う。numpy.array()
を使う。numpy.nanmean()
を使わない。
20 評価値ベクトルの形状変換
ru_mean
の形状を(5, 1)
に変換するコードを書きなさい。
コード
print('ru_mean = \n{}'.format(【 問20 】))
結果
ru_mean =
[[2.5 ]
[4. ]
[3.5 ]
[1.75]
[2.4 ]]
★
ndarray.reshape()
を使う。
21 平均中心化評価値行列
評価値行列\(\boldsymbol{R}\)の平均中心化評価値行列\(\boldsymbol{R}^{'}\)をndarray
として生成するコードを書きなさい。得られたndarray
をR2
とすること。
コード
【 問21 】
print('R\' = \n{}'.format(R2))
結果
R' =
[[ nan 1.5 0.5 -1.5 -0.5 nan]
[ 1. 1. 0. nan -1. -1. ]
[ 0.5 nan 1.5 -0.5 -1.5 nan]
[ nan 1.25 nan 0.25 -0.75 -0.75]
[-0.4 -1.4 -0.4 1.6 nan 0.6 ]]
★★
ndarray.reshape()
を使う。