Шаблон стратегии при реализации алгоритмов машинного обучения для задач науки о данных в Python.

Шаблон стратегии — это широко используемый шаблон проектирования для реализации алгоритмов. Он используется для того, чтобы сделать поведение объекта динамичным.

Существует несколько алгоритмов, которые можно использовать для решения задачи кластеризации, такие как кластеризация Kmeans, DBSCAN, иерархическая кластеризация и т. д. Шаблон стратегии позволяет группировать эти алгоритмы, инкапсулировать и использовать их взаимозаменяемо.

Поскольку семейство алгоритмов используется для решения конкретной задачи, они имеют схожие входные и выходные данные.

Прежде чем перейти к шаблону стратегии, давайте вспомним принципы SOLID для объектно-ориентированного проектирования.

Пример :

Объединить учащихся в группы «n» в зависимости от их академической успеваемости.

Вышеупомянутая проблема кластеризации должна поддерживать Kmeans, DBSCAN, алгоритмы иерархической кластеризации. Это также должно быть расширено до новых алгоритмов.

Как показано в следующем коде, класс «ClusteringAlgo» подчиняется принципу единой ответственности SOLID, согласно которому каждый класс должен отвечать за одну задачу, в этом случае за назначение выбранного алгоритма для применения.

clustering_algo = ClusteringAlgo(Algorithm.kmeans)
clustering = Clustering()
cluster = clustering.cluster(clustering_algo)
###########################################################
class ClusteringAlgo(object):
def __init__(self, algo):
        self._algo = algo
@property
    def algo(self)
        return self._algo
class Algorithm(object):
    
    kmeans = 1
    DBSCAN = 2
    hierarchial= 3
class Clustering(object):
    
    def cluster(self, clustering_algo, input):
        if clustering_algo.algo == Algorithm.kmeans:
            return kmeans(input)
        elif clustering_algo.algo == Algorithm.DBSCAN:
            return ....
        elif ...........
        else:
            raise ValueError("Invalid Algorithm")

Но класс «Кластеризация» следует изменить, добавив «если еще», чтобы добавить новый алгоритм. Это нарушает принцип открытости/закрытости, согласно которому класс должен быть открыт для наследования, но закрыт для изменений. Наличие слишком большого количества условий If-Else является признаком нарушения SOLID.

Существует также другое нарушение принципа SOLID, если оно видно выше класса «Кластеризация», то есть создание экземпляра нового объекта «кластеризация» и программирование реализации «кластера» метод. Это нарушает инверсию зависимостей «D», которая всегда направлена ​​на абстракцию, а не на реализацию.

Приведенный выше код нарушает следующие принципы:

  1. Открытый/Закрытый Принцип
  2. Инверсия зависимости

Паттерн стратегии можно использовать для устранения вышеуказанных нарушений. На следующей диаграмме UML показан шаблон стратегии. Контекст слева использует интерфейс стратегии для вызова различных алгоритмов, определенных конкретными стратегиями, которые реализуют базовый класс.

Реализованная конкретная стратегия использует ту же структуру, ввод и вывод интерфейса, который называется ABC (абстрактный базовый класс) в терминологии Python.

Ниже приведена реализация абстрактной стратегии.

from abc import ABCMeta, abstractmethod
class AbsStrategy(object):
    __metaclass__ = ABCMeta
@abstractmethod
    def cluster(self, clustering_algo, input):
    """clustering Algo"""

Теперь, когда мы внедрили абстрактный базовый класс, нам нужно реализовать стратегии для каждого отдельного алгоритма.

import AbsStrategy
class KmeansStrategy(AbsStartegy):
    def cluster(self, input):
    """implement kmeans"""

Class DBSCANStrategy(AbsStrategy):
    def cluster(self, input):
    """Implement DBSCAN"""

Class HierarchialStrategy(AbsStrategy):
    def cluster(self, input):
    """Implement Hierarchial"""

Теперь, когда у нас есть эта реализация, основная программа выглядит так

import HierarchialStrategy, DBSCANStrategy, KmeansStrategy
clustering_algo = ClusteringAlgo(Algorithm.kmeans)
strategy = KmeansStrategy()
clustering = Clustering(strategy)
cluster = clustering.cluster(clustering_algo)

Достижения путем рефакторинга кода, как указано выше

  1. Больше никаких нарушений принципа Open/Closed
  2. Алгоритмы легко тестируются.

Нарушение инверсии зависимостей все еще существует, давайте посмотрим в следующей статье, как это исправить с помощью фабричного шаблона.

Предпосылки:

Чтобы извлечь максимальную пользу из приведенной выше статьи, вам помогут следующие знания.

  1. Понимание концепций ООП.
  2. Понимание синтаксиса Python.