我的任务如下:我有一个包含X, Y, Class
列的表格
其中x坐标在笛卡尔坐标系中,
笛卡尔坐标系中的y坐标
和一个点的类别,例如1级,2级)。
我需要找到一条划分平面的线,使得单独的类的点位于坐标系的两个独立部分中。这是我第一次使用线性分类器。我想知道如何使用一个select
查询来实现这一点 - 允许子查询。
答案 0 :(得分: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
请注意,此代码选择category1的一侧,而这反过来会强制另一方为类别2.您不能为每个选择最佳的一面,因为您的所有数据点可能位于线。
此外,这对垂直线不起作用,但它很接近。
将这些放在一起时,我不说这是解决此问题的最佳方法。但是,对于少量数据点,它实际上可能工作得很好。