Advertisement
Guest User

Untitled

a guest
Apr 4th, 2020
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.18 KB | None | 0 0
  1. def sigmoid(h):
  2.     return 1. / (1 + np.exp(-h))
  3.  
  4. class LogisticRegressionGD:
  5.     '''
  6.    A simple logistic regression for binary classification with gradient descent
  7.    '''
  8.    
  9.     def __init__(self):
  10.             self.W = None
  11.    
  12.     def __extend_X(self, X):
  13.         """
  14.            Данный метод должен возвращать следующую матрицу:
  15.            X_ext = [1, X], где 1 - единичный вектор
  16.            это необходимо для того, чтобы было удобнее производить
  17.            вычисления, т.е., вместо того, чтобы считать X@W + b
  18.            можно было считать X_ext@W_ext
  19.        """
  20.         return np.concatenate((np.ones((X.shape[0], 1)), X), axis = 1)
  21.    
  22.     def init_weights(self, input_size, output_size):
  23.         """
  24.            Инициализирует параметры модели
  25.            W - матрица размерности (input_size, output_size)
  26.            инициализируется рандомными числами из
  27.            нормального распределения со средним 0 и стандартным отклонением 0.01
  28.        """
  29.         np.random.seed(42)
  30.         self.W = np.random.normal(0, 0.01, (input_size, output_size))
  31.        
  32.     def get_loss(self, p, y):
  33.         return - 1 / y.shape[0] * np.mean(y * np.log(p) + (1 - y) * np.log(1 - p))
  34.         """
  35.            Данный метод вычисляет логистическую функцию потерь
  36.            @param p: Вероятности принадлежности к классу 1
  37.            @param y: Истинные метки
  38.        """
  39.         #YOUR_CODE
  40.    
  41.     def get_prob(self, X):
  42.         """
  43.            Данный метод вычисляет P(y=1|X,W)
  44.            Возможно, будет удобнее реализовать дополнительный
  45.            метод для вычисления сигмоиды
  46.        """
  47.         if X.shape[1] != self.W.shape[0]:
  48.             X = self.__extend_X(X)
  49.         return sigmoid(X @ self.W)
  50.        
  51.    
  52.     def get_acc(self, p, y, threshold=0.5):
  53.         """
  54.            Данный метод вычисляет accuracy:
  55.            acc = \frac{1}{len(y)}\sum_{i=1}^{len(y)}{I[y_i == (p_i >= threshold)]}
  56.        """
  57.         return np.sum(y == (p >= threshold)) / len(y)
  58.  
  59.     def fit(self, X, y, num_epochs=100, lr=0.001):
  60.        
  61.         X = self.__extend_X(X)
  62.         self.init_weights(X.shape[1], y.shape[1])
  63.        
  64.         accs = []
  65.         losses = []
  66.         for _ in range(num_epochs):
  67.             p = self.get_prob(X)
  68.  
  69.             W_grad = X.T @ (p - y) / len(y)
  70.             self.W -= lr * W_grad
  71.            
  72.             # необходимо для стабильности вычислений под логарифмом
  73.             p = np.clip(p, 1e-10, 1 - 1e-10)
  74.            
  75.             log_loss = self.get_loss(p, y)
  76.             losses.append(log_loss)
  77.             acc = self.get_acc(p, y)
  78.             accs.append(acc)
  79.        
  80.         return accs, losses
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement