ClassDef MovieLensData
MovieLensData: MovieLensData 类用于处理和加载MovieLens数据集。
属性:
- train_data_path: 字符串类型,表示训练数据文件的路径。
- val_data_path: 字符串类型,表示验证数据文件的路径。
代码描述: MovieLensData 类继承自 BaseData 类,专门用于处理MovieLens数据集。它提供了一系列方法来加载和处理数据,包括用户特征、项目特征、评分等信息。
__init__
方法初始化数据路径。get_features
方法根据是否包含用户信息返回用户特征、项目特征和奖励特征。get_df
方法根据文件名加载数据,并返回处理后的数据框架。get_domination
方法获取项目特征的统治性信息。get_item_similarity
方法计算项目之间的相似度。get_item_popularity
方法计算项目的流行度。load_category
静态方法加载项目的类别信息。load_item_feat
静态方法加载项目特征。load_user_feat
静态方法加载用户特征。load_mat
静态方法加载评分矩阵。get_lbe
静态方法获取用户和项目的标签编码器。
MovieLensData 类在项目中被 MovieLensEnv 类调用,用于加载环境数据,包括评分矩阵、用户和项目的标签编码器以及项目之间的距离矩阵。这些数据是进行推荐系统模拟和评估的基础。
注意:
- 在使用
get_df
方法时,需要确保数据文件路径正确,并且数据文件格式符合预期。 - 在处理大型数据集时,部分方法可能需要较长的执行时间,特别是在计算项目相似度和流行度时。
输出示例:
假设调用 get_features
方法且 is_userinfo=True
,可能的返回值为:
(["user_id", "gender", "age_range", "occupation"], ['item_id', 'feat0', 'feat1', 'feat2', 'feat3', 'feat4', 'feat5'], ["rating"])
这表示用户特征包括用户ID、性别、年龄范围和职业;项目特征包括项目ID和六个其他特征;奖励特征为评分。
FunctionDef init(self)
init: 此函数的功能是初始化MovieLensData类的实例。
参数: 此函数没有接受任何外部参数。
代码描述:
此函数是MovieLensData
类的构造函数,用于初始化类的实例。在这个函数中,首先通过super(MovieLensData, self).__init__()
调用父类的构造函数来确保父类被正确初始化。接着,函数设置了两个实例变量train_data_path
和val_data_path
,分别用于存储训练数据和验证数据的文件路径。这里,训练数据和验证数据的文件名被硬编码为"movielens-1m-train.csv"和"movielens-1m-test.csv",这意味着MovieLensData
类的实例将默认使用这两个CSV文件作为训练和验证数据源。
注意:
- 使用
MovieLensData
类之前,确保当前工作目录或指定的路径中存在名为"movielens-1m-train.csv"和"movielens-1m-test.csv"的文件,否则在尝试访问这些文件时可能会遇到文件找不到的错误。 - 此类的设计假设了数据文件的特定命名约定,如果有需要处理不同命名的文件,需要修改
train_data_path
和val_data_path
的值或重写此构造函数。
FunctionDef get_features(self, is_userinfo)
get_features: 此函数的功能是获取用户特征、项目特征和奖励特征的列表。
参数:
- is_userinfo: 布尔值,用于指定是否包含除用户ID外的用户信息。
代码描述:
get_features
函数用于生成和返回用户特征、项目特征和奖励特征的列表。用户特征默认包括"user_id"、"gender"、"age_range"和"occupation"。如果参数is_userinfo
为False,则用户特征仅包含"user_id"。项目特征包括"item_id"和六个以"feat"为前缀的特征,如"feat0"、"feat1"等。奖励特征包括"rating"。
在项目中,get_features
函数被save_all_models
方法调用,用于获取用户特征、项目特征和奖励特征的列表,这些特征随后用于计算和保存模型的预测结果和方差,以及模型的参数和嵌入。这表明get_features
函数在模型训练和评估过程中起着至关重要的作用,它为后续的数据处理和模型训练提供了必要的特征信息。
注意:
- 在调用此函数时,需要根据实际情况决定是否需要包含完整的用户信息。如果数据集中用户的其他信息(如性别、年龄范围、职业等)对模型训练和预测不是必需的,可以通过将
is_userinfo
设置为False来仅包含用户ID,以简化模型的输入特征。
输出示例:
调用get_features(is_userinfo=True)
可能会返回以下列表:
- 用户特征: ["user_id", "gender", "age_range", "occupation"]
- 项目特征: ["item_id", "feat0", "feat1", "feat2", "feat3", "feat4", "feat5"]
- 奖励特征: ["rating"]
调用get_features(is_userinfo=False)
可能会返回以下列表:
- 用户特征: ["user_id"]
- 项目特征: ["item_id", "feat0", "feat1", "feat2", "feat3", "feat4", "feat5"]
- 奖励特征: ["rating"]
FunctionDef get_df(self, name)
get_df: 该函数的功能是加载并预处理MovieLens数据集中的用户-电影交互数据。
参数:
- name: 字符串类型,默认值为"movielens-1m-train.csv"。用于指定要加载的数据文件名称。
代码描述:
get_df
函数首先根据提供的文件名从预设的数据路径(DATAPATH)中读取电影交互数据。数据文件默认为"movielens-1m-train.csv",该文件包含用户对电影的评分信息。函数使用pandas
库的read_csv
方法加载数据,指定文件的第一行为列名,列名包括"user_id"、"item_id"、"rating"和"timestamp"。
接着,函数将数据按照"user_id"和"timestamp"进行排序,以确保数据的顺序性。此步骤对于某些基于序列的推荐系统模型特别重要。
函数调用load_user_feat
方法加载用户特征数据,并调用load_category
方法加载电影类别数据。这两个方法分别从"users.dat"和"movies.dat"文件中读取数据,并进行必要的预处理。
最后,函数通过join
方法将用户特征数据和电影类别数据与交互数据合并,以便构建完整的数据集。合并操作基于"user_id"和"item_id"进行。
在项目中,get_df
函数被get_domination
和get_item_popularity
两个函数调用。get_domination
函数使用get_df
加载的数据来计算特征占优势的信息,而get_item_popularity
函数则利用get_df
加载的数据来计算电影的流行度。
注意:
- 在调用
get_df
函数之前,确保数据文件已经位于预定的DATAPATH
路径下。 - 数据文件应包含正确的列名和数据格式,以避免加载过程中的错误。
- 由于
get_df
函数依赖于load_user_feat
和load_category
两个方法,确保这两个方法能够正确执行并返回所需的数据结构。
输出示例:
函数返回四个对象:df_data
、df_user
、df_item
和list_feat
。其中df_data
是一个DataFrame,包含了合并后的用户-电影交互数据;df_user
是一个DataFrame,包含了用户特征数据;df_item
是一个DataFrame,包含了电影特征数据;list_feat
是一个列表,包含了电影类别特征。例如:
(df_data:
user_id item_id rating timestamp gender age occupation genre
0 1 119 5 978300760 1 10 5 [Comedy]
1 2 66 3 978302109 2 20 10 [Drama]
...,
df_user:
gender age occupation
user_id
1 1 10 5
2 2 20 10
...,
df_item:
movie_title genre
item_id
119 Toy Story [Comedy]
66 Jumanji [Drama]
...,
list_feat:
[[Comedy], [Drama], ...])
这里,df_data
展示了合并后的数据结构,包括用户ID、电影ID、评分、时间戳以及用户和电影的特征信息;df_user
和df_item
分别展示了用户特征和电影特征的数据结构;list_feat
展示了电影类别特征的列表。
FunctionDef get_domination(self)
get_domination: 该函数的功能是获取电影特征的占优势信息。
参数: 该函数没有参数。
代码描述: get_domination
函数首先调用 get_df
方法从 "movielens-1m-train.csv" 文件中加载电影交互数据,包括用户对电影的评分信息以及电影特征数据。接着,函数检查是否已经存在一个名为 "feature_domination.pickle" 的文件,该文件存储了电影特征的占优势信息。如果该文件存在,则直接从文件中加载占优势信息;如果不存在,则调用 get_sorted_domination_features
方法计算电影特征的占优势信息。计算完成后,将结果保存到 "feature_domination.pickle" 文件中,以便后续使用。最终,函数返回电影特征的占优势信息。
get_sorted_domination_features
方法用于计算并排序电影特征的占比情况。该方法根据是否使用多热编码处理特征(is_multi_hot
参数),以及指定的目标列名称(yname
)和阈值(threshold
),来决定如何处理数据。该方法返回一个字典,其中包含特征名称及其排序后的占比列表。
get_df
方法用于加载并预处理MovieLens数据集中的用户-电影交互数据。该方法返回包含合并后的用户-电影交互数据、用户特征数据、电影特征数据以及电影类别特征的多个对象。
在项目中,get_domination
方法被多个场景调用,例如在学习策略、用户模型训练等场景中,用于获取电影特征的占优势信息,以支持不同的数据处理和分析需求。
注意:
- 在调用
get_domination
方法之前,确保 "movielens-1m-train.csv" 文件已经位于预定的路径下,并且数据格式正确。 - 该方法依赖于
pickle
库来保存和加载电影特征的占优势信息,确保在使用前已正确安装该库。 - 由于
get_domination
方法涉及文件操作,需要确保程序具有相应的文件读写权限。
输出示例:
{
'feature1': [(1, 0.5), (0, 0.5)],
'feature2': [(0, 0.75), (1, 0.25)]
}
此示例展示了一个可能的返回值,其中包含了两个特征(feature1
和 feature2
)的占优势信息。对于 feature1
,值为1的占比为50%,值为0的占比也为50%;对于 feature2
,值为0的占比为75%,值为1的占比为25%。
FunctionDef get_item_similarity(self)
get_item_similarity: 此函数的功能是获取物品之间的相似度矩阵。
参数: 此函数不接受任何外部参数。
代码描述: get_item_similarity
函数首先尝试从预定的数据路径(PRODATAPATH
)加载名为 "item_similarity_add1.pickle" 的文件。如果该文件存在,则直接加载并返回物品相似度矩阵。如果文件不存在,函数将执行以下步骤来计算相似度矩阵:
- 调用
load_mat
函数加载评分矩阵。 - 使用
get_saved_distance_mat
函数计算或获取保存的距离矩阵。 - 根据距离矩阵计算物品相似度,计算公式为
1 / (mat_distance + 1)
,以确保相似度值在0到1之间。 - 由于MovieLens数据集中的物品ID从1开始,为了匹配物品ID和相似度矩阵的索引,函数会创建一个新的矩阵
item_similarity_add1
,其形状比原相似度矩阵的行和列都多1,并将原相似度矩阵的值填充到新矩阵的从第二行第二列开始的位置。 - 最后,计算得到的相似度矩阵被保存到 "item_similarity_add1.pickle" 文件中,以便未来使用。
此函数在项目中被 prepare_train_envs_local
和 learn_policy
两个函数调用。在 prepare_train_envs_local
函数中,get_item_similarity
用于获取物品相似度矩阵,以便在训练环境中使用。在 learn_policy
函数中,它用于评估策略时获取物品相似度,以计算用户体验相关的指标。
注意:
- 确保
PRODATAPATH
路径正确设置,并且有足够的权限进行文件读写操作。 - 物品相似度矩阵的计算可能会根据评分矩阵的大小和复杂度消耗较长时间,特别是首次计算时。
输出示例: 假设物品数量为3,get_item_similarity
函数可能返回如下形式的4x4相似度矩阵(具体数值依据评分矩阵的内容而定):
[[nan, nan, nan, nan],
[nan, 1.0, 0.5, 0.33],
[nan, 0.5, 1.0, 0.25],
[nan, 0.33, 0.25, 1.0]]
此矩阵的第一行和第一列为 nan
,表示这些位置不对应任何物品。其余部分表示物品之间的相似度,例如,第二行第三列的值0.5表示ID为1的物品和ID为2的物品的相似度为0.5。
FunctionDef get_item_popularity(self)
get_item_popularity: 该函数的功能是计算并获取电影项目的流行度。
参数: 该函数没有参数。
代码描述: get_item_popularity
函数首先尝试从预设的路径(PRODATAPATH)中加载名为"item_popularity_add1.pickle"的文件,该文件假设已经包含了电影项目的流行度信息。如果该文件存在,则直接加载并返回该数据。
如果文件不存在,则函数会调用get_df
方法来加载"movielens-1m-train.csv"文件中的用户-电影交互数据。基于这些数据,函数计算评分大于等于4的电影的流行度。流行度是通过计算给定电影评分大于等于4的用户数与总用户数的比例来定义的。
计算流行度后,函数会创建一个新的DataFrame,其中包含所有电影项目的ID和它们的流行度。对于那些没有评分数据的电影项目,它们的流行度将被设置为0。最终,这个流行度数据会被保存到"item_popularity_add1.pickle"文件中,以便将来使用。
值得注意的是,由于MovieLens数据集中的项目ID从1开始,函数在流行度数组的开头添加了一个NaN值,以使数组索引与项目ID对齐。
注意:
- 确保
PRODATAPATH
路径正确,并且有足够的权限来读写文件。 - 在调用此函数之前,确保"movielens-1m-train.csv"文件已经位于预定的路径下,并且格式正确。
- 由于流行度的计算依赖于用户对电影的评分数据,确保这些数据是最新的,以反映最准确的流行度信息。
输出示例: 函数返回一个numpy数组,其中包含所有电影项目的流行度。例如,如果有1000个电影项目,返回的数组可能如下所示(假设数组的第一个元素为NaN,以对齐项目ID):
array([ nan, 0. , 0.1 , 0.05 , ..., 0.2 ])
在项目中,get_item_popularity
函数被prepare_train_envs_local
和learn_policy
两个函数调用。在prepare_train_envs_local
中,该函数用于获取电影项目的流行度信息,以便在训练环境中使用这些信息来模拟用户对电影的偏好。在learn_policy
中,该函数同样用于获取电影项目的流行度信息,以便在策略学习过程中考虑电影的流行度,从而提高推荐系统的性能。
FunctionDef load_category(tag_label)
load_category: 该函数的功能是加载电影类别数据,并对其进行预处理和特征编码。
参数:
- tag_label: 一个字符串参数,默认值为"tags"。用于指定返回的DataFrame中标签列的列名。
代码描述:
load_category
函数首先从指定的数据路径中读取电影数据文件movies.dat
,使用pandas
库的read_csv
方法加载数据。该数据包括电影ID、电影标题和电影类型等信息。在读取数据时,指定了分隔符为"::",并且没有文件头(header=None),同时指定了列名和各列的数据类型。
接着,函数对电影标题中的发布年份进行提取,并将其转换为整型。同时,从电影标题中移除年份信息。电影类型(genre)列中的类型被分割成列表,并计算每部电影的类型数量。
函数将电影ID设置为DataFrame的索引,并对缺失的电影ID进行填充,确保连续的ID序列。对于缺失的电影类型数据,将其填充为空列表。
然后,函数使用LabelEncoder
对电影类型进行编码,生成一个新的DataFrame,其中包含编码后的电影类型特征。编码后的特征被添加到原始DataFrame中,作为新的列。
在项目中,load_category
函数被get_df
和load_item_feat
两个函数调用。在get_df
函数中,load_category
用于加载电影类别特征,并将其与用户交互数据进行合并,以便进行后续的数据分析或模型训练。在load_item_feat
函数中,load_category
的结果被用来加载电影特征,以便进行特征分析或模型训练。
注意:
- 确保在调用此函数之前,数据文件
movies.dat
已经位于预定的DATAPATH
路径下。 - 由于使用了
latin1
编码读取数据文件,确保文件编码与此一致,以避免编码错误。 - 函数内部对电影类型进行了编码,这一步骤可能会根据电影类型的不同而产生不同的编码结果,因此在使用编码后的特征进行模型训练或分析时应注意。
输出示例:
函数返回两个对象:list_feat_num
和df_feat
。其中list_feat_num
是一个列表,包含了编码后的电影类型特征;df_feat
是一个DataFrame,包含了电影ID和对应的编码后的电影类型特征。例如:
([1, 2, 3, 0, 4, 5],
feat0 feat1 feat2 feat3 feat4 feat5 tags
1 1 0 0 0 0 0 [1]
2 2 3 0 0 0 0 [2, 3]
...)
这里,list_feat_num
展示了一部分编码后的电影类型特征列表,而df_feat
展示了对应的DataFrame结构,包括每部电影的多个类型特征列和一个tags
列,后者使用传入的tag_label
参数命名。
FunctionDef load_item_feat
load_item_feat: 该函数的功能是加载电影特征数据。
参数: 该函数不接受任何参数。
代码描述: load_item_feat
函数首先调用 MovieLensData
类中的 load_category
函数来加载和预处理电影类别数据。load_category
函数返回两个对象:一个是电影类别特征的列表,另一个是包含电影ID和对应编码后电影类别特征的DataFrame。在 load_item_feat
函数中,只使用了 load_category
返回的DataFrame对象,即电影特征数据,并将其赋值给 df_item
变量。随后,函数打印出“item features loaded!”信息,表示电影特征数据已成功加载。最后,函数返回 df_item
,即包含电影特征的DataFrame。
在项目中,load_item_feat
函数被 get_lbe
函数调用。get_lbe
函数用于生成用户特征和电影特征的标签编码器(LabelEncoder)。在 get_lbe
函数中,通过调用 load_item_feat
函数获取电影特征数据,然后使用电影ID作为标签编码器的训练数据。这表明 load_item_feat
函数的输出,即电影特征数据,在项目中用于进一步的数据处理和模型训练。
注意: 在调用 load_item_feat
函数之前,确保已经正确执行了 load_category
函数中的数据加载和预处理步骤,包括电影数据文件的读取、电影类别的编码等。这是因为 load_item_feat
函数的正常运行依赖于 load_category
函数的输出。
输出示例: 函数返回的 df_item
可能的外观如下:
feat0 feat1 feat2 feat3 feat4 feat5 tags
1 1 0 0 0 0 0 [1]
2 2 3 0 0 0 0 [2, 3]
...
这里,DataFrame df_item
包含了每部电影的多个类型特征列和一个 tags
列,tags
列使用了 load_category
函数中的 tag_label
参数命名,展示了编码后的电影类型特征。
FunctionDef load_user_feat
load_user_feat: 该函数的功能是加载用户特征。
参数: 该函数没有参数。
代码描述: load_user_feat
函数主要用于从项目数据路径中的 "users.dat" 文件加载用户特征数据,并对这些数据进行预处理,以便后续的数据分析和模型训练使用。首先,函数通过 pd.read_csv
读取用户数据,指定分隔符为"::",并为数据框指定列名["user_id", "gender", "age", "occupation", "zip_code"]。接着,对 "zip_code" 列进行处理,只保留邮编的前部分。然后,使用 pd.cut
对用户的年龄进行分段,创建一个新的 "age_range" 列。对于 "gender"、"occupation" 和 "zip_code" 列,函数使用 LabelEncoder
对这些类别特征进行编码,以便将文本数据转换为模型可以处理的数值类型。最后,将 "user_id" 设置为数据框的索引。
在项目中,load_user_feat
函数被 get_df
和 get_lbe
函数调用。在 get_df
函数中,load_user_feat
被用来加载用户特征数据,并将这些数据与其他数据框进行合并,以构建完整的数据集。在 get_lbe
函数中,load_user_feat
被用来加载用户特征数据,以便对用户ID进行标签编码,这对于处理推荐系统中的用户-项目交互数据是必要的。
注意: 在使用 load_user_feat
函数时,需要确保项目数据路径中存在 "users.dat" 文件,并且该文件的格式符合函数预期。此外,对于 "zip_code" 的处理可能会根据具体的业务需求进行调整。
输出示例:
gender age occupation zip_code age_range
user_id
1 1 10 5 100 2
2 2 20 10 200 3
...
在这个示例中,"gender"、"occupation" 和 "zip_code" 列已经被编码,"age_range" 列显示了年龄分段的结果。
FunctionDef load_mat
load_mat: 该函数的功能是加载评分矩阵。
参数: 此函数不接受任何参数。
代码描述: load_mat
函数首先尝试从指定的数据路径(DATAPATH
)加载名为 "rating_matrix.csv" 的文件。如果该文件存在,则使用 pandas
库读取 CSV 文件并将其转换为 numpy 数组。如果文件不存在,函数将调用 provide_MF_results.main()
方法来生成评分矩阵。加载或生成评分矩阵后,函数会对矩阵中的数据进行处理,确保所有评分值在 0 到 5 的范围内,即将小于 0 的值设置为 0,大于 5 的值设置为 5。最后,处理后的评分矩阵将作为 numpy 数组返回。
在项目中,load_mat
函数被 get_item_similarity
和 load_env_data
两个函数调用。在 get_item_similarity
函数中,load_mat
用于加载评分矩阵以计算物品之间的相似度。在 load_env_data
函数中,它用于加载环境数据,包括用户和物品的标签编码以及评分矩阵,这对于构建推荐系统环境至关重要。
注意: 确保 DATAPATH
路径正确设置,并且 "rating_matrix.csv" 文件存在于该路径下,或者 provide_MF_results.main()
方法能够正确生成评分矩阵。此外,处理评分矩阵时,确保所有操作都符合项目的评分逻辑。
输出示例: 假设 "rating_matrix.csv" 文件如下所示:
4,5,0
3,0,2
0,4,5
则 load_mat
函数的返回值可能是一个 numpy 数组,如下:
[[4. 5. 0.]
[3. 0. 2.]
[0. 4. 5.]]
请注意,如果原始 CSV 文件中包含负数或大于 5 的值,它们将被调整到 0 到 5 的范围内。
FunctionDef get_lbe
get_lbe: 该函数的功能是生成用户和电影特征的标签编码器。
参数: 该函数不接受任何参数。
代码描述: get_lbe
函数首先调用 MovieLensData
类中的 load_user_feat
和 load_item_feat
函数来分别加载用户特征数据和电影特征数据。加载完成后,函数分别为用户ID和电影ID创建标签编码器(LabelEncoder)实例。通过调用 fit
方法,使用用户ID和电影ID的索引来训练这两个标签编码器。这一步骤是为了将用户ID和电影ID转换为连续的整数索引,这对于处理推荐系统中的稀疏数据是非常有用的。最后,函数返回两个训练好的标签编码器实例:lbe_user
和 lbe_item
。
在项目中,get_lbe
函数被 MovieLensEnv
类中的 load_env_data
函数调用。在 load_env_data
函数中,通过调用 get_lbe
函数获取用户和电影的标签编码器,这些编码器将用于后续的数据处理和模型训练过程中,以确保用户ID和电影ID能够被模型正确识别和处理。
注意: 在调用 get_lbe
函数之前,确保已经通过 load_user_feat
和 load_item_feat
函数加载了用户和电影的特征数据。这两个函数的正确执行是 get_lbe
函数能够成功运行的前提。
输出示例: 函数返回的 lbe_user
和 lbe_item
是两个标签编码器实例。虽然这些编码器的具体内容不会直接显示,但它们已经被训练好,可以将用户ID和电影ID映射为连续的整数索引。例如,如果有5个不同的用户ID和10个不同的电影ID,那么这些ID将被映射为从0开始的连续整数,用户ID可能被映射为0到4的整数,而电影ID可能被映射为0到9的整数。