You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IP地址数据集单变量PDF计算与绘图异常问题排查

问题分析:IP数据集PDF计算与绘图异常排查

我有两个各包含10k个整数编码IP地址的数据集,一个是真实网络捕获数据,另一个是AI生成的合成数据。为对比二者分布差异,我尝试计算单变量概率密度函数(PDF),但计算和绘图过程中出现异常。


用户原始代码

数据预处理代码

import numpy as np
import pandas as pd

q=np.array(real_data_1m.srcip) 
p=np.array(syn_data_1m.srcip)

#get all possible discrete events from p and q
px=np.array(list(set(p))) #use set here to remove duplicates
qx=np.array(list(set(q))) #use set here to remove duplicates

#concatenate px and qx
mx=np.concatenate([px,qx])

mx.sort() #sort them, as they are anyway integers
mx=np.array(list(set(mx))) #remove duplicates by creating a set
#mx.reshape((len(mx),1)) #reshape from 1D to nD, where n=len(mx)

概率分布计算函数

def create_prob_dist(data: np.array, sample_space: np.array):
  #number of all events
  sum_of_events = sample_space.size
  #get the counts of each event via pandas.crosstab()
  data_counts = pd.crosstab(index='counts', columns=data)
  
  #create probabilities for each event
  prob_dist=dict()

  for i in sample_space:
    if i in data_counts:
      prob_dist[i]=(data_counts[i]['counts'])/sum_of_events
    else: 
      prob_dist[i]=0

  return prob_dist

绘图代码

#create true PDFs of p and q using mx
p_pdf=create_prob_dist(p, mx)
q_pdf=create_prob_dist(q, mx)

#get the probability values only from the dictionary
p_pdf=np.array(list(p_pdf.values())) #already sorted according to mx
q_pdf=np.array(list(q_pdf.values())) #already sorted according to mx

plt.figure()
plt.plot(mx, q_pdf, 'g', label="Q")
plt.plot(mx, p_pdf, 'r', label="P")
plt.legend(loc="upper right")
plt.show()

核心问题分析

  1. 概率计算逻辑错误:
    • 用sample_space.size(所有唯一IP的数量)作为分母计算概率是错误的。离散概率的正确计算方式是每个IP的出现次数 / 数据集总样本数(即10k),错误的分母会导致概率值被严重缩放,完全偏离真实分布。
  2. pd.crosstab使用不当:
    • pd.crosstab(index='counts', columns=data)生成的DataFrame结构不符合预期,后续索引查找容易出错。更高效可靠的方式是用np.unique(data, return_counts=True)直接获取唯一值和对应计数。
  3. 绘图方式不匹配离散IP分布:
    • IP是离散且跨度极大的整数,用plt.plot绘制折线图时,大量零概率IP会导致图像出现密集的垂直跳跃线,无法直观展示分布特征。

修正后的代码实现

1. 修正概率计算函数

def create_prob_dist(data: np.array):
    # 获取唯一IP及对应出现次数
    unique_ips, counts = np.unique(data, return_counts=True)
    # 计算真实概率:次数 / 总样本数
    probs = counts / len(data)
    return dict(zip(unique_ips, probs))

2. 生成对齐的概率数组(用于绘图)

# 获取所有唯一IP的联合样本空间并排序
all_ips = np.sort(np.unique(np.concatenate([p, q])))

# 生成真实数据的概率数组(缺失IP补0)
q_probs = np.array([create_prob_dist(q).get(ip, 0) for ip in all_ips])
# 生成合成数据的概率数组(缺失IP补0)
p_probs = np.array([create_prob_dist(p).get(ip, 0) for ip in all_ips])

3. 更合适的绘图方式

方式一:直方图(直观展示频率分布)
import matplotlib.pyplot as plt

plt.figure(figsize=(12, 6))
# 真实数据直方图(density=True转为概率密度)
plt.hist(q, bins=50, alpha=0.5, label="真实数据", density=True)
# 合成数据直方图
plt.hist(p, bins=50, alpha=0.5, label="合成数据", density=True)
plt.xlabel("整数编码IP")
plt.ylabel("概率密度")
plt.legend()
plt.show()
方式二:核密度估计(KDE,平滑展示分布趋势)
from scipy.stats import gaussian_kde

plt.figure(figsize=(12, 6))
# 真实数据KDE曲线
kde_q = gaussian_kde(q)
xvals = np.linspace(min(all_ips), max(all_ips), 1000)
plt.plot(xvals, kde_q(xvals), 'g', label="真实数据")

# 合成数据KDE曲线
kde_p = gaussian_kde(p)
plt.plot(xvals, kde_p(xvals), 'r', label="合成数据")

plt.xlabel("整数编码IP")
plt.ylabel("概率密度")
plt.legend()
plt.show()

可选:离散PDF散点图(过滤零概率值)

如果坚持展示离散概率分布,需过滤掉零概率IP避免图像混乱:

# 过滤真实数据的非零概率IP
non_zero_mask_q = q_probs > 0
filtered_ips_q = all_ips[non_zero_mask_q]
filtered_probs_q = q_probs[non_zero_mask_q]

# 过滤合成数据的非零概率IP
non_zero_mask_p = p_probs > 0
filtered_ips_p = all_ips[non_zero_mask_p]
filtered_probs_p = p_probs[non_zero_mask_p]

plt.figure(figsize=(12, 6))
plt.scatter(filtered_ips_q, filtered_probs_q, c='g', label="真实数据", s=5)
plt.scatter(filtered_ips_p, filtered_probs_p, c='r', label="合成数据", s=5)
plt.xlabel("整数编码IP")
plt.ylabel("概率")
plt.legend()
plt.show()

内容的提问来源于stack exchange,提问作者cs.lev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 07:48:21