请教各位大佬:如何求最右边的所有点
本帖最后由 随便的C# 于 2022-5-27 21:57 编辑比如图上有好几列点,我想获得最右边的所有点,例如方框里的点。
大佬们能给个解题思路吗?
本帖最后由 landsat99 于 2022-5-31 17:07 编辑
响应大佬,也来一段代码,, Canopy算法的,也算一种簇类分析定质心。
Github : https://github.com/AlanConstantine/CanopyByPython
修改: 添加了核心参数T1,T2的粗略判断。取为整体矩阵 Data[:,0] 最大值和最小值区间的比例参数。
用楼上大咖的点位数据 再次试算。
# -*- coding: utf-8 -*-
# @Title: Algorithm.Canopy :: Class.Canopy.py
# @From: https://github.com/AlanConstantine/CanopyByPython
# @Date: 2022.05.31
import math
import random
import numpy as np
from datetime import datetime
from pprint import pprint as p
import matplotlib.pyplot as plt
class Canopy:
def __init__(self, dataset):
self.dataset = dataset
self.t1 = 0
self.t2 = 0
# 设置初始阈值
def setThreshold(self, t1, t2):
if t1 > t2:
self.t1 = t1
self.t2 = t2
else:
print('t1 needs to be larger than t2!')
# 使用欧式距离进行距离的计算
def euclideanDistance(self, vec1, vec2):
return math.sqrt(((vec1 - vec2)**2).sum())
# 根据当前dataset的长度随机选择一个下标
def getRandIndex(self):
return random.randint(0, len(self.dataset) - 1)
def clustering(self):
if self.t1 == 0:
print('Please set the threshold.')
else:
canopies = []# 用于存放最终归类结果
while len(self.dataset) != 0:
rand_index = self.getRandIndex()
current_center = self.dataset# 随机获取一个中心点,定为P点
current_center_list = []# 初始化P点的canopy类容器
delete_list = []# 初始化P点的删除容器
self.dataset = np.delete(
self.dataset, rand_index, 0)# 删除随机选择的中心点P
for datum_j in range(len(self.dataset)):
datum = self.dataset
distance = self.euclideanDistance(
current_center, datum)# 计算选取的中心点P到每个点之间的距离
if distance < self.t1:
# 若距离小于t1,则将点归入P点的canopy类
current_center_list.append(datum)
if distance < self.t2:
delete_list.append(datum_j)# 若小于t2则归入删除容器
# 根据删除容器的下标,将元素从数据集中删除
self.dataset = np.delete(self.dataset, delete_list, 0)
canopies.append((current_center, current_center_list))
return canopies
def showCanopy(canopies, dataset, t1, t2):
fig = plt.figure()
sc = fig.add_subplot(111)
colors = ['brown', 'green', 'blue', 'y', 'r', 'tan', 'dodgerblue', 'deeppink', 'orangered', 'peru', 'blue', 'y', 'r',
'gold', 'dimgray', 'darkorange', 'peru', 'blue', 'y', 'r', 'cyan', 'tan', 'orchid', 'peru', 'blue', 'y', 'r', 'sienna']
markers = ['*', 'h', 'H', '+', 'o', '1', '2', '3', ',', 'v', 'H', '+', '1', '2', '^',
'<', '>', '.', '4', 'H', '+', '1', '2', 's', 'p', 'x', 'D', 'd', '|', '_']
for i in range(len(canopies)):
canopy = canopies
center = canopy
components = canopy
sc.plot(center, center, marker=markers,
color=colors, markersize=30)
t1_circle = plt.Circle(
xy=(center, center), radius=t1, color='dodgerblue', fill=False)
t2_circle = plt.Circle(
xy=(center, center), radius=t2, color='skyblue', alpha=0.2)
sc.add_artist(t1_circle)
sc.add_artist(t2_circle)
for component in components:
sc.plot(component, component,
marker=markers, color=colors, markersize=1.5)
maxvalue = np.amax(dataset)
minvalue = np.amin(dataset)
plt.xlim(minvalue - t1, maxvalue + t1)
plt.ylim(minvalue - t1, maxvalue + t1)
plt.show()
# 随机生成600个二维[0,1)平面点
# dataset = np.random.rand(600, 2)
dataset = np.array([[-3,0], [-2.5,1], [-3.5,3], [-0.5,0], , , , , ])
if __name__ == '__main__':
NMax = np.max(dataset[:, 0])
NMin = np.min(dataset[:, 0])
t1 = (NMax - NMin) * 0.7
t2 = t1 * 0.75
gc = Canopy(dataset)
gc.setThreshold(t1, t2)
canopies = gc.clustering()
print('Get %s initial centers.' % len(canopies))
showCanopy(canopies, dataset, t1, t2)
红框内,指定的参数T1 ,T2。 缩小区间,质心数量增加。
另外,聚类分析好像还有 Kmeans++ ,Kmeans II 等算法估CenterPoi。
革天明 发表于 2022-5-29 08:23
看了讨论,楼主想要的是不给定公差的情况下,自行计算,请参考K-means进行聚类即可
谢谢分享~
之前觉得应该是用机器学习或者深度学习可能才能得到这个,但之前没有认真学过,不懂聚类。
于是学习了一下,颇有收获
以下是用ANACONDA的SPYDER编写PYTHON代码,主要用的sklearn
# 参考 https://www.tutorialspoint.com/machine_learning_with_python/machine_learning_with_python_clustering_algorithms_k_means.htm
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import KMeans
XY=np.array([[-3,0], [-2.5,1], [-3.5,3], [-0.5,0], , , , , ])
#显示原始数据
plt.scatter(XY[:, 0], XY[:, 1], s = 30);
plt.show()
#人为定义为3组,y_kmeans就是预测的分组
kmeans = KMeans(n_clusters = 3)
kmeans.fit(XY)
y_kmeans = kmeans.predict(XY)
#显示聚类后的数据
plt.scatter(XY[:, 0], XY[:, 1], c = y_kmeans, s = 30, cmap = 'rainbow')
#显示聚类后的类中心
centers = kmeans.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c = 'blue', s = 100, alpha = 0.9);
plt.show()
结果如下:左是归类前,右是归类后
不过这个里面,人为规定了类数是3个,不知道有没有更好的自动算类的方法,但看到一般的KMEANS算法好像都有这个
后续:
假如用飞狐兄的PYCAD,估计可以编入PY插件
或者可以试试看ML.NET,看看编个C#插件可能也可以
几个想法聊聊。抛砖引玉。。
1. 简单法。给出选区 -> 选区x轴右侧比如所有点
2. 均值/方差选择。给定两点(用直线、两点、窗口方式都OK)本质是给定均值和方差或方差的函数. 即可找到符合你要求的点。算量基本是O(N)
3. 色阶法。 分析全图所有点得到几种分布指标 -> 以分布指标极值附近某点为均值,方差为参数选择。 类似PS的图片色阶算法。算量约O(2~3N)。
如果第二步不用方差鲁棒定界,指定算法或AI识别等其他,比如离散动力学估界,会指数级增加算量O(N^2) .O(N^2.5)。
算法无上限,看应用场景、成本 X坐标值最大的点啊 烟盒迷唇 发表于 2022-5-28 06:43
X坐标值最大的点啊
这只能求到最大的一个点,而不是一列点,我想求的就是最右列的所有点。 烟盒迷唇 发表于 2022-5-28 06:43
X坐标值最大的点啊
这个法应该最简单
landsat99 发表于 2022-5-28 11:11
几个想法聊聊。抛砖引玉。。
1. 简单法。给出选区 -> 选区x轴右侧比如所有点
方差我感觉不太行,因为就如那张示意图一样,假如最左一列的所有点的X坐标相同的话,两点关于X坐标最小的方差就是最左列的点了。 随便的C# 发表于 2022-5-28 17:47
这只能求到最大的一个点,而不是一列点,我想求的就是最右列的所有点。
给X值一个公差,差值范内所有点为一列、 自贡黄明儒 发表于 2022-5-28 18:09
给X值一个公差,差值范内所有点为一列、
这样的话就得每次都定义不同的方差范围 看了讨论,楼主想要的是不给定公差的情况下,自行计算,请参考K-means进行聚类即可 革天明 发表于 2022-5-29 08:23
看了讨论,楼主想要的是不给定公差的情况下,自行计算,请参考K-means进行聚类即可
感谢大佬的点拨!
页:
[1]
2