为了账号安全,请及时绑定邮箱和手机立即绑定

标签传播(llgc)实现

标签:
算法

下面通过 Python 写了一个可以通过修改 sigma 参数的 lgc (Learning with Local and Global Consistency1)模型。参考 Wittawat Jitkrittum 解读

下面是具体的代码细节:

%matplotlib inline
import numpy as np
from sklearn.metrics import pairwise_distances


def calculate_W(X, sigma, Y=None):
    dm = pairwise_distances(X, Y, metric='euclidean')
    W = rbf(dm, sigma)
    np.fill_diagonal(W, 0)  # 对角线全为 0
    return W


def one_hot(labels):
    '''
    对标签做 one_hot 编码

    参数
    =====
    n_classes: 
    '''
    label_dict = dict(enumerate(np.unique(labels)))
    n_classes = len(label_dict)  # 类别数
    index_dict = {v: k for k, v in label_dict.items()}
    Y = np.asanyarray([index_dict[label] for label in labels])
    out = Y[:, None] == np.arange(n_classes)
    return out.astype(float), label_dict


def rbf(x, sigma):
    return np.exp((-x) / (2 * sigma**2))


class LGC:
    def __init__(self, x_l, x_u, y_l, sigma, epochs):
        self._epochs = epochs
        self._X = np.concatenate([x_l, x_u])
        Y_l, self.label_dict = one_hot(y_l)
        self.labels = y_l
        self.n_classes = len(self.label_dict)
        Y_u = np.zeros((x_u.shape[0], self.n_classes))
        self._sigma = sigma
        self._input = np.concatenate([Y_l, Y_u])

    @property
    def sigma(self):
        return self._sigma

    @sigma.setter
    def sigma(self, value):
        return value

    @property
    def W(self):
        dm = pairwise_distances(self._X, metric='cosine')  # 余弦距离
        W = rbf(dm, self.sigma)
        np.fill_diagonal(W, 0)  # 对角线全为 0
        return W

    @property
    def D(self):
        # calculate D
        diago = np.sum(self.W, axis=1)
        return np.diag(diago)

    @property
    def S(self):
        d = np.sum(self.W, axis=1)
        # S 是 np.sqrt(np.dot(diag(D),diag(D)^T))
        S = np.sqrt(d * d[:, np.newaxis])
        return np.divide(self.W, S, where=S != 0)

    def fit(self, alpha):
        self.F = self._input
        for t in range(self._epochs):
            self.F = np.dot(self.S, self.F) * alpha + (1 - alpha) * self._input

    def score(self, y_u):
        return (self.F.argmax(1)[len(self.labels):] == y_u).mean()


def test_lgc(lgc_params):
    from matplotlib import pyplot as plt
    lc = np.arange(.1, 1, 0.09)
    lscore = []

    for c in lc:
        model = LGC(*lgc_params)
        model.fit(c)
        lscore.append(model.score(y_u))

    print("The best c: %f" % lc[np.argmax(np.array(lscore))])
    print("The best score: %f" % np.max(np.array(lscore)))
    plt.figure(figsize=(6, 6))
    plt.plot(lc, lscore)
    plt.title('The lgc score influenced by alpha')
    plt.xlabel('alpha')
    plt.ylabel('accuracy')
    plt.grid()
    plt.show()


if __name__ == "__main__":
    from sklearn.datasets import make_moons
    n = 800  # 样本数
    n_labeled = 10  # 有标签样本数
    X, Y = make_moons(n, shuffle=True, noise=0.1, random_state=1000)
    x_l, x_u = X[:n_labeled], X[n_labeled:]
    y_l, y_u = Y[:n_labeled], Y[n_labeled:]
    epochs = 200
    sigma = .2
    lgc_params = x_l, x_u, y_l, sigma, epochs
    test_lgc(lgc_params)
The best c: 0.280000
The best score: 0.829114

图片描述

详细内容见:动手实践标签传播算法


  1. Zhou D, Bousquet O, Lal T N, et al. Learning with Local and Global Consistency[C]. neural information processing systems, 2003: 321-328. ↩︎

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消