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

为何radius_neighbors误将shape(1,188)的输入判定为1D数组?

解决sklearn radius_neighbors维度不匹配问题

问题详情

  • 调用sklearn.neighbors.NearestNeighbors.radius_neighbors时触发ValueError,提示期望2D数组却得到1D数组,但查询向量是通过df.loc[[index], :]获取的,理论上形状应为(1,188)的2D数组
  • 环境版本:sklearn 1.6.1,pandas 2.2.2;目标DataFrame是合并后的透视表,df.values形状为(2891,188)
  • 调试尝试:
    • 使用numpy.expand_dims扩展维度会触发3D数组错误
    • 将查询向量的values重塑为(-1,1)可消除维度错误,但出现特征数不匹配(期望188个特征,实际仅1个)

问题原因

核心问题出在自定义距离函数的维度处理上:
sklearn的NearestNeighbors在使用自定义metric时,会对单个查询样本自动降维——当传入(1, n)的2D查询数组时,自定义函数会收到1D的数组参数,但你调用的cosine_distances要求输入必须是2D数组,这就导致内部维度不匹配,最终向外抛出维度错误。

解决方案

修改自定义距离函数,通过np.atleast_2d()确保输入参数始终为2D数组,适配cosine_distances的要求。

修改后的可运行代码

from pandas import DataFrame as df
import numpy as np
from sklearn.neighbors import NearestNeighbors as nrb
from pandas import pivot_table
from sklearn.metrics.pairwise import cosine_distances 

dummy_df = df({"no": [9, 0], "T": ["ex1", "ex2"]})
dummy_df2 = df({"no": [9, 0], "vec": [3, 4]})
merger = dummy_df.merge(dummy_df2, on="no")

mat_sim = merger.pivot_table(index="T", values="vec")

# 修改自定义距离函数,确保输入为2D数组
def dum_cusmet(x, x2):
    x_2d = np.atleast_2d(x)
    x2_2d = np.atleast_2d(x2)
    return cosine_distances(x_2d, x2_2d)[0][0]

model = nrb(n_neighbors=5, metric=dum_cusmet, algorithm="brute")
model.fit(mat_sim)

# 修正原示例的索引错误(mat_sim实际索引为ex1、ex2)
loc = mat_sim.loc[["ex1"], :].values
rng = model.radius_neighbors(loc, radius=0.5)
print(rng)

额外说明

  • 修正了原最小复现代码中的索引错误(原代码使用不存在的["im tired"]索引)
  • 修改后的函数会自动处理1D/2D输入,既适配sklearn的参数传递逻辑,又满足cosine_distances的输入要求

内容的提问来源于stack exchange,提问作者Fia Shofia Zahra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 02:33:12