使用 Label Propagation/Spreading 为具有多个标签的数据框训练缺失标签

Training missing labels using Label Propagation/Spreading for a dataframe with several labels

下面的示例用于在应用于我的数据集之前使用虚拟数据集(此处参考: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

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

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

我希望得到以下输出:

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

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

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 个数据点,下面显示的是 t运行 分类版本:

让我们看看缺少标签的点:

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

内核:

String identifier for kernel function to use or the kernel function itself. Only ‘rbf’ and ‘knn’ strings are valid inputs. The function passed should take two inputs, each of shape (n_samples, n_features), and return a (n_samples, n_samples) shaped weight matrix.

定义权重矩阵生成器后 my_kernel,您应该在构造函数中提供它,如下所示

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