Python 如何从数据集中消除类似行?
我有一个大约90k个样本和140个属性的数据集。在将数据集拆分为测试集和训练集之后,我尝试构建xgboost模型。我得到了一个非常高的准确率约99%,我认为是容易出错。我从测试集中采集了前100个样本,并找到了火车组中所有样本的欧利德距离。我发现列车组中有许多行的值几乎相同。现在,我希望从训练集中删除这些行。我如何完成这项任务?是否有一些库函数可以执行此操作?(查找成对欧几里德距离并将行置于阈值以下)请帮助。对前100行进行测试是可以的,如何对整个测试集进行测试?有什么有效的方法吗?您可以使用scikit学习来计算成对差异,以便在您的训练集中找到类似的值Python 如何从数据集中消除类似行?,python,pandas,numpy,scikit-learn,data-analysis,Python,Pandas,Numpy,Scikit Learn,Data Analysis,我有一个大约90k个样本和140个属性的数据集。在将数据集拆分为测试集和训练集之后,我尝试构建xgboost模型。我得到了一个非常高的准确率约99%,我认为是容易出错。我从测试集中采集了前100个样本,并找到了火车组中所有样本的欧利德距离。我发现列车组中有许多行的值几乎相同。现在,我希望从训练集中删除这些行。我如何完成这项任务?是否有一些库函数可以执行此操作?(查找成对欧几里德距离并将行置于阈值以下)请帮助。对前100行进行测试是可以的,如何对整个测试集进行测试?有什么有效的方法吗?您可以使用s
- 一旦有了2d距离数组,就可以依靠numpy消除行与自身比较时的0距离
- 然后简单地定义一个阈值并创建一个布尔数组来识别那些低于阈值的值
- 要获取
值的索引,请使用返回y和x索引True
- 现在,压缩y和x索引,并使用集合理解和排序来删除重复项(如[0,5]和[5,0])
import pandas as pd
import numpy as np
from sklearn import metrics
# setup dummy data
df = pd.DataFrame(np.random.random(size=(30, 5)))
print(df.head)
0 1 2 3 4
0 0.778678 0.041665 0.149135 0.171045 0.522252
1 0.993003 0.503661 0.799485 0.279497 0.735382
2 0.153082 0.897404 0.279562 0.561585 0.213728
3 0.376735 0.445812 0.931879 0.450042 0.154132
4 0.517949 0.779655 0.486816 0.785099 0.194537
# get distances
distances = metrics.pairwise.euclidean_distances(df)
# set self-distances to NaN
np.fill_diagonal(distances, np.NaN)
# define threshold
threshold = 0.3
# get indices
y_index, x_index = np.where(distances < threshold)
# get unique indices
close_indices = {tuple(sorted(x)) for x in zip(y_index, x_index)}
print(close_indices)
>>> {(0, 26), (1, 10), (4, 12), (10, 18), (12, 14), (13, 27)}
result
是一个生成器表达式。你通常可以绕着它转一圈。要显示结果,可以使用打印(列表(结果))
。您可以在迭代行块而不是只迭代一行时提高性能。我希望您正在为现有的数据点创建数据帧。你可以简单地通过:df.drop_duplicates(cols='A',take_last=True)@SijanBhandari-True过滤掉它,我已经做到了。但该函数会删除精确匹配和不相似匹配。考虑和几乎是相似的,我想放弃其中一个。我猜drop_duplicates()不会这样做:-)按欧几里德距离排序,然后保持最大的x
%?确定距离阈值,屏蔽不超过阈值的数据。上述方法是一个很酷的想法。但当我在数据集上调用欧几里德距离时,我得到了一个内存错误。@NiranjanAgnihotri更新了答案。太好了!我们有没有办法把这个操作并行化?sklearn中有这样的功能吗?@NiranjanAgnihotri请自己看看,或者打开一个新问题,因为这本身就是一个不同的主题。
def iterate_distances(sub_df, threshold):
def compute(sub_row):
distances = metrics.pairwise.euclidean_distances(sub_df.iloc[sub_row, :].values.reshape(1, -1),
sub_df.iloc[sub_row + 1:, :])
y_index, x_index = np.where(distances < threshold)
return ((sub_row, x + sub_row + 1) for x in x_index)
row_count = sub_df.shape[0]
return (index_pair
for row in range(row_count-1)
for index_pair in compute(row))
result = iterate_distances(df, threshold)