AX5.0 Table Template

本文详细介绍了AX5.0系统中如何创建和使用表模板,包括设置允许空模板的方法、模板的保存机制及代码实现。通过具体实例展示了模板在表中的应用过程。

AX5.0 Table Template

AX系统只允许属于MainGroup组的table使用模板,而一个表是否可以有空模板是通过两种方式来设置的,一是在tablemethod下加一个静态方法canAllowBlankRecordTemplate,返回true时在第一次创建模板时会设置允许使用空模板。二是直接编辑模板来决定是否使用空模板,点击Basic->Setup->Record Template,弹出form 1,勾选Allow bland可以设置该tablereference table ID是该tableID)可以使用空模板。

 

1

下边我们将使用一个例子来演示如何创建和使用模板,以及系统在代码级别是怎么做的。

一.             使用模板

1.1   首先新建一个表davTempalte,并设置该表的tableGroupMain,然后添加Itemid,ItemName,InventDimId三个field,如图1-1-1

 

1-1-1

1.2   新建一个form davTemplate,添加davTemplate表为数据源,在formdesign中新建Grid,添加davTemplate数据源的字段Itemid,ItemName,InventDimId,如图1-2-1

 

 

1-2-1

1.3   打开davTempalte form,新建一条记录并保存,如图1-3-1.

 

 

1-3-1

1.4   使用新建的记录创建一个模板。首先在刚建立的记录上右键单击,在弹出的快捷菜单中选record info,弹出form 1-4-1. 本例我们只讲解company template,所以请点击company accounts template, 弹出form1-4-2,在form1-4-2中,Name为模板的名字,Description是该模板的描述。点击Ok就可以新建一个company template,这里我添加的模板名是davidTest

 

1-4-1

 

1-4-2

1.5   使用模板创建记录。在图1-3-1form上,点击左上角的新建按钮,弹出模板选择对话框如图1-5-1,选择模板davidTest,点击OK就会根据模板上的数据来创建一条新的记录,你会发现使用模板建立的新记录与我们用于建立模板的记录拥有相同的数据。

注意form1-5-1左下角的Do not ask Again,如果你勾选了该选框,下次再新建记录时会默认使用davidTest模板并且不再弹出此对话框。如果你想在你勾选Do not ask again以后,在新建记录时重新弹出此对话框,请在任意一条已经建立好的记录上右键单击,在弹出的快捷菜单中选Record info,弹出form1-5-2,单击右下角的Show template selection就可以了。

 

1-5-1

 

1-5-2

二.             模板是如何保存的

2.1使用用于浏览container的类查看我们刚才建立的模板可以得到form 2-1-1.

 

2-1-1

         2.2 用来保存模板数据的container的结构

 

 

该结构用图表表示如图2-2-1,模板一般都是在form上建立的,它会有一组Datasource,其中有一个表会是主datasource,其余表都连接到这个表,如InventTable form上的主Datasourceinventtable。对于这样的一个主table,所有以它为主datasourcetemplate都会放到一个容器里面,我们暂且称之为以某table位主datasource的一组datasource的模板被放在一个容器里,这个容器对应于我们图2-2-1中的caontainer 1.

如果以某table位主datasource的一组datasource有多个模板,那么它们对应于图2-2-1中的 container template1 ~ container template n,注意中间的容器我没有画出。

现在我们把焦点移到这组datasource的第一个模板上,也就是container template 1, 它有4个元素,第一个是template name,也就是模板的名字;第二个是is default,指该模板是否为默认使用的模板;第三个是一个容器container tables,它包含了这组datasource中每个表的模板数据;第四个是description,该模板的描述信息。

然后我们来看container tables, 如果这组datasource N table,那么会有N个容器来分别存放每一个table的模板数据,这些容器对应于2-2-1中的container table 1~ container table n,我没有画出中间的n-2个容器。如InventTable form 4Datasource,那么对应的就有4container

现在我们把注意力集中到存储这组datasource中某一个table的模板数据的容器上,如container table 1,它有2个元素,第一个是tableid,第二个是容器,用来存储该table所有不属于系统字段的字段的fieldId 和值,这个容器会包含很多小的容器如container field 1,这些容器只有两个元素,第一个是字段的field id,第二个是该字段对于的模板值。

到这里,您可以参照图2-2-12-1-1及步骤一中我们如何创建使用模板的理解模板究竟是怎么保存的。

                  

2-2-1

2.3 代码是如何运行的

这里我不打算把代码拷过来,我只写明路径和关键的变量。

当我们打开form1-4-1时,是在打开Forms/SysRecordInfo, SysRecordInfo/methods/init里你可以看到变量mainTableslist),通过调用SysRecordTemplate的静态方法mainTables赋值。

mainTables = SysRecordTemplate::mainTables(callerForm, common.TableId)

callerform是调用form 1-4-1的父formcommon 是我们右键点击时所在的记录,在该语句执行以后maintables就保存了所有Join到该commontable的活动记录,同时也包含了common在里面。如在Inventtable form上打开form1-4-1maintables就会含有4条记录,分别是每个datasource的当前活动记录。

form1-4-2关闭时,会返回新模板所要使用的Namedescription.

当你点击form 1-4-1company accounts template 时,首先会调用Forms/ SysRecordInfo/methods/ setAsCompanyDefault方法,该方法首先声明并且实例化变量sysRecordTemplateStorage ,该变量实际上是class SysRecordTemplateStorageCompany的一个实例,然后调用sysRecordTemplateStorage.set方法,该方法会弹出form1-4-2, form1-4-2关闭以后,会根据该组Datasource是否有可用的模板来分两类来给变量sysRecordTemplateTable赋值。该变量是table sysRecordTemplateTable的实例,它有3个字段,Data字段指对应于图2-2-1中的container 1table字段指该组datasource的主datasourcetableidallowBlank字段指该组datasource所在的form在新建记录时是否可以使用空模板。在set方法里你可以看到container 1被加入的第一个元素就是版本号。当退出set方法时,我们的新模板就已经被写入数据库了。

set方法里,给新模板添加数据是由下面这条语句执行的:

sysRecordTemplateSystemTable.Data  += [[description, sysRecordTemplateSystemTable?false:true, this.packList(),details]];

packList方法的路径是classes/ SysRecordTemplateStorage/packList,该方法会遍历我们前边提到的mainTables,把每一条记录的没一个字段的每一个元素都加到容器中,但只添加非系统字段。将记录的字段加入容器是由下面这条语句执行的:

packedCommon = SysRecordTemplateStorage::packCommon(tmpCommon);

在理解了图2-2-1以后,这些代码是比较容易看懂的。

三.             模板的使用的代码实现

当你新建记录是,系统会按图3-1调用方法。

 

3-1

我们把焦点放到Classes/sysRecordTemplate/createRecord方法上。

一进入该方法,注意storageCompany变量是使用common变量实例化的,也就是说所有的datasource的都会使用它当前记录来实例化变量storageCompany,每一个datasource都会调用createRecord方法。当进入该方法时,下面的代码:

If(this.isCached())

是不成立的,因为还没有向cache添加数据,所以走else语句块。下面这句

companyData = storageCompany.get();

在执行之后companyData对应于图2-2-1中的container 1.下面这句:

recordValues = this.promptSelect(userData, condel(companyData,1,1), copyData, allowBlank);

会弹出form1-5-1, form1-5-1关闭时会返回一个container,对应于图2-2-1中的container tables

RecordValues就是我们要使用的模板。那么是如何根据模板来初始各表的数据的呢?

根据FORM2-2-1可以看到一个container tables有很多个container table,而最关键的代码就在if(this.iscached())  if (recordValues) 下的语句块了。代码如下:

this.initValue(this.getFirstValues(recordValues), forceCompanyTemplate != '', onlyEditableFieldsOnCreate);

recordValues = condel(recordValues,1,1);

if (recordvalues)

this.setCache(recordValues);

首先,取container tables 的第一个容器container 1(对应form2-2-1), 然后使用方法getFirstValues 方法得到container fields容器(对应于form2-2-1),在InitValue方法里面遍历container field里边的 container field容器,并根据fieldId Values 来给datasource调用createRecord时传入的common赋值(这样说是不准确的,common并不是直接传递过来的)。然后把用过的这个container table recordValues(对应2-2-1中的container talbes)中删除,并将剩余的container table也即recordValues放入cache。当子datasourece调用是,会按照同样的步骤来给其common赋值,但会走Ifthis.isCached())的语句块。等createRecord方法退出,数据就都被使用模板赋值了。

        

 

import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.metrics.pairwise import cosine_similarity from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error, mean_absolute_error from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.metrics.pairwise import linear_kernel import seaborn as sns from flask import Flask, request, jsonify, render_template import json import os from collections import defaultdict import time from datetime import datetime class MovieRecommenderSystem: """电影推荐系统主类,整合各种推荐算法和评估方法""" def __init__(self, ratings_path='ratings.csv', movies_path='movies.csv', tags_path='tags.csv'): """初始化推荐系统,加载数据并预处理""" self.ratings_path = ratings_path self.movies_path = movies_path self.tags_path = tags_path # 数据属性 self.ratings_data = None self.movies_data = None self.tags_data = None self.merged_data = None self.user_movie_matrix = None self.user_movie_matrix_filled = None self.user_similarity_df = None self.item_similarity_df = None self.movie_content_matrix = None # 模型属性 self.collaborative_model = None self.content_model = None self.hybrid_model = None # 评估指标 self.evaluation_results = {} # 加载数据 self.load_data() self.preprocess_data() self.build_similarity_matrices() def load_data(self): """加载并检查数据集""" print(f"Loading data from {self.ratings_path}, {self.movies_path}, and {self.tags_path}") # 检查并加载评分数据 if os.path.exists(self.ratings_path): try: self.ratings_data = pd.read_csv(self.ratings_path) print(f"Ratings data loaded with {len(self.ratings_data)} entries") except Exception as e: print(f"Error loading ratings data: {e}") self.create_sample_data() else: print(f"Ratings file not found at {self.ratings_path}") self.create_sample_data() # 检查并加载电影数据 if os.path.exists(self.movies_path): try: self.movies_data = pd.read_csv(self.movies_path) print(f"Movies data loaded with {len(self.movies_data)} entries") except Exception as e: print(f"Error loading movies data: {e}") self.create_sample_data() else: print(f"Movies file not found at {self.movies_path}") if self.ratings_data is None: # 如果评分数据也没有,创建示例数据 self.create_sample_data() # 检查并加载标签数据 if os.path.exists(self.tags_path): try: self.tags_data = pd.read_csv(self.tags_path) print(f"Tags data loaded with {len(self.tags_data)} entries") except Exception as e: print(f"Error loading tags data: {e}") self.tags_data = pd.DataFrame(columns=['userId', 'movieId', 'tag', 'timestamp']) else: print(f"Tags file not found at {self.tags_path}. Content-based filtering will be limited.") self.tags_data = pd.DataFrame(columns=['userId', 'movieId', 'tag', 'timestamp']) def create_sample_data(self): """创建示例数据用于测试""" print("Creating sample data for testing purposes") # 创建示例评分数据 self.ratings_data = pd.DataFrame({ 'userId': [1, 1, 2, 2, 3, 3], 'movieId': [1, 2, 2, 3, 1, 3], 'rating': [5.0, 4.0, 3.0, 5.0, 4.0, 3.0], 'timestamp': [1234567890] * 6 }) # 创建示例电影数据 self.movies_data = pd.DataFrame({ 'movieId': [1, 2, 3], 'title': ['Toy Story', 'Jumanji', 'Grumpier Old Men'], 'genres': ['Adventure|Animation|Children|Comedy|Fantasy', 'Adventure|Children|Fantasy', 'Comedy|Romance'] }) # 创建示例标签数据 self.tags_data = pd.DataFrame({ 'userId': [1, 2, 3], 'movieId': [1, 2, 3], 'tag': ['family', 'board game', 'romantic comedy'], 'timestamp': [1234567890] * 3 }) def preprocess_data(self): """预处理数据,构建用户-电影评分矩阵""" print("Preprocessing data...") if self.ratings_data is None or self.movies_data is None: print("Insufficient data for preprocessing. Please check your data files.") return # 合并数据集 self.merged_data = pd.merge(self.ratings_data, self.movies_data, on='movieId') # 构建用户-电影评分矩阵 self.user_movie_matrix = self.merged_data.pivot_table( index='userId', columns='title', values='rating') # 处理缺失值 self.user_movie_matrix_filled = self.user_movie_matrix.fillna(0) # 提取电影年份 self.movies_data['year'] = self.movies_data['title'].str.extract(r'\((\d{4})\)') self.movies_data['year'] = pd.to_datetime(self.movies_data['year'], format='%Y').dt.year # 计算每部电影的平均评分和评分数量 movie_stats = self.ratings_data.groupby('movieId').agg( rating_count=('rating', 'count'), avg_rating=('rating', 'mean') ).reset_index() self.movies_data = pd.merge(self.movies_data, movie_stats, on='movieId') print(f"User-movie matrix shape: {self.user_movie_matrix.shape}") print(f"Processed {len(self.movies_data)} movies") def build_similarity_matrices(self): """构建用户相似度矩阵和物品相似度矩阵""" print("Building similarity matrices...") if self.user_movie_matrix is None: print("User-movie matrix not available. Cannot build similarity matrices.") return # 计算用户之间的相似度(余弦相似度) user_similarity = cosine_similarity(self.user_movie_matrix_filled) self.user_similarity_df = pd.DataFrame( user_similarity, index=self.user_movie_matrix.index, columns=self.user_movie_matrix.index ) # 计算电影之间的相似度 item_similarity = cosine_similarity(self.user_movie_matrix_filled.T) self.item_similarity_df = pd.DataFrame( item_similarity, index=self.user_movie_matrix.columns, columns=self.user_movie_matrix.columns ) # 构建基于内容的电影相似度矩阵 self.build_content_similarity_matrix() print("Similarity matrices built successfully") def build_content_similarity_matrix(self): """基于电影内容(类型、标签)构建相似度矩阵""" print("Building content-based similarity matrix...") if self.movies_data is None: print("Movies data not available. Cannot build content-based similarity matrix.") return # 合并电影类型和标签 if not self.tags_data.empty: # 聚合用户标签 movie_tags = self.tags_data.groupby('movieId').agg( tags=('tag', lambda x: ' '.join(x.astype(str))) ).reset_index() # 合并到电影数据 self.movies_data = pd.merge( self.movies_data, movie_tags, on='movieId', how='left') self.movies_data['tags'] = self.movies_data['tags'].fillna('') # 合并类型和标签 self.movies_data['content'] = self.movies_data['genres'].str.replace('|', ' ') + ' ' + self.movies_data['tags'] else: # 如果没有标签数据,仅使用类型 self.movies_data['content'] = self.movies_data['genres'].str.replace('|', ' ') # 使用TF-IDF向量化内容 tfidf = TfidfVectorizer(stop_words='english') tfidf_matrix = tfidf.fit_transform(self.movies_data['content']) # 计算余弦相似度 cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix) # 创建相似度DataFrame self.movie_content_matrix = pd.DataFrame( cosine_sim, index=self.movies_data['title'], columns=self.movies_data['title'] ) def recommend_movies_user_based(self, user_id, num_recommendations=10, min_rating=3.0): """基于用户的协同过滤推荐""" if self.user_similarity_df is None: print("User similarity matrix not available.") return [] if user_id not in self.user_similarity_df.index: print(f"User {user_id} not found in the dataset") return [] # 获取相似用户 similar_users = self.user_similarity_df[user_id].sort_values(ascending=False)[1:num_recommendations*2].index # 获取相似用户喜欢的电影 similar_users_movies = self.user_movie_matrix.loc[similar_users].mean(axis=0).sort_values(ascending=False) # 过滤掉评分过低的电影 high_rated_movies = similar_users_movies[similar_users_movies >= min_rating] # 过滤掉用户已经看过的电影 user_watched_movies = self.user_movie_matrix.loc[user_id][self.user_movie_matrix.loc[user_id] > 0].index recommendations = high_rated_movies[~high_rated_movies.index.isin(user_watched_movies)].head(num_recommendations) return list(recommendations.index) def recommend_movies_item_based(self, movie_title, num_recommendations=10): """基于物品的协同过滤推荐""" if self.item_similarity_df is None: print("Item similarity matrix not available.") return [] if movie_title not in self.item_similarity_df.index: print(f"Movie '{movie_title}' not found in the dataset") return [] # 获取相似电影 similar_movies = self.item_similarity_df[movie_title].sort_values(ascending=False)[1:num_recommendations+1] return list(similar_movies.index) def recommend_movies_content_based(self, movie_title, num_recommendations=10): """基于内容的推荐""" if self.movie_content_matrix is None: print("Content similarity matrix not available.") return [] if movie_title not in self.movie_content_matrix.index: print(f"Movie '{movie_title}' not found in the dataset") return [] # 获取相似电影 similar_movies = self.movie_content_matrix[movie_title].sort_values(ascending=False)[1:num_recommendations+1] return list(similar_movies.index) def recommend_movies_hybrid(self, user_id, movie_title, num_recommendations=10, cf_weight=0.5, content_weight=0.5): """混合推荐:结合协同过滤和内容推荐""" if self.user_similarity_df is None or self.movie_content_matrix is None: print("Similarity matrices not available.") return [] if user_id not in self.user_similarity_df.index: print(f"User {user_id} not found in the dataset") return [] if movie_title not in self.item_similarity_df.index or movie_title not in self.movie_content_matrix.index: print(f"Movie '{movie_title}' not found in the dataset") return [] # 协同过滤推荐 cf_recommendations = self.recommend_movies_item_based(movie_title, num_recommendations*2) cf_scores = {movie: self.item_similarity_df.loc[movie_title, movie] for movie in cf_recommendations} # 内容推荐 content_recommendations = self.recommend_movies_content_based(movie_title, num_recommendations*2) content_scores = {movie: self.movie_content_matrix.loc[movie_title, movie] for movie in content_recommendations} # 混合评分 hybrid_scores = defaultdict(float) for movie in set(cf_recommendations + content_recommendations): cf_score = cf_scores.get(movie, 0) content_score = content_scores.get(movie, 0) hybrid_scores[movie] = cf_weight * cf_score + content_weight * content_score # 排序并过滤用户已看过的电影 user_watched_movies = self.user_movie_matrix.loc[user_id][self.user_movie_matrix.loc[user_id] > 0].index sorted_recommendations = sorted(hybrid_scores.items(), key=lambda x: x[1], reverse=True) filtered_recommendations = [movie for movie, _ in sorted_recommendations if movie not in user_watched_movies][:num_recommendations] return filtered_recommendations def train_collaborative_filtering_model(self): """训练协同过滤模型""" if self.user_movie_matrix is None: print("User-movie matrix not available. Cannot train collaborative filtering model.") return None print("Training collaborative filtering model...") start_time = time.time() # 准备训练数据 X = self.user_movie_matrix_filled.values y = self.user_movie_matrix_filled.values # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42 ) # 使用线性回归模型 self.collaborative_model = LinearRegression() self.collaborative_model.fit(X_train, y_train) # 评估模型 train_time = time.time() - start_time self.evaluate_model(self.collaborative_model, X_test, y_test, "Collaborative Filtering") print(f"Collaborative filtering model trained in {train_time:.2f} seconds") return self.collaborative_model def evaluate_model(self, model, X_test, y_test, model_name): """评估模型性能""" if model is None: print(f"Model {model_name} is not trained.") return None print(f"Evaluating {model_name} model...") # 预测 predicted_ratings = model.predict(X_test) # 计算评估指标 mse = mean_squared_error(y_test, predicted_ratings) rmse = np.sqrt(mse) mae = mean_absolute_error(y_test, predicted_ratings) # 记录评估结果 self.evaluation_results[model_name] = { 'mse': mse, 'rmse': rmse, 'mae': mae, 'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S') } print(f"{model_name} Evaluation Results:") print(f"MSE: {mse:.4f}") print(f"RMSE: {rmse:.4f}") print(f"MAE: {mae:.4f}") return self.evaluation_results[model_name] def visualize_evaluation_results(self): """可视化评估结果""" if not self.evaluation_results: print("No evaluation results available. Train a model first.") return # 准备数据 models = list(self.evaluation_results.keys()) metrics = ['mse', 'rmse', 'mae'] # 创建图表 fig, axes = plt.subplots(1, len(metrics), figsize=(15, 5)) for i, metric in enumerate(metrics): values = [self.evaluation_results[model][metric] for model in models] sns.barplot(x=models, y=values, ax=axes[i]) axes[i].set_title(f'{metric.upper()} Comparison') axes[i].set_xlabel('Models') axes[i].set_ylabel(metric.upper()) axes[i].tick_params(axis='x', rotation=45) # 添加数值标签 for j, v in enumerate(values): axes[i].text(j, v + 0.01, f'{v:.4f}', ha='center') plt.tight_layout() plt.savefig('model_evaluation_comparison.png') print("Evaluation results visualization saved to 'model_evaluation_comparison.png'") def get_movie_details(self, movie_title): """获取电影详细信息""" if self.movies_data is None or movie_title not in self.movies_data['title'].values: return None movie = self.movies_data[self.movies_data['title'] == movie_title].iloc[0] # 确保所有数值类型都是Python原生类型 return { 'title': movie['title'], 'genres': movie['genres'], 'year': int(movie['year']) if pd.notna(movie['year']) else None, 'rating_count': int(movie['rating_count']), 'avg_rating': float(round(movie['avg_rating'], 2)) } def export_recommendations_to_json(self, user_id, recommendations, file_path='recommendations.json'): """将推荐结果导出为JSON文件""" result = { 'user_id': user_id, 'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'recommendations': [] } for movie_title in recommendations: details = self.get_movie_details(movie_title) if details: result['recommendations'].append(details) try: with open(file_path, 'w') as f: json.dump(result, f, indent=4) print(f"Recommendations exported to {file_path}") except Exception as e: print(f"Error exporting recommendations: {e}") return result # Flask API app = Flask(__name__) # 检查是否有数据文件可用 def check_data_files(): """检查数据文件是否存在""" data_files = ['ratings.csv', 'movies.csv', 'tags.csv'] missing_files = [] for file in data_files: if not os.path.exists(file): missing_files.append(file) if missing_files: print("警告: 以下数据文件缺失:") for file in missing_files: print(f"- {file}") print("将使用示例数据运行系统。若要使用完整功能,请确保这些文件存在。") # 初始化推荐系统 check_data_files() recommender = MovieRecommenderSystem() @app.route('/') def index(): """API首页""" return render_template('index.html', total_users=len(recommender.user_movie_matrix) if recommender.user_movie_matrix is not None else 0, total_movies=len(recommender.movies_data) if recommender.movies_data is not None else 0) @app.route('/recommend/user/<int:user_id>', methods=['GET']) def get_user_recommendations(user_id): """基于用户的协同过滤推荐API""" num_recommendations = int(request.args.get('num', 10)) recommendations = recommender.recommend_movies_user_based(user_id, num_recommendations) return jsonify({ 'user_id': user_id, 'num_recommendations': num_recommendations, 'recommendations': [recommender.get_movie_details(movie) for movie in recommendations if recommender.get_movie_details(movie)] }) @app.route('/recommend/movie/<string:movie_title>', methods=['GET']) def get_movie_recommendations(movie_title): """基于物品的协同过滤推荐API""" num_recommendations = int(request.args.get('num', 10)) recommendations = recommender.recommend_movies_item_based(movie_title, num_recommendations) return jsonify({ 'movie_title': movie_title, 'num_recommendations': num_recommendations, 'recommendations': [recommender.get_movie_details(movie) for movie in recommendations if recommender.get_movie_details(movie)] }) @app.route('/recommend/content/<string:movie_title>', methods=['GET']) def get_content_recommendations(movie_title): """基于内容的推荐API""" num_recommendations = int(request.args.get('num', 10)) recommendations = recommender.recommend_movies_content_based(movie_title, num_recommendations) return jsonify({ 'movie_title': movie_title, 'num_recommendations': num_recommendations, 'recommendations': [recommender.get_movie_details(movie) for movie in recommendations if recommender.get_movie_details(movie)] }) @app.route('/recommend/hybrid/<int:user_id>/<string:movie_title>', methods=['GET']) def get_hybrid_recommendations(user_id, movie_title): """混合推荐API""" num_recommendations = int(request.args.get('num', 10)) cf_weight = float(request.args.get('cf_weight', 0.5)) content_weight = float(request.args.get('content_weight', 0.5)) recommendations = recommender.recommend_movies_hybrid( user_id, movie_title, num_recommendations, cf_weight, content_weight ) return jsonify({ 'user_id': user_id, 'movie_title': movie_title, 'num_recommendations': num_recommendations, 'cf_weight': cf_weight, 'content_weight': content_weight, 'recommendations': [recommender.get_movie_details(movie) for movie in recommendations if recommender.get_movie_details(movie)] }) @app.route('/movie/<string:movie_title>', methods=['GET']) def get_movie_details(movie_title): """获取电影详细信息API""" details = recommender.get_movie_details(movie_title) if details: return jsonify(details) else: return jsonify({'error': f'Movie "{movie_title}" not found'}), 404 @app.route('/evaluate', methods=['GET']) def evaluate_models(): """评估模型API""" if not recommender.collaborative_model: recommender.train_collaborative_filtering_model() return jsonify(recommender.evaluation_results) if __name__ == '__main__': # 训练协同过滤模型 if recommender.user_movie_matrix is not None: recommender.train_collaborative_filtering_model() # 可视化评估结果 recommender.visualize_evaluation_results() else: print("无法训练模型:用户-电影矩阵不可用") # 示例推荐 if recommender.user_movie_matrix is not None and len(recommender.user_movie_matrix) > 0: sample_user_id = recommender.user_movie_matrix.index[0] sample_movie_title = "Toy Story" if "Toy Story" in recommender.movies_data['title'].values else recommender.movies_data['title'].values[0] if len(recommender.movies_data) > 0 else "" if sample_user_id is not None: print(f"\nSample Recommendations for User {sample_user_id}:") user_recommendations = recommender.recommend_movies_user_based(sample_user_id) for i, movie in enumerate(user_recommendations, 1): print(f"{i}. {movie}") if sample_movie_title: print(f"\nSample Similar Movies to '{sample_movie_title}':") movie_recommendations = recommender.recommend_movies_item_based(sample_movie_title) for i, movie in enumerate(movie_recommendations, 1): print(f"{i}. {movie}") # 导出推荐结果 if user_recommendations: recommender.export_recommendations_to_json(sample_user_id, user_recommendations) # 启动API服务器 print("\nStarting Flask API server...") app.run(debug=True)这代码运行不出来改正错误
06-20
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值