2025-03-30-最大最小归一化-蚂蚁金服
题目内容
假设你正在为一个电子商务网站工作,网站收集了用户的行为数据,包括用户的点击次数( c l i c k s clicks clicks),浏览时间( d u r a t i o n duration duration)以及购买次数( p u r c h a s e s purchases purchases),你的任务是分析这些数据,计算出每个用户的行为分数,以便于网站根据分数提供个性化的产品推荐。
给定一个用户的行为数据,每个用户有三个特征:点击次数( c l i c k s clicks clicks)、浏览时间( d u r a t i o n duration duration)以及购买次数( p u r c h a s e s purchases purchases)。我们希望对这三个特征进行归一化处理,然后计算每个用户的行为分数。行为分数的计算公式为:
s c o r e = log ( 1 + n o r m a l i z e d _ c l i c k s ) + exp ( n o r m a l i z e d _ d u r a t i o n ) + n o r m a l i z e d _ p u r c h a s e s × ( n o r m a l i z e d _ p u r c h a s e s + 1 2 ) score = \log(1 + normalized\_clicks) + \exp(normalized\_duration) + normalized\_purchases \times (\frac{normalized\_purchases + 1}{2}) score=log(1+normalized_clicks)+exp(normalized_duration)+normalized_purchases×(2normalized_purchases+1)
其中, log \log log 是自然对数, exp \exp exp 是指数的数。
你需要编写一个 P y t h o n Python Python 的函数,该函数接受上述格式的输入数据,从终端读取输入,然后计算每个用户的行为分数,并指结果输出到终端。
输入描述
输入是一个字典,键是用户的 i d id id (字符串),值是一个字典,包含 “clicks”、“duration”、“purchases” 三个键,分别代表用户的点击次数、停留时间、购买次数(均为整数)。
输出描述
返回一个字典,格式与输入相同,但是输出每个用户的行为得分。
补充说明
得分使用 r o u n d round round 至多保留三位小数。当所有用户的点击次数浏览时间和购买次数都为零时,期望输出返回 N a N NaN NaN 。
样例
输入:
{"user1":{"clicks":10,"duration":3600,"purchases":2},"user2":{"clicks":20,"duration":7200,"purchases":1},"user3":{"clicks":30,"duration":10800,"purchases":0}}
输出:
{user1":{"score":2.0},"user2":{"score":2.429},"user3":{"score":3.411}}
说明: 读入字典,读入每个用户的"clicks"、“duration”、"purchases"三列数据,再对所有用户的三列数据进行最大最小归一化,然后根据所给公式单独计算得分。
import numpy as np
import pandas as pd
import math
input_data = eval(input())
data = np.array(pd.DataFrame(input_data)).T
data
array([[ 10, 3600, 2],
[ 20, 7200, 1],
[ 30, 10800, 0]])
# 归一化
def max_min(data):
# 计算每列的最小值和最大值
min_val = np.min(data, axis=0)
max_val = np.max(data, axis=0)
# 检查是否有最大值和最小值相同的列
# 如果相同,则将该列的归一化结果设置为 0
scale_data = np.where(max_val == min_val, 0, (data - min_val) / (max_val - min_val))
return scale_data
data = max_min(data)
data
array([[0. , 0. , 1. ],
[0.5, 0.5, 0.5],
[1. , 1. , 0. ]])
if np.all(data==0):
result = {f'user{i}': {"score": "NaN"} for i in range(len(data))}
print(result)
# 计算分数
def get_score(data):
result = []
for item in data:
score = math.log(1 + item[0]) + math.exp(item[1]) + item[2] * (item[2] + 1)/2
result.append(score)
return result
scores = get_score(data)
scores
[2.0, 2.429186378808293, 3.4114290090189905]
# 输出
res_dict = {}
for i in range(len(data)):
score = {'score': float(f"{scores[i]:.3f}")} # 去掉尾部的0
user = f"user{i+1}"
res_dict[user] = score
print(res_dict)
{"user1": {'score': 2.0}, "'user'2": {'score': 2.429}, "'user'3": {'score': 3.411}}