【问题标题】:Training missing labels using Label Propagation/Spreading for a dataframe with several labels使用标签传播/传播为具有多个标签的数据框训练缺少的标签
【发布时间】:2021-12-25 13:59:38
【问题描述】:

下面的示例用于在应用于我的数据集之前使用虚拟数据集(此处参考:https://scikit-learn.org/stable/auto_examples/semi_supervised/plot_label_propagation_digits.html)测试标签传播算法。

import numpy as np
from sklearn import datasets

digits = datasets.load_digits()
rng = np.random.RandomState(2)
indices = np.arange(len(digits.data))
rng.shuffle(indices)

X = digits.data[indices[:340]]
y = digits.target[indices[:340]]
images = digits.images[indices[:340]]

tot_samples = len(y)
labeled_points = 40

indices = np.arange(tot_samples)

non_labeled_set = indices[labeled_points:]

# Shuffle
y_train = np.copy(y)
y_train[non_labeled_set] = -1

我想将标签传播应用于我拥有并具有以下字段的现有数据集:

User1   User2     Class   Weight
A1       B1         1      2.1
A1       C1         1      3.3
A2       D3        -1      2.1
C3       C1         0      2.5
D1       A1         1      1.3
C3       D1        -1      2.5
A2       A4        -1      1.5

类是 User1 的属性。 节点是 A1、A2、B1、C1、C3、D1、D3、A4,但只有 A1、A2、C3 和 D1 有标签。其他人(B1、C1、D3、A4)没有。我想使用标签传播算法来预测他们的标签。 有人可以解释我如何在我的情况下应用上述代码,因为挑战在于确定多个标签?我认为它应该仍然有效,即使我正在考虑多类数据样本。

根据所考虑的算法,我认为它需要根据权重将标签传播到相邻的未标记节点。此步骤应重复多次,直到最终未标记节点上的标签达到平衡(这将是这些节点的预测)。

我希望得到以下输出:

B1: 1
C1: 0
D3: -1
A4: -1

【问题讨论】:

  • 您想替换哪些值以及您想用什么替换它们?
  • 嗨 itprorh66。我的数据集已完全标记,因此我需要在其上测试算法以查看输出是否令人满意。我想在每个类中保留一个/两个标签,并确定剩余的,如果可能的话,无论哪些值将被替换。我可能希望其他未标记的可以通过算法找到。我知道这是一个具有挑战性的数据集,因为它包含多个类。我希望这是有道理的,如果没有,请告诉我。谢谢
  • 很抱歉,您的解释并不能帮助我理解您的问题。您能否提供一个示例,说明您的输入以及您想要的输出是什么样的?
  • 我试着编辑一下这个问题。希望现在应该更清楚一点。我已经包含了一个权重边缘属性(我最初忘记包含它)和预期的输出(它可能略有不同)。如果还不清楚,请告诉我。谢谢

标签: python machine-learning scikit-learn multilabel-classification


【解决方案1】:

让我们首先制作一些要使用的数据。由于我们在用户之间创建随机配对,以及随机类标签,预测将没有意义,但是,它将帮助我们运行和说明代码。

import random
import numpy as np
import pandas as pd

from sklearn.preprocessing import OneHotEncoder
from sklearn.semi_supervised import LabelSpreading

seed = 0
random.seed(seed)
np.random.seed(seed)

u_nodes = ['A1', 'A2', 'B1', 'C1', 'C3', 'D1', 'D3', 'A4']
n_nodes = len(u_nodes)

data = {'User1': [], 'User2': [], 'Class': [], 'Weight': []}
idxs = np.arange(n_nodes)
for u in u_nodes:
    data['User1'].extend([u]*n_nodes)
    data['User2'].extend(u_nodes) # we'll shuffle and remove duplicates in a bit
    cls = np.asarray([random.randint(0, 1) for i in range(n_nodes)])
    # delete two random labels
    cls[np.random.choice(idxs, 2)] = -1
    data['Class'].extend(list(cls))
    # build random weights in the range (0, 1)
    data['Weight'].extend([round(random.uniform(0, 1), 2) for i in range(n_nodes)])

df = pd.DataFrame(data)
df = df[~(df.User1 == df.User2)].sample(frac=1).reset_index(drop=True)
print(df)

生成了所有 56 个数据点,下面显示的是截断版本:

我们来看看标签缺失的点:

df_missing = df[df.Class == -1]
unlabeled_set = list(df_missing.index)
print(df_missing)

输出:

最后,编码特征并训练标签传播模型。

X = df[['User1', 'User2']]
y_train = df['Class'].values

enc = OneHotEncoder(sparse=False)
enc.fit(X[['User1']])

# using the same encoder assuming that the A1 whether as User1 or User2 are the same
X_train = np.concatenate((enc.transform(X[['User1']]), enc.transform(X[['User2']])), axis=1)

# without weights
lp_model = LabelSpreading(gamma=0.25, max_iter=20)
lp_model.fit(X_train, y_train)
predicted_labels = lp_model.transduction_[unlabeled_set]
print(predicted_labels)

估计的标签是从这个模型打印出来的。显然,这些没有任何意义,因为特征和标签都是随机生成的。

[0 1 1 0 1 0 0 0 1 1 1 1 1]

我还没有使用过权重。您需要按照本文档LabelSpreading

中的说明,根据数据的性质定义权重矩阵的内核

内核:

要使用的内核函数或内核函数本身的字符串标识符。只有‘rbf’和‘knn’字符串是有效的输入。传递的函数应该接受两个输入,每个输入的形状为 (n_samples, n_features),并返回一个 (n_samples, n_samples) 形状的权重矩阵。

一旦你定义了你的权重矩阵生成器my_kernel,你应该在构造函数中提供它,如下所示

lp_model = LabelSpreading(gamma=0.25, max_iter=20, kernel=my_kernel)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-19
    • 2020-12-01
    • 2020-02-17
    相关资源
    最近更新 更多