data_analysis.py 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import pandas as pd
  2. import json
  3. from datetime import datetime
  4. import matplotlib.pyplot as plt
  5. # 设置Matplotlib的默认字体
  6. plt.rcParams['font.sans-serif'] = ['SimHei'] # 'SimHei' 是一种支持中文的字体
  7. plt.rcParams['axes.unicode_minus'] = False # 正确显示负号
  8. # 读取和解析日志文件
  9. def load_log_to_df(filepath):
  10. data = []
  11. with open(filepath, 'r') as file:
  12. for line in file:
  13. try:
  14. timestamp = line[:19]
  15. json_str = line[20:]
  16. json_data = json.loads(json_str)
  17. # json_data 的所有key-value
  18. for key, value in json_data.items():
  19. # print(f"key: {key}, value: {value}")
  20. # 假设每条记录都包含uid和timestamp,你可能需要根据实际记录结构调整
  21. data.append({'uid': key, 'timestamp': timestamp, 'bet_count': value['bet_count'],
  22. 'betAmount': value['betAmount']})
  23. except json.JSONDecodeError:
  24. continue
  25. return pd.DataFrame(data)
  26. # 按每小时的下注频率和其他用户的差异来区分机器人用户
  27. def parse_by_user_hour_bet():
  28. # 将时间戳转换为小时(这里假设timestamp是以某种格式的字符串存储)
  29. df['timestamp'] = pd.to_datetime(df['timestamp'])
  30. df['hour'] = df['timestamp'].dt.hour
  31. # 计算每个用户在每个小时的活动次数
  32. activity_by_hour = df.groupby(['uid', 'hour']).size().unstack(fill_value=0)
  33. # 计算标准差来评估活动的均匀程度
  34. activity_std = activity_by_hour.std(axis=1)
  35. # 识别疑似机器人用户
  36. threshold = activity_std.quantile(0.95)
  37. suspected_bots = activity_std[activity_std > threshold].index
  38. robot_user = list(suspected_bots)
  39. print(f"疑似机器人数量{len(robot_user)}\n用户ID列表: {robot_user}")
  40. # 可视化
  41. activity_std.hist(bins=30)
  42. plt.title('用户活动时间标准差分布')
  43. plt.xlabel('标准差')
  44. plt.ylabel('用户数量')
  45. plt.show()
  46. # 通过用户活跃时间段来判断
  47. def parse_by_user_activity_time_wide():
  48. percent = 0.90 # 时间覆盖率
  49. # 将时间戳转换为小时(这里假设timestamp是以某种格式的字符串存储)
  50. df['timestamp'] = pd.to_datetime(df['timestamp'])
  51. # 创建新列,将日期和小时合并为字符串形式
  52. df['date_hour'] = df['timestamp'].dt.strftime('%Y-%m-%d_%H')
  53. # 确定有活动记录的小时
  54. active_hours = df['date_hour'].unique()
  55. # 计算每个用户在哪些小时有活动
  56. user_hours = df.groupby('uid')['date_hour'].apply(set)
  57. # 计算活动时间覆盖率
  58. user_coverage = user_hours.apply(lambda x: len(x) / len(active_hours))
  59. # 识别疑似机器人:以活动时间覆盖率的percent%分位数为阈值
  60. threshold = user_coverage.quantile(percent)
  61. suspected_bots = user_coverage[user_coverage > threshold].index
  62. # 打印疑似机器人数量和ID列表
  63. print(f"疑似机器人数量: {len(suspected_bots)}")
  64. print(f"用户ID列表: {list(suspected_bots)}")
  65. # 可视化活动时间覆盖率分布
  66. plt.hist(user_coverage, bins=40, alpha=0.7)
  67. plt.axvline(x=threshold, color='r', linestyle='--', label=f'{percent * 100}%分位数阈值')
  68. plt.title('用户活动时间覆盖率分布')
  69. plt.xlabel('活动时间覆盖率')
  70. plt.ylabel('用户数量')
  71. plt.legend()
  72. plt.show()
  73. if __name__ == '__main__':
  74. # 将日志文件转换为DataFrame
  75. df = load_log_to_df('../user_bet.log')
  76. # parse_by_user_hour_bet()
  77. parse_by_user_activity_time_wide()