python - 使用标签传播/传播对具有多个标签的数据帧训练缺失标签

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

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

最佳答案

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

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 个数据点,下面显示的是截断版本:

enter image description here

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

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

输出:

enter image description here

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

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)

关于python - 使用标签传播/传播对具有多个标签的数据帧训练缺失标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69956151/

相关文章:

machine-learning - 我可以在 GPU 上运行包含 seaborn 代码的 jupyter 笔记本吗?

python - 提取二维二进制数组的索引

python - 如何仅对数据集的特定列进行标签编码?

python - 对动态框架中的数据进行透视/分组

python - 在python中使用Boto3从dynamodb获取结果并解析成可用的变量或字典

python - 如何在背景中绘制文字和图像?

python - 在Python中加密Windows exe文件

machine-learning - 回归分析中的分类和序数特征数据表示?

python - 使用 sklearn 中的拟合进行协方差估计时出错

python - 在 sklearn 中使用数据标签自定义 transformerMixin