6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Sparkでコサイン類似度を求める

Last updated at Posted at 2017-12-27

たまに、レコードが持つ変数間でコサイン類似度を計算したい時があるので、備忘として書いておく

なお、以下の例で扱うデータは、適当なIDと紐づけられたベクトルをもつデータフレームとする。

データ例

from pyspark.mllib.linalg import Vectors

data = sc.parallelize([
    ("a", Vectors.dense([0, 1, 2])),
    ("b", Vectors.dense([3, 4, 5])),
    ("c", Vectors.dense([6, 7, 8])) 
]).toDF(["id", "features"])

1対1で計算する

ベクトル型の関数を定義して、コサイン距離を計算する。
指定の組み合わせで計算する場合はこちらが楽。

1対1のコサイン類似度計算

# 適当に交差結合で組み合わせデータ
_data = data.select(col("id").alias("_id"), col("features").alias("_features"))
tgt_data = data.crossJoin(_data)

# コサイン類似度を計算
dist_data = tgt_data.rdd.map(
    lambda r: (r.id, r._id, r.features.dot(r._features) / (r.features.norm(2) * r._features.norm(2)) )
).toDF(["id", "_id", "similarity"])

※UDFを定義して計算する方法もあるが、ここでは使用していない。

全対全で計算する

1対1の指定の組み合わせで計算する場合の手順を拡張してもいいが、
RowMatrixのColumnSimilaritiesを使うと簡単。

DIMSUMを利用しているこちらの方が加工の手間を差し引いても(多分)計算量が少なくなる。

20180510 追記:
要素に欠損値があると、0として扱われて計算されるらしく、コサイン類似度で得たい結果を得ることができない。

全対全のコサイン類似度計算

from pyspark.mllib.linalg.distributed import CoordinateMatrix, MatrixEntry

# RowMatrixに変換
mat = RowMatrix(data.select("features").rdd.map(lambda r: r.features))

# RowMatrixを転置
mat_t = \
CoordinateMatrix(
    mat.rows.zipWithIndex().flatMap(
        lambda x: [MatrixEntry(x[1], j, v) for j, v in enumerate(x[0])])
).transpose()
 
# コサイン距離を全パターンで計算し、DF化
dist_mat = \
mat_t.toRowMatrix().columnSimilarities() \
.entries.map(lambda r: (r.i, r.j, r.value)).toDF(["i", "j", "similarity"])

関連

6
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?