如何对大型数据库进行采样并在 R 中实现 K-means 和 K-nn?

Posted

技术标签:

【中文标题】如何对大型数据库进行采样并在 R 中实现 K-means 和 K-nn?【英文标题】:How to sample large database and implement K-means and K-nn in R? 【发布时间】:2012-11-20 06:35:42 【问题描述】:

我是 R 的新用户,正试图摆脱 SAS。我在这里问这个问题是因为我对所有可用于 R 的软件包和源代码感到有些沮丧,而且我似乎主要由于数据大小而无法使其正常工作。

我有以下几点:

本地 mysql 数据库中名为 SOURCE 的表,具有 200 个预测器特征和一个类变量。该表有 300 万条记录,大小为 3GB。每个类的实例数不相等。

我想:

    随机抽样 SOURCE 数据库以创建一个较小的数据集 每个类具有相同数量的实例。 将样本分成训练集和测试集。 在训练集上执行 k 均值聚类以确定每个类的 k 个质心。 使用质心对测试数据进行 k-NN 分类。

【问题讨论】:

欢迎来到!我建议你:RMysqlite 包来提取你的数据,sample 函数(base 包)进行采样! kmeans * 函数(base 包)! *knn 函数(包) 如何处理大数据?数据库的问题,预采样被保存在内存中。只有 4Gb 内存。 尝试使用db引擎执行随机选择:***.com/q/580639/269476. @entropy 你看过ff 包吗?数据类型ffdf 类似于data.frame,但存储在磁盘而不是内存中。 你的意思是'k-nn分类测试数据与质心'。这不是 k-nn 的常用工作方式,您通常只提供 k- 邻居数而不是类的质心。你在想一些 k-nn 的变体吗? 【参考方案1】:

我可以帮你解决两个问题。 1-分层抽样 2 拆分训练和测试(即校准验证)

        n = c(2.23, 3.5, 12,2, 93, 57, 0.2,
 33, 5,2, 305, 5.3,2, 3.9, 4) 
     s = c("aa", "bb", "aa","aa", "bb", "cc","aa", "bb",
 "bb","aa", "aa","aa","aa","bb", "cc") 
         id = c(1, 2, 3,4, 5, 6,7, 8, 9,
10, 11, 12,13, 14, 15) 
         df = data.frame(id, n, s )       # df is a data frame

        source("http://news.mrdwab.com/stratified")
        sample<- stratified(df=df, 
                            id=1, #ID of your dataframe, 
                            #if there isn't you have to create it
                            group=3, #the position of your predictor features
                            size=2, #cardinality of selection
                            seed="NULL") 

        #then add a new column to your selection 
        sample["cal_val"]<- 1

        #now, you have a random selection of group 3, 
        #but you need to split it for cal and val, so:

        sample2<- stratified(df=sample, #use your previous selection
                             id=1, 
                             group=3, #sample on the same group used previously
                             size=1,#half of the previous selection
                             seed="NULL")

        sample2["val"]<- 1
        #merge the two selection
        merge<- merge(sample, sample2, all.x=T, by="id")
        merge[is.na(merge)] <- 0 #delete NA from merge
    #create a column where 1 is for calibration and 2 for validation    
    merge["calVal"]<- merge$cal_val.x + merge$cal_val.y 
#now "clean" you dataframe, because you have too many useless columns       
 id<- merge$id  
        n<- merge$n.x 
        s<- merge$s.x
        calval<- merge$calVal
        final_sample<- data.frame(id, n, s, calval)

【讨论】:

【参考方案2】:

我的做法是:

1) 将表的 id 列表提取到 R,您可以使用 RMySQL 库通过简单的 SQL 查询来完成此操作。

2) 在 R 中以您喜欢的任何方式拆分 id,然后使用 RMySQL 再次执行后续 SQL 查询(我发现这种两步方法比直接在 MySQL 中采样要快得多)。

3) 根据您的样本有多大,您可以通过使用基本 R kmeans 实现来避免,但是对于更大的样本,这可能会失败,在这种情况下,您应该考虑使用库 biganalytics 中的 bigkmeans。

【讨论】:

【参考方案3】:

我认为您的许多问题都可以通过使用 caret 包来解决。关于具有相等类成员资格的随机抽样,我会将其推回到 SQL 中,只需为每个指定的类运行两个具有您想要的大小的查询。其他人提到 RMySql、RODBC 或 RJDBC 也可以。要将数据分成训练集和测试集,请使用以下插入符号函数:

# separate data into test and train sets, 70/30 split in this case

splitIndex <- createDataPartition(mydata$mytargetcolumn, p = 0.7, list = FALSE)
train <- mydata[splitIndex, ]
test <- mydata[-splitIndex, ]
testInd <- test[ ,!colnames(test) %in% "mytargetcolumn"]
testDep <- as.factor(test[, names(test) == "mytargetcolumn"]) 

您也可以使用插入符号进行 KNN,如下所示:

modelKNN <- knn3(mytargetcolumn ~ ind1 + ind2, data = train, k = neighborCount, prob = TRUE)

然后预测很容易:

# prediction using KNN to get class probabilities, change 'type' if you just want class prediction

predKNN <- predict(modelKNN, testInd, type = "prob")

您也可以使用插入符号进行评估:

# Generate confusion matrix from class predictions and actual values

confKNN <- confusionMatrix(testDep, predKNN)

虽然我个人使用 AUC(通过 pROC 包)进行分类模型评估,因为它是比准确度更细粒度的分类器强度度量。

【讨论】:

以上是关于如何对大型数据库进行采样并在 R 中实现 K-means 和 K-nn?的主要内容,如果未能解决你的问题,请参考以下文章

理论上如何在STM32F3中实现最大采样率?

大型数据集上的 R 中的 hclust()

如何在 R Shiny 中实现对数据表的内联编辑

如何在R中实现对空间面板数据的LM检验

如何在 R/Python 中迭代/循环一个大型(>2GB)JSON 数据集? [复制]

如何在 R 中实现保留验证