在R中进行K-Means聚类出现错误

3

我有一个在R中创建的数据集,其结构如下:

> head(btc_data)
           Date btc_close eth_close vix_close gold_close DEXCHUS change
1647 2010-07-18      0.09        NA        NA         NA      NA      0
1648 2010-07-19      0.08        NA     25.97    115.730      NA     -1
1649 2010-07-20      0.07        NA     23.93    116.650      NA     -1
1650 2010-07-21      0.08        NA     25.64    115.850      NA      1
1651 2010-07-22      0.05        NA     24.63    116.863      NA     -1
1652 2010-07-23      0.06        NA     23.47    116.090      NA      1

我正在尝试使用k-means对观测值进行聚类。然而,我收到了以下错误信息:
> km <- kmeans(trainingDS, 3)
Error in do_one(nmeth) : NA/NaN/Inf in foreign function call (arg 1)
In addition: Warning message:
In storage.mode(x) <- "double" : NAs introduced by coercion 

这是什么意思?我是否在错误地预处理数据? 我该怎么办才能解决这个问题? 我不能删除NA,因为在4500次初始观测中,如果我运行complete cases,我只剩下100次观测。
基本上,我希望基于具有-1、0、1值的change列形成3个聚类。 然后,我希望分析每个聚类的组件,以找出变化最强的预测因子。 哪些其他算法对此最有用?
我还尝试使用以下代码删除所有NA值,但仍然收到相同的错误消息:
> complete_cases <- btc_data[complete.cases(btc_data), ]
> km <- kmeans(complete_cases, 3, nstart = 20)
Error in do_one(nmeth) : NA/NaN/Inf in foreign function call (arg 1)
In addition: Warning message:
In storage.mode(x) <- "double" : NAs introduced by coercion

> sum(!sapply(btc_data, is.finite)) 
[1] 8008
> sum(sapply(btc_data, is.nan))
[1] 0
> 
> sum(!sapply(complete_cases, is.finite)) 
[1] 0
> sum(sapply(complete_cases, is.nan))
[1] 0

以下是数据格式:

> sapply(btc_data, class)
      Date  btc_close  eth_close  vix_close gold_close    DEXCHUS     change 
    "Date"  "numeric"  "numeric"  "numeric"  "numeric"  "numeric"   "factor" 

`> sum(!sapply(btc_data, is.finite)) [1] 8008
sum(!sapply(btc_data, is.nan)) [1] 18193`
- zsad512
@coffeinjunky 我编辑了问题...另外,我不知道为什么完整案例的sum721,特别是因为只有103个观察值...当我手动检查df时,没有NA。 - zsad512
好的,我去掉了 ! 并编辑了问题...你的意思是 knn 应该在 complete_cases 上工作,但我仍然收到相同的错误消息。 - zsad512
好的,我已经添加了那个信息。 - zsad512
1
很好。在这种情况下,日期列很可能是罪魁祸首。 - coffeinjunky
3个回答

3

出现此错误消息的原因有很多,尤其是在存在无效数据类型(NA、NaN、Inf)或日期时。让我们逐个了解:

但首先,让我们检查它是否适用于mtcars数据集,因为我将使用它:

kmeans(mtcars, 3)
K-means clustering with 3 clusters of sizes 9, 7, 16
--- lengthy output omitted

Likely problem 1: invalid data types: NA/NaN/Inf

df <- mtcars
df[1,1] <- NA
kmeans(df, 3)
Error in do_one(nmeth) : NA/NaN/Inf in foreign function call (arg 1)

df[1,1] <- Inf
kmeans(df, 3)
Error in do_one(nmeth) : NA/NaN/Inf in foreign function call (arg 1)

df[1,1] <- NaN
kmeans(df, 3)
Error in do_one(nmeth) : NA/NaN/Inf in foreign function call (arg 1)

您可以使用以下方式检查这些值:

df[1:3,1] <- c(NA, Inf, NaN) # one NA, one Inf, one NaN
sum(sapply(df, is.na))
[1] 2
sum(sapply(df, is.infinite))
[1] 1
sum(sapply(df, is.nan))
[1] 1

为了消除这些问题,我们可以删除相应的观察结果。但请注意,complete.cases 不会删除 Inf
complete_df <- df[complete.cases(df),]
sum(sapply(complete_df, is.infinite))
[1] 1

相反,使用例如。
df[apply(sapply(df, is.finite), 1, all),]

你可以重新分配这些值或填充它们,但这是一个完全不同的过程。
可能的问题二:日期:请参见以下内容:
library(lubridate)
df <- mtcars
df$date <- seq.Date(from=ymd("1990-01-01"), length.out = nrow(df), by=1)
kmeans(df, 3)
Error in do_one(nmeth) : NA/NaN/Inf in foreign function call (arg 1)
In addition: Warning message:
In kmeans(df, 3) : NAs introduced by coercion

您可以通过排除日期或将日期转换为其他形式来解决此问题,例如。
df$newdate <- seq_along(df$date)
df$date <- NULL
kmeans(df, 3)
K-means clustering with 3 clusters of sizes 9, 7, 16
---- lengthy output omitted

或者您可以在将其传递给 kmeans 之前自己尝试将日期强制转换为数字:

df <- mtcars
df$date <- seq.Date(from=ymd("1990-01-01"), length.out = nrow(df), by=1)
df$date <- as.numeric(df$date)
kmeans(df, 3)
K-means clustering with 3 clusters of sizes 9, 16, 7
--- lengthy output omitted

我明白,但有两个问题 - 当我删除NA时,数据太小了。更重要的是,我运行了complete_cases,然后进行了knn,但仍然出现相同的错误。 - zsad512
如果你没有足够的数据,我们真的无法提供太多帮助。唯一可以尝试的是输入数据而不是删除它。关于你的第二个问题,我无法发表评论,因为你没有发布那段代码或错误信息。 - coffeinjunky

2

检查您正在聚类的变量的数据类型。如果数据类型为非数字,则很可能会出现错误。在聚类之前,请确保正确处理日期格式。


那并没有为一年前已有且被接受的答案增加任何内容。 - Roland Weber

0
你在聚类中使用了“日期”列吗?
在使用k-means聚类时,应该使用数值类型的数据。
可以尝试这样做:

btc_data$Date = as.numeric(gsub("-", "", as.character(btc_data$Date)))


不需要使用 gsub/as.character,只需使用 as.numeric(btc_data$Date) 即可。 - Rui Barradas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接