You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过线性划分实现三类线性分布数据的聚类?

如何通过线性划分实现三类线性分布数据的聚类?

看起来你已经试过不少标准聚类算法,但因为你的数据是三条明显的线性分布,这些基于距离或密度的算法完全没get到你想要的划分方式——毕竟它们的设计初衷不是处理这种线性分离的集群嘛!别担心,咱们可以直接针对数据的线性特点来解决,给你几个实用的方法:

方法一:手动拟合分割线(简单直接,适合规律明显的场景)

既然你已经从图上看到了清晰的三条线,那最直接的方式就是手动找出两条能把它们分开的直线,然后根据点相对于直线的位置来归类。

  • 第一步:观察你的可视化图表,确定分割线的方程。假设你是用line_position作为x轴,real_seq作为y轴绘图,那两条分割线可以表示为 y = m1*x + c1 和 y = m2*x + c2,你需要根据图中的位置估算出m(斜率)和c(截距)的数值。
  • 第二步:用代码给每个点判断归属,比如用Python+Pandas的话:
import pandas as pd

# 读取你的数据
df = pd.read_csv("your_data_file.csv")

# 根据你的图表调整这两个线的参数
m1, c1 = 400, 12000  # 第一条分割线的斜率和截距
m2, c2 = 400, 32000  # 第二条分割线的斜率和截距

# 定义集群分配逻辑
def assign_cluster(row):
    x = row['line_position']
    y = row['real_seq']
    if y < m1 * x + c1:
        return 0  # 第一个集群
    elif y > m2 * x + c2:
        return 2  # 第三个集群
    else:
        return 1  # 中间的集群

# 给每个数据行添加集群标签
df['cluster'] = df.apply(assign_cluster, axis=1)
  • 优点:完全贴合你看到的图形规律,零训练成本;缺点:需要人工调整参数,如果数据后续有变化,可能要重新校准分割线。

方法二:用线性分类器自动找分割线(更灵活,适合自动化需求)

你可以把这个问题转化为一个半监督的分类任务:先手动给一小部分数据打标签,再训练线性分类器来自动划分所有数据。

  • 第一步:从三个集群里各挑几个典型样本(比如每个集群选3-5个点),手动标记它们的集群编号。
  • 第二步:用这些带标签的样本训练线性分类器(比如逻辑回归、线性核的SVM),然后用模型预测所有数据的集群归属:
from sklearn.linear_model import LogisticRegression
import pandas as pd

df = pd.read_csv("your_data_file.csv")

# 手动标记部分样本(这里的索引要对应你数据里的典型点)
labeled_idx = [0, 4, 10, 15]  # 例子索引,你要自己调整
df.loc[labeled_idx, 'label'] = [0, 1, 2, 0]  # 给这些点分配集群标签

# 分离带标签的特征和标签
X_labeled = df.dropna(subset=['label'])[['line_position', 'real_seq']]
y_labeled = df.dropna(subset=['label'])['label']

# 训练多分类逻辑回归模型
clf = LogisticRegression(multi_class='multinomial', solver='lbfgs')
clf.fit(X_labeled, y_labeled)

# 预测所有数据的集群
df['cluster'] = clf.predict(df[['line_position', 'real_seq']])
  • 优点:不需要手动算分割线参数,模型会自动学习数据的线性分离规律;缺点:需要少量手动标记的样本,但标记工作量很小。

方法三:拟合每条线,按距离分集群(最贴合“三条线”的本质)

既然数据本身是三条线,那我们可以先给每条线拟合出线性模型,然后把每个点分到距离最近的那条线对应的集群里。

  • 第一步:先通过简单的阈值(比如根据y轴范围)把数据粗略分成三个子集,然后对每个子集拟合线性回归模型。
  • 第二步:计算每个点到三条拟合线的垂直距离,距离最近的线对应的集群就是这个点的归属:
from sklearn.linear_model import LinearRegression
import pandas as pd
import numpy as np

df = pd.read_csv("your_data_file.csv")

# 先粗略划分三个子集(根据你观察的y轴范围调整阈值)
sub1 = df[df['real_seq'] < 15000]
sub2 = df[(df['real_seq'] >= 15000) & (df['real_seq'] < 30000)]
sub3 = df[df['real_seq'] >= 30000]

# 给每个子集拟合线性回归模型
line_models = []
for subset in [sub1, sub2, sub3]:
    X = subset[['line_position']]
    y = subset['real_seq']
    lr = LinearRegression()
    lr.fit(X, y)
    line_models.append(lr)

# 计算点到直线的垂直距离
def calc_distance(x, y, model):
    m = model.coef_[0]
    b = model.intercept_
    # 直线方程:mx - y + b = 0,垂直距离公式
    return abs(m * x - y + b) / np.sqrt(m**2 + 1)

# 分配集群
def assign_cluster(row):
    x = row['line_position']
    y = row['real_seq']
    distances = [calc_distance(x, y, model) for model in line_models]
    return distances.index(min(distances))

df['cluster'] = df.apply(assign_cluster, axis=1)
  • 优点:完全基于“点到线的距离”来划分,结果最贴合数据的线性分布本质;缺点:需要初始的粗略划分,但这个划分不需要太精确,只要能把三个集群大致分开就行。

总结

你的数据属于线性分离型集群,KMeans这类基于中心的聚类算法自然会失效,而上面这三种方法都是针对线性划分的场景设计的,你可以根据自己的需求选择:

  • 如果数据规律稳定,选手动拟合分割线最快;
  • 如果想自动化,用线性分类器更省心;
  • 如果追求最贴合“三条线”的划分逻辑,就选拟合线条再算距离的方法。

备注:内容来源于stack exchange,提问作者Pavel Botsman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 07:13:09