web-dev-qa-db-ja.com

knn関数のエラー

私はこの行を実行しようとします:

knn(mydades.training[,-7],mydades.test[,-7],mydades.training[,7],k=5)

しかし、私はいつもこのエラーを受け取ります:

Error in knn(mydades.training[, -7], mydades.test[, -7], mydades.training[,  : 
  NA/NaN/Inf in foreign function call (arg 6)
In addition: Warning messages:
1: In knn(mydades.training[, -7], mydades.test[, -7], mydades.training[,  :
  NAs introduced by coercion
2: In knn(mydades.training[, -7], mydades.test[, -7], mydades.training[,  :
  NAs introduced by coercion

何かアイデアはありますか?

PS:mydades.trainingとmydades.testは次のように定義されています:

N <- nrow(mydades) 
permut <- sample(c(1:N),N,replace=FALSE)
ord <- order(permut)
mydades.shuffled <- mydades[ord,]
prop.train <- 1/3
NOMBRE <- round(prop.train*N)
mydades.training <- mydades.shuffled[1:NOMBRE,]
mydades.test <- mydades.shuffled[(NOMBRE+1):N,]
12
user2443456

あなたの問題は、「mydades」に非数値データフィールドがあることにあると思います。エラー行:

NA/NaN/Inf in foreign function call (arg 6)

c言語の実装へのknn関数の呼び出しが失敗したのではないかと疑いました。 Rの多くの関数は、実際にRだけでアルゴリズムを実装する代わりに、基礎となるより効率的なC実装を呼び出します。Rコンソールで「knn」だけを入力すると、「knn」のR実装を検査できます。次の行が存在します:

 Z <- .C(VR_knn, as.integer(k), as.integer(l), as.integer(ntr), 
        as.integer(nte), as.integer(p), as.double(train), as.integer(unclass(clf)), 
        as.double(test), res = integer(nte), pr = double(nte), 
        integer(nc + 1), as.integer(nc), as.integer(FALSE), as.integer(use.all))

ここで、.Cは、提供された関数引数を使用して「VR_knn」という名前のC関数を呼び出すことを意味します。エラーが2つあるため

NAs introduced by coercion

As.double/as.integer呼び出しの2つが失敗し、NA値が導入されると思います。パラメータのカウントを開始すると、6番目の引数は次のようになります。

as.double(train)

次のような場合に失敗する可能性があります。

# as.double can not translate text fields to doubles, they are coerced to NA-values:
> as.double("sometext")
[1] NA
Warning message:
NAs introduced by coercion
# while the following text is cast to double without an error:
> as.double("1.23")
[1] 1.23

おそらく「as.double(train)」と「as.double(test)」によって与えられる2つの強制エラーが発生します。 「mydades」の正確な詳細を提供していなかったので、ここに私の最良の推測(および人工多変量正規分布データ)の一部を示します。

library(MASS)
mydades <- mvrnorm(100, mu=c(1:6), Sigma=matrix(1:36, ncol=6))
mydades <- cbind(mydades, sample(LETTERS[1:5], 100, replace=TRUE))

# This breaks knn
mydades[3,4] <- Inf
# This breaks knn
mydades[4,3] <- -Inf
# These, however, do not introduce the coercion for NA-values error message

# This breaks knn and gives the same error; just some raw text
mydades[1,2] <- mydades[50,1] <- "foo"
mydades[100,3] <- "bar"

# ... or perhaps wrongly formatted exponential numbers?
mydades[1,1] <- "2.34EXP-05"

# ... or wrong decimal symbol?
mydades[3,3] <- "1,23" 
# should be 1.23, as R uses '.' as decimal symbol and not ','

# ... or most likely a whole column is non-numeric, since the error is given twice (as.double problem both in training AND test set)
mydades[,1] <- sample(letters[1:5],100,replace=TRUE)

数値データとクラスラベルの両方を1つの行列に保持しないでください。おそらく、次のようにデータを分割できます。

mydadesnumeric <- mydades[,1:6] # 6 first columns
mydadesclasses <- mydades[,7]

通話の使用

str(mydades); summary(mydades)

は、問題のあるデータエントリを見つけて数値エントリに修正したり、非数値フィールドを省略したりするのにも役立ちます。

提供された残りの実行コード(データを分割した後):

N <- nrow(mydades) 
permut <- sample(c(1:N),N,replace=FALSE)
ord <- order(permut)
mydades.shuffled <- mydades[ord,]
prop.train <- 1/3
NOMBRE <- round(prop.train*N)
mydades.training <- mydades.shuffled[1:NOMBRE,]
mydades.test <- mydades.shuffled[(NOMBRE+1):N,]

# 7th column seems to be the class labels
knn(train=mydades.training[,-7],test=mydades.test[,-7],mydades.training[,7],k=5)
20

素晴らしい回答by @ Teemu。

これはよく読まれている質問なので、分析の観点から同じ答えを出します。

KNN関数は、ポイント間のユークリッド距離を計算してデータポイントを分類します。これは数を必要とする数学的な計算です。したがって、KNNのすべての変数は数値に強制変換可能でなければなりません。

KNNのデータ準備には、多くの場合3つのタスクが含まれます。
(1)すべてのNAまたは ""値を修正します
(2)すべての因子を、因子の各レベルに1つずつ、ブール値のセットに変換します
(3)各変数の値を範囲0:1に正規化して、変数の範囲が距離測定に過度に大きな影響を与えないようにします。

11
SpiritusPrana

また、整数を使用すると関数が失敗するように見えることも指摘しておきます。 knn関数を呼び出す前に、すべてを「num」型に変換する必要がありました。これには、Rのほとんどのメソッドが因子型を使用するターゲット機能が含まれます。したがって、as.numeric(my_frame $ target_feature)が必要です。

0
Cybernetic