【问题标题】:Really confused with this numpy shape mismatch error真的对这个 numpy 形状不匹配错误感到困惑
【发布时间】:2018-01-19 11:21:03
【问题描述】:

我在谷歌云平台 ml 引擎上实现了一个来自 sklearn 的简单 k-最近邻算法。我使用自定义度量来计算两个输入向量之间的距离,以便距离是两个向量之间的元素平方差中元素的加权和。代码如下:

import os.path
from sklearn import neighbors
import numpy as np
from six.moves import cPickle as pickle
import tensorflow as tf
from tensorflow.python.lib.io import file_io

flags = tf.app.flags
FLAGS = flags.FLAGS
flags.DEFINE_string('input_dir', 'input', 'Input Directory.')
flags.DEFINE_string('input_train_data','train_data','Input Training Data File Name.')
pickle_file = os.path.join(FLAGS.input_dir, FLAGS.input_train_data)

def mydist(x, y):
    return np.dot((x - y) ** 2, weight)

with file_io.FileIO(pickle_file, 'r') as f:
    save = pickle.load(f)
    train_dataset, train_labels, valid_dataset, valid_labels = save['train_dataset'], save['train_labels'], save[
        'valid_dataset'], save['valid_labels']

train_data = train_dataset[:1000]
train_label = train_labels[:1000]
test_data = valid_dataset[:100]
weight = [1.0]* len(train_dataset[1])
knn = neighbors.KNeighborsRegressor(weights='distance', n_neighbors=20, metric=lambda x, y: mydist(x, y))
knn.fit(train_data, train_label)
predict = knn.predict(test_data)
print(predict)

train_dataset 是一个形状为 (86667,13) 的 numpy 数组,valid_dataset 的形状为 (8000,13)。 Train_labels 具有形状 (86667,1) 和 valid_labels (8000,1)。由于某种原因,我得到了尺寸不匹配:

line 15, in mydist return np.dot((x - y) ** 2, weight) ValueError: shapes 
(10,) and (13,) not aligned: 10 (dim 0) != 13 (dim 0)

自定义指标输入中的 x 和 y 的大小都应该是 13,但不知何故它们的大小是 10。谁能解释这里出了什么问题?

【问题讨论】:

  • “重量”的形状是什么?另外我不熟悉 KNeighborRegressor 函数,但是你在哪里指定 x 和 y 是什么?
  • weight 是一个长度为 13 的列表。我将自定义度量函数 mydist 放在 KNeighborsRegressor 实例化的 metric 参数中。

标签: python numpy scikit-learn


【解决方案1】:

您在错误的术语之间拉开距离。您不能计算标签和火车特征之间的距离。这是两个不同的维度。您需要计算任意两个特征点之间的距离,例如 x1 和 x2,不是标签与其特征点之间的距离(例如 x1 和 y1)。其次,在声明 KNeighborsRegressor 对象时,您错误地指定了参数。在“度量”参数中,您指定“字符串”或“距离度量”对象。 首先您必须创建一个距离度量对象,然后将其作为度量传递。所以,这是调用函数的正确方法:

my_metric=DistanceMetric.get_metric('myfunc',func=mydist)
knn = neighbors.KNeighborsRegressor(weights='distance', n_neighbors=20, metric='myfunc')

Sklearn 会自己处理参数在距离函数中的传递方式。我假设 weights 变量是全局变量,您的代码才能正常运行。

【讨论】:

  • 那么我应该如何修改我的自定义度量函数以计算两个输入 x1、x2 之间的加权元素平方差?
  • 我认为您的自定义指标定义是正确的。您只需将其更改为如上例所示的 DistanceMetric 对象,并将其传递给 KNeighborsRegressor 对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-29
  • 2013-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 1970-01-01
相关资源
最近更新 更多