第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()を使う。