[Stove AI] Машинное обучение 032 — Расчет сходства между пользователями

машинное обучение искусственный интеллект Python scikit-learn

[Stove AI] Машинное обучение 032 — Расчет сходства между пользователями

(Библиотеки Python и номера версий, используемые в этой статье: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2)

При создании рекомендательного механизма обычно необходимо вычислить сходство между двумя пользователями, чтобы найти пользователей, похожих на конкретного пользователя в базе данных. Существует множество способов расчета сходства, два из которых наиболее распространены: вычисление евклидова расстояния и коэффициента корреляции Пирсона.В этой статье описывается использование этих двух методов для расчета сходства между пользователями.


1. Рассчитайте евклидово расстояние между двумя пользователями

Евклидово расстояние — это обычное расстояние между двумя точками в евклидовом пространстве, то есть расстояние по прямой, составленной из двух точек. Можно сказать, что его формула расчета является основной формулой в математике, а именно: ее основное значение заключается в вычислении пространственного расстояния между двумя точками.

Евклидово расстояние очень интуитивно понятно и является распространенным алгоритмом подобия. Основная идея состоит в том, чтобы создать многомерное пространство на основе элементов, которые два пользователя оценивают вместе как измерение, а оценка пользователя по одному измерению может формировать массив или вектор.После определения вектора можно определить, что пользователь находится в этом месте в многомерном пространстве. Однако после того, как мы поместим нескольких пользователей в это многомерное пространство, можно будет считать, что два пользователя, которые находятся очень близко друг к другу, имеют очень большое сходство между собой Евклидово расстояние между пользователями в этом многомерном пространстве отмечает сходство между ними. их.

Однако в повседневном использовании мы, как правило, привыкли не к маленькому значению, а к высокому сходству, поэтому мы берем обратное значение этого значения, чтобы значение находилось в диапазоне 0-1, то есть используем 1/(1+Distance(X , Y)) полученный диапазон сходства: 0

Следующий код используется для вычисления евклидова расстояния между двумя пользователями.Идея состоит в том, чтобы вычислить сумму квадратов двух пользователей во всех элементах в наборе данных, а затем извлечь квадратный корень, чтобы получить расстояние между двумя пользователями. , воспользовавшись обратным изменением закона.

# 定义一个函数来计算两个用户之间的欧式距离
def euclidean_distance(dataset,user1,user2):
    # 首先要排除一种情况,如果数据集中不存在同时被两个用户评价过的电影,
    # 则表示两个用户之间的没有相似度,直接返回0
    both_rated_num=0 # 表示同时被两个用户都评价过的电影的数目
    for item in dataset[user1]: # 在user1评价过的电影中
        if item in dataset[user2]: # 如果user2也评价过,则+1
            both_rated_num+=1
    if both_rated_num==0:# 不存在同时被两个用户都评价过的电影
        return 0 # 直接返回0,表示两个用户之间相似度为0
    
    squared_difference=[] # 每一个元素表示同时被两个用户都评价过的电影得分的欧式距离
    for item in dataset[user1]:
        if item in dataset[user2]:
            squared_difference.append(np.square(dataset[user1][item]-dataset[user2][item]))
    return 1/(1+np.sqrt(np.sum(squared_difference)))

Поскольку исходные данные рейтинга фильмов хранятся в файле movie_ratings.json, необходимо использовать модуль json для загрузки данных и их анализа.

# 原始的电影评价数据都放置在 movie_ratings.json文件中,我们加载进来看看结果
import json
with open("E:\PyProjects\DataSet\FireAI\movie_ratings.json",'r') as file:
    dataset=json.loads(file.read())
    
# 现在计算两个随机用户之间的欧式距离
user1='John Carson'
user2='Michelle Peterson'
print(" Euclidean score: ",euclidean_distance(dataset,user1,user2))

------------------ потерять --------- вывод ------------ ---------- ----------

Euclidean score: 0.29429805508554946

--------------------------------Заканчивать----------------- --------------------

То есть евклидово расстояние между двумя пользователями рассчитывается равным 0,29, а сходство не очень велико.

Хотя евклидово расстояние является широко используемым методом расчета схожести пользователей, у него есть присущие ему недостатки, такие как:

1. Поскольку расчет основан на абсолютном значении каждого элемента измерения, евклидово расстояние должно гарантировать, что каждый индекс измерения находится на одном уровне масштаба.

2. Евклидово расстояние является интуитивным проявлением данных.Это кажется простым, но эффект не очевиден при работе с некоторыми скоринговыми данными, на которые сильно влияют субъективные факторы. То есть, когда оценка оценщика сильно отклоняется от среднего уровня, евклидово расстояние не может хорошо выявить истинное сходство.


2. Рассчитайте коэффициент корреляции Пирсона двух пользователей.

В статистике коэффициент корреляции Пирсона используется для измерения линейной корреляции между двумя переменными, и его значение находится в диапазоне от -1 до 1. Когда коэффициент корреляции равен 1, это становится полной положительной корреляцией; когда коэффициент корреляции равен -1, это становится полной отрицательной корреляцией; чем больше абсолютное значение коэффициента корреляции, тем сильнее корреляция; чем ближе коэффициент корреляции до 0, тем слабее корреляция.

# 定义一个函数来计算两个用户之间的皮尔逊相关系数
def pearson_score(dataset,user1,user2):
    # 和上面的函数类似,先排除相似度为0的情况
#     both_rated_num=0 # 表示同时被两个用户都评价过的电影的数目
#     for item in dataset[user1]: # 在user1评价过的电影中
#         if item in dataset[user2]: # 如果user2也评价过,则+1
#             both_rated_num+=1
#     if both_rated_num==0:# 不存在同时被两个用户都评价过的电影
#         return 0 # 直接返回0,表示两个用户之间相似度为0

    both_rated={}
    for item in dataset[user1]:
        if item in dataset[user2]:
            both_rated[item]=1
    num_ratings=len(both_rated)
    if num_ratings==0: # 不存在同时被两个用户都评价过的电影
        return 0
    
    # 计算每个用户对每个相同电影的评价之和
    user1_sum=np.sum([dataset[user1][item] for item in both_rated])
    user2_sum=np.sum([dataset[user2][item] for item in both_rated])
    
    # 计算每个用户对每个相同电影的评价的平方和
    user1_squared_sum = np.sum([np.square(dataset[user1][item]) for item in both_rated])
    user2_squared_sum = np.sum([np.square(dataset[user2][item]) for item in both_rated])

    # 计算两个用户的相同电影的乘积
    product_sum=np.sum([dataset[user1][item]*dataset[user2][item] for item in both_rated])
    
    # 计算Pearson 相关系数
    Sxy = product_sum - (user1_sum * user2_sum / num_ratings)
    Sxx = user1_squared_sum - np.square(user1_sum) / num_ratings
    Syy = user2_squared_sum - np.square(user2_sum) / num_ratings
    
    if Sxx * Syy == 0:
        return 0

    return Sxy / np.sqrt(Sxx * Syy)

Точно так же коэффициент корреляции Пирсона двух пользователей рассчитывается как: Показатель Писона: 0,396. Сходство нельзя сравнивать по горизонтали, то есть нельзя сравнивать показатель Пирсона и евклидово расстояние. Это сравнение бессмысленно и может только использовать для вертикального сравнения.

########################резюме########################## ######

1. Сходство между пользователями можно рассчитать по евклидову расстоянию или по коэффициенту корреляции Пирсона.

2. Кажется, что коэффициент корреляции Пирсона лучше выражает сходство, и во многих случаях он может преодолеть некоторые недостатки представления евклидова расстояния.

#################################################################


Примечание. Эта часть кода была загружена в (мой гитхаб), добро пожаловать на скачивание.

Использованная литература:

1. Классические примеры машинного обучения Python, Пратик Джоши, перевод Тао Цзюньцзе и Чена Сяоли.