Fisher分类器/LDA

来源:互联网 发布:java源文件的扩展名 编辑:程序博客网 时间:2024/06/04 01:34

最近看特征选择的方法,有一篇文章提到用fisher score来挑选特征

然后就顺手回顾一下fisher分类器和LDA


先来说LDA,不同于PCA, LDA是有监督的降维,需要类标签

它的想法是我们希望投影过后类内样本的距离尽可能小,类间样本的距离尽可能大,所以它想到用一个除式作为目标函数来求解


其中分子为样本间距离,分子为类内样本方差之和

我们通过拉格朗日乘子展开对w求偏导,和PCA一样又能转化为求特征值和特征向量的问题


当我们把它映射到一维上时,我们很自然想到设阈值对其进行分类,于是乎fisher分类器就整出来了


开工写代码

class Fisher:    def __init__(self):        self._w = self._b = None    def fit(self, x, y):        x, y = np.asarray(x, dtype=np.float32), np.asarray(y, dtype=np.float32)        x0, x1 = np.mean(x[y == -1], axis=0), np.mean(x[y == 1], axis=0)        Sb = x0.reshape(len(x0), 1).dot(x1.reshape(1, len(x1)))        Sw = (x[y == -1]-x0).T.dot(x[y == -1]-x0) + (x[y == 1]-x1).T.dot(x[y == 1]-x1)        w, _, _ = np.linalg.svd(np.linalg.inv(Sw).dot(Sb))        self._w = w[:, 0]        self._b = 0.        self._b = np.mean(y-self.predict(x, raw=True))        if (lda.predict(x) == y).mean() < 0.5:            self._w = -self._w            self._b = -self._b    def predict(self, x, raw=False):        pre = x.dot(self._w)+self._b        if raw:            return pre        else:            return np.sign(pre).astype(np.float32)
看看效果



不错,收....


日常等等


值得一提的是SB,哦不Sb这个用以衡量类间距离的矩阵的秩最大为C-1(C为类别数目),因为最后一个μc可以用μ1...μc-1来表示


收工。

原创粉丝点击