0

KNeighborClassifierに数値以外のデータを訓練しようとしていますが、サンプル間の類似度を計算できるカスタムメトリックを提供しています。数値以外のデータを持つKNeighborClassifierは失敗します

from sklearn.neighbors import KNeighborsClassifier 

#Compute the "ASCII" distance: 
def my_metric(a,b): 
    return ord(a)-ord(b) 

#Samples and labels 
X = [["a"],["b"], ["c"],["m"], ["z"]] 

#S=Start of the alphabet, M=Middle, E=end 
y = ["S", "S", "S", "M", "E"] 

model = KNeighborsClassifier(metric=my_metric) 
model.fit(X,y) 

X_test = [["e"],["f"],["w"]] 
y_test = [["S"],["M"],["E"]] 
model.score(X_test, y_test) 

私は次のエラーを取得する:

Traceback (most recent call last): 
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/IPython/core/interactiveshell.py", line 2862, in run_code 
    exec(code_obj, self.user_global_ns, self.user_ns) 
File "<ipython-input-20-e339c96eea22>", line 1, in <module> 
    model.score(X_test, y_test) 
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/base.py", line 350, in score 
    return accuracy_score(y, self.predict(X), sample_weight=sample_weight) 
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/neighbors/classification.py", line 145, in predict 
    neigh_dist, neigh_ind = self.kneighbors(X) 
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/neighbors/base.py", line 361, in kneighbors 
    **self.effective_metric_params_) 
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/metrics/pairwise.py", line 1247, in pairwise_distances 
    return _parallel_pairwise(X, Y, func, n_jobs, **kwds) 
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/metrics/pairwise.py", line 1090, in _parallel_pairwise 
    return func(X, Y, **kwds) 
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/metrics/pairwise.py", line 1104, in _pairwise_callable 
    X, Y = check_pairwise_arrays(X, Y) 
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/metrics/pairwise.py", line 110, in check_pairwise_arrays 
    warn_on_dtype=warn_on_dtype, estimator=estimator) 
File "/home/marcofavorito/virtualenvs/nlp/lib/python3.5/site-packages/sklearn/utils/validation.py", line 402, in check_array 
    array = np.array(array, dtype=dtype, order=order, copy=copy) 
ValueError: could not convert string to float: 'e' 

私はしかしsklearn分類器のすべての機能なしで、非常に簡単なアルゴリズムを実装することができますね。私はいくつかのオプションが欠けている?あるいは、サンプルを浮動小数点に変換する前にモデルを訓練することはできません。

N.B.私はこの問題が文字の代わりに数字を入れることで簡単に解決できることを知っています。しかし、数値以外のデータを処理する別の問題を解決する必要があります。また、以前にも述べたように、浮動小数点への単純なマッピングが見つからない場合があります。

答えて

1

コードにいくつかの誤りがあります。まず、カテゴリデータを何らかの形で数値データに変換しなければならないということです。 SklearnのKNN分類器は、カテゴリデータをまだサポートしていません。次に、カスタムメトリックを使用するには、sklearnでmake_Scorer()関数を使用する必要があります。 KNNのデフォルトscore関数は、指定したメトリックではなく平均精度を返します。あなたはそれについての詳細を読むことができますhere。 KNN ClassifierのこのSklearn実装を使用するには、あなたのデータセットを変更する必要があります。

2

モハメッドが既に言及しているものの他に:あなたのアプローチは数学的に欠陥がありますとsklearnはおそらく何が起こるか保証しません。

KNNクラシファイアは、KD-treesBall-treesのようなコアデータ構造の単なるラッパーです。 Here you can see what kind of assumptions those need

Here func is a function which takes two one-dimensional numpy arrays, and returns a distance. Note that in order to be used within the BallTree, the distance must be a true metric: i.e. it must satisfy the following properties

Non-negativity: d(x, y) >= 0

Identity: d(x, y) = 0 if and only if x == y

Symmetry: d(x, y) = d(y, x)

Triangle Inequality: d(x, y) + d(y, z) >= d(x, z)

公正であること。 That's just what a metric is

このように記載されているメトリックは実際のメトリックではありません。

ここでは、ボールツリー(KDツリーではない)に関する警告のみが表示され、KNNはその下にあるツリー構造を選択しています

これらの前提がKDツリーにも必要なのかどうかはわかりませんが、私はyesとjust pointがkd-trees docsになると思いますというメトリックと利用可能なkd_tree.valid_metricsを使用しています(ただし、このリストはsklearnに付属の共通メトリックの一部です)。

+0

私は1つを残していた重要なことを指摘する!この情報をありがとう。メトリックプロパティについて:) –

関連する問題