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