Python如何无需可视化从绘图数值序列中提取最优k值
无可视化提取两类曲线最优k值实现方案
给定输入字典结构如下:
data = { 'kValues': [2, 3, 4, 5, 6, 7, 8, 9, 10], 'WSS': [21455, 5432, 4897, 4675, 4257, 3954, 3852, 3756, 3487], 'SS': [0.75, 0.85, 0.7, 0.52, 0.33, 0.38, 0.42, 0.46, 0.47] }
按照给定判定规则,分别实现两类曲线的最优k提取逻辑即可,无需绘图。
SS曲线最优k提取
规则说明:SS曲线整体先上升后下降,取上升段最高点对应k值。
逻辑实现:遍历SS序列,找到第一个数值开始下降的位置,该位置就是上升段最高点,对应索引映射到同位置的k值即可。该逻辑可以自动规避下降段后续小幅波动回升的干扰,匹配规则要求。
WSS曲线肘点提取
规则说明:WSS为单调递减序列,肘点是序列下降速率从陡骤变为平缓的拐点。
逻辑实现:采用肘部法则通用的距离法计算:
- 取WSS序列首尾两个点连成直线
- 计算序列中每个点到该直线的垂直距离
- 距离最大的点即为肘点,对应索引映射到同位置的k值即可。
完整可运行代码
import math def get_ss_best_k(k_list, ss_list): # 找上升段第一个下降点,即为上升段最高点 for i in range(len(ss_list)-1): if ss_list[i] > ss_list[i+1]: return k_list[i] # 全序列上升的边界情况,取最后一个k return k_list[-1] def get_wss_elbow_k(k_list, wss_list): # 首尾点坐标 p1 = (k_list[0], wss_list[0]) p2 = (k_list[-1], wss_list[-1]) # 转换为直线一般式 Ax + By + C = 0 A = p2[1] - p1[1] B = p1[0] - p2[0] C = p2[0]*p1[1] - p1[0]*p2[1] # 计算每个点到直线的距离,找最大距离对应索引 max_dist = -1 elbow_idx = 0 for idx in range(len(wss_list)): x = k_list[idx] y = wss_list[idx] dist = abs(A*x + B*y + C) / math.sqrt(A*A + B*B) if dist > max_dist: max_dist = dist elbow_idx = idx return k_list[elbow_idx] # 加载数据 data = {'kValues': [2, 3, 4, 5, 6, 7, 8, 9, 10], 'WSS': [21455, 5432, 4897, 4675, 4257, 3954, 3852, 3756, 3487], 'SS': [0.75, 0.85, 0.7, 0.52, 0.33, 0.38, 0.42, 0.46, 0.47]} # 计算最优k ss_best_k = get_ss_best_k(data['kValues'], data['SS']) wss_best_k = get_wss_elbow_k(data['kValues'], data['WSS']) print(f"SS曲线最优k值:{ss_best_k}") print(f"WSS曲线肘点对应k值:{wss_best_k}")
运行上述代码输出结果为:
SS曲线最优k值:3 WSS曲线肘点对应k值:3
和已知的最优k结果完全匹配。
内容的提问来源于stack exchange,提问作者hanzgs
相关产品推荐
相关产品推荐

