2013-12-18 26 views
2

我試圖在使用knn迴歸模型時應用我自己的自定義距離度量函數。 我的數據集是名義,有序,數字和二進制類型的字段如何使用KNeighboursRegressor的自定義距離度量?

代碼的混合物:

def cus_distance(array1, array2, **kwargs): 
    # calculate the distance, return a float 
    pass 

knn = neighbors.KNeighborsRegressor(weights='distance', metric=cus_distance) 

# train_data is a pandas dataframe obj 
knn.fit(train_data.ix[:, fields_list], train_data['time_costs']) 

最後一行將導致異常:

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-284-04520b227b8a> in <module>() 
----> 1 knn.fit(train_data.ix[:, fields_list], train_data['time_costs']) 

/usr/local/lib/python2.7/dist-packages/sklearn/neighbors/base.pyc in fit(self, X, y) 
    587    X, y = check_arrays(X, y, sparse_format="csr") 
    588   self._y = y 
--> 589   return self._fit(X) 
    590 
    591 

/usr/local/lib/python2.7/dist-packages/sklearn/neighbors/base.pyc in _fit(self, X) 
    214    self._tree = BallTree(X, self.leaf_size, 
    215         metric=self.effective_metric_, 
--> 216         **self.effective_metric_kwds_) 
    217   elif self._fit_method == 'kd_tree': 
    218    self._tree = KDTree(X, self.leaf_size, 

/usr/local/lib/python2.7/dist-packages/sklearn/neighbors/ball_tree.so in sklearn.neighbors.ball_tree.BinaryTree.__init__ (sklearn/neighbors/ball_tree.c:7983)() 

/usr/local/lib/python2.7/dist-packages/numpy/core/numeric.pyc in asarray(a, dtype, order) 
    318 
    319  """ 
--> 320  return array(a, dtype, copy=False, order=order) 
    321 
    322 def asanyarray(a, dtype=None, order=None): 

ValueError: could not convert string to float: Unknown 

我知道這個錯誤導致通過字符串值('未知'是其中之一)在我的數據集。
這讓我困惑,在我的理解中,函數cus_distance應該處理這些str值,而KNeighborsRegressor只是使用函數的返回值。

問:
*這是在KNN迴歸中使用自定義定義距離度量的正確方法嗎?
*如果是這樣,爲什麼我遇到這個異常?
*如果不是,那麼正確的方法是什麼?

+0

那麼,如果你點擊「未知」,它會返回什麼? –

+0

@IvoFlipse這個「it」是指函數cus_distance嗎? – simomo

+0

是的,那就是我所指的。但似乎@jakevdp已經提供了答案 –

回答

4

無論使用哪種度量標準,球樹和KD樹都需要浮點數據。如果你的數據不能轉換爲浮點數,那麼你會得到這樣的錯誤。

>>> import numpy as np 
>>> data = [1, "Unknown", 2] 
>>> np.asarray(data, dtype=float) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
----> 1 np.asarray(data, dtype=float) 

ValueError: could not convert string to float: Unknown 
1

謝謝@jakevdp。
的scikit學習支持蠻力,球樹和KD樹,並根據@jakevdp的答案,我唯一可以用的是蠻力algorighm,所以我的代碼更改爲:

knn = neighbors.KNeighborsRegressor(weights='distance', metric=cus_distance, algorithm='brute') 
knn.fit(train_data.ix[:, fields_list], train_data['time_costs']) 

這時間它不會再提出錯誤,謝謝jakevdp!

但是新的問題來了,當我嘗試使用此KNN對象:

knn.predict(check_data.ix[:, fields_list]) 

這會導致同樣的錯誤在我的問題。所以我期待到scikit學習的源代碼,發現this line原因這個錯誤:

elif callable(metric): 
    # Check matrices first (this is usually done by the metric). 
    X, Y = check_pairwise_arrays(X, Y) 
    n_x, n_y = X.shape[0], Y.shape[0] 

功能check_pairwise_arrays將嘗試轉換所有值浮動,「未知」再次導致錯誤。

我認爲這是一種錯誤,因爲scikit的內置度量標準不支持混合類型的數據集,我寫了一個客戶度量函數,但是這條線仍然強制數據集爲純浮點類型。
而作爲這條線以上的評論稱,檢查工作應該由客戶指標來完成,所以我只是評論這條線,重新加載這個模塊,我的KNN對象可以完美地工作現在:)

PS:我正在努力將這一改變推向scikit-learn官方github回購。

+0

這不是一個錯誤。這確保了在許多設置中的正確行爲。 sklearn不支持使用熊貓數據框。我認爲爲自己的設置編寫自己的KNN應該相當簡單。 –

相關問題