1

我的任务如下:我有一个表格,X, Y, Class 其中包含笛卡尔坐标系中的 x 坐标、笛卡尔坐标系中的 y 坐标以及点的类,例如 1 类、2 类)。我需要找到一条线来划分平面,使不同类的点位于坐标系的两个独立部分中。这是我第一次使用线性分类器。我想知道如何只使用一个select查询来实现这一点 - 允许子查询。

4

1 回答 1

1

我的第一反应是,这不是 SQL 可以解决的问题,您应该查找统计/数据分析软件。支持向量机 (SVM) 提供了“最佳”这样的线路,您可以查找它。

但是,如果您有很多时间,或者很少有积分,您可以尝试蛮力方法。也就是说,浏览一个可能的行列表,看看它们的分割程度。

所以,假设一条线有一个方程y = mx + b。这是一组具有不同斜率的线的测试。您可以通过y - mx + b是正面还是负面来测试线的一侧。然后,您为每一边和每个类别汇总此信息,并使用一些逻辑来选择类别的边。

为此,我使用 SQL Server 语法:

with nums as (  -- get a bunch of nums
      select row_number() over (order by null) as n
      from information_schema.columns c
     ),
    m as (
     select n - 10 as m  -- from -10 to 10
     from nums
     where n <= 21
    ),
    b as (
     select n - 10 as b  -- from -10 to 10
     from nums
     where n <= 21
    )
    lines as (
     select m, b
     from m cross join b
    )
select m, b,
       (case when cat1_side1 > cat1_side2 then 'side1' else 'side2'
        end) as cat1_side,
       (case when cat1_side1 > cat1_side2 then cat1_side1 else cat1_side2
        end) as cat1_correct,
      (case when cat1_side1 > cat1_side2 then 'side2' else 'side1'
       end) as cat2_side,  -- force cat2 to the other side
      (case when cat1_side1 > cat1_side2 then cat2_side2 else cat2_side1
       end) as cat2_correct
from (select l.m, l.b, 
             sum(case when p.category = 'cat1' and p.y - (p.x*l.m + l.b) < 0
                      then 1 else 0
                 end) as cat1_side1_cnt,
             sum(case when p.category = 'cat1' and p.y - (p.x*l.m + l.b) > 0
                      then 1 else 0
                 end) as cat1_side2_cnt,
             sum(case when p.category = 'cat2' and p.y - (p.x*l.m + l.b) < 0
                      then 1 else 0
                 end) as cat2_side1_cnt,
             sum(case when p.category = 'cat2' and p.y - (p.x*l.m + l.b) > 0
                      then 1 else 0
                 end) as cat2_side2_cnt,
      from points p cross join
           lines l
      group by l.m, l.b, p.category
     ) lp
order by (cat1_correct + cat2_correct) desc

请注意,此代码选择类别 1 的一侧,而这反过来又强制类别 2 的另一侧。您不能为每个选择最佳一侧,因为您的所有数据点可能都在线的一侧。

此外,这不适用于垂直线,但它很接近。

把这些放在一起,我并不是说这是解决这个问题的最佳方法。但是,对于少量的数据点,它实际上可能工作得很好。

于 2013-03-30T12:04:22.710 回答