はじめに:なんか「運命」を感じるコスメに出会ったこと、ある?
こんにちは!突然ですが、みなさん、ネットショッピングで「あ、これ、私が欲しかったやつ!」って、偶然ぴったりのコスメに出会ったこと、ありませんか?
実はそれ、偶然じゃないかもしれません。もしかしたら、AIがこっそりあなたの「好き」を見抜いているのかも。今日は、そんなAIの秘密兵器、「コサイン類似度」っていうちょっと魔法みたいなデータ分析術のお話をしちゃいますね。
コサイン類似度って、なんだろう?
コサイン類似度って聞くと、「なんか難しそう…」って思うかもしれませんが、実はとってもシンプル!
たとえば、あなたが買い物カゴに「化粧水」と「美容液」を入れたとします。別の誰かも同じように「化粧水」と「美容液」を買っていたら、二人の買い物カゴって「似てる」って感じますよね。
コサイン類似度は、この「似てる」を数学的に測ってくれるんです。商品の種類を座標軸にして、あなたの買い物カゴをベクトルっていう矢印で表します。この矢印の「向き」がどれだけ同じかを計算してくれるのが、コサイン類似度です。
作成したコード
import math
import pandas as pd
def calc_cosine_similarity(vector1, vector2):
"""
コサイン類似度を計算する関数。
2つのベクトルがどれだけ同じ方向を向いているかを0.0から1.0の間の値で返します。
値が1.0に近いほど、ベクトルの向きが似ていることを意味します。
"""
# ベクトルの要素数が同じであることを確認。異なる場合はエラーを発生させる。
if len(vector1) != len(vector2):
raise ValueError("ベクトルの要素数が一致しません。")
# 分子(ベクトルの内積)を計算
# zip()関数で2つのリストの要素をペアにし、各ペアの積の合計を求める
numerator = sum(v1 * v2 for v1, v2 in zip(vector1, vector2))
# 分母(各ベクトルの大きさ、ノルム)を計算
# 各要素を二乗して合計し、その平方根を求める
temp_v1_norm_sq = sum(v**2 for v in vector1)
temp_v2_norm_sq = sum(v**2 for v in vector2)
denominator = math.sqrt(temp_v1_norm_sq) * math.sqrt(temp_v2_norm_sq)
# 分母が0の場合(ベクトルの要素が全て0の場合)、ゼロ除算を避ける
if denominator == 0:
return 0.0
return numerator / denominator
def get_recommendations(target_customer_id, purchase_data):
"""
特定の顧客にパーソナライズされた商品をレコメンドする。
最も似ている顧客を見つけ、その顧客が購入した未購入商品を推奨します。
Args:
target_customer_id (str): レコメンドを行う顧客のID
purchase_data (list of dict): 顧客の購入履歴データ
Returns:
list of str: 推奨商品のリスト
"""
# データをPandas DataFrameに変換し、顧客-商品行列を作成
# index: 顧客ID, columns: 商品名, values: 購入回数
# fill_value=0 で購入していない商品の値を0にする
df = pd.DataFrame(purchase_data)
purchase_matrix = df.pivot_table(index='customer_id', columns='product', values='purchase_count', fill_value=0)
# ターゲット顧客の購買ベクトルを取得
target_vector = purchase_matrix.loc[target_customer_id].tolist()
similarities = []
# 他の全ての顧客の購買ベクトルと比較
for customer_id, customer_vector in purchase_matrix.iterrows():
# ターゲット顧客自身との比較はスキップ
if customer_id == target_customer_id:
continue
# calc_cosine_similarity関数を使って、類似度を計算
similarity = calc_cosine_similarity(target_vector, customer_vector.tolist())
similarities.append((customer_id, similarity))
# 類似度が高い順に顧客をソート
similarities.sort(key=lambda x: x[1], reverse=True)
# 最も類似度が高い顧客のIDを取得
most_similar_customer_id = similarities[0][0]
# レコメンドする商品を特定
# ターゲット顧客と最も似ている顧客の購買データを取得
target_purchases = purchase_matrix.loc[target_customer_id]
similar_customer_purchases = purchase_matrix.loc[most_similar_customer_id]
recommendations = []
# 類似顧客が購入していて、ターゲット顧客がまだ購入していない商品を探す
for product, purchased in similar_customer_purchases.items():
# 類似顧客が購入しており、かつターゲット顧客が購入していない商品
if purchased > 0 and target_purchases[product] == 0:
recommendations.append(product)
return recommendations
# --- 使用例 ---
purchase_data = [
{'customer_id': 'C1', 'product': '化粧水A', 'purchase_count': 1},
{'customer_id': 'C1', 'product': '美容液B', 'purchase_count': 1},
{'customer_id': 'C2', 'product': '美容液B', 'purchase_count': 1},
{'customer_id': 'C2', 'product': 'クリームC', 'purchase_count': 1},
{'customer_id': 'C3', 'product': '化粧水A', 'purchase_count': 1},
{'customer_id': 'C3', 'product': '美容液B', 'purchase_count': 1},
{'customer_id': 'C3', 'product': 'パックD', 'purchase_count': 1},
{'customer_id': 'C4', 'product': '化粧水A', 'purchase_count': 1},
{'customer_id': 'C4', 'product': 'クリームC', 'purchase_count': 1},
]
target_customer = 'C1'
recommendations = get_recommendations(target_customer, purchase_data)
print(f"顧客ID '{target_customer}' へのレコメンド商品:")
print(recommendations)
まとめ
コサイン類似度は、これからの美容マーケティングにおいて、
単なる流行を超えた必須の戦略となるでしょう。
ありがとうございました!