You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

理解数据泄露:如何通过利用测试数据获取满分?

我最近读了一篇关于数据泄露的文章,里面讲的黑客松场景里的玩法挺有意思的——明明不用看训练数据,居然能靠泄露点在测试集拿满分,但一开始我完全没搞懂核心逻辑。下面把文章里的步骤拆解给你看:

加载测试数据

注意哦,这里没有训练数据,只有测试数据,而且我们甚至不需要用到测试对象的任何特征,只需要那个用来对比的索引对文件就行。先加载测试索引数据:

test = pd.read_csv('../test_pairs.csv')
test.head(10)

输出的前10条数据是这样的:

pairIdFirstIdSecondId
014278053
1170447681
21923720966
3800520765
416837599
5365712504
628367582
761366111
8232959817
966217672

执行test.shape[0]得到的结果是368550,也就是说总共有368550个待判断的样本对。

你可以把测试数据集想象成一个图像集合,每个图像都分配了唯一的Id(从0到N-1,N是图像总数)。上面这个数据框里的FirstId和SecondId就是指向这些图像Id的,我们的任务很简单:判断每一对图像是不是属于同一类别——是就预测1,否则预测0。这里不用关心图像本身或者具体的对比逻辑,只要知道这是个二分类任务就行。

再看看参与配对的图像数量:

print(test['FirstId'].nunique())
print(test['SecondId'].nunique())

输出结果是:

26325
26310

可见待分类的样本对数量(36万+)远少于所有可能的图像对总数。

要利用这个泄露点,首先得假设(或者能证明)测试集里的正样本对(也就是同类的图像对)总数远少于总样本对。举两个直观的例子:

  • 比如一个有1000个类别、每个类别N张图像的数据集,正样本对的数量是1000*N*(N-1)/2,而所有可能的图像对总数是1000*N*(1000N-1)/2,正样本占比极低。
  • 还有Quora竞赛的例子:任务是判断问题对是不是重复项,所有可能的问题对数量极大,但真正的重复项(正样本对)少得可怜。

文章里还做了个小实验:提交全1的预测,看看准确率。代码是这样的:

test['Prediction'] = np.ones(test.shape[0])
sub=pd.DataFrame(test[['pairId','Prediction']])
sub.to_csv('sub.csv',index=False)

结果是:All ones have accuracy score is 0.500000.

这说明测试集根本不是随机采样的,而是用了特定的采样算法,把类别1的样本过采样了——不然全1的准确率应该远低于0.5才对。那怎么利用这个泄露点呢?文章里用了「魔法特征」来解决:

构建魔法特征

关联矩阵

首先要构建一个关联矩阵:我们可以把每个(FirstId, SecondId)看作无向图里的一条边,关联矩阵的大小是(maxId+1, maxId+1),每行(每列)i对应第i个图像Id。如果(i,j)或者(j,i)在给定的样本对里,那矩阵的[i,j]位置就设为1,其他位置都是0。

要注意的是,这个关联矩阵通常是极度稀疏的,根本没法用密集格式存储,得用稀疏矩阵来表示。可以用scipy里的sparse.coo_matrix((data, (i,j)))来构建,当然你也可以用循环来实现。


内容的提问来源于stack exchange,提问作者shan

火山引擎 最新活动