Haskell 多态性和类型类实例

Haskell polymorphism and typeclass instance

我正在尝试在 Haskell 中编写一个机器学习库,以提高我的 Haskell 技能。 我想到了一个涉及 class 的通用设计,如下所示:

  class Classifier classifier where
    train :: X -> y -> trainingData
    classify :: trainingData -> x -> y

例如,给定一组样本 X,以及它们的真实标签 y,训练 returns classify 函数中使用的 trainingData。

所以,如果我想实现 KNN,我会这样做:

data KNN = KNN Int (Int -> Int -> Float) 

其中第一个整数是邻居的数量,函数是计算向量之间距离的度量

  instance Classifier KNN where
---This is where I am stuck---

如何实现分类器类型 class 函数,使它们成为通用的 我将创建的所有 classifier? 我觉得我对待 Haskell 太像命令式的了 OOP 就像语言,我想用 Haskell 的方式来做这件事。

假设你的类型 class 不知道 classifier 提供什么,你可以做类似

class Classifier c where
  train :: [x] -> [y] -> c -> [(x,y)]
  classify :: [(x,y)] -> c -> x > y

在这里,train 正在获取 x 类型的样本列表、y 类型的标签列表以及某种类型 class 的 classifier c,并且需要 return sample/label 对的列表。

classify 获取 sample/label 对的列表(例如由 train 生成的)、classifier 和一个样本,并生成一个新标签.

(不过,至少,我可能会将 [(x,y)] 替换为 Map x y。)

关键是 classifier 本身需要同时被 trainclassify 使用,尽管你不需要知道这看起来像什么时间。

您的 KNN 实例可能看起来像

instance Classifier KNN where

  train samples labels (KNN n f) = ...
  classify td (KNN n f) sample = ...

这里,nf 都可以用来创建训练数据,并帮助为样本点选择最接近的训练数据成员。

我会说你需要多参数类型 类(具有可选的功能依赖性或类型族;我忽略了那些)。

 class Classifier c s l  k where
      train :: c -> [(s, l)] -> k
      classify :: c -> k -> s -> l
      combine :: c -> k -> k -> k

分类器、样本、标签和知识类型之间存在四方关系。

train 方法从一组样本 (s) — 标签 (l) 对中导出一些知识 (k)。分类方法使用该知识来推断样本的标签。 (combine方法将两个知识拼接在一起,不知道是否总是适用)