缩凸壳

如何解决缩凸壳

我在2D空间中有一堆点,并为它们计算了一个凸包。我现在想“拧紧”船体,使其不再必然包含所有要点。在典型的带橡皮板钉子的比喻中,我想要实现的是能够调整橡皮筋的弹性并允许钉子在高于某个极限的压力下弯曲。这只是一个类比,这里没有真正的物理学。如果删除给定点,这可能与船体面积的减少有关,但并不是完全一样,因为可能存在两个彼此非常接近的点。这不一定与离群值检测有关,因为您可以想象一个模式,如果钉子在狭窄的线上,很大一部分钉子会弯曲(例如,想象成锤子形)。所有这一切必须相当快地达到数千个点。有什么提示我应该在算法方面看吗?用R实现是完美的,但不是必需的。

enter image description here

评论后编辑:我所标记的三个点是那些如果不包括在内则具有最大的减小船体面积的潜力。在图中,没有其他三点会导致更大的面积减少。我正在寻找的一个简单的实现可能是随机采样点的一部分,计算船体面积,迭代地移除船体上的每个点,重新计算面积,重复多次并移除可能导致高面积减少。也许可以在一些随机森林变体中实现?不过,这不太正确,因为我希望一点一点地删除点,以便获得以下结果。如果您一目了然地查看了所有点,则最好从“锤头”的边缘进行修剪。

enter image description here

解决方法

假设我有如下几点:

set.seed(69)

x <- runif(20)
y <- runif(20)

plot(x,y)

enter image description here

然后可以很容易地找到位于凸包上的子集点:

ss <- chull(x,y)

这意味着我们可以通过以下方式绘制凸包:

lines(x[c(ss,ss[1])],y[c(ss,col = "red")

enter image description here

现在,我们可以执行以下操作,随机移除凸包上的任一点(即“弯曲钉子”):

bend <- ss[sample(ss,1)]

x <- x[-bend]
y <- y[-bend]

然后我们可以重复寻找新点集的凸包的过程:

ss <- chull(x,y)
lines(x[c(ss,col = "blue",lty = 2)

enter image description here

要弄清点,将其移除时会导致最大的面积减少,其中一个选项是以下功能:

library(sp)

shrink <- function(coords)
{
  ss <- chull(coords[,1],coords[,2])
  outlier <- ss[which.min(sapply(seq_along(ss),function(i) Polygon(coords[ss[-i],],hole = FALSE)@area))]
  coords[-outlier,]
}

因此您可以执行以下操作:

coords <- cbind(x,y)

new_coords <- shrink(coords)

new_chull <- new_coords[chull(new_coords[,new_coords[,2]),]
new_chull <- rbind(new_chull,new_chull[1,])

plot(x,y)

lines(new_chull[,new_chull[,2],col = "red")

enter image description here

当然,您可以循环执行此操作,以便将new_coords多次反馈到shrink中。

,

在MASS中使用mcd.cov并从其得出每个点的马哈拉诺比斯距离(在心理中使用mahalanobis)来计算鲁棒的中心和方差。然后,我们使用PlotMD来自modi的马哈拉诺比斯距离的分位数图,并且在第二个图中以红色显示了相关的离群值。 (modi中还有其他功能可能也很有趣。)

library(MASS)
library(modi)
library(psych)

set.seed(69)   
x <- runif(20)
y <- runif(20)
m <- cbind(x,y)

mcd <- cov.mcd(m)
md <- mahalanobis(m,mcd$center,mcd$cov)
stats <- PlotMD(md,2,alpha = 0.90)

给予:

(截图后续) screenshot

,我们使用线条和红色的离群值显示凸包:

plot(m)    
ix <- chull(m)
lines(m[c(ix,ix[1]),])

wx <- which(md > stats$halpha)
points(m[wx,col = "red",pch = 20)

screenshot

,

谢谢你们!我尝试了各种方法进行离群值检测,但这并不是我想要的。由于我的集群形状怪异,所以它们工作不佳。我知道我谈论过凸包区域,但是我认为对段长度进行过滤会产生更好的结果,并且更接近于我真正想要的。然后看起来像这样:

shrink <- function(xy,max_length = 30){
      to_keep <- 1:(dim(xy)[1])
      centroid <- c(mean(xy[,1]),mean(xy[,2]))

      while (TRUE){
        ss <- chull(xy[,xy[,2])
        ss <- c(ss,ss[1])
        lengths <- sapply(1:(length(ss)-1),function(i) sum((xy[ss[i+1],] - xy[ss[i],])^2))

        # This gets the point with the longest convex hull segment. chull returns points
        # in clockwise order,so the point to remove is either this one or the one
        # after it. Remove the one furthest from the centroid.
        max_point <- which.max(lengths)
        if (lengths[max_point] < max_length) return(to_keep)

        if (sum((xy[ss[max_point],] - centroid)^2) > sum((xy[ss[max_point + 1],] - centroid)^2)){
          xy <- xy[-ss[max_point],]
          to_keep <- to_keep[-ss[max_point]]
        }else{
          xy <- xy[-ss[max_point + 1],]
          to_keep <- to_keep[-ss[max_point + 1]]
        }
      }
    }

这不是最佳选择,因为它会影响到质心的距离,我想避免这种情况,并且有一个max_length参数应该从数据中计算出来,而不要进行硬编码。

没有过滤器: enter image description here

看起来像这样,因为这里有50万个单元,当从大约20000尺寸投影到2时,许多最终以“错误”告终。

过滤器: enter image description here

请注意,它会过滤掉某些聚类的尖端的点。这不是最理想的,但是还可以。一些簇之间的重叠是正确的,应该存在。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res