2017-08-11 83 views
2

我正在谷歌雲平臺ml引擎上的sklearn實現一個簡單的k最近鄰算法。我使用自定義度量來計算兩個輸入向量之間的距離,以便距離是兩個向量之間的元素平方差中元素的加權和。該代碼是下面:真的與這種numpy形狀不匹配錯誤相混淆

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)和valid_dataset的numpy的陣列具有形狀(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誰能解釋一下什麼是錯在這裏?

+0

'重量'的形狀是什麼?此外,我不熟悉KNeighborRegressor函數,但您在哪裏指定x和y是什麼? – BenT

+0

weight是一個長度爲13的列表。我將自定義度量函數mydist放入KNeighborsRegressor的實例化中的度量參數中。 –

回答

0

您正在考慮錯誤條款之間的距離。你不能把標籤和火車功能之間的距離。這些是兩個不同的方面。您需要計算任意兩個特徵點之間的距離,比如x1和x2,,而不是標籤和它的特徵點(比如x1和y1)之間的距離。其次,在聲明KNeighborsRegressor對象時,您指定了錯誤的參數。在'metric'參數中,您指定'string'或'DistanceMetric'對象。 首先,您必須製作一個距離度量對象,然後將其作爲度量標準傳遞。所以,這是你的調用函數的正確方法:

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

Sklearn本身將採取的參數是如何在距離函數傳遞關懷。我假設權重變量是全局的,您的代碼才能正常運行。

+0

那麼,我應該如何修改我的自定義度量函數以計算兩個輸入x1,x2之間的加權元素平方差? –

+0

我認爲您的自定義指標定義是正確的。您只需要將其變成如上所示的示例的DistanceMetric對象,並將其傳遞到KNeighborsRegressor對象。 –

+0

感謝您的幫助! –