one-hot 编码2
DictVectorizer
考虑一个两列构成的输入数据:
city | temperature |
---|---|
New York | 70 |
San Francisco | 50 |
可以看到,这里第一列是一个类别特征,第二列是一个实数型特征。前面我们通过LabelBinarizer
对标签进行one-hot
编码,这里我们可以通过DictVectorizer
实现对输入特征的自动one-hot
编码:
考虑一个两列构成的输入数据:
city | temperature |
---|---|
New York | 70 |
San Francisco | 50 |
可以看到,这里第一列是一个类别特征,第二列是一个实数型特征。前面我们通过LabelBinarizer
对标签进行one-hot
编码,这里我们可以通过DictVectorizer
实现对输入特征的自动one-hot
编码:
考虑我们有一张物料表和库存表。
CREATE TABLE IF NOT EXISTS public.mm_material
(
"Id" integer NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
"Code" character varying(64) COLLATE pg_catalog."default" NOT NULL,
"ShortName" character varying(256) COLLATE pg_catalog."default" NOT NULL,
"Specification" character varying(50) COLLATE pg_catalog."default" NOT NULL,
"Status" integer NOT NULL,
"MeasureUnitId" integer NOT NULL,
CONSTRAINT "PK_mm_material" PRIMARY KEY ("Id"),
CONSTRAINT "AK_mm_material_Code" UNIQUE ("Code"),
CONSTRAINT "FK_mm_material_mm_material_measureunit_MeasureUnitId" FOREIGN KEY ("MeasureUnitId")
REFERENCES public.mm_material_measureunit ("Id") MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
)
-- 索引略
;
CREATE TABLE IF NOT EXISTS public.mm_inventory
(
"Id" uuid NOT NULL,
"IsLocked" boolean NOT NULL,
"Locker" text COLLATE pg_catalog."default" NOT NULL,
"WarehouseId" integer NOT NULL,
"Slot" text COLLATE pg_catalog."default" NOT NULL,
"Scope" text COLLATE pg_catalog."default" NOT NULL,
"MaterialCode" text COLLATE pg_catalog."default" NOT NULL,
"MaterialId" integer NOT NULL,
"Batch" text COLLATE pg_catalog."default" NOT NULL,
"ExternalCode" text COLLATE pg_catalog."default" NOT NULL,
"Amount" numeric NOT NULL,
"StockKind" integer NOT NULL,
"Note" text COLLATE pg_catalog."default",
"ProducedAt" timestamp with time zone,
"ExpiredAt" timestamp with time zone NOT NULL,
"CreatedAt" timestamp with time zone NOT NULL,
CONSTRAINT "PK_mm_inventory" PRIMARY KEY ("Id"),
CONSTRAINT "FK_mm_inventory_mm_material_MaterialId" FOREIGN KEY ("MaterialId")
REFERENCES public.mm_material ("Id") MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE,
CONSTRAINT "FK_mm_inventory_mm_warehouse_WarehouseId" FOREIGN KEY ("WarehouseId")
REFERENCES public.mm_warehouse ("Id") MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE CASCADE
)
-- 索引略
;
为了测试,我们向这张物料单表中插入大概10万条测试数据:
对于一个分类问题,假设有N种类别,不妨记作 [ "A类", "B类", "C类", "D类", ...]
,有时候我们可能倾向于直接用数字编号表示,表示成 [ 0, 1, 2, 3, ...]
。但是问题是数字编号预设了一个不应该存在的限制:我们在任意两个类别之间强加了比较关系,比如"D类"(类别3) > "B类"(类别2)。一方面,这种类别之间的大小比较毫无意义。另一方面,这种顺序会导致距离测算错误。
假设某个情况是"D类"(类别3) 。在第一种情况下,它被我们错误的分类成了"A类"(类别0) ,这时候二者距离是 3 - 0 =3;在第二种情况下,它被我们错误分类成了"C类"(类别2) ,这时候二者的距离是 3 -2 = 1。这表明,在这种机制下,把"D类"归类成"C类"这种情况,会被当做优于把"D类"归类成"A类"这种情况,这会极大程度上误导机器学习朝着更优的方向进行。
一种解决办法是采用one-hot编码。拿上面的例子来说:
[1, 0, 0, 0, ...]
[0, 1, 0, 0, ...]
[0, 0, 1, 0, ...]
[0, 0, 0, 1, ...]
由于这些向量都是单位正交向量,任意两个向量之间的余弦距离都是一样的,这表明类别归类错误程度("距离")在这种机制下可以被正确计算。