05、基于梯度下降的协同过滤算法

05、基于梯度下降的协同过滤算法理论与实践Python

开始学习机器学习啦,已经把吴恩达的课全部刷完了,现在开始熟悉一下复现代码。对这个手写数字实部比较感兴趣,作为入门的素材非常合适。

协同过滤算法是一种常用的推荐算法,基于对用户历史行为数据的挖掘发现用户的喜好偏向,并预测用户可能喜好的产品进行推荐。它的主要实现方式包括

  1. 根据和你有共同喜好的人给你推荐。
  2. 根据你喜欢的物品给你推荐相似物品。

因此,常用的协同过滤算法分为两种,基于用户的协同过滤算法(user-based collaborative filtering),以及基于物品的协同过滤算法(item-based collaborative filtering)。

这种算法的特点可以概括为“人以类聚,物以群分”,并据此进行预测和推荐。例如,基于物品的协同过滤算法会给用户推荐与他之前喜欢的物品相似的物品;而基于用户的协同过滤算法会给用户推荐与他兴趣相似的用户喜欢的物品。

1、基于用户的协同过滤算法案例与直观解释

协同过滤算法算是上到今天的课中比较弯弯绕绕的东西了,在此以下面的电影打分案例为例:
在这里插入图片描述
竖过来那一栏是电影的名称,横着的四个是打分的人的名字,最后两个x是电影的特征。问号表示该用户没有对电影进行过评分,与此同时,电影的特征x是完全未知的

从电影推荐的角度来讲,对正在浏览的用户,若其对某个电影潜在的评分越高,则越有可能将此电影推荐给这个用户。而这个潜在的评分正是算法所需要得到的。

这个算法是如何运作的呢?其底层的直觉是基于用户的相似性。比如,小张是个爱猫人士,喜欢看有猫猫的电影,他看过许多猫猫电影并给这类电影打了高分;然后,小王来了,小王初来乍到也给几部猫猫片打了高分,平台此时认为小王和小张相似,从而把小张打高分的电影推荐给小王。
但是,平台并不知道小张和小王的相似之处在于喜欢看猫猫片(并不了解事物的特征的具体情况),其只知道这两个人爱好类似而已。

这种基于相似度的机制在很多文章中有介绍。如:推荐算法之协同过滤算法详解(原理,流程,步骤,适用场景)。但是,在吴恩达的课程里面,所介绍的基于梯度下降的协同过滤算法好像并没有专门涉及这一相似的矩阵计算概念?在此对这种基于机器学习的协同过滤算法简单介绍。

2、基于梯度下降的协同过滤算法实现原理

这边主要是介绍吴恩达视频里面的实现思路。用户给电影打高分,是因为用户喜欢电影的某项特征,以下面为例(用户Alice和Bob给Love at last打高分其实是两个条件,其一是电影具备浪漫特征,其二是用户喜欢浪漫的东西):
在这里插入图片描述
简单来说可以简化为以下的公式(w就是用户自己的喜好特征,x是电影本身的特质,最终得到的是电影的打分):
在这里插入图片描述
但是对于基于用户的协同过滤算法案例的数据,也就是第一张图,用户自己的喜好特征和电影本身的特质都是未知的(只有部分用户的打分已知),那么该如何进行打分呢?答案是随机初始化(或者合理猜测)然后使用梯度下降得到最优的w、x、b,然后就能计算打分数据y进而进行推荐了。

这个梯度下降实际包含两个过程,首先是从电影的特征和实际打分训练得到用户的特征w、b,其次是从用户的特征w、b和实际打分训练得到电影的特征,这两个过程的成本函数可以相加合一,毕竟实际的未知量是w、b、x:
在这里插入图片描述

3、基于梯度下降的协同过滤算法实现步骤

step1:加载数据
其中R是bool类型的矩阵,第i行第j列代表第j个用户是否对第i个电影打分
Y是打分的矩阵,第i行第j列代表第j个用户对第i个电影的打分的分数

def load_ratings_small():file = open('./Collaborative_Filtering_data/small_movies_Y.csv', 'rb')Y = loadtxt(file, delimiter=",")file = open('./Collaborative_Filtering_data/small_movies_R.csv', 'rb')R = loadtxt(file, delimiter=",")return (Y, R)
#加载数据# Y是所有电影的打分的数据,数据大小是nm*nu
# R的数据大小是nm*nu,格式为bool,表示第j列的用户是否对第i行的用户打分
Y, R = load_ratings_small()
num_movies, num_users = Y.shape

step2:构建成本函数
成本函数的构建参考2、基于梯度下降的协同过滤算法实现原理中的图片里面的公式,当然可以使用循环来实现(X, W, b可以随机初始化):

def cofi_cost_func(X, W, b, Y, R, lambda_):  """  计算协同过滤的代价函数。  参数:  X -- 电影的特征矩阵  W -- 用户的权重矩阵  b -- 用户的偏置向量  Y -- 用户对电影的评分矩阵  R -- 指示用户是否对电影进行了评分的矩阵  lambda_ -- 正则化参数  返回:  J -- 代价函数的值  """  nm, nu = Y.shape  # 获取评分矩阵Y的形状,nm为电影数量,nu为用户数量  J = 0  # 初始化代价函数值为0  # 遍历每一个用户  for j in range(nu):  # 获取第j个用户的兴趣权重  w = W[j, :]  b_j = b[0, j]  # 获取第j个用户的偏置值  # 遍历每一部电影  for i in range(nm):  # 获取第i部电影的特征,和第j个用户对其的打分  x = X[i, :]  y = Y[i, j]  r = R[i, j]  # 获取第j个用户对第i部电影的评分指示值(是否进行了评分)  # 计算代价函数中的误差项并累加到J中  J += np.square(r * (np.dot(w, x) + b_j - y))  # 正则化部分,防止过拟合  J += lambda_ * (np.sum(np.square(W)) + np.sum(np.square(X)))  J = J / 2  # 对J进行平均处理  return J  # 返回计算得到的代价函数值

更好的方法是使用矩阵运算来实现,这样速度更快:

def cofi_cost_func_v(X, W, b, Y, R, lambda_):  """  计算基于内容的过滤的代价函数。  为了速度进行了向量化。使用TensorFlow操作以与自定义训练循环兼容。  参数:  X (ndarray (num_movies,num_features)):物品特征矩阵  W (ndarray (num_users,num_features)):用户参数矩阵  b (ndarray (1, num_users)):用户参数向量  Y (ndarray (num_movies,num_users)):用户对电影的评分矩阵  R (ndarray (num_movies,num_users)):矩阵,其中R(i, j) = 1表示第j个用户对第i部电影进行了评分  lambda_ (float):正则化参数  返回:  J (float):代价函数的值  """  # 使用矩阵乘法和偏置计算预测评分,然后与实际评分相减,并乘以评分指示矩阵R  j = (tf.linalg.matmul(X, tf.transpose(W)) + b - Y) * R  # 计算代价函数的值,包括正则化部分  J = 0.5 * tf.reduce_sum(j**2) + (lambda_ / 2) * (tf.reduce_sum(X**2) + tf.reduce_sum(W**2))  return J

step3:训练数据预处理与随机初始化

def normalizeRatings(Y, R):"""规范化用户评分矩阵,使其具有零均值。参数:Y (ndarray): 用户对物品的评分矩阵,形状通常为 (num_users, num_items)。R (ndarray): 指示矩阵,其中 R[i, j] = 1 表示用户 i 对物品 j 进行了评分,否则为 0。返回:Ynorm (ndarray): 规范化后的评分矩阵。Ymean (ndarray): 每个用户的平均评分。"""# 计算每个用户的加权平均分。这里,加权是指只考虑用户实际评分的项目。# 分母加上 1e-12 是为了避免除以零的情况。Ymean = (np.sum(Y * R, axis=1) / (np.sum(R, axis=1) + 1e-12)).reshape(-1, 1)# 从原始评分中减去每个用户的平均分,得到规范化后的评分。# 注意,我们只更新那些用户实际评分的项目。Ynorm = Y - np.multiply(Ymean, R)return Ynorm, Ymean
# 加载评分 
Y, R = load_ratings_small()  
# 规范化数据集,使其具有零均值  
Ynorm, Ymean = normalizeRatings(Y, R)  # 开始训练  
num_movies, num_users = Y.shape  # 获取电影和用户的数量  
num_features = 100  # 设置特征的数量  # 设置初始参数(W, X),使用tf.Variable来跟踪这些变量,这样在训练过程中可以更新它们。  
tf.random.set_seed(1234)  # 设置随机种子以确保结果的一致性  
W = tf.Variable(tf.random.normal((num_users,  num_features), dtype=tf.float64), name='W')  # 用户参数矩阵  
X = tf.Variable(tf.random.normal((num_movies, num_features), dtype=tf.float64), name='X')  # 电影特征矩阵  
b = tf.Variable(tf.random.normal((1, num_users), dtype=tf.float64), name='b')  # 用户偏置参数

step4:设置优化器,开始梯度下降

# 实例化一个优化器,这里选择的是Adam优化器,学习率设置为0.1  
optimizer = keras.optimizers.Adam(learning_rate=1e-1)  # 设置迭代次数和正则化参数  
iterations = 400  
lambda_ = 1  # 开始迭代  
for iter in range(iterations):  # 使用TensorFlow的GradientTape来记录计算代价所涉及的操作  with tf.GradientTape() as tape:  # 计算代价(前向传播已经包含在cost_value中)  cost_value = cofi_cost_func_v(X, W, b, Ynorm, R, lambda_)  # 使用gradient tape自动获取可训练变量关于损失的梯度  grads = tape.gradient(cost_value, [X, W, b])  # 使用优化器运行一步梯度下降,更新变量的值以最小化损失  optimizer.apply_gradients(zip(grads, [X, W, b]))  # 定期记录训练损失  if iter % 20 == 0:  print(f"Training loss at iteration {iter}: {cost_value:0.1f}")

step5:对所有用户进行预测,并去归一化

# Make a prediction using trained weights and biases
p = np.matmul(X.numpy(), np.transpose(W.numpy())) + b.numpy()
#restore the mean
pm = p + Ymean

step6:查看结果

# 查看第一个用户的结果
my_predictions = pm[:,0]
# sort predictions
ix = tf.argsort(my_predictions, direction='DESCENDING')
# 查看第一个用户的打分最高的结果
for i in range(17):j = ix[i]if j not in my_rated:print(f'Predicting rating {my_predictions[j]:0.2f} for movie {movieList[j]}')
# 查看第一个用户的预测打分和实际打分对比     
print('\n\nOriginal vs Predicted ratings:\n')
for i in range(len(Y[:,0])):if Y[i,0] > 0:print(f'Original {Y[i,0]}, Predicted {my_predictions[i]:0.2f} for {movieList[i]}')

查看的是第一个用户的结果,首先查看的是系统对第一个用户的打分的排名最高的结果,其次是系统对第一个用户预计的打分结果和实际打分结果的对比:
在这里插入图片描述

4、全部代码

数据集和全部代码在最上方链接下载:

import numpy as np
import tensorflow as tf
from tensorflow import keras
from numpy import loadtxt
import pandas as pddef normalizeRatings(Y, R):"""规范化用户评分矩阵,使其具有零均值。参数:Y (ndarray): 用户对物品的评分矩阵,形状通常为 (num_users, num_items)。R (ndarray): 指示矩阵,其中 R[i, j] = 1 表示用户 i 对物品 j 进行了评分,否则为 0。返回:Ynorm (ndarray): 规范化后的评分矩阵。Ymean (ndarray): 每个用户的平均评分。"""# 计算每个用户的加权平均分。这里,加权是指只考虑用户实际评分的项目。# 分母加上 1e-12 是为了避免除以零的情况。Ymean = (np.sum(Y * R, axis=1) / (np.sum(R, axis=1) + 1e-12)).reshape(-1, 1)# 从原始评分中减去每个用户的平均分,得到规范化后的评分。# 注意,我们只更新那些用户实际评分的项目。Ynorm = Y - np.multiply(Ymean, R)return Ynorm, Ymeandef load_precalc_params_small():file = open('./Collaborative_Filtering_data/small_movies_X.csv', 'rb')X = loadtxt(file, delimiter=",")file = open('./Collaborative_Filtering_data/small_movies_W.csv', 'rb')W = loadtxt(file, delimiter=",")file = open('./Collaborative_Filtering_data/small_movies_b.csv', 'rb')b = loadtxt(file, delimiter=",")b = b.reshape(1, -1)num_movies, num_features = X.shapenum_users, _ = W.shapereturn (X, W, b, num_movies, num_features, num_users)def load_ratings_small():file = open('./Collaborative_Filtering_data/small_movies_Y.csv', 'rb')Y = loadtxt(file, delimiter=",")file = open('./Collaborative_Filtering_data/small_movies_R.csv', 'rb')R = loadtxt(file, delimiter=",")return (Y, R)def load_Movie_List_pd():""" returns df with and index of movies in the order they are in in the Y matrix """df = pd.read_csv('./Collaborative_Filtering_data/small_movie_list.csv', header=0, index_col=0,  delimiter=',', quotechar='"')mlist = df["title"].to_list()return(mlist, df)
def cofi_cost_func(X, W, b, Y, R, lambda_):nm, nu = Y.shapeJ = 0for j in range(nu):# 获取第j个用户的兴趣权重w = W[j, :]b_j = b[0, j]for i in range(nm):#获取第i个电影的特征,和第j个用户对其的打分x = X[i, :]y = Y[i, j]r = R[i, j]J += np.square(r * (np.dot(w, x) + b_j - y))# 正则化J += lambda_ * (np.sum(np.square(W)) + np.sum(np.square(X)))J = J / 2return Jdef cofi_cost_func_v(X, W, b, Y, R, lambda_):"""计算基于内容的过滤的代价函数。为了速度进行了向量化。使用TensorFlow操作以与自定义训练循环兼容。参数:X (ndarray (num_movies,num_features)):物品特征矩阵W (ndarray (num_users,num_features)):用户参数矩阵b (ndarray (1, num_users)):用户参数向量Y (ndarray (num_movies,num_users)):用户对电影的评分矩阵R (ndarray (num_movies,num_users)):矩阵,其中R(i, j) = 1表示第j个用户对第i部电影进行了评分lambda_ (float):正则化参数返回:J (float):代价函数的值"""# 使用矩阵乘法和偏置计算预测评分,然后与实际评分相减,并乘以评分指示矩阵Rj = (tf.linalg.matmul(X, tf.transpose(W)) + b - Y) * R# 计算代价函数的值,包括正则化部分J = 0.5 * tf.reduce_sum(j ** 2) + (lambda_ / 2) * (tf.reduce_sum(X ** 2) + tf.reduce_sum(W ** 2))return J#加载数据
# Y是所有电影的打分的数据,数据大小是nm*nu
# R的数据大小是nm*nu,格式为bool,表示第j列的用户是否对第i行的用户打分
Y, R = load_ratings_small()
num_movies, num_users = Y.shapeprint("Y", Y.shape, "R", R.shape)
print("num_movies",   num_movies)
print("num_users",    num_users)# 按照自己的喜好给电影打分
movieList, movieList_df = load_Movie_List_pd()
my_ratings = np.zeros(num_movies)          #  Initialize my ratings
# Check the file small_movie_list.csv for id of each movie in our dataset
# For example, Toy Story 3 (2010) has ID 2700, so to rate it "5", you can set
my_ratings[2700] = 5
#Or suppose you did not enjoy Persuasion (2007), you can set
my_ratings[2609] = 2;
# We have selected a few movies we liked / did not like and the ratings we
# gave are as follows:
my_ratings[929]  = 5   # Lord of the Rings: The Return of the King, The
my_ratings[246]  = 5   # Shrek (2001)
my_ratings[2716] = 3   # Inception
my_ratings[1150] = 5   # Incredibles, The (2004)
my_ratings[382]  = 2   # Amelie (Fabuleux destin d'Amélie Poulain, Le)
my_ratings[366]  = 5   # Harry Potter and the Sorcerer's Stone (a.k.a. Harry Potter and the Philosopher's Stone) (2001)
my_ratings[622]  = 5   # Harry Potter and the Chamber of Secrets (2002)
my_ratings[988]  = 3   # Eternal Sunshine of the Spotless Mind (2004)
my_ratings[2925] = 1   # Louis Theroux: Law & Disorder (2008)
my_ratings[2937] = 1   # Nothing to Declare (Rien à déclarer)
my_ratings[793]  = 5   # Pirates of the Caribbean: The Curse of the Black Pearl (2003)
my_rated = [i for i in range(len(my_ratings)) if my_ratings[i] > 0]
print('\nNew user ratings:\n')
for i in range(len(my_ratings)):if my_ratings[i] > 0 :print(f'Rated {my_ratings[i]} for  {movieList_df.loc[i,"title"]}')# 加载评分
Y, R = load_ratings_small()
# Y= np.c_[my_ratings, Y]
# R= np.c_[(my_ratings != 0).astype(int), R]
# 规范化数据集,使其具有零均值
Ynorm, Ymean = normalizeRatings(Y, R)# 开始训练
num_movies, num_users = Y.shape  # 获取电影和用户的数量
num_features = 100  # 设置特征的数量# 设置初始参数(W, X),使用tf.Variable来跟踪这些变量,这样在训练过程中可以更新它们。
tf.random.set_seed(1234)  # 设置随机种子以确保结果的一致性
W = tf.Variable(tf.random.normal((num_users, num_features), dtype=tf.float64), name='W')  # 用户参数矩阵
X = tf.Variable(tf.random.normal((num_movies, num_features), dtype=tf.float64), name='X')  # 电影特征矩阵
b = tf.Variable(tf.random.normal((1, num_users), dtype=tf.float64), name='b')  # 用户偏置参数# 实例化一个优化器,这里选择的是Adam优化器,学习率设置为0.1
optimizer = keras.optimizers.Adam(learning_rate=1e-1)
# 设置迭代次数和正则化参数
iterations = 400
lambda_ = 1
# 开始迭代
for iter in range(iterations):# 使用TensorFlow的GradientTape来记录计算代价所涉及的操作with tf.GradientTape() as tape:# 计算代价(前向传播已经包含在cost_value中)cost_value = cofi_cost_func_v(X, W, b, Ynorm, R, lambda_)# 使用gradient tape自动获取可训练变量关于损失的梯度grads = tape.gradient(cost_value, [X, W, b])# 使用优化器运行一步梯度下降,更新变量的值以最小化损失optimizer.apply_gradients(zip(grads, [X, W, b]))# 定期记录训练损失if iter % 20 == 0:print(f"Training loss at iteration {iter}: {cost_value:0.1f}")# Make a prediction using trained weights and biases
p = np.matmul(X.numpy(), np.transpose(W.numpy())) + b.numpy()
#restore the mean
pm = p + Ymeanmy_predictions = pm[:,0]
# sort predictions
ix = tf.argsort(my_predictions, direction='DESCENDING')for i in range(17):j = ix[i]if j not in my_rated:print(f'Predicting rating {my_predictions[j]:0.2f} for movie {movieList[j]}')
print('\n\nOriginal vs Predicted ratings:\n')
for i in range(len(Y[:,0])):if Y[i,0] > 0:print(f'Original {Y[i,0]}, Predicted {my_predictions[i]:0.2f} for {movieList[i]}')

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/185202.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

新型信息基础设施下的IP追溯技术:构建数字化安全新境界

随着新型信息基础设施的快速发展,IP(Internet Protocol)追溯技术在数字化安全领域变得愈发重要。IP追溯不仅能够帮助识别网络攻击源,提升网络安全水平,还有助于数字证据追踪、合规性审计等方面。本文将探讨新型信息基础…

Vue 和 React 的优点分别是什么?如何选择?

目录 为什么我更喜欢Vue? 低代码平台的前端框架采用Vue的优势有哪些? JNPF-Web-Vue3 的技术栈介绍 (1)Vue3.x (2)Vue-router4.x (3)Vite4.x (4)Ant-D…

『Jmeter超级干货』| Linux下Jmeter安装配置、脚本设计执行、监控及报告完整过程

『Jmeter超级干货』| Linux下Jmeter安装配置、脚本设计执行、监控及报告完整过程 1 JDK安装部署1.1 JDK下载1.2 JDK配置 2 Jmeter安装部署2.1 Jmeter下载2.2 Jmeter安装2.3 Jmeter相关目录配置2.4 Jmeter启动配置2.5 检查并启动 3 Jmeter汉化3.1 临时修改3.2 永久修改 4 准备测…

docker 学习总结

docker 概念 -云计算的基石 docker的一个软件: 开源 docker基本组成 docker主机(Host):安装了Docker程序的机器(Docker直接安装在操作系统之上); docker仓库(Registry):用来保存各种打包好的软件镜像&a…

中信建投在金融电于化期刊发布 DataOps 实践

文 ‖ 中信建投证券股份有限公司 马丽霞 高宇航 李可 许哲 李海伟 近年来,数据的分析和应用对各行各工业的业务模式和竞争形态进行重塑,而积极应对挑战和顺应时代变化是各个市场参与者的必选项。作为资本市场数字化转型的领航者,中信建投证券…

【meta】Scaling Speech Technology to 1,000+ Languages

nvidia-NeMo包含TTS的模型,开源数据 uroma转写工具介绍 uroman转写工具 N-to-M mapping 转写的规范,包含一些中文-拼音,拉丁文-读法的规则转换。字符串匹配规则下的查字典; 将字母对应到发音单元 转写规范 转写过程尽量做到可…

打字练习--Master of Typing 3

Master of Typing 3是一款适用于Mac OS平台的打字速度提升和键盘技能训练软件。它旨在帮助用户提高打字速度、准确性和键盘操作技能,无论用户是初学者还是熟练的键盘操作者,都能提供适合的练习模式。Master of Typing 3提供了一系列结构化的打字课程和实…

(2023码蹄杯)省赛(初赛)第二场真题(原题)(题解+AC代码)

题目1&#xff1a;MC0214捡麦子 码题集OJ-捡麦子 (matiji.net) 思路: 1.第n米在前n-1米的基础上多加一个n个麦子&#xff0c;那么直接从1开始枚举&#xff0c;累加答案即可 AC_Code:C #include<bits/stdc.h> using namespace std;int main( ) {int n; cin>>n;…

三维模型重建中地面控制点刺点输入常见问题及解决方法

三维模型重建中地面控制点刺点输入常见问题及解决方法 在倾斜摄影三维模型重建中&#xff0c;地面控制点的人工刺点输入是一个重要的环节。然而&#xff0c;这个过程可能会遇到一些常见问题。以下是一些常见问题及相应的解决方法&#xff1a; 1、问题&#xff1a;标定点位置不…

路由跳转到另一个页面

点击添加员工跳转到详情页 <el-button size"mini" type"primary" click"$router.push(/employee/detail)">添加员工</el-button>配置员工详情的路由信息 import layout from "/layout"; export default {path: "/em…

OBC、DCDC自动化测试解决方案!

OBC(车载充电机&#xff09;和DCDC&#xff08;直流-直流变换器&#xff09;是电动汽车的核心部件&#xff0c;DCDC和OBC的功能质量对于整车的性能和安全性至关重要。在OBC和DCDC&#xff0c;以及整车开发测试过程中&#xff0c;需要对OBC和DCDC进行功能和性能方面进行全面的测…

水溶性肥料行业分析:预计2028年将达到202亿美元

随着我国农业的集约化、规模化不断发展&#xff0c;以及大型农场涌现&#xff0c;水肥一体化面积将会不断扩大。同时&#xff0c;水溶肥是符合更加环保、更加可持续发展的新一代肥料&#xff0c;是中国肥料产业未来的重点发展课题。 水溶性肥料(Water Soluble Fertilizer&…

ChatGPT生成的一些有趣的文件管理用python小程序

1. 在前位置中的所有文件夹内增加一个名为 abc 的新文件夹 import osdef create_abc_directories(root_dir.):# 获取当前目录下的所有目录subdirectories [d for d in os.listdir(root_dir) if os.path.isdir(os.path.join(root_dir, d))]# 在每个目录中创建名为abc的子目录f…

Android自动化测试中使用ADB进行网络状态管理!

技术分享&#xff1a;使用ADB进行Android网络状态管理 Android自动化测试中的网络状态切换是提高测试覆盖率、捕获潜在问题的关键步骤之一&#xff0c;本文将介绍 如何使用ADB检测和管理Android设备的网络状态。 自动化测试中的网络状态切换变得尤为重要。 网络状态查询 adb s…

【23真题】复录比高达2.24,但题目很棒!

今天分享的是23年广东工业837的信号与系统试题及解析。注意官方不公示真题&#xff0c;所以这套试卷为回忆版本。 本套试卷难度分析&#xff1a;22年广东工业837考研真题&#xff0c;我也发布过&#xff0c;若有需要&#xff0c;戳这里自取&#xff01;平均分107.93&#xff…

Java中的Lambda表达式

lambda表达式是一个可传递的代码块&#xff0c;可以在以后执行一次或多次。 1.lambda表达式的语法 eg&#xff1a;有如下lambda表达式&#xff1a; (int a, int b) -> {return ab}; 这个表达式的本质是一个函数。 一般的函数类似如下&#xff1a; int add(int a, int …

我的创作纪念日--成为创作者的 第1825天(5年) 啦

醉颜凉 &#xff0c;不知不觉今天已经是你成为创作者的 第1825天&#xff08;5年&#xff09; 啦。 机缘 1、作为一个创作者&#xff0c;我最初成为创作者的初心是出于对技术的热爱和对分享的渴望。我希望通过创作&#xff0c;将自己在实战项目中的经验分享给大家&#xff0c;…

ECONGU4280 Corporate Finance

ECONGU4280 Corporate Finance WeChat: zh6-86

P8649 [蓝桥杯 2017 省 B] k 倍区间(前缀和+优化(桶分类))

分析&#xff1a; &#xff08;1&#xff09;任意连续子序列可用两个前缀和的差来表示 &#xff08;2&#xff09;判断该子序列是否为k的倍数 p1-p2 模 0 (mod k) 等价于&#xff1a;前缀和模 k 是否同余 &#xff08;3&#xff09;同余的任意两前缀和组合的序列均满足…

WEB安全之Python

WEB安全之python python-pyc反编译 python类似java一样&#xff0c;存在编译过程&#xff0c;先将源码文件*.py编译成 *.pyc文件&#xff0c;然后通过python解释器执行 生成pyc文件 创建一个py文件随便输入几句代码(1.py) 通过python交互终端 >>>import py_compil…