Ссылка на Kaggle Notebook для всех этих упражнений вместе

В: преобразование десятичного числа в двоичное

Выполнение короткого деления на два с остатком (для целой части)

Это простой метод, который включает деление числа, которое нужно преобразовать. Пусть десятичное число равно N, тогда разделите это число на 2, потому что основание двоичной системы счисления равно 2. Запишите значение остатка, которое будет либо 0, либо 1. Снова разделите оставшееся десятичное число, пока оно не станет 0, и запишите каждый остаток каждого шаг. Затем запишите остатки снизу вверх (или в обратном порядке), которые будут эквивалентны двоичному числу данного десятичного числа. Это процедура преобразования целого десятичного числа, алгоритм приведен ниже.

В качестве делимого возьмите десятичное число.

Разделите это число на 2 (2 - это основание двоичной системы, поэтому здесь делитель).

Сохраните остаток в массиве (он будет либо 0, либо 1 из-за делителя 2).

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

Распечатайте массив в обратном порядке (что будет эквивалентно двоичному числу заданного десятичного числа).

Обратите внимание, что делимое (здесь дано десятичное число) - это делимое число, делитель (здесь основание двоичного числа, т. Е. 2) в числе, на которое делится делимое, и частное (оставшееся разделенное десятичное число) является результатом разделение.

Пример для number = 112

Остаток деления (клавиша R)

112/2 = 56 остаток-0

56/2 = Остаток-28 0

28/2 = Остаток-14 0

14/2 = Остаток-7 0

7/2 = 3 остатка -1

3/2 = 1 остаток -1

1/2 = 0 остаток-1

Теперь запишите остаток снизу вверх (в обратном порядке), это будет 1110000, что эквивалентно двоичному числу десятичного целого числа 112.

def decimal_to_binary(number):
   if number == 0:
     return ""
   else:
    print(number)
    return decimal_to_binary(number // 2) + str(number % 2)
print(decimal_to_binary(112))
# In Python, you can simply use the bin() function to convert from a decimal value to its corresponding binary value.
# And similarly, the int() function to convert a binary to its decimal value. The int() function takes as second argument the base of the number to be converted, which is 2 in case of binary numbers.
# print(bin(112))  # 0b1110000
# print(int('0b1110000', 2))

Q: Произведение двух матриц

Учитывая две матрицы, выведите произведение этих двух матриц.

Решение с объяснениями и теорией

Основы умножения матриц

Запомните правило умножения - здесь также поток - строка, а затем столбец.

  1. Сумма-произведение первой строки * 1st Column = ›Становится 1-st_Row-1-st_Column результирующей матрицы
  2. Сумма-произведение 1-й строки * 2-й столбец = ›Становится 1-й_строкой-2-й_столбец результирующей матрицы

Вот четыре простых правила, которые помогут нам в умножении матриц:

1. Во-первых, мы можем перемножить две матрицы только тогда, когда количество столбцов в матрице A равно количеству строк в матрице B.

2. Во-вторых, первая строка матрицы A, умноженная на первый столбец матрицы B, дает нам первый элемент в матрице AB и так далее.

3. В-третьих, при умножении важен порядок, а именно: AB ≠ BA.

4. Наконец, элемент в строке i, столбце j является произведением i-й строки матрицы A и j-го столбца матрицы B.

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

# This works in O(n^3)
def multiply_matrix(matrix1,matrix2):
    results = []
    try:
        for i in range(len(matrix1)):
            rows = []
            for j in range(len(matrix2[0])):
                item = 0
                for k in range(len(matrix1[0])):
                    item += matrix1[i][k] * matrix2[k][j]
                rows.append(item)
            results.append(rows)
        return results
    except:
        return "These matrices aren't compatible."



A1 = [[1, 2],
      [3, 4]]

B1 = [[1, 2, 3, 4, 5],
      [5, 6, 7, 8, 9]]


print(multiply_matrix(A1, B1))

# [[11, 14, 17, 20, 23], [23, 30, 37, 44, 51]]

Заменить символы в имени файла

В: Пропорциональная вероятностная выборка

Выбрать число случайным образом с вероятностью, пропорциональной его величине, из заданного массива из n элементов.

Рассмотрим эксперимент, выбирая элемент из списка A случайным образом с вероятностью, пропорциональной его величине. предположим, что мы проводим один и тот же эксперимент 100 раз с заменой, в каждом эксперименте вы будете печатать число, выбранное случайным образом из A.

Пример 1: A = [1, 5, 27, 6, 13, 28, 100, 45, 10, 79] пусть f (x) обозначает количество раз, когда x выбирается в 100 экспериментах. f (100) ›f (79)› f (45) ›f (28)› f (27) ›f (13)› f (10) ›f (6)› f (5) ›f (0)

Решение, пояснения и примечания к методам, шагам, алгоритмам

Приведенное ниже решение основано на объяснениях, приведенных в this Stackoverflow question.com

Чтобы подробнее объяснить вопрос -

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

arr[0] = 100
arr[1] = 200

В этом примере для элемента 0 будет 66% выбора, а для элемента 1 - 33%.

Общий алгоритм

  • суммировать массив
  • Выберите случайное число от 0 до суммы
  • Накапливайте значения, начиная с начала массива, пока не достигнете ›= случайного значения.

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

Обычный метод - преобразовать массив в массив совокупных сумм:

[10 60 5 25]  --> [10 70 75 100]

Выберите случайное число в диапазоне от нуля до совокупной суммы (в примере: 0 <= x < 100). Затем используйте деление пополам на кумулятивном массиве, чтобы найти индекс в исходном массиве:

Random variable x      Index in the Cumulative Array      Value in Original Array
-----------------      -----------------------------      ----------------------
 0 <= x < 10                      0                            10
10 <= x < 70                      1                            60
70 <= x < 75                      2                             5
75 <= x < 100                     3                            25

Например, если случайная величина x равна 4, деление кумулятивного массива пополам дает индекс позиции 0, который соответствует 10 в исходном массиве.

И, если случайная величина x равна 72, деление кумулятивного массива пополам дает индекс позиции 2, который соответствует 5 в исходном массиве.

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

[10 60 5 25]  -->  [1/10  1/60  1/5  1/25]  -->  [1/10  7/60  19/60  107/300]

Фактическая функция

import random

def pick_num_from_list(A):
    sum=0
    cum_sum=[]
    for i in range(len(A)):
        sum = sum + A[i]
        cum_sum.append(sum)
    #print(cum_sum)
    r = int(random.uniform(0,sum))
    print(r)
    number=0
    for index in range(len(cum_sum)):
        if(r>=cum_sum[index] and r<cum_sum[index+1]):
            return A[index+1]
    return number

def sampling_connected_to_magnitued():
    # A = [0,5,27,6,13,28,100,45,10,79]
    A = [1, 5, 27, 6, 13, 28, 100, 45, 10, 79]
    a = dict()
    #A.sort()
    print(A,sum(A))
    for i in range(1,100):
        number = pick_num_from_list(A)
        #print(number)
        if number not in a:
            a[number] = 1
        else:
            a[number]+=1
    print(a)


sampling_connected_to_magnitued()

Q: Ближайшие точки (на основе косинусного расстояния)

Найдите ближайшие точки (на основе косинусного расстояния) в S (это n точек данных в виде списка кортежей) из P (которая является точкой P=(p,q))

Предположим, вы указали n точек данных в виде списка кортежей, например

S=[(x1,y1),(x2,y2),(x3,y3),(x4,y4),(x5,y5),..,(xn,yn)] и точка P=(p,q)

Ваша задача найти 5 ближайших точек (по косинусному расстоянию) в S от P

косинусное расстояние между двумя точками (x, y) и (p, q) определяется как

Ex:

S= [(1,2),(3,4),(-1,1),(6,-7),(0, 6),(-5,-8),(-1,-1)(6,0),(1,-1)] P= (3,-4)

Выход: (6, -7) (1, -1) (6,0) (-5, -8) (-1, -1)

Решение, пояснения и примечания к методам, шагам, алгоритмам

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

Примечания к концепции косинусного расстояния

Косинусное расстояние измеряет угловое косинусное расстояние между векторами a и b. В то время как косинусное сходство измеряет сходство между двумя векторами внутреннего пространства продукта. Он измеряется косинусом угла между двумя векторами и определяет, указывают ли два вектора примерно в одном направлении.

Сравнение евклидова расстояния (d) и косинусного подобия (θ).

Расстояние d выше - это евклидово расстояние. Что можно измерить, как показано ниже

√{(x2-x1)² + (y2-y1)²}

Но косинус учитывает угол между векторами (таким образом, не принимая во внимание их вес или величину).

Источник вышеуказанного изображения

Для двух полностью идентичных векторов косинусное сходство будет равно 1. Для векторов, которые полностью не связаны между собой, это значение будет равно 0. Если между двумя векторами существует противоположное соотношение, на этот раз значение косинусного сходства будет равно -1. (cos0 = 1, cos90 = 0, cos180 = -1)

import math


def clst_pts(S, P):
    clst_pts = []
    final_list = []

    for point in S:
        dnmntr = math.sqrt((point[0] ** 2) + (point[1] ** 2)) * math.sqrt((P[0] ** 2) + (P[1] ** 2))
        nmrtr = point[0] * P[0] + point[1] * P[1]

        if dnmntr != 0:
            cosine_distance_for_this_point = math.acos(nmrtr / dnmntr)
            clst_pts.append((cosine_distance_for_this_point, point))

    for item in sorted(clst_pts, key=lambda x: x[0])[:5]:
        final_list.append(item[1])

    return final_list


S = [(1, 2), (3, 4), (-1, 1), (6, -7), (0, 6), (-5, -8), (-1, -1), (6, 0), (1, -1)]
P = (3, -4)

clst_pts = clst_pts(S, P)
print("Closest point-cosine-distance - top 5:", *[point for point in clst_pts], sep="\n")

Быстрый способ перечислить все простые числа ниже n

import itertools
def erat2( ):
    D = {  }
    yield 2
    for q in itertools.islice(itertools.count(3), 0, None, 2):
        p = D.pop(q, None)
        if p is None:
            D[q*q] = q
            yield q
        else:
            x = p + q
            while x in D or not (x&1):
                x += p
            D[x] = p

def get_primes_erat(n):
  return list(itertools.takewhile(lambda p: p < n, erat2()))

print(get_primes_erat(30))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

Найдите все простые делители числа.

import math

def generate_prime_factors(n):
    p_factors_list = []

    while n % 2 == 0:
        p_factors_list.append(2)
        n = n / 2

    for i in range(3, int(math.sqrt(n)) + 1, 2):
        while n % i == 0:
            p_factors_list.append(int(i))
            n = n / i

    if n > 1:
        p_factors_list.append(int(n))

    return p_factors_list


print(generate_prime_factors(84))
[2, 2, 3, 7]

Реализуйте формулы перестановок и комбинаций.

Количество перестановок n объектов, взятых r за раз: p (n, r) = n! / (п-р)!

from math import factorial

def p(n, r):
    return int(factorial(n) / factorial(n - r))


def c(n, r):
    return int(factorial(n) / (factorial(r) * factorial(n - r)))


print(p(7, 3))
print(c(7, 3))


# Without using math.factorial

def generate_factrl(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)


def permutation(n, r):
    return int(generate_factrl(n) / generate_factrl(n - r))


def combination(n, r):
    return int(factorial(n) / (factorial(r) * factorial(n-r)))


print(permutation(7, 3))
print(combination(7, 3))
210
35
210
35

Q - Определить, может ли данная линия (уравнение в x и y) успешно разделить два списка точек (кортежей)

считайте, что вы дали два набора точек данных в виде списка кортежей, например

Red =[(R11,R12),(R21,R22),(R31,R32),(R41,R42),(R51,R52),..,(Rn1,Rn2)]

Blue=[(B11,B12),(B21,B22),(B31,B32),(B41,B42),(B51,B52),..,(Bm1,Bm2)]

и набор линейных уравнений (в строковом формате, т.е. список строк)

Lines = [a1x+b1y+c1, a2x+b2y+c2, a3x+b3y+c3, a4x+b4y+c4,.., K lines]

Примечание: вам нужно выполнить синтаксический анализ строки и получить коэффициенты x, y и перехвата

ваша задача - для каждой заданной строки напечатать «ДА» / «НЕТ», вы напечатаете «да», если все красные точки находятся на одной стороне линии, а синие точки - на другой стороне линии, в противном случае нет

Пример :-

Красный = [(1,1), (2,1), (4,2), (2,4), (-1,4)] Синий = [(-2, -1), (- 1, - 2), (- 3, -2), (- 3, -1), (1, -3)]

Строки = [«1x + 1y + 0», «1x-1y + 0,» 1x + 0y-3, »0x + 1y-0,5]

Выход:

ДА НЕТ НЕТ ДА

Решение, пояснения и примечания к методам, шагам, алгоритмам

Математическая теория - если линейное уравнение y = ax + b и координаты точки (x_0, y_0), тогда сравните y_0 и ax_0 + b, например, если y_0 ›ax_0 + b, то точка находится над линией и т. Д. .

В данном конкретном случае -

Математика, чтобы определить, находятся ли 2 точки на противоположных сторонах линии

"Источник"

Итак, я беру уравнение линии, скажем «1x + 1y + 0».

Теперь рассмотрим 2 точки (1,1) и (-6, -1).

Для точки (1, 1) = ›1 (1) + 1 (1) = 2, что составляет› 0

Для точки (-6, -1) = 1 (-6) + (1) (- 1) = -7, что равно ‹0

Таким образом, можно заключить, что (1,1) и (-6, -1) лежат по разные стороны от прямой S.

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

Общий математический принцип

Вот алгоритм, которому я буду следовать для реализации Python ниже.

  • Вопрос уже упоминался - «здесь нужно выполнить синтаксический анализ строки и получить коэффициенты x, y и перехват».
  • Я знаю, что строка в уравнении будет иметь форму some_number*x и some_number*y, где «some_number» - это коэффициенты при x и y. Поэтому мне нужно разбить строку таким образом, чтобы у меня остались только числа, а затем заменить значение x и y в уравнении на значение точек, которые я оцениваю.
  • Задайте для переменной sign_of_equation_with_red_point_tuple значение минус 1 (-1)
  • Возьмите первый кортеж из списка Red_side (т.е. красный [0] [0] и красный 0) и замените его в Equation. Если при этом знак уравнения становится положительным, измените sign_of_equation_with_red_point_tuple на плюс 1 (1).
  • Теперь, предполагая, что sign_of_equation_with_red_point_tuple будет плюс один (1), выполните следующий шаг.
  • Один за другим проверьте все кортежи (точки) красной стороны - если знак уравнения становится отрицательным для любой точки ›Это означает, что одна точка находится по другую сторону от линейного уравнения.
  • В таком случае верните из функции «NO».
  • Аналогичным образом на следующем шаге, предполагая, что sign_of_equation_with_red_point_tuple имеет отрицательное значение 1 (-1), выполните следующий шаг.
  • По очереди проверяйте все кортежи (точки) на красной стороне - если знак уравнения становится положительным для любой точки ›Это означает, что одна точка находится по другую сторону от линейного уравнения.
  • В таком случае верните из функции «NO».
  • Выполните оба вышеуказанных шага и для синей стороны.
  • И если ни один из вышеуказанных 4 шагов не вернет ответ «НЕТ», то, наконец, верните «ДА» из функции.
import math


def find_who(red, blue, line):
    sign_of_r_pts_eq = -1

    if eval(line.replace('x', '*%s' % red[0][0]).replace('y', '*%s' % red[0][1])) > 0:
        sign_of_r_pts_eq = 1

    for r_pt in red:
        if sign_of_r_pts_eq == 1 and eval(
                line.replace('x', '*%s' % r_pt[0]).replace('y', '*%s' % r_pt[1])) < 0:
            return 'NO'

        if sign_of_r_pts_eq == -1 and eval(
                line.replace('x', '*%s' % r_pt[0]).replace('y', '*%s' % r_pt[1])) > 0:
            return 'NO'


    sign_of_b_pts_eq = -1 * sign_of_r_pts_eq

    for b_pts in blue:
        if sign_of_b_pts_eq == 1 and eval(
                line.replace('x', '*%s' % b_pts[0]).replace('y', '*%s' % b_pts[1])) < 0:
            return 'NO'

        if sign_of_b_pts_eq == -1 and eval(
                line.replace('x', '*%s' % b_pts[0]).replace('y', '*%s' % b_pts[1])) > 0:
            return 'NO'

    return 'YES'


Red = [(1, 1), (2, 1), (4, 2), (2, 4), (-1, 4)]
Blue = [(-2, -1), (-1, -2), (-3, -2), (-3, -1), (1, -3)]

Lines = ["1x+1y+0", "1x-1y+0", "1x+0y-3", "0x+1y-0.5"]

for i in Lines:
    yes_or_no = find_who(Red, Blue, i)
    print(yes_or_no)
YES
NO
NO
YES

Q - Заполнение пропущенных значений в указанном формате

Вам будет предоставлена ​​строка с цифрами и символами ‘_’ (отсутствующее значение), которые вы должны заменить символы ‘_’, как описано

Пример 1: _, _, _, 24 == ›24/4, 24/4, 24/4, 24/4 т.е. мы. распределили 24 поровну на все 4 места

Пример 2: 40, _, _, _, 60 == ›(60 + 40) / 5, (60 + 40) / 5, (60 + 40) / 5, (60 + 40) / 5, (60+ 40) / 5 == ›20, 20, 20, 20, 20 т.е. сумма (60 + 40) распределяется поровну на все 5 мест

Пример 3: 80, _, _, _, _ == ›80 / 5,80 / 5,80 / 5,80 / 5,80 / 5 ==› 16, 16, 16, 16, 16 т.е. 80 - это распределяется качественно по всем 5 недостающим значениям, подходящим для него

Ex 4: _, _, 30, _, _, _, 50, _, _

== ›заполним недостающие значения слева направо a. сначала мы распределим 30 слева на два пропущенных значения (10, 10, 10, _, _, _, 50, _, _) b. теперь распределите сумму (10 + 50) пропущенных значений между (10, 10, 12, 12, 12, 12, 12, _, ) c. теперь мы распределим 12 пропущенных значений справа (10, 10, 12, 12, 12, 12, 4, 4, 4) для данной строки с разделенными запятыми значениями, которые будут иметь оба числа пропущенных значений, например ex: «, _, x, _, _, _ »вам необходимо заполнить недостающие значения Q: ваша программа считывает строку вида ex:«,, x,,, _ »и возвращает заполненную последовательность.

Ex:

Вход1: «,, _, 24» Выход1: 6,6,6,6

Вход2: «40, ,, _, 60» Выход2: 20,20,20,20,20

Input3: «80, ,, ,» Output3: 16,16,16,16,16

Input4: «,, 30, ,, , 50,, _» Output4: 10,10,12,12,12,12, 4,4,4

Итак, правило для вычисления пропущенных значений -

  1. Везде, где есть пропущенные значения, я должен добавить немедленно продолжающееся значение и сразу следующее доступное значение, а затем разделить его на количество пропущенных значений. Затем замените доступное значение вычисленным значением, как указано выше.
  2. Для вычисления следующего отсутствующего значения, для непосредственно предшествующего доступного значения возьмите вычисленное значение, как описано выше.
def curve_smoothing(string):
    index_of_non_empty_cells_list = []

    split_string = string.split(',')
    # print(split_string)
    # ['_', '_', '30', '_', '_', '_', '50', '_', '_']

    for idx in range(len(split_string)):
        if split_string[idx] != '_':
            index_of_non_empty_cells_list.append(idx)

    # Also add to index_of_non_empty_cells_list
    # The total index-length of the original list
    index_of_non_empty_cells_list.append(len(split_string) - 1)

    print(index_of_non_empty_cells_list)
    [2, 6, 8]

    # Now loop over index_of_non_empty_cells_list to modify the
    # original list by filing up empty_cells
    position_to_start = 0

    for element in index_of_non_empty_cells_list:
        # Wherever, there is a missing values, I have to add the immediately proceeding value
        # and the immediately next available value and then divide it by the number of missing values.
        # So, initiate a variable to 'cumulative_sum_prev_and_next_value' to hold the cumulative sum of
        # available (i.e. non-empty) cells
        cumulative_sum_prev_and_next_value = int(split_string[element]) if split_string[element] != '_' else 0
        cumulative_sum_prev_and_next_value += int(split_string[position_to_start]) if split_string[
                                                                                          position_to_start] != '_' and position_to_start != element else 0
        # print(cumulative_sum_prev_and_next_value)

        # Now divide the cumulative_sum of prev and next value
        # by the number of missing values
        integer_to_replace_each_previous_empty_cell = cumulative_sum_prev_and_next_value // (
                element - position_to_start + 1)

        # print("integer_to_replace_each_previous_empty_cell value is ", integer_to_replace_each_previous_empty_cell)
        # For the first loop it will give me 10 which is what I will replace each emtpy value with

        # And now modify the original list by replacing the empty cells with the above
        # value i.e.  integer_to_replace_each_previous_empty_cell
        split_string = [
            integer_to_replace_each_previous_empty_cell if position_to_start <= x <= element else split_string[x] for x
            in range(len(split_string))]

        # print("element: %s cumulative_sum_prev_and_next_value: %s  split_string: %s" %(element, cumulative_sum_prev_and_next_value, split_string ))

        # After original list has been updated by filling up the empty cells
        # now update the starting position for the next loop

        position_to_start = element

    return split_string


#  ------------------------
S = "_,_,30,_,_,_,50,_,_"
ans = smoothed_values = curve_smoothing(S)
# print(curve_smoothing(S))
print(ans)
[2, 6, 8]
[10, 10, 12, 12, 12, 12, 4, 4, 4]

Q - Реализовать функцию потери журнала на простом Python

Вам будет предоставлен список списков, каждый подсписок будет иметь длину 2, т.е. [[x, y], [p, q], [l, m] .. [r, s]] рассмотрите его как матрицу n строки и два столбца

  • а. первый столбец Y будет содержать целочисленные значения
  • б. второй столбец 𝑌𝑠𝑐𝑜𝑟𝑒Yscore будет иметь значения с плавающей запятой

Ваша задача найти значение нижеприведенного

Пример: [[1, 0,4], [0, 0,5], [0, 0,9], [0, 0,3], [0, 0,6], [1, 0,1], [1, 0,9], [1, 0,8]. ] вывод: 0.4243099

Пояснения и примечания относительно потери журнала

Логарифмическая потеря (т.е. логарифмическая потеря, а также потеря кросс-энтропии) - это функция потерь классификации. Log Loss количественно оценивает точность классификатора, наказывая ложные классификации. Минимизация потерь журнала в основном эквивалентна максимальной точности классификатора.

Потеря журнала используется, когда мы получаем ответ {0,1}. В этих случаях лучшие модели дают нам значения с точки зрения вероятностей. Функция логарифмических потерь - это просто целевая функция, которую необходимо минимизировать, чтобы подогнать логарифмическую линейную вероятностную модель к набору примеров с двоичными пометками.

В несколько иной форме журнал выражается как

Log Loss - это небольшая модификация функции правдоподобия. Фактически, Log Loss равен -1 * логарифму функции правдоподобия.

Log Loss измеряет точность классификатора. Он используется, когда модель выводит вероятность для каждого класса, а не только для наиболее вероятного класса.

Проще говоря, потеря журнала измеряет НЕОПРЕДЕЛЕННОСТЬ вероятностей вашей модели, сравнивая их с истинными метками. Давайте внимательно посмотрим на его формулу и посмотрим, как она измеряет НЕОПРЕДЕЛЕННОСТЬ.

Теперь вопрос в том, что ваши обучающие метки - 0 и 1, но ваши прогнозы обучения - 0,4, 0,6, 0,89, 0,1122 и т. Д. Итак, как нам вычислить меру ошибки нашей модели? Если мы напрямую классифицируем все наблюдения, имеющие значения ›0,5, в 1, то мы рискуем усилить ошибочную классификацию. Это потому, что может случиться так, что многие значения с вероятностями 0,4, 0,45, 0,49 могут иметь истинное значение 1.

Здесь на помощь приходит logLoss.

Логарифмические потери - это «мягкое» измерение точности, которое включает в себя идею вероятностной уверенности. Это тесно связано с теорией информации: лог-потери - это перекрестная энтропия между распределением истинных меток и прогнозов. Интуитивно говоря, энтропия измеряет непредсказуемость чего-либо. Перекрестная энтропия включает энтропию истинного распределения плюс дополнительную непредсказуемость, когда предполагается, что распределение отличается от истинного распределения. Таким образом, лог-потери - это теоретико-информационная мера для измерения «дополнительного шума», который возникает из-за использования предсказателя, а не истинных меток. Минимизируя перекрестную энтропию, можно максимизировать точность классификатора.

Случаи, когда функция Log-Loss может в основном использоваться

Функция потери журнала используется в качестве метрики оценки моделей классификатора ML. Это важная метрика, поскольку это только метрика, которая использует фактическую прогнозируемую вероятность для оценки модели (ROC - AUC использует порядок значений, но не фактические значения). Это очень полезно, поскольку это сильно наказывает модель, если она очень уверенно предсказывает неправильный класс (пожалуйста, проверьте график -log (x)). Мы оптимизируем нашу модель, чтобы минимизировать потери журнала. Следовательно, эта метрика очень полезна в случаях, когда цена предсказания неправильного класса очень высока. Следовательно, модель пытается уменьшить вероятность принадлежности к неправильному классу, и мы можем выбрать более высокий порог вероятности для предсказания метки класса. Этот показатель можно использовать как для двоичной, так и для многоклассовой классификации. Значение потерь журнала находится в диапазоне от 0 (включительно) до бесконечности. Это единственный недостаток потери журнала, так как его трудно интерпретировать. Мы знаем, что в лучшем случае значение потери журнала будет равно 0, однако мы не можем интерпретировать другие значения потери журнала. В некоторых случаях потеря журнала, равная 1, может быть хорошей, в то время как для других ее может быть недостаточно. Один из приемов заключается в том, что мы можем измерить потери журнала случайной модели и попытаться уменьшить потери журнала нашей реальной модели от этого значения, насколько это возможно, без увеличения дисперсии.

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

Пример использования Logloss

Скажем, я предсказываю рак по моей модели машинного обучения. И предположим, у вас есть 5 случаев. 2 случая были раком (y1 = y2 = 1) и 3 случая были доброкачественными (y3 = y4 = y5 = 0). Предположим, ваша модель предсказала, что каждая модель имеет 0,5 вероятности рака. В этом случае потеря журнала…

−1 / 5 ∗ (log (0.5) + log (0.5) + (1−0) ∗ log (1−0.5) + (1−0) ∗ log (1−0.5) + (1−0) ∗ log ( 1−0,5))

По сути, y_i и (1 - y_i) определяют, какой член следует отбросить, в зависимости от наземной метки истинности. В зависимости от истинности будет выбран логарифм (y_hat) или log (1-y_hat), чтобы определить, насколько далека от истины сгенерированная вероятность вашей модели.

Мы можем использовать функцию log_loss из scikit-learn, с документацией, найденной здесь: Но здесь мы реализуем версию на чистом Python

Наконец простая реализация Python

from math import log


def get_loss_log(matrix):
    logistic_loss = 0
    for row in matrix:
        logistic_loss += (row[0] * log(row[1], 10) + ((1 - row[0]) * log(1 - row[1], 10)))

    log_loss = -1 * logistic_loss / len(matrix)
    return log_loss


A = [[1, 0.4], [0, 0.5], [0, 0.9], [0, 0.3], [0, 0.6], [1, 0.1], [1, 0.9], [1, 0.8]]
print(get_loss_log(A))

Градиентный спуск в Python с нуля без использования какой-либо библиотеки

import numpy as np
import random
import pandas as pd


'''
  Gradient Descent for a single feature
  It will NOT work for multiple feature
'''

number_of_data_points = 50

# For predictor x, generate a Numpy array containing number betwen 2 and 9
x = np.random.randint(2, 9, number_of_data_points)

# print('x before dataframe ', x)
x = pd.DataFrame(x)
# print('df ', x)

# Standardize x
x = (x - x.mean()) / x.std()

# ***************************************************************

# Add one column for gradient-descent
x = np.c_[np.ones(x.shape[0]), x]
# print('x after adding one column ', x)

# For the target variable y, generate a Numpy array containing number betwen 1 and 26
y = np.random.randint(1, 26, number_of_data_points )
y = pd.DataFrame(y, columns = ['Y-Value'])
y = y['Y-Value']

# ********* Now the Gradient descent formulae implementation **********

alpha = 0.01 # Learning Step size
iterations = 100 #No. of iterations
np.random.seed(123) #Set the seed
theta = np.random.rand(2) #Pick some random values to start with


#GRADIENT DESCENT
def gradient_descent(x, y, theta, iterations, alpha):
    prev_cost = []
    prev_thetas = [theta]
    for i in range(iterations):
        prediction = np.dot(x, theta)
        error = prediction - y

        cost = 1/(2*number_of_data_points) * np.dot(error.T, error)
        prev_cost.append(cost)
        theta = theta - (alpha * (1/number_of_data_points) * np.dot(x.T, error))
        prev_thetas.append(theta)

    return prev_thetas, prev_cost

prev_thetas, prev_cost = gradient_descent(x, y, theta, iterations, alpha)
theta = prev_thetas[-1]

print("Gradient Descent: {:.2f}, {:.2f}".format(theta[0], theta[1]))

Некоторые полезные и хитрые скрипты Python

Узнайте стоимость зарядки ноутбуков

Высокоточные часы в Python

Скажем, мне нужно напечатать сообщение прямо в 08: 00: 00.000000. Следовательно, я попытался получить текущее время моей системы с точностью до микросекунд. Для этого я использовал datetime.datetime.now (). Но я обнаружил кое-что странное, что заставило меня подумать, что это не так. Когда я запускаю следующий код в системе с процессором Intel (R) Corei7–8550U @ 1,80 ГГц, 1,99 ГГц и Windows 10:

import datetime
import time
x = datetime.datetime.now()
t=2**10000
y = datetime.datetime.now()
print(x, '\n', y)

Дает вам точное время, например:

2020–07–13 02:28:28.763578

2020–07–13 02:28:28.763602

Итак, чтобы устранить указанную выше неточность, мы можем полагаться на f time.time_ns () -

который был введен в Python 3.7 как новые функции для модуля времени, обеспечивающие более высокое разрешение:

Https://docs.python.org/3/library/time.html - аналогично time (), но возвращает время в виде целого числа наносекунд с начала эпохи.

time1 = time.time_ns()
print(time1)
# 1530228533161016309
time2 = time.time_ns() / (10 ** 9)
# The above will convert to floating-point seconds
print(time2)
# 1530228544.0792289