R、SOM、Kohonen 包、异常值检测

2023-12-27

我用 SOM 做了一些实验。首先,我在 Python 中使用 MiniSOM,但没有留下深刻的印象,于是改用 R 中的 kohonen 包,它比以前提供了更多功能。基本上,我将 SOM 应用到三个用例:(1) 使用生成的数据进行二维聚类,(2) 使用更多维数据进行聚类:内置葡萄酒数据集,以及 (3) 异常值检测。我解决了所有三个用例,但我想提出一个与我应用的异常值检测有关的问题。为此,我使用了向量索姆$距离,其中包含输入数据集每行的距离。具有出色距离的值可能是异常值。但是,我不知道这个距离是如何计算的。包描述(https://cran.r-project.org/web/packages/kohonen/kohonen.pdf https://cran.r-project.org/web/packages/kohonen/kohonen.pdf)该指标的状态:“到最近单位的距离”。

  1. 你能告诉我这个距离是如何计算的吗?
  2. 您能评论一下我使用的异常值检测吗?你会怎么做呢? (在生成的数据集中,它确实找到了异常值。在 真实的葡萄酒数据集中,177个葡萄酒品种中,有四个相对优秀的数值。看 下面的图表。我突然想到使用条形图来描述这一点,我真的很喜欢。)

Charts:

  • Generated data, 100 point in 2D in 5 distinct clusters and 2 outliers (Category 6 shows the outliers): enter image description here

  • Distances shown for all the 102 data points, the last two ones are the outliers which were correctly identified. I repeated the test with 500, and 1000 data points and added solely 2 outliers. The outliers were also found in those cases. enter image description here

  • Distances for the real wine data set with potential outliers: enter image description here

潜在异常值的行 ID:

# print the row id of the outliers
# the threshold 10 can be taken from the bar chart,
# below which the vast majority of the values fall
df_wine[df_wine$value > 10, ]

it produces the following output:
    index    value
59     59 12.22916
110   110 13.41211
121   121 15.86576
158   158 11.50079

我带注释的代码片段:

        data(wines)

        scaled_wines <- scale(wines)

        # creating and training SOM
        som.wines <- som(scaled_wines, grid = somgrid(5, 5, "hexagonal"))
        summary(som.wines)

        #looking for outliers, dist = distance to the closest unit
        som.wines$distances

        len <- length(som.wines$distances)
        index_in_vector <- c(1:len)
        df_wine<-data.frame(cbind(index_in_vector, som.wines$distances))
        colnames(df_wine) <-c("index", "value")

        po <-ggplot(df_wine, aes(index, value)) + geom_bar(stat = "identity") 
        po <- po + ggtitle("Outliers?") + theme(plot.title = element_text(hjust = 0.5)) + ylab("Distances in som.wines$distances") + xlab("Number of Rows in the Data Set")
        plot(po)

        # print the row id of the outliers
        # the threshold 10 can be taken from the bar chart,
        # below which the vast majority of the values fall
        df_wine[df_wine$value > 10, ]

更多代码示例

关于评论中的讨论,我还发布了所需的代码片段。据我记得,负责聚类的代码行是根据我在 Kohonen 包的描述中找到的示例构建的(https://cran.r-project.org/web/packages/kohonen/kohonen.pdf https://cran.r-project.org/web/packages/kohonen/kohonen.pdf)。不过,我不太确定,那是一年多前的事了。该代码按原样提供,没有任何保证:-)。请记住,特定的聚类方法可能会在不同的数据上以不同的精度执行。我还建议将其与葡萄酒数据集上的 t-SNE 进行比较(data(wines)在 R 中可用)。此外,实施热图来演示如何定位有关各个变量的数据。 (在上面有 2 个变量的示例中,这并不重要,但对于葡萄酒数据集来说会很好)。

具有五个聚类和 2 个离群值的数据生成和绘图

            library(stats)
            library(ggplot2)

            library(kohonen)


            generate_data <- function(num_of_points, num_of_clusters, outliers=TRUE){
              num_of_points_per_cluster <- num_of_points/num_of_clusters
              cat(sprintf("#### num_of_points_per_cluster = %s, num_of_clusters = %s \n", num_of_points_per_cluster, num_of_clusters))
              arr<-array()
              
              standard_dev_y <- 6000
              standard_dev_x <- 2
              
              # for reproducibility setting the random generator
              set.seed(10)
              
              for (i in 1:num_of_clusters){
                centroid_y <- runif(1, min=10000, max=200000)
                centroid_x <- runif(1, min=20, max=70)
                cat(sprintf("centroid_x = %s \n, centroid_y = %s", centroid_x, centroid_y ))
                
                vector_y <- rnorm(num_of_points_per_cluster, mean=centroid_y, sd=standard_dev_y)
                vector_x <- rnorm(num_of_points_per_cluster, mean=centroid_x, sd=standard_dev_x)
                cluster <- array(c(vector_y, vector_x), dim=c(num_of_points_per_cluster, 2))
                cluster <- cbind(cluster, i)
                
                arr <- rbind(arr, cluster)
              }
              
              if(outliers){
                #adding two outliers
                arr <- rbind(arr, c(10000, 30, 6))
                arr <- rbind(arr, c(150000, 70, 6))
              }
              
              colnames(arr) <-c("y", "x", "Cluster")
              # WA to remove the first NA row
              arr <- na.omit(arr)
              return(arr)
            }

            scatter_plot_data <- function(data_in, couloring_base_indx, main_label){
              
              df <- data.frame(data_in)
              colnames(df) <-c("y", "x", "Cluster")

              pl <- ggplot(data=df, aes(x = x,y=y)) + geom_point(aes(color=factor(df[, couloring_base_indx]))) 
              pl <- pl + ggtitle(main_label) + theme(plot.title = element_text(hjust = 0.5))
              print(pl)
              
            }

            ##################
            # generating data
            data <- generate_data(100, 5, TRUE)
            print(data)
            scatter_plot_data(data, couloring_base_indx<-3, "Original Clusters without Outliers \n 102 Points")

准备、聚类和绘图

我使用了 Kohonen Map (SOM) 的层次聚类方法。

            normalising_data <- function(data){
              # normalizing data points not the cluster identifiers
              mtrx <- data.matrix(data)
              umtrx <- scale(mtrx[,1:2])
              umtrx <- cbind(umtrx, factor(mtrx[,3]))
              colnames(umtrx) <-c("y", "x", "Cluster")
              return(umtrx)
            }

            train_som <- function(umtrx){
              # unsupervised learning
              set.seed(7)
              g <- somgrid(xdim=5, ydim=5, topo="hexagonal")
              #map<-som(umtrx[, 1:2], grid=g, alpha=c(0.005, 0.01), radius=1, rlen=1000)
              map<-som(umtrx[, 1:2], grid=g)
              summary(map)
              
              return(map)
            }

            plot_som_data <- function(map){
              par(mfrow=c(3,2))
              # to plot some charactristics of the SOM map
              plot(map, type='changes')
              plot(map, type='codes', main="Mapping Data")
              plot(map, type='count')
              plot(map, type='mapping') # how many data points are held by each neuron
              plot(map, type='dist.neighbours') # the darker the colours are, the closer the point are; the lighter the colours are, the more distant the points are
              
              #to switch the plot config to the normal
              par(mfrow=c(1,1))
            }

            plot_disstances_to_the_closest_point <- function(map){
              
              # to see which neuron is assigned to which value 
              map$unit.classif
              
              #looking for outliers, dist = distance to the closest unit
              map$distances
              max(map$distances)
              
              len <- length(map$distances)
              index_in_vector <- c(1:len)
              df<-data.frame(cbind(index_in_vector, map$distances))
              colnames(df) <-c("index", "value")
              
              po <-ggplot(df, aes(index, value)) + geom_bar(stat = "identity") 
              po <- po + ggtitle("Outliers?") + theme(plot.title = element_text(hjust = 0.5)) + ylab("Distances in som$distances") + xlab("Number of Rows in the Data Set")
              plot(po)
              
              return(df)
              
            }


            ###################
            # unsupervised learning

            umtrx <- normalising_data(data)

            map<-train_som(umtrx)
            plot_som_data(map)

            #####################
            # creating the dendogram and then the clusters for the neurons
            dendogram <- hclust(object.distances(map, "codes"), method = 'ward.D')
            plot(dendogram)

            clusters <- cutree(dendogram, 7)
            clusters
            length(clusters)

            #visualising the clusters on the map
            par(mfrow = c(1,1))
            plot(map, type='dist.neighbours', main="Mapping Data")
            add.cluster.boundaries(map, clusters)

聚类图

您还可以为选定的变量创建漂亮的热图,但我还没有实现它们以使用 2 个变量进行聚类,这实际上没有意义。如果您为葡萄酒数据集实现它,请将代码和图表添加到本文中。

            #see the predicted clusters with the data set
            # 1. add the vector of the neuron ids to the data
            mapped_neurons <- map$unit.classif
            umtrx <- cbind(umtrx, mapped_neurons)

            # 2. taking the predicted clusters and adding them the the original matrix
            # very good description of the apply functions:
            # https://www.guru99.com/r-apply-sapply-tapply.html
            get_cluster_for_the_row <- function(x, cltrs){
              return(cltrs[x])
            }

            predicted_clusters <- sapply (umtrx[,4], get_cluster_for_the_row, cltrs<-clusters)

            mtrx <- cbind(mtrx, predicted_clusters)
            scatter_plot_data(mtrx, couloring_base_indx<-4, "Predicted Clusters with Outliers \n 100 points")

请参阅下面的预测集群,了解是否存在异常值。


  1. 虽然我不太确定,但我经常发现驻留在特定维度空间中的两个物体的距离测量主要使用欧几里德距离。例如,位置为A(x=3,y=4)和B(x=6,y=8)的二维空间中的两个点A和B相距5个距离单位。它是执行平方根((3-6)^2 + (4-8)^2)计算的结果。这也适用于维度较大的数据,通过添加特定维度中两点值之差的两个尾随幂。如果 A(x=3, y=4, z=5) 和 B(x=6, y=8, z=7) 则距离为平方根((3-6)^2 + (4-8)^ 2 + (5-7)^2),依此类推。在kohonen中,我认为模型完成训练阶段后,算法会计算每个数据到所有节点的距离,然后将其分配给最近的节点(与其距离最小的节点)。最终,模型返回的变量“距离”内的值是每个数据到其最近节点的距离。脚本中需要注意的一件事是,算法不会直接测量与数据所具有的原始属性值的距离,因为它们在将数据输入模型之前已经进行了缩放。距离测量应用于数据的缩放版本。缩放是消除一个变量对另一个变量的主导地位的标准程序。
  2. 我相信你的方法是可以接受的,因为“距离”变量内的值是每个数据到最近节点的距离。因此,如果一个数据与其最近的节点之间的距离值很高,那么这也意味着:该数据到其他节点的距离显然要高得多。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

R、SOM、Kohonen 包、异常值检测 的相关文章

  • Rsolnp:在 cbind(temp, funv) 中:结果的行数不是向量长度的倍数(arg 1)

    我是 stackoverflow 的新手 搜索了很多 但找不到我的问题的答案 我正在尝试使用优化包 Rsolnp 来最小化以下问题 尽管求解器为我提供了解决方案 但每次运行代码时我都会收到以下警告消息 警告消息 1 在 cbind temp
  • R 脚本自动化时的不同结果

    以下命令对 pdf 文件执行 Ghostscript 这pdf file变量包含该 pdf 的路径 bbox lt system paste C gs gs8 64 bin gswin32c exe sDEVICE bbox dNOPAUS
  • 如何让 print() 将参数传递给 R 中用户定义的打印方法?

    我在 R 中定义了一个 S3 类 它需要自己的打印方法 当我创建这些对象的列表并打印它时 R 按其应有的方式对列表中的每个元素使用我的打印方法 我想对打印方法实际显示的数量进行一些控制 因此 我的类的 print 方法需要一些额外的参数 但
  • 如何提取与 R 中主题 ID 列表匹配的行?

    我有一个包含许多主题 ID 的数据框 每个主题都有重复观察 我还有一个单独的数据框 其中只有一个主题 ID 列表 我想从更大的数据框中匹配和提取 如何以允许我引用不同数据帧中的SubjectID列表的方式编写代码 不确定我是否完全理解这个问
  • 从 R 中的向量中选择所有可能的元组

    我正在尝试用 R 编写一个程序 当给定一个向量时 将返回所有可能的tuples http en wikipedia org wiki Tuples该向量中的元素 例如 元组 c a b c c a b c 出租车 c a c c b c c
  • 基于另一个数据集获取数据集的子集

    假设我有一个数据集 即 dat1 ID block plot SPID TotHeight 1 1 1 4 44 5 2 1 1 4 51 3 1 1 4 28 7 4 1 1 4 24 5 5 1 1 4 27 3 6 1 1 4 20
  • .wav 文件长度/持续时间,无需读入文件

    有没有办法提取有关 wav 文件长度 持续时间的信息 而无需在 R 中读取文件 我有数千个这样的文件 如果我必须阅读每个文件才能找到其持续时间 那将需要很长时间 Windows 文件资源管理器为您提供了打开 长度 字段的选项 并且您可以查看
  • 是否可以通过扫描从控制台读取而不回显字符?

    这是一个示例函数 passwordEntry lt function cat Enter your password pwd lt scan n 1 what character quiet TRUE invisible pwd 并测试该功
  • numpy.histogram 的 hist 维度,密度 = True

    假设我有这个数组 A array 0 0019879 0 00172861 0 00527226 0 00639585 0 00242005 0 00717373 0 00371651 0 00164218 0 00034572 0 008
  • 重复测量引导统计数据,按多个因素分组

    我有一个看起来像这样的数据框 但显然还有更多行等 df lt data frame id c 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 cond c A A B B A A B B A A B B A A B B co
  • 使用 purrr 迭代替换数据帧列中的字符串

    我想用purrr使用以下命令在数据框列上迭代运行多个字符串替换gsub 功能 这是示例数据框 df lt data frame Year 2019 Text c rep a aa 5 rep a bb 3 rep a cc 2 gt df
  • 多功能测试仪替代 system.time

    我已经看到 我认为是这样 使用了类似于 system time 的函数 它可以同时评估多个函数的时间并输出一个输出 我不记得它是什么 并且用我正在使用的术语进行互联网搜索并没有得到我想要的响应 有人知道我正在谈论的功能的名称 位置吗 你想要
  • 在 R 中创建虚拟变量,排除某些情况为 NA

    我的数据看起来像这样 V1 V2 A 0 B 1 C 2 D 3 E 4 F 5 G 9 我想创建一个虚拟变量R where 0 1 1 2 3 4 and NA 0 5 9 应该很简单 有人可以帮忙吗 我们可以转换V2 into a fa
  • 在 R 格子包中微调点图

    我正在尝试为不同的数据集和不同的算法绘制一堆 ROC 区域 我有三个变量 方案 指定所使用的算法 数据集 是正在测试算法的数据集 以及 Area under ROC 我正在 R 中使用lattice库 命令如下 点图 方案 Area und
  • Purrr::map_df() 删除 NULL 行

    使用时purrr map df 我偶尔会传递一个数据框列表 其中一些项目是NULL 当我做 map df 返回行数少于原始列表的数据框 我想发生的事情是这样的map df calls dplyr bind rows 它忽略了NULL价值观
  • 以引用透明的方式从函数的省略号参数中提取符号

    事情又发生了 我正要按下发布答案按钮的问题被删除了 我正在寻找一种方法来从函数的省略号参数中提取绑定到符号的对象的值以及符号 也就是说 我试图以引用透明的方式从省略号中提取符号 我尝试过使用替代品和lazy dots 但没有成功 funct
  • r 中训练和测试数据的最小最大缩放/归一化

    我正在创建一个函数 它将训练集和测试集作为其参数 最小 最大缩放 标准化并返回训练集并使用这些same最小值和最小 最大范围的值 标准化并返回测试集 到目前为止 这是我想出的功能 min max scaling lt function tr
  • ggplot2 geom_密度和geom_histogram在一个图中

    如何制作一个所有条形加起来为 1 的直方图 并在适合的上方添加一个密度层 set seed 1234 df lt data frame sex factor rep c F M each 200 weight round c rnorm 2
  • 将数据框中重叠的范围合并到唯一的组中

    我有一个 n 行 3 的数据框 df lt data frame start c 178 400 983 1932 33653 end c 5025 5025 5535 6918 38197 group c 1 1 2 2 3 df sta
  • 相当于 min() 的 rowMeans()

    我在 R 邮件列表上多次看到这个问题 但仍然找不到满意的答案 假设我有一个矩阵m m lt matrix rnorm 10000000 ncol 10 我可以通过以下方式获得每行的平均值 system time rowMeans m use

随机推荐

  • Rails 中同一个类的多个关联的最佳实践?

    我认为我的问题最好作为一个例子来描述 假设我有一个名为 Thing 的简单模型 它有一些简单数据类型的属性 就像是 Thing foo string goo string bar int 这并不难 db 表将包含具有这三个属性的三列 我可以
  • 如何用 PHP 计算 AWS 签名?

    我正在 bref 中编写一个 webhook 并希望它向 SQS 发送消息 为此使用整个 AWS SDK 是一种巨大的浪费 我如何计算签名 const AWS DATETIME FORMAT Ymd THis Z url getenv SQ
  • 如何查看php的执行时间? [复制]

    这个问题在这里已经有答案了 我的网站中有大量 PHP 代码 我想知道执行时间处理时间的处理 我怎样才能做到这一点 您可以使用microtime as the start and end你的 PHP 代码
  • Spark 结构化流 ForeachWriter 和数据库性能

    我已经尝试过像这样实现结构化流 myDataSet map r gt StatementWrapper Transform r writeStream foreach MyWrapper myWriter start awaitTermin
  • 如何在 ASP.NET Core 中将备用文件夹配置为 wwwroot?

    是否可以配置不同的文件夹来替换wwwroot在 ASP NET Core 中 如果是的话 怎么办 这种改变有副作用吗 目前唯一包含的配置wwwroot在整个项目中发现project json如下面的代码所示 但用新文件夹的名称替换该值对于静
  • 高阶函数,如何在不铸造的情况下从模型中推导出注入类型

    我有点坚持这个非常简单的想法 想象一下 我们有一个简单的高阶函数 它接受另一个函数和某个对象并返回另一个函数 const hof callback data gt model gt callback data model 现在我想做的是 类
  • 如何在 iOS 7 和 iOS 8 中锁定设备方向

    我的应用程序有问题 我无法锁定应用程序的方向 我需要做的就是将一个视图控制器锁定为横向模式 其余的为纵向模式 这是我的应用程序的层次结构 Navigation Controller TabBarController ViewControll
  • 更新函数内的全局 js 变量并将更新后的内容发送到 HTML 文档

    我在更新全局变量并将更新后的内容发送到 HTML 时遇到了很大的困难 我在 HTML 中有以下内容 We found places for you 在 JavaScript 中 var mainCount 3 Global variable
  • 如何在 PyMuPDF 中获取文本的背景颜色

    我试图看看是否可以使用文本的背景和前景色识别 PDF 内表格中可能的表格标题 通过 PyMuPDF 文本提取 我能够获得前景色 想知道是否有办法也获得背景颜色 我使用 pymupdf 1 16 2 和 python 3 7 我已检查过文档
  • NSPointerArray 奇怪的压缩

    我有一个弱者NSPointerArray和一些NSObject已被释放 致电之前compact我看到的是 lldb po currentArray count 1 lldb po currentArray pointerAtIndex 0
  • Next.js - router.push 无需滚动到顶部

    我正在通过导入使用下一个路由器useRouter from next router 我正在尝试找到一种解决方案 当我更改 URL 的查询时 该解决方案不会滚动到页面顶部 有什么解决办法吗 我知道 Next 的 Link 组件有这个选项 但我
  • 创建 CSS 网格布局

    我需要使用 CSS 网格创建一个布局 如下图所示 分辨率高于 900px For resolutions below 900px I need the layout to look like this 到目前为止 我已经尝试过 contai
  • 如何在Java中获取当前日期/时间[重复]

    这个问题在这里已经有答案了 在 Java 中获取当前日期 时间的最佳方法是什么 在 Java 中获取当前日期 时间的最佳方法是什么 没有 最好 的方法 这取决于您想要什么形式的日期 时间 If you want the date time
  • 如何使用 ANTLR4 创建 AST?

    我对此进行了很多搜索 但找不到任何有用的东西可以真正帮助我构建 AST 我已经知道 ANTLR4 不像 ANTLR3 那样构建 AST 每个人都说 嘿 使用访问者 但我找不到任何示例或更详细的解释如何做到这一点 我有一个必须像 C 语言一样
  • LINQ 内部如何工作?

    我喜欢在 NET 中使用 LINQ 但我想知道它的内部工作原理是什么 询问 LINQ 的某个特定方面更有意义 这有点像问 Windows 是如何工作的 从 C 的角度来看 LINQ 的关键部分对我来说是 表达式树 这些是代码作为数据的表示
  • 带有选项字段的 F# 记录在 Asp.Net WebApi 2.x 应用程序中无法正确反序列化

    我有一个 C Asp Net MVC 5 2 7 应用程序 支持面向 Net 4 5 1 的 WebApi 2 x 我正在尝试使用 F 并向解决方案中添加了一个 F 库项目 Web 应用程序引用 F 库 现在 我希望能够让 C WebApi
  • System.Data.Entity.Infrastruct.CommitFailedException:C# 多线程和 SQL Server 2012

    我们有一个 C 多线程 100 个线程 程序 它从数据库读取记录 每个线程获取一条记录 每个线程一个实体框架连接 并更新单个数据库表 在最初的几分钟 5 分钟 内 程序运行良好 没有异常 然后突然所有线程开始抛出以下错误消息 大约 1 分钟
  • 参数化 SQL、ORACLE 与带有正则表达式的 SQL Server

    Oracle 和 Sql 服务器在参数化字符串中使用不同的参数前缀 sql使用 p1 ORA使用 p1 我想在我的 SQL 中使用 如果使用 ORA 数据库 字符应替换为 你能帮我创建正则表达式吗 下面是一些 SQL 示例 update t
  • c# 仍然返回错误的核心数

    好的 所以我发布了在 C 中 GetEnvironmentVariable NUMBER OF PROCESSORS 返回错误的数字 https stackoverflow com questions 11571994 in c sharp
  • R、SOM、Kohonen 包、异常值检测

    我用 SOM 做了一些实验 首先 我在 Python 中使用 MiniSOM 但没有留下深刻的印象 于是改用 R 中的 kohonen 包 它比以前提供了更多功能 基本上 我将 SOM 应用到三个用例 1 使用生成的数据进行二维聚类 2 使