Что такое метод класса в python и зачем нужен

Методы[править]

Методправить

Синтаксис описания метода ничем не отличается от описания функции, разве что его положением внутри класса и характерным первым формальным параметром , с помощью которого внутри метода можно ссылаться на сам экземпляр класса (название self является соглашением, которого придерживаются программисты на Python):

class MyClass(object):
    def mymethod(self, x):
        return x == self._x

Статический методправить

Статические методы в Python являются синтаксическими аналогами статических функций
в основных языках программирования. Они не получают ни экземпляр (),
ни класс () первым параметром.
Для создания статического метода (только классы могут иметь статические методы) используется

>>> class D(object):  
       @staticmethod
       def test(x):
           return x == 
...
>>> D.test(1)    # доступ к статическому методу можно получать и через класс
False
>>> f = D()
>>> f.test()    # и через экземпляр класса
True

Статические методы реализованы с помощью
.

Метод классаправить

Классовые методы в Python занимают промежуточное положение между
статическими и обычными. В то время как обычные методы получают первым
параметром экземпляр класса, а статические не получают ничего, в классовые
методы передается класс. Возможность создания классовых методов является
одним из следствий того, что в Python классы также являются объектами.
Для создания классового (только классы могут иметь классовые методы) метода можно использовать
декоратор

>>> class A(object):  
      def __init__(self, int_val):
          self.val = int_val + 1
      @classmethod
      def fromString(cls, val):   # вместо self принято использовать cls
          return cls(int(val))
...
>>> class B(A):pass
...
>>> x = A.fromString("1")
>>> print x.__class__.__name__
A
>>> x = B.fromString("1")
>>> print x.__class__.__name__
B

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

Мультиметодыправить

Примером для иллюстрации сути мультиметода может служить функция из модуля :

>>> import operator as op
>>> print op.add(2, 2), op.add(2.0, 2), op.add(2, 2.0), op.add(2j, 2)
4 4.0 4.0 (2+2j)
from multimethods import Dispatch

class Asteroid(object): pass
class Spaceship(object): pass

def asteroid_with_spaceship(a1, s1): print "A-><-S"
def asteroid_with_asteroid(a1, a2): print "A-><-A"
def spaceship_with_spaceship(s1, s2): print "S-><-S"

collide = Dispatch()
collide.add_rule((Asteroid, Spaceship), asteroid_with_spaceship)
collide.add_rule((Asteroid, Asteroid), asteroid_with_asteroid)
collide.add_rule((Spaceship, Spaceship), spaceship_with_spaceship)
collide.add_rule((Spaceship, Asteroid), lambda x,y asteroid_with_spaceship(y,x))

a, s1, s2 = Asteroid(), Spaceship(), Spaceship()

collision1 = collide(a, s1)[
collision2 = collide(s1, s2)[

Исследовательский анализ данных

набор данныхмы будем использовать содержит 8124 экземпляров грибов с 22 функциями. Среди них мы находим форму крышки гриба, цвет крышки, цвет жабры, тип вуали и т. Д. Конечно, это также говорит нам, является ли гриб съедобным или ядовитым.

Давайте импортируем некоторые библиотеки, которые помогут нам импортировать данные и манипулировать ими. В вашей записной книжке запустите следующий код:

Общий первый шаг для проекта науки о данных состоит в том, чтобы выполнитьисследовательский анализ данных(ЭДА). Этот шаг обычно включает в себя изучение дополнительных данных, с которыми вы работаете. Возможно, вы захотите узнатьформавашего набора данных (сколько строк и столбцов), количество пустых значений и визуализировать части данных, чтобы лучше понять взаимосвязь между функциями и целью.

Импортируйте данные и увидите первые пять столбцов со следующим кодом:

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

После запуска этой ячейки кода вы должны увидеть первые пять строк. Вы замечаете, что каждая функция является категориальной, и для определения определенного значения используется буква. Конечно, классификатор не может принимать буквы в качестве входных данных, поэтому нам придется изменить это в конце концов.

Пока давайте посмотрим, если наш набор данныхнесбалансированный.Несбалансированный набор данных — это когдаодин класс гораздо больше, чем другой, В идеале, в контексте классификации, мы хотим равное количество экземпляров каждого класса. В противном случае нам нужно будет реализовать расширенные методы выборки, такие какпередискретизация меньшинства.

В нашем случае мы хотим посмотреть, есть ли в наборе данных равное количество ядовитых и съедобных грибов. Мы можем построить частоту каждого класса следующим образом:

И вы получите следующий график:


Подсчет каждого класса

Потрясающе! Это похоже на довольно сбалансированный набор данных с почти равным количеством ядовитых и съедобных грибов.

Теперь я хотел посмотреть, как каждая функция влияет на цель. Для этого я сделал гистограмму всех возможных значений, разделенных классом грибов. Делать это вручную для всех 22 функций не имеет смысла, поэтому мы создаем эту вспомогательную функцию:

оттенокдаст цветовой код ядовитому и съедобному классу.данныеПараметр будет содержать все функции, кроме класса гриба. Выполнение кода ячейки ниже:

Вы должны получить список из 22 участков. Вот пример вывода:


Поверхность крышки

Потратьте некоторое время на просмотр всех графиков.

Теперь посмотрим, есть ли у нас пропущенные значения. Запустите этот кусок кода:

И вы должны увидеть каждый столбец с количеством пропущенных значений. К счастью, у нас есть набор данных без пропущенных значений. Это очень редко, но мы не будем жаловаться.

Что такое self?

Классам нужен способ, что ссылаться на самих себя. Это не из разряда нарциссичного отношения со стороны класса. Это способ сообщения между экземплярами. Слово self это способ описания любого объекта, буквально. Давайте взглянем на пример, который мне кажется наиболее полезным, когда я сталкиваюсь с чем-то новым и странным:Добавьте этот код в конец класса, который вы написали ранее и сохраните:

Python

class Vehicle(object):
«»»docstring»»»

def __init__(self, color, doors, tires):
«»»Constructor»»»
self.color = color
self.doors = doors
self.tires = tires

def brake(self):
«»»
Stop the car
«»»
return «Braking»

def drive(self):
«»»
Drive the car
«»»
return «I’m driving!»

if __name__ == «__main__»:
car = Vehicle(«blue», 5, 4)
print(car.color)

truck = Vehicle(«red», 3, 6)
print(truck.color)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

classVehicle(object)

«»»docstring»»»

def__init__(self,color,doors,tires)

«»»Constructor»»»

self.color=color

self.doors=doors

self.tires=tires

defbrake(self)

«»»

        Stop the car
        «»»

return»Braking»

defdrive(self)

«»»

        Drive the car
        «»»

return»I’m driving!»

if__name__==»__main__»

car=Vehicle(«blue»,5,4)

print(car.color)

truck=Vehicle(«red»,3,6)

print(truck.color)

Условия оператора if в данном примере это стандартный способ указать Пайтону на то, что вы хотите запустить код, если он выполняется как автономный файл. Если вы импортировали свой модуль в другой скрипт, то код, расположенный ниже проверки if не заработает. В любом случае, если вы запустите этот код, вы создадите два экземпляра класса автомобиля (Vehicle): класс легкового и класс грузового. Каждый экземпляр будет иметь свои собственные атрибуты и методы. Именно по этому, когда мы выводи цвета каждого экземпляра, они и отличаются друг от друга. Причина в том, что этот класс использует аргумент self, чтобы указать самому себе, что есть что. Давайте немного изменим класс, чтобы сделать методы более уникальными:

Python

class Vehicle(object):
«»»docstring»»»

def __init__(self, color, doors, tires, vtype):
«»»Constructor»»»
self.color = color
self.doors = doors
self.tires = tires
self.vtype = vtype

def brake(self):
«»»
Stop the car
«»»
return «%s braking» % self.vtype

def drive(self):
«»»
Drive the car
«»»
return «I’m driving a %s %s!» % (self.color, self.vtype)

if __name__ == «__main__»:
car = Vehicle(«blue», 5, 4, «car»)
print(car.brake())
print(car.drive())

truck = Vehicle(«red», 3, 6, «truck»)
print(truck.drive())
print(truck.brake())

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

classVehicle(object)

«»»docstring»»»

def__init__(self,color,doors,tires,vtype)

«»»Constructor»»»

self.color=color

self.doors=doors

self.tires=tires

self.vtype=vtype

defbrake(self)

«»»

        Stop the car
        «»»

return»%s braking»%self.vtype

defdrive(self)

«»»

        Drive the car
        «»»

return»I’m driving a %s %s!»%(self.color,self.vtype)

if__name__==»__main__»

car=Vehicle(«blue»,5,4,»car»)

print(car.brake())

print(car.drive())

truck=Vehicle(«red»,3,6,»truck»)

print(truck.drive())

print(truck.brake())

В этом примере мы передаем другой параметр, чтобы сообщить классу, какой тип транспортного средства мы создаем. После этого мы вызываем каждый метод для каждого экземпляра. Если вы запустите данный код, вы получите следующий вывод:

Python

car braking
I’m driving a blue car!
I’m driving a red truck!
truck braking

1
2
3
4

car braking

I’m driving a blue car!

I’mdrivingared truck!

truck braking

Это показывает, как экземпляр отслеживает свой аргумент self. Вы также могли заметить, что мы можем переместить переменные атрибутов из метода __init__ в другие методы. Это возможно потому, что все эти атрибуты связанны с аргументом self. Если бы мы этого не сделали, переменные были бы вне области видимости в конце метода __init__ .

Инкапсуляция в Python

Это концепция упаковки данных так, что внешний мир имеет доступ только к открытым свойствам. Некоторые свойства могут быть скрыты, чтобы уменьшить уязвимость. Это так называемая реализация сокрытия данных. Например, вы хотите купить брюки с интернет-сайта. Данные, которые вам нужны, это их стоимость и доступность. Количество предметов и их расположение — это информация, которая вас не беспокоит. Следовательно, эта информация скрыта.

В Python это реализуется путем создания private, protected и public переменных и методов экземпляра.

Private свойства имеют двойное подчеркивание (__) в начале, в то время как protected имеют одиночное подчеркивание (_). По умолчанию, все остальные переменные и методы являются public.

Private атрибуты доступны только внутри класса и недоступны для дочернего класса (если он унаследован). Protected доступны внутри класса, но доступны и дочернему классу. Все эти ограничения сняты для public атрибутов.

Следующие фрагменты кода являются примером этой концепции:

Типы внутренних классов

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

1. Несколько Внутренних Классов

class Employe:
    def __init__(self):
       
       .intern()
       .head()

    def show(self):
        print('Employe List')
        print('Name:', self.name)

    class intern:
        def __init__(self):
           
           


        def display(self):
            print("Name:", self.name)
            print("Id:", self.Id)

    class head:


        def __init__(self):
           
           

        def display(self):
            print("Name:", self.name)
            print("Degree:", self.Id)

()
outer.show()
.intern.head
print()
d1.display()
print()
d2.display()

Выход:

Employe List
Name: Facebook
Name: Smith
Id: 657
Name: Auba
Degree: 007

Класс, имеющий внутри себя более одного внутреннего класса, называется множественным внутренним классом. Выше мы его успешно реализовали. Здесь класс Сотрудников-это наш внешний класс. Внутри которого мы создали 2 подкласса. Один из них носит имя Стажера, а другой-имя руководителя.

2. Многоуровневый внутренний класс

class multi:


    def __init__(self):

       .Inner()

       .inner.InnerInner()

    def show(self):
        print("This is Outer class")
        

    ## inner class
    class Inner:


        def __init__(self):

           .InnerInner()

        def show_classes(self):
            print("This is Inner class")
            print(self.innerinner)


        class InnerInner:

            def inner_display(self, msg):
                print("InnerInner class")
                print(msg)

        def inner_display(self, msg):
            print("This is Inner class")
            print(msg)
()
outer.show().Inner()

.InnerInner()


innerinner.inner_display("completed")

Выход:

This is Outer class
InnerInner class
completed

Многоуровневый класс можно понимать как класс, имеющий внутренний класс. Кроме того, у внутреннего класса есть внутренний класс. Из кода вы можете получить представление о том, как выполнить этот конкретный процесс. Оба типа просты в исполнении и понимании. Вы можете использовать их в соответствии с вашими потребностями.

9.4. Random Remarks¶

If the same attribute name occurs in both an instance and in a class,
then attribute lookup prioritizes the instance:

>>> class Warehouse
        purpose = 'storage'
        region = 'west'

>>> w1 = Warehouse()
>>> print(w1.purpose, w1.region)
storage west
>>> w2 = Warehouse()
>>> w2.region = 'east'
>>> print(w2.purpose, w2.region)
storage east

Data attributes may be referenced by methods as well as by ordinary users
(“clients”) of an object. In other words, classes are not usable to implement
pure abstract data types. In fact, nothing in Python makes it possible to
enforce data hiding — it is all based upon convention. (On the other hand,
the Python implementation, written in C, can completely hide implementation
details and control access to an object if necessary; this can be used by
extensions to Python written in C.)

Clients should use data attributes with care — clients may mess up invariants
maintained by the methods by stamping on their data attributes. Note that
clients may add data attributes of their own to an instance object without
affecting the validity of the methods, as long as name conflicts are avoided —
again, a naming convention can save a lot of headaches here.

There is no shorthand for referencing data attributes (or other methods!) from
within methods. I find that this actually increases the readability of methods:
there is no chance of confusing local variables and instance variables when
glancing through a method.

Often, the first argument of a method is called . This is nothing more
than a convention: the name has absolutely no special meaning to
Python. Note, however, that by not following the convention your code may be
less readable to other Python programmers, and it is also conceivable that a
class browser program might be written that relies upon such a convention.

Any function object that is a class attribute defines a method for instances of
that class. It is not necessary that the function definition is textually
enclosed in the class definition: assigning a function object to a local
variable in the class is also ok. For example:

# Function defined outside the class
def f1(self, x, y):
    return min(x, x+y)

class C
    f = f1

    def g(self):
        return 'hello world'

    h = g

Now , and are all attributes of class that refer to
function objects, and consequently they are all methods of instances of
— being exactly equivalent to . Note that this practice
usually only serves to confuse the reader of a program.

Methods may call other methods by using method attributes of the
argument:

class Bag
    def __init__(self):
        self.data = []

    def add(self, x):
        self.data.append(x)

    def addtwice(self, x):
        self.add(x)
        self.add(x)

Methods may reference global names in the same way as ordinary functions. The
global scope associated with a method is the module containing its
definition. (A class is never used as a global scope.) While one
rarely encounters a good reason for using global data in a method, there are
many legitimate uses of the global scope: for one thing, functions and modules
imported into the global scope can be used by methods, as well as functions and
classes defined in it. Usually, the class containing the method is itself
defined in this global scope, and in the next section we’ll find some good
reasons why a method would want to reference its own class.

Строки

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

Операции со строками

string извлекает символ в позиции i
string извлекает последний символ
string извлекает символы в диапазоне от i до j

Методы работы сос строками

string.upper() преобразует строку в верхний регистр
String.lower() преобразует в строку в нижний регистр
string.count(x) подсчитывает, сколько раз появляется x
string.find(x) позиция первой строки вхождения x
string.replace(x, y) заменяет x на y
string.strip(x) удаляет как начальные, так и конечные символы x
string.join (List) объединяет список строк

LDA для более чем одного предсказателя

Расширяя теперь для нескольких предикторов, мы должны предположить, чтоИксвзят измногомерное распределение Гаусса, с классом среднего вектора и общей ковариационной матрицей.

Пример коррелированного и некоррелированного гауссовского распределения показан ниже.


Слева: некоррелированное нормальное распределение. Справа: коррелированное нормальное распределение

Теперь, выражая дискриминантное уравнение с помощью векторной записи, получим:


Дискриминантное уравнение с матричной нотацией

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

__dict__

Переменные инстанса хранятся внутри инстанса. По сути инстанс и представляет из себя набор этих данных — всё остальное живёт в типе.

Самый распространённый метод хранения данных инстанса — переменная . Это словарь, который живёт под капотом инстанса класса: ключи — строки с названиями полей, значения — значения соответсвующих переменных. Пример:

Обратите внимание на поведение : она появилась в только после того, как была определена у инстанса класса. До этого её в не было, хотя она была доступна через (и вернула бы единицу)

— это не представление данных инстанса в формате словаря, они именно так и хранятся. Это полноценный словарь:

Это значит, что под капотом у него могут происходить хеширование, коллизии, увеличение адресного пространства и реаллокация — как у обычного словаря. Также это позволяет нам делать то же, что с обычным словарём, например удалять элементы. Вернёмся к предыдущему примеру:

У самого типа тоже есть — ведь он инстанс :

У классов — это не словарь, а . Он делает несколько полезных вещей: во-первых, убеждается, что ключи словаря — строки, а во-вторых делает его доступным только для чтения. Действительно, добавить элемент в такой словарь не выйдет:

А ещё это значит, что можно в инстанса добавить ключ не-строку:

Зачем нужна такая возможность — непонятно, но у классов её нет.Это сделано для большей стабильности работы интерпретатора и возможности использовать оптимизации — для них открывается больше простора, если у класса доступен только для чтения. Больше можно почитать в баге Bypassing __dict__ readonlyness на python.org (там 2007 год, но в общем всё актуально).

Переменной нет в двух случаях: если класс реализован на Cили если у класса объявлены слоты. К первому случаю относятся почти все встроенные типы, а о втором поговорим подробнее.

Если у класса определить , в котором перечислить все возможные поля инстанса, то пропадает смысл хранить их в словаре. Поэтому в таком случае под капотом у инстансов класса будет не словарь, а список.

Посмотреть, что происходит при использовании слотов можно в . Если коротко, то над слотами проводятся проверки на их вменяемость, правильно считаются все ссылки для сборщика мусора и, наконец, создаётся список со значениями для инстанса.

Для демонстрации посмотрим, сколько памяти экономит использование слотов в простом случае. Чтобы посчитать полный размер объекта со всеми вложенными в него объектами (например, вместе с и его ключами и значениями), используем модуль pympler:

Как работает доступ к атрибутам

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

Библиотека math

Для проведения вычислений с действительными числами язык Python содержит много дополнительных функций, собранных в библиотеку, которая называется math. Для использования этих функций в начале программы необходимо подключить библиотеку, что делается командой

import math           # подключение модуля библиотеки

После подключения программа получает доступ ко всем функциям, методам и классам, содержащимся в нём. После подключения можно вызвать любую функцию из подключенной библиотеки по следующему правилу: указывается имя модуля и через точку имя функции

имя_модуля.имя_функции

Например, пусть мы хотим вызвать функцию вычисления Синус угла, задаваемого в радианахimport math y = sin(5)         # ошибка не подключен модуль mathx = math.sin(5)    # записываем имя модуля и через точку имя функции

Можно подключать не весь модуль, а какую-то его часть. Например, программист хочет использовать только одну функцию из математической библиотеки math. Если он подключит всю библиотеку, то будет добавлено более 40 функций, которые будут занимать место. Чтобы добавить в проект какую-то часть, используют ключевое слово from

from <имя подключаемого модуля> import <название функции>

Например.

from math import sin       # подключена только одна функция siny = sin(5)                 # операция выполненаx = cos(5)               # ошибка функция cos не подключена

Ниже приведен список основных функций модуля math. Некоторые из перечисленных функций (int, round, abs) являются стандартными и не требуют подключения модуля math для использования.

Основные операторы

Оператор

Краткое описание

+

Сложение (сумма x и y)

Вычитание (разность x и y)

*

Умножение (произведение x и y)

Деление
Внимание! Если x и y целые, то результат всегда будет целым числом! Для получения вещественного результата хотя бы одно из чисел должно быть вещественным. Пример: 40/5 → 8, а вот 40/5.0 → 8.0

=

Присвоение

+=

y+=x; эквивалентно y = y + x;

-=

y-=x; эквивалентно y = y — x;

*=

y*=x; эквивалентно y = y * x;

/=

y/=x; эквивалентно y = y / x;

%=

y%=x; эквивалентно y = y % x;

==

Равно

!=

не равно

Больше

=

больше или равно

Часть после запятой отбрасывается
4 // 3 в результате будет 125 // 6 в результате будет 4

**

Возведение в степень
5 ** 2 в результате будет 25

and

логическое И

or

логическое ИЛИ

not

логическое отрицание НЕ

Определение конструктора для класса

Если вы заметили реализацию класса Employee, невозможно установить значение employee_id. Мы можем определить отдельный метод для установки значения employee_id. Но это обязательное свойство объекта Employee. Лучшее место для установки этих свойств — через конструктор.

Давайте продолжим и создадим конструктор для класса Employee. Мы ожидаем, что вызывающая программа передаст значение employee_id в качестве аргумента.

class Employee:

    def __init__(self, i):
        self.employee_id = i

    def work(self):
        print(f'{self.employee_id} is working')


emp = Employee(100)
emp.work()

Выход:

Примечание: предыдущий код для создания объекта Employee теперь не будет работать, потому что конструктор Employee ожидает аргумент. Если мы вызовем , он вызовет ошибку TypeError: в init() отсутствует 1 обязательный позиционный аргумент: ‘id’.

Можем ли мы иметь несколько конструкторов?

В отличие от других популярных объектно-ориентированных языков программирования, Python не поддерживает перегрузку методов и конструкторов.

Однако, если мы определим несколько конструкторов в классе, это не вызовет никаких ошибок. Последний конструктор перезапишет ранее определенное определение конструктора. Давайте посмотрим на это на примере.

class Employee:

    def __init__(self, id):
        self.employee_id = id
    
    # this will overwrite earlier defined constructor
    def __init__(self, id, n):  
        self.employee_id = id
        self.emp_name = n

    def work(self):
        print(f'{self.emp_name} is working')


emp = Employee(100, 'Pankaj')
emp.work()

emp = Employee(100)  # will raise Error
emp.work()

Вывод:

Pankaj is working
Traceback (most recent call last):
  File "/Users/pankaj/Documents/PycharmProjects/AskPython/hello-world/class_examples.py", line 19, in <module>
    emp = Employee(100)
TypeError: __init__() missing 1 required positional argument: 'n'

Support for automatically setting __slots__?

At least for the initial release, __slots__ will not be supported.
__slots__ needs to be added at class creation time. The Data
Class decorator is called after the class is created, so in order to
add __slots__ the decorator would have to create a new class, set
__slots__, and return it. Because this behavior is somewhat
surprising, the initial version of Data Classes will not support
automatically setting __slots__. There are a number of
workarounds:

  • Manually add __slots__ in the class definition.
  • Write a function (which could be used as a decorator) that inspects
    the class using fields() and creates a new class with
    __slots__ set.

The __init__() Method

Python has a special method called that you can add to your class. The method is invoked whenever an object is created from the class. Therefore you can make use of the method without having to explictly call it.

Here’s a simple example to demonstrate:

# Create the class
class MyClass:

def __init__(self):
self.a = «Hey»

def b(self):
return «Hello World»

# Create an object from the class
o = MyClass()

# Now we can work with the object
print(o.a)
print(o.b())Result

Hey
Hello World

We can access the variable using (i.e. ). So if we had an object called and another called then we could use and respectively.

Как оценить производительность модели

При классификации иногда нет необходимости использовать точность для оценки производительности модели.

Подумайте об анализе сильно несбалансированного набора данных. Например, вы пытаетесь определить, является ли транзакция мошеннической или нет, но только 0,5% вашего набора данных содержит мошенническую транзакцию. Тогда вы можете предсказать, что ни одна из транзакций не будет мошеннической и будет иметь показатель точности 99,5%! Конечно, это очень наивный подход, который не помогает обнаруживать мошеннические транзакции.

Так что мы используем?

Обычно мы используемчувствительностьа такжеспецифичность,

чувствительностьистинный положительный показатель: пропорции фактических положительных значений правильно определены.

специфичностьявляется истинным отрицательным показателем: доля фактических отрицательных значений правильно определена.

Давайте дадим некоторый контекст, чтобы лучше понять. Используя проблему обнаружения мошенничества,чувствительностьдоля мошеннических операций, определенных как мошенническиеспецифичностьэто доля не мошеннических операций, определенных как не мошеннические.

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

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

Пример кривой ROC. Прямая линия является базовой моделью

Квадратичный Дискриминантный Анализ (QDA)

Здесь мы придерживаемся тех же предположений, что и для LDA, но теперь каждое наблюдениеКТИкласс имеет свою собственную ковариационную матрицу

Для QDA дискриминант выражается как:

Дискриминантное уравнение для QDA

Без каких-либо сюрпризов вы заметите, что уравнение теперь квадратичное.

Но почему стоит выбирать QDA вместо LDA?

QDA — лучший вариант для больших наборов данных, так как он имеет тенденцию к меньшему смещению и большей дисперсии.

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

проект

Большой! Теперь, когда мы глубоко понимаем, как работают логистическая регрессия, LDA и QDA, давайте применим каждый алгоритм для решения проблемы классификации.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector