গ্রাফ কাঠামোগত ডেটাতে সাইকিট-লার্ন লেবেল প্রচার কীভাবে ব্যবহার করবেন?


11

আমার গবেষণার অংশ হিসাবে, আমি একটি গ্রাফে লেবেল প্রচার সম্পাদন করতে আগ্রহী। আমি এই দুটি পদ্ধতিতে বিশেষত আগ্রহী:

  • জিয়াজিন ঝু ও জউবিন ঘড়ামণি। লেবেল প্রচারের সাথে লেবেলযুক্ত এবং লেবেলযুক্ত ডেটা থেকে শিক্ষা নেওয়া। প্রযুক্তিগত প্রতিবেদন CMU-CALD-02-107, কার্নেগি মেলন বিশ্ববিদ্যালয়, ২০০২ http://pages.cs.wisc.edu/~jerryzhu/pub/CMU-CALD-02-107.pdf
  • দেঙ্গিয়াং ঝো, অলিভিয়ার বাউসকেট, টমাস নবীন লাল, জেসন ওয়েস্টন, বার্নহার্ড শোয়েলকোফ। স্থানীয় এবং বৈশ্বিক ধারাবাহিকতার সাথে শেখা (2004) http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.115.3219

আমি দেখেছি যে সাইকিট-লার্ন এটি করার জন্য একটি মডেল সরবরাহ করে। তবে এই মডেলটি ভেক্টর স্ট্রাকচার্ড ডেটাতে প্রয়োগ করার কথা রয়েছে ( যেমন ডেটা পয়েন্ট) ।

মডেলটি কার্নেল ব্যবহার করে ডেটা পয়েন্টগুলি থেকে একটি অ্যাফিনিটি ম্যাট্রিক্স তৈরি করে এবং তারপরে নির্মিত ম্যাট্রিক্সে অ্যালগরিদম চালায়। আমি অনুরূপতা ম্যাট্রিক্সের জায়গায় আমার গ্রাফের সংলগ্ন ম্যাট্রিক্সকে সরাসরি ইনপুট করতে সক্ষম হতে চাই।

কীভাবে তা অর্জন করবেন সে সম্পর্কে কোনও ধারণা? বা আপনি কি এমন কোনও পাইথন লাইব্রেরি জানেন যা উল্লিখিত দুটি পদ্ধতির জন্য গ্রাফ স্ট্রাকচার্ড ডেটাতে সরাসরি লেবেল প্রচার চালানোর অনুমতি দেবে?

আপনার সাহায্যের জন্য আগাম ধন্যবাদ!


আপনি কি সাইকিট-লার্নিং সোর্স কোডটি পরীক্ষা করে দেখেছেন এটি ম্যাট্রিক্স অ্যাফিলিটি গণনার পরে কী করে? হয়তো আপনার পার্শ্ববর্তী ম্যাট্রিক্সে সরাসরি প্রয়োগ করার জন্য এই অংশটির পরে কোডটি "অনুলিপি" করতে পারে।
তাসোস

আপনার মন্তব্যের জন্য ধন্যবাদ! সুতরাং, আসলে, আমি বর্তমানে এটিই করছি, তবে আমার প্রয়োজন অনুসারে কোডটি সংশোধন করার দরকারের কিছু অংশ কিছুটা রহস্যজনক। আমি আশঙ্কা করছি যে সেগুলি আবার লিখলে ত্রুটি ঘটবে। আমি আশা করছিলাম সেখানে আরও সোজা পদ্ধতি আছে।
থাইবাড মার্টিনেজ

1
Github.com/scikit-learn/scikit-learn/blob/7389dba/sklearn/… - এ উত্স কোডটি বলে যে বাস্তবায়নগুলি _ বিল্ড_গ্রাফিক পদ্ধতিকে ওভাররাইড করে। সুতরাং প্রাকৃতিকভাবে আপনার এমন একটি উদ্ভূত শ্রেণি তৈরির চেষ্টা করা উচিত যা প্রাকম্পিউটেড ম্যাট্রিক্স গ্রহণ করে।
মিকালাই

উত্তর:


2

এখানে আমার নিজের প্রশ্নের উত্তর দেওয়া, যেমনটি আমি আশা করি এটি কিছু পাঠকের পক্ষে কার্যকর হবে।

সাইকিট-লার্ন প্রাথমিকভাবে ভেক্টর স্ট্রাকচার্ড ডেটা নিয়ে কাজ করার জন্য ডিজাইন করা হয়েছে। অতএব, আপনি যদি গ্রাফ-কাঠামোগত ডেটাতে লেবেল প্রচার / লেবেল ছড়িয়ে দিতে চান তবে আপনি সম্ভবত স্কাইকিট ইন্টারফেস ব্যবহার না করে নিজেই পদ্ধতিটি পুনরায় সংশোধন করার চেয়ে ভাল।

পাইটর্চে লেবেল প্রচার এবং লেবেল স্প্রেডিংয়ের একটি বাস্তবায়ন এখানে রয়েছে।

দুটি পদ্ধতি সামগ্রিকভাবে একই অ্যালগরিদমিক পদক্ষেপগুলি অনুসরণ করে, কীভাবে সংলগ্ন ম্যাট্রিক্সটি স্বাভাবিক করা হয় এবং প্রতিটি পদক্ষেপে কীভাবে লেবেলগুলি প্রচার করা হয় তার বিভিন্নতার সাথে। সুতরাং, আসুন, আমাদের দুটি মডেলের জন্য একটি বেস ক্লাস তৈরি করা যাক।

from abc import abstractmethod
import torch

class BaseLabelPropagation:
    """Base class for label propagation models.

    Parameters
    ----------
    adj_matrix: torch.FloatTensor
        Adjacency matrix of the graph.
    """
    def __init__(self, adj_matrix):
        self.norm_adj_matrix = self._normalize(adj_matrix)
        self.n_nodes = adj_matrix.size(0)
        self.one_hot_labels = None 
        self.n_classes = None
        self.labeled_mask = None
        self.predictions = None

    @staticmethod
    @abstractmethod
    def _normalize(adj_matrix):
        raise NotImplementedError("_normalize must be implemented")

    @abstractmethod
    def _propagate(self):
        raise NotImplementedError("_propagate must be implemented")

    def _one_hot_encode(self, labels):
        # Get the number of classes
        classes = torch.unique(labels)
        classes = classes[classes != -1]
        self.n_classes = classes.size(0)

        # One-hot encode labeled data instances and zero rows corresponding to unlabeled instances
        unlabeled_mask = (labels == -1)
        labels = labels.clone()  # defensive copying
        labels[unlabeled_mask] = 0
        self.one_hot_labels = torch.zeros((self.n_nodes, self.n_classes), dtype=torch.float)
        self.one_hot_labels = self.one_hot_labels.scatter(1, labels.unsqueeze(1), 1)
        self.one_hot_labels[unlabeled_mask, 0] = 0

        self.labeled_mask = ~unlabeled_mask

    def fit(self, labels, max_iter, tol):
        """Fits a semi-supervised learning label propagation model.

        labels: torch.LongTensor
            Tensor of size n_nodes indicating the class number of each node.
            Unlabeled nodes are denoted with -1.
        max_iter: int
            Maximum number of iterations allowed.
        tol: float
            Convergence tolerance: threshold to consider the system at steady state.
        """
        self._one_hot_encode(labels)

        self.predictions = self.one_hot_labels.clone()
        prev_predictions = torch.zeros((self.n_nodes, self.n_classes), dtype=torch.float)

        for i in range(max_iter):
            # Stop iterations if the system is considered at a steady state
            variation = torch.abs(self.predictions - prev_predictions).sum().item()

            if variation < tol:
                print(f"The method stopped after {i} iterations, variation={variation:.4f}.")
                break

            prev_predictions = self.predictions
            self._propagate()

    def predict(self):
        return self.predictions

    def predict_classes(self):
        return self.predictions.max(dim=1).indices

মডেল গ্রাফের সংলগ্ন ম্যাট্রিক্স এবং নোডগুলির লেবেলগুলিকে ইনপুট হিসাবে গ্রহণ করে। লেবেলগুলি লেবেলযুক্ত নোডের অবস্থানে -1 দিয়ে প্রতিটি নোডের শ্রেণি সংখ্যা নির্দেশ করে একটি পূর্ণসংখ্যার ভেক্টরের আকারে থাকে।

লেবেল প্রচার অ্যালগরিদম নীচে উপস্থাপন করা হয়।

ওয়াট: গ্রাফের সংলগ্ন ম্যাট্রিক্স তির্যক ডিগ্রি ম্যাট্রিক্স গণনা করুন ডি দ্বারা ডিআমিআমিΣওয়াটআমি আরম্ভ ওয়াই^(0)(Y1,...,Y,0,0,...,0) পুনরুক্তি  1। ওয়াই^(টি+ +1)ডি-1ওয়াটওয়াই^(টি) 2। ওয়াই^(টি+ +1)ওয়াই রূপান্তর পর্যন্ত ওয়াই^() লেবেল পয়েন্ট এক্সআমি এর চিহ্ন দ্বারা Y^আমি()

থেকে Xiaojin চু এবং Zoubin Ghahramani। লেবেল প্রচারের সাথে লেবেলযুক্ত এবং লেবেলযুক্ত ডেটা থেকে শিক্ষা নেওয়া। প্রযুক্তিগত প্রতিবেদন CMU-CALD-02-107, কার্নেগি মেলন বিশ্ববিদ্যালয়, 2002

আমরা নিম্নলিখিত বাস্তবায়ন পেতে।

class LabelPropagation(BaseLabelPropagation):
    def __init__(self, adj_matrix):
        super().__init__(adj_matrix)

    @staticmethod
    def _normalize(adj_matrix):
        """Computes D^-1 * W"""
        degs = adj_matrix.sum(dim=1)
        degs[degs == 0] = 1  # avoid division by 0 error
        return adj_matrix / degs[:, None]

    def _propagate(self):
        self.predictions = torch.matmul(self.norm_adj_matrix, self.predictions)

        # Put back already known labels
        self.predictions[self.labeled_mask] = self.one_hot_labels[self.labeled_mask]

    def fit(self, labels, max_iter=1000, tol=1e-3):
        super().fit(labels, max_iter, tol)

লেবেল স্প্রেডিং অ্যালগরিদম হ'ল:

ওয়াট: গ্রাফের সংলগ্ন ম্যাট্রিক্স তির্যক ডিগ্রি ম্যাট্রিক্স গণনা করুন ডি দ্বারা ডিআমিআমিΣওয়াটআমি নরমালাইজড গ্রাফ ল্যাপ্লেসিয়ান গণনা করুন এলডি-1/2ওয়াটডি-1/2 আরম্ভ ওয়াই^(0)(Y1,...,Y,0,0,...,0) একটি পরামিতি চয়ন করুন α[0,1) পুনরুক্তি ওয়াই^(টি+ +1)αএলওয়াই^(টি)+ +(1-α)ওয়াই^(0) রূপান্তর পর্যন্ত ওয়াই^() লেবেল পয়েন্ট এক্সআমি এর চিহ্ন দ্বারা Y^আমি()

থেকে Dengyong ঝু, অলিভিয়ের Bousquet, টমাস নবীন লাল, জেসন ওয়েসটন, বের্নহার্ট Schoelkopf। স্থানীয় এবং বৈশ্বিক ধারাবাহিকতার সাথে শেখা (2004)

বাস্তবায়ন তাই, নিম্নলিখিত।

class LabelSpreading(BaseLabelPropagation):
    def __init__(self, adj_matrix):
        super().__init__(adj_matrix)
        self.alpha = None

    @staticmethod
    def _normalize(adj_matrix):
        """Computes D^-1/2 * W * D^-1/2"""
        degs = adj_matrix.sum(dim=1)
        norm = torch.pow(degs, -0.5)
        norm[torch.isinf(norm)] = 1
        return adj_matrix * norm[:, None] * norm[None, :]

    def _propagate(self):
        self.predictions = (
            self.alpha * torch.matmul(self.norm_adj_matrix, self.predictions)
            + (1 - self.alpha) * self.one_hot_labels
        )

    def fit(self, labels, max_iter=1000, tol=1e-3, alpha=0.5):
        """
        Parameters
        ----------
        alpha: float
            Clamping factor.
        """
        self.alpha = alpha
        super().fit(labels, max_iter, tol)

আসুন এখন সিন্থেটিক ডেটাতে আমাদের প্রচারের মডেলগুলি পরীক্ষা করি। এটি করতে, আমরা একটি ক্যাভম্যান গ্রাফ ব্যবহার করতে পছন্দ করি ।

import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt

# Create caveman graph
n_cliques = 4
size_cliques = 10
caveman_graph = nx.connected_caveman_graph(n_cliques, size_cliques)
adj_matrix = nx.adjacency_matrix(caveman_graph).toarray()

# Create labels
labels = np.full(n_cliques * size_cliques, -1.)

# Only one node per clique is labeled. Each clique belongs to a different class.
labels[0] = 0
labels[size_cliques] = 1
labels[size_cliques * 2] = 2
labels[size_cliques * 3] = 3

# Create input tensors
adj_matrix_t = torch.FloatTensor(adj_matrix)
labels_t = torch.LongTensor(labels)

# Learn with Label Propagation
label_propagation = LabelPropagation(adj_matrix_t)
label_propagation.fit(labels_t)
label_propagation_output_labels = label_propagation.predict_classes()

# Learn with Label Spreading
label_spreading = LabelSpreading(adj_matrix_t)
label_spreading.fit(labels_t, alpha=0.8)
label_spreading_output_labels = label_spreading.predict_classes()

# Plot graphs
color_map = {-1: "orange", 0: "blue", 1: "green", 2: "red", 3: "cyan"}
input_labels_colors = [color_map[l] for l in labels]
lprop_labels_colors = [color_map[l] for l in label_propagation_output_labels.numpy()]
lspread_labels_colors = [color_map[l] for l in label_spreading_output_labels.numpy()]

plt.figure(figsize=(14, 6))
ax1 = plt.subplot(1, 4, 1)
ax2 = plt.subplot(1, 4, 2)
ax3 = plt.subplot(1, 4, 3)

ax1.title.set_text("Raw data (4 classes)")
ax2.title.set_text("Label Propagation")
ax3.title.set_text("Label Spreading")

pos = nx.spring_layout(caveman_graph)
nx.draw(caveman_graph, ax=ax1, pos=pos, node_color=input_labels_colors, node_size=50)
nx.draw(caveman_graph, ax=ax2, pos=pos, node_color=lprop_labels_colors, node_size=50)
nx.draw(caveman_graph, ax=ax3, pos=pos, node_color=lspread_labels_colors, node_size=50)

# Legend
ax4 = plt.subplot(1, 4, 4)
ax4.axis("off")
legend_colors = ["orange", "blue", "green", "red", "cyan"]
legend_labels = ["unlabeled", "class 0", "class 1", "class 2", "class 3"]
dummy_legend = [ax4.plot([], [], ls='-', c=c)[0] for c in legend_colors]
plt.legend(dummy_legend, legend_labels)

plt.show()

প্রয়োগ করা মডেলগুলি সঠিকভাবে কাজ করে এবং গ্রাফের সম্প্রদায়গুলি সনাক্ত করতে দেয়।

লেবেল প্রচার এবং লেবেল ছড়িয়ে প্রয়োগের প্রয়োগগুলি একটি ক্যাভম্যান গ্রাফে পরীক্ষিত

দ্রষ্টব্য: উপস্থাপিত বংশবিস্তার পদ্ধতিগুলি নির্দেশিত গ্রাফগুলিতে ব্যবহার করা বোঝায়।

কোডটি এখানে একটি ইন্টারেক্টিভ জুপিটার নোটবুক হিসাবে উপলব্ধ ।

দপ্তরী

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.