这在一定程度上取决于您到底想做什么。
-
忽略所有带有空值的列:我想这不是您要问的,因为这更多是数据预处理步骤,并不是 sklearn 真正独有的。即使在纯 Python 中,也只需搜索包含空值的列索引,然后构造一个过滤掉这些索引的新数据集。
-
在向量比较中忽略空值:这实际上很有趣。本质上,您是在说
[1, 2, 3, 4, None, 6] 和[1, None, 3, 4, 5, 6] 之间的距离是sqrt(1*1 + 3*3 + 4*4 + 6*6)。在这种情况下,您需要某种 sklearn 支持的自定义指标。不幸的是,您无法在 KNN fit() 方法中输入空值,因此即使使用自定义指标,您也无法完全得到您想要的。解决方案是预先计算距离。例如:
from math import sqrt, isfinite
X_train = [
[1, 2, 3, 4, None, 6],
[1, None, 3, 4, 5, 6],
]
y_train = [3.14, 2.72] # we're regressing something
def euclidean(p, q):
# Could also use numpy routines
return sqrt(sum((x-y)**2 for x,y in zip(p,q)))
def is_num(x):
# The `is not None` check needs to happen first because of short-circuiting
return x is not None and isfinite(x)
def restricted_points(p, q):
# Returns copies of `p` and `q` except at coordinates where either vector
# is None, inf, or nan
return tuple(zip(*[(x,y) for x,y in zip(p,q) if all(map(is_num, (x,y)))]))
def dist(p, q):
# Note that in this form you can use any metric you like on the
# restricted vectors, not just the euclidean metric
return euclidean(*restricted_points(p, q))
dists = [[dist(p,q) for p in X_train] for q in X_train]
knn = KNeighborsRegressor(
n_neighbors=1, # only needed in our test example since we have so few data points
metric='precomputed'
)
knn.fit(dists, y_train)
X_test = [
[1, 2, 3, None, None, 6],
]
# We tell sklearn which points in the knn graph to use by telling it how far
# our queries are from every input. This is super inefficient.
predictions = knn.predict([[dist(q, p) for p in X_train] for q in X_test])
如果您要回归的输出中有空值,仍然存在一个悬而未决的问题,但您的问题陈述并没有让人觉得这对您来说是个问题。