blob: d5dfcd3133999beef308534766fbed557ec23432 [file] [log] [blame]
Raverd7895172025-06-18 17:54:38 +08001#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3"""
4测试基于redbook数据库的推荐系统
5"""
6
7import sys
8import os
9import time
10sys.path.append(os.path.dirname(os.path.abspath(__file__)))
11
12from app.services.recommendation_service import RecommendationService
13from app.utils.graph_build import build_user_post_graph
14import pymysql
15
16def test_database_connection():
17 """测试数据库连接"""
18 print("=== 测试数据库连接 ===")
19 try:
20 db_config = {
21 'host': '10.126.59.25',
22 'port': 3306,
23 'user': 'root',
24 'password': '123456',
25 'database': 'redbook',
26 'charset': 'utf8mb4'
27 }
28 conn = pymysql.connect(**db_config)
29 cursor = conn.cursor()
30
31 # 检查用户数量
32 cursor.execute("SELECT COUNT(*) FROM users")
33 user_count = cursor.fetchone()[0]
34 print(f"用户总数: {user_count}")
35
36 # 检查帖子数量
37 cursor.execute("SELECT COUNT(*) FROM posts WHERE status = 'published'")
38 post_count = cursor.fetchone()[0]
39 print(f"已发布帖子数: {post_count}")
40
41 # 检查行为数据
42 cursor.execute("SELECT type, COUNT(*) FROM behaviors GROUP BY type")
43 behavior_stats = cursor.fetchall()
44 print("行为统计:")
45 for behavior_type, count in behavior_stats:
46 print(f" {behavior_type}: {count}")
47
48 cursor.close()
49 conn.close()
50 print("数据库连接测试成功!")
51 return True
52 except Exception as e:
53 print(f"数据库连接失败: {e}")
54 return False
55
56def test_graph_building():
57 """测试图构建"""
58 print("\n=== 测试图构建 ===")
59 try:
60 user2idx, post2idx = build_user_post_graph(return_mapping=True)
61 print(f"用户数量: {len(user2idx)}")
62 print(f"帖子数量: {len(post2idx)}")
63
64 # 显示前几个用户和帖子的映射
65 print("前5个用户映射:")
66 for i, (user_id, idx) in enumerate(list(user2idx.items())[:5]):
67 print(f" 用户{user_id} -> 索引{idx}")
68
69 print("前5个帖子映射:")
70 for i, (post_id, idx) in enumerate(list(post2idx.items())[:5]):
71 print(f" 帖子{post_id} -> 索引{idx}")
72
73 print("图构建测试成功!")
74 return True
75 except Exception as e:
76 print(f"图构建失败: {e}")
77 return False
78
79def test_cold_start_recommendation():
80 """测试冷启动推荐"""
81 print("\n=== 测试冷启动推荐 ===")
82 try:
83 service = RecommendationService()
84
85 # 使用一个不存在的用户ID进行冷启动测试
86 fake_user_id = 999999
87
88 # 计时开始
89 start_time = time.time()
90 recommendations = service.get_recommendations(fake_user_id, topk=10)
91 end_time = time.time()
92
93 # 计算推荐耗时
94 recommendation_time = end_time - start_time
95 print(f"冷启动推荐耗时: {recommendation_time:.4f} 秒")
96
97 print(f"冷启动推荐结果(用户{fake_user_id}):")
98 for i, rec in enumerate(recommendations):
TRM-coding3127efa2025-06-18 22:54:25 +080099 print(f" {i+1}. 帖子ID: {rec['id']}, 标题: {rec['title'][:50]}...")
Raverd7895172025-06-18 17:54:38 +0800100 print(f" 作者: {rec['username']}, 热度: {rec['heat']}")
101 print(f" 点赞: {rec.get('like_count', 0)}, 评论: {rec.get('comment_count', 0)}")
102
103 print("冷启动推荐测试成功!")
104 return True
105 except Exception as e:
106 print(f"冷启动推荐失败: {e}")
107 return False
108
109def test_user_recommendation():
110 """测试用户推荐"""
111 print("\n=== 测试用户推荐 ===")
112 try:
113 service = RecommendationService()
114
115 # 获取一个真实用户ID
116 db_config = service.db_config
117 conn = pymysql.connect(**db_config)
118 cursor = conn.cursor()
119 cursor.execute("SELECT DISTINCT user_id FROM behaviors LIMIT 1")
120 result = cursor.fetchone()
121
122 if result:
Raver9d0ecf52025-06-25 17:35:39 +0800123 user_id = 33
124 cursor.execute("select username from users where id = %s", (user_id,))
125 username = cursor.fetchone()[0]
Raverd7895172025-06-18 17:54:38 +0800126 print(f"测试用户ID: {user_id}")
Raver9d0ecf52025-06-25 17:35:39 +0800127 print(f"测试用户名: {username}")
Raverd7895172025-06-18 17:54:38 +0800128
129 # 查看用户的历史行为
130 cursor.execute("""
131 SELECT b.type, COUNT(*) as count
132 FROM behaviors b
133 WHERE b.user_id = %s
134 GROUP BY b.type
135 """, (user_id,))
136 user_behaviors = cursor.fetchall()
137 print("用户历史行为:")
138 for behavior_type, count in user_behaviors:
139 print(f" {behavior_type}: {count}")
140
141 cursor.close()
142 conn.close()
143
144 # 尝试获取推荐 - 添加计时
145 print("开始生成推荐...")
146 start_time = time.time()
147 recommendations = service.get_recommendations(user_id, topk=10)
148 end_time = time.time()
149
150 # 计算推荐耗时
151 recommendation_time = end_time - start_time
152 print(f"用户推荐耗时: {recommendation_time:.4f} 秒")
153
154 print(f"用户推荐结果(用户{user_id}):")
155 for i, rec in enumerate(recommendations):
TRM-coding3127efa2025-06-18 22:54:25 +0800156 print(f" {i+1}. 帖子ID: {rec['id']}, 标题: {rec['title'][:50]}...")
Raverd7895172025-06-18 17:54:38 +0800157 print(f" 作者: {rec['username']}, 热度: {rec['heat']}")
158 print(f" 点赞: {rec.get('like_count', 0)}, 评论: {rec.get('comment_count', 0)}")
159 if 'recommendation_score' in rec:
160 print(f" 推荐分数: {rec['recommendation_score']:.4f}")
161 else:
162 print(f" 热度分数: {rec['heat']}")
163
164 print("用户推荐测试成功!")
165 return True
166 else:
167 print("没有找到有行为记录的用户")
168 cursor.close()
169 conn.close()
170 return False
171
172 except Exception as e:
173 print(f"用户推荐失败: {e}")
174 return False
175
176def test_recommendation_performance():
177 """测试推荐性能 - 多次调用统计"""
178 print("\n=== 测试推荐性能 ===")
179 try:
180 service = RecommendationService()
181
182 # 获取几个真实用户ID进行测试
183 db_config = service.db_config
184 conn = pymysql.connect(**db_config)
185 cursor = conn.cursor()
186 cursor.execute("SELECT DISTINCT user_id FROM behaviors LIMIT 5")
187 user_ids = [row[0] for row in cursor.fetchall()]
188 cursor.close()
189 conn.close()
190
191 if not user_ids:
192 print("没有找到有行为记录的用户")
193 return False
194
195 print(f"测试用户数量: {len(user_ids)}")
196
197 # 进行多次推荐测试
198 times = []
199 test_rounds = 3 # 每个用户测试3轮
200
201 for round_num in range(test_rounds):
202 print(f"\n第 {round_num + 1} 轮测试:")
203 round_times = []
204
205 for i, user_id in enumerate(user_ids):
206 start_time = time.time()
207 recommendations = service.get_recommendations(user_id, topk=10)
208 end_time = time.time()
209
210 recommendation_time = end_time - start_time
211 round_times.append(recommendation_time)
212 times.append(recommendation_time)
213
214 print(f" 用户 {user_id}: {recommendation_time:.4f}s, 推荐数量: {len(recommendations)}")
215
216 # 计算本轮统计
217 avg_time = sum(round_times) / len(round_times)
218 min_time = min(round_times)
219 max_time = max(round_times)
220 print(f" 本轮平均耗时: {avg_time:.4f}s, 最快: {min_time:.4f}s, 最慢: {max_time:.4f}s")
221
222 # 计算总体统计
223 print(f"\n=== 性能统计总结 ===")
224 print(f"总测试次数: {len(times)}")
225 print(f"平均推荐耗时: {sum(times) / len(times):.4f} 秒")
226 print(f"最快推荐耗时: {min(times):.4f} 秒")
227 print(f"最慢推荐耗时: {max(times):.4f} 秒")
228 print(f"推荐耗时标准差: {(sum([(t - sum(times)/len(times))**2 for t in times]) / len(times))**0.5:.4f} 秒")
229
230 # 性能等级评估
231 avg_time = sum(times) / len(times)
232 if avg_time < 0.1:
233 performance_level = "优秀"
234 elif avg_time < 0.5:
235 performance_level = "良好"
236 elif avg_time < 1.0:
237 performance_level = "一般"
238 else:
239 performance_level = "需要优化"
240
241 print(f"性能评级: {performance_level}")
242
243 print("推荐性能测试成功!")
244 return True
245
246 except Exception as e:
247 print(f"推荐性能测试失败: {e}")
248 return False
249
250def main():
251 """主测试函数"""
252 print("开始测试基于redbook数据库的推荐系统")
253 print("=" * 50)
254
255 tests = [
Raver9d0ecf52025-06-25 17:35:39 +0800256 # test_database_connection,
Raverd7895172025-06-18 17:54:38 +0800257 test_graph_building,
Raver9d0ecf52025-06-25 17:35:39 +0800258 # test_cold_start_recommendation,
Raverd7895172025-06-18 17:54:38 +0800259 test_user_recommendation,
Raver9d0ecf52025-06-25 17:35:39 +0800260 # test_recommendation_performance
Raverd7895172025-06-18 17:54:38 +0800261 ]
262
263 passed = 0
264 total = len(tests)
265
266 for test in tests:
267 try:
268 if test():
269 passed += 1
270 except Exception as e:
271 print(f"测试异常: {e}")
272
273 print("\n" + "=" * 50)
274 print(f"测试完成: {passed}/{total} 通过")
275
276 if passed == total:
277 print("所有测试通过!")
278 else:
279 print("部分测试失败,请检查配置和代码")
280
281if __name__ == "__main__":
282 main()