令和5年度 基本情報技術者試験 科目B 問5の解説|コサイン類似度を計算するプログラム

基本情報技術者試験

令和5年度 科目B 公開問題 問5擬似言語・式とコードの対応・for で合計最終更新 2026-09-19

令和5年度の科目B、その5問目です。「コサイン類似度」という見慣れない言葉が出てきますが、意味を知らなくても解けます。解けるかどうかは、問題文の式とコードを見比べて、2か所に気づけるかで決まります。その2か所は、出題のあとの節で示します。

出題

まず原文のまま読んでみてください。記号の読み方は次の節にまとめてありますので、読めなくてもここでは問題ありません。

出典:令和5年度 基本情報技術者試験 科目B 公開問題 問5

次のプログラム中の  a  と  b  に入れる正しい答えの組合せを,解答群の中から選べ。ここで,配列の要素番号は1 から始まる。

コサイン類似度は,二つのベクトルの向きの類似性を測る尺度である。関数calcCosineSimilarity は,いずれも要素数がn(n≧1) である実数型の配列vector1 とvector2 を受け取り,二つの配列のコサイン類似度を返す。配列vector1 が {a1, a2, …, an},配列vector2 が {b1, b2, …, bn} のとき,コサイン類似度は次の数式で計算される。ここで,配列vector1 と配列vector2 のいずれも,全ての要素に0 が格納されていることはないものとする。

a1b1 + a2b2 + … + anbna12 + a22 + … + an2 b12 + b22 + … + bn2

〔プログラム〕

○実数型: calcCosineSimilarity(実数型の配列: vector1,
                               実数型の配列: vector2)
  実数型: similarity, numerator, denominator, temp ← 0
  整数型: i
  numerator ← 0

  for (i を 1 から vector1の要素数 まで 1 ずつ増やす)
    numerator ← numerator +  a 
  endfor

  for (i を 1 から vector1の要素数 まで 1 ずつ増やす)
    temp ← temp + vector1[i]の2乗
  endfor
  denominator ← tempの正の平方根

  temp ← 0
  for (i を 1 から vector2の要素数 まで 1 ずつ増やす)
    temp ← temp + vector2[i]の2乗
  endfor
  denominator ←  b 

  similarity ← numerator ÷ denominator
  return similarity

解答群

ア a = (vector1[i] × vector2[i])の正の平方根 / b = denominator × (tempの正の平方根)

イ a = (vector1[i] × vector2[i])の正の平方根 / b = denominator + (tempの正の平方根)

ウ a = (vector1[i] × vector2[i])の正の平方根 / b = tempの正の平方根

エ a = vector1[i] × vector2[i] / b = denominator × (tempの正の平方根)

オ a = vector1[i] × vector2[i] / b = denominator + (tempの正の平方根)

カ a = vector1[i] × vector2[i] / b = tempの正の平方根

キ a = vector1[i]の2乗 / b = denominator × (tempの正の平方根)

ク a = vector1[i]の2乗 / b = denominator + (tempの正の平方根)

ケ a = vector1[i]の2乗 / b = tempの正の平方根

※ 解答群の原本は a・b を2つの列に分けた表です。当サイトでは1行にまとめて引用しました(字句は変えていません)。

答えだけ先に見る

正解は エです。

この問題に出てくる記号

読めない記号があったときだけ開いてください。

擬似言語の記号の読み方をひらく
書き方 読み方
numerator ← numerator + … ← は、右の式を計算して左の箱へ入れる。右に同じ名前があれば、いま入っている値を使って計算してから入れ直します(10 が入っていて + 2 なら 12 になる)
実数型: numerator 小数も入る箱を1つ用意する。整数型 は整数だけが入る箱です
for (i を 1 から vector1の要素数 まで 1 ずつ増やす)
endfor
i を 1、2、3 … と増やしながら、あいだの行をくり返す。i が要素数と等しいときも実行されます
vector1[i] 配列 vector1 の i 番目の値。要素番号は1から数えます
vector1[i]の2乗 その値を2回かけたもの(3 なら 9)
tempの正の平方根 2乗すると temp になる正の数(25 なら 5)。式の √ のことです
× ÷ かけ算と割り算

記号でつまずいたら、下の教科書から、先にそこだけ読んでください(G6 のような番号は、当サイトの擬似言語の教科書の第何回かを表します)。

この2か所に気づけば、空欄 a・b が決まる

コサイン類似度の意味は要りません。見るのは問題文の式とコードの形だけです。

気づくところ

1. コードは、式の部品ごとにかたまりになっている。変数の用意(先頭の5行)のあとは空行で4つに分かれていて、上から「分子」「分母の左の √」「分母の右の √」「割り算」を計算しています。

2. 分母の2つの √ は、かけ算。あいだに記号はありませんが、数式では並べて書いたらかけ算です。

式に番号を付けると、部品は3つです。

①a1b1 + a2b2 + … + anbn②a12 + a22 + … + an2 ③b12 + b22 + … + bn2

  • ① 分子 ── 同じ番号どうしをかけた aibi を、1 から n まで足したもの
  • ② 分母の左 ── a の側を2乗して全部足し、√ をとったもの
  • ③ 分母の右 ── b の側で同じことをしたもの。分母は ② × ③

1つ目に気づけば、a は①を、b は③と分母の仕上げを計算する場所だと分かります。2つ目に気づけば、b の中身が決まります。かたまりごとに並べると、こうなります。

式の部品と、コードのかたまり

左の番号札は、式の部品に当サイトで付けたものです。コードは〔プログラム〕の、変数の用意(先頭の5行)より下を空行で区切ったかたまりを、そのまま切り出しています。

① 分子 ↔ 1つ目のかたまり

①a1b1 + a2b2 + … + anbn

  for (i を 1 から vector1の要素数 まで 1 ずつ増やす)
    numerator ← numerator +  a 
  endfor

分子は、1番目どうしの積から n 番目どうしの積までの合計です。for は i を 1 から n(vector1の要素数)まで回し、1周ごとに numerator へ1つ足します。だから1周で足すのは i 番目どうしの積 aibi。問題文は vector1 が {a1, …, an}、vector2 が {b1, …, bn} と言っているので、ai は vector1[i]、bi は vector2[i] です。→ a = vector1[i] × vector2[i]

② 分母の左 ↔ 2つ目のかたまり

②a12 + a22 + … + an2

  for (i を 1 から vector1の要素数 まで 1 ずつ増やす)
    temp ← temp + vector1[i]の2乗
  endfor
  denominator ← tempの正の平方根

temp は先頭の宣言で 0 になっています。そこへ vector1(a の側)を2乗して足し集め、最後に √ をとっています。②はここで完成し、denominator に入りました。

③ 分母の右 ↔ 3つ目のかたまり

③b12 + b22 + … + bn2

  temp ← 0
  for (i を 1 から vector2の要素数 まで 1 ずつ増やす)
    temp ← temp + vector2[i]の2乗
  endfor
  denominator ←  b 

temp を 0 に戻し、今度は vector2(b の側)で同じことをしています。endfor を抜けたとき、temp は √ の中の合計です。その正の平方根が③です。分母は ② × ③。②はもう denominator に入っているので、それに③をかけて denominator に入れ直します。→ b = denominator × (tempの正の平方根)

分数の横線 ↔ 4つ目のかたまり

  similarity ← numerator ÷ denominator
  return similarity

分子(①)を分母(② × ③)で割っています。ここは空欄がありません。

空欄に入るもの

a = vector1[i] × vector2[i] / b = denominator × (tempの正の平方根)

答え合わせ

この組合せは、解答群の エ だけです。

ほかの8つは、どれも式の部品を1つ取り違えています。a を (…)の正の平方根 で包んだもの(ア〜ウ)は、分子に無い √ をとっています。a を vector1[i]の2乗 にしたもの(キ〜ケ)は、②の材料を分子に入れています。b を tempの正の平方根 だけにしたもの(ウ・カ・ケ)は、②を上書きして消し、分母が③だけになります。+ にしたもの(イ・オ・ク)は、かけ算を足し算にしています。

数を入れて確かめます。vector1 を {3, 4}、vector2 を {8, 6} にすると、式では ① = 3×8 + 4×6 = 48、② = √(9 + 16) = 5、③ = √(64 + 36) = 10 で、48 ÷ (5 × 10) = 0.96 です。エ を入れたプログラムが同じ値を返すかを、「次へ」で1行ずつ見てください。

1行ずつ追う 正解の エ(vector1 = {3, 4}/vector2 = {8, 6})

出典:令和5年度 科目B 公開問題 問5(空欄に エ を入れ、配列の値を当サイトで与えたもの)


ループ開始前

配列

▲ いま読んでいる

いま計算していること

まだ計算していません

変数の状態

トレース表(進めると1行ずつ積み上がります)

次に読む

この問題でどこに手間取ったかで、行き先が変わります。

この記事で引用した資料

いずれも独立行政法人情報処理推進機構(IPA)が公表したものです。IPAは公表済みの試験問題について、教育目的での使用に許諾および使用料を不要としていますが、著作権は放棄していません。本記事では問題文を改変せずに引用しています。

シミュレータで vector1 に {3, 4}、vector2 に {8, 6} を与えたのは当サイトです(原文は値を決めていません)。数式の部品に付けた ①〜③ の番号札も当サイトで付けたものです。

Copied title and URL