daily pastebin goal
90%
SHARE
TWEET

Untitled

a guest Jan 23rd, 2019 63 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import numpy as np
  2. from math import exp, log
  3.  
  4.  
  5. def sigmoid(x):
  6.     return 1 / (1 + exp(-x))
  7.  
  8.  
  9. class FactorizationMachines:
  10.     def __init__(self, epoch: int=1000, k: int=3, eta: float=0.01, seed: int=0):
  11.         np.random.seed(seed)
  12.  
  13.         self.n = None
  14.         self.epoch = epoch
  15.         self.k = k
  16.         self.lamb = 0.01
  17.         self.eta = eta
  18.         self.sigma = 0.001
  19.  
  20.         self.w0 = 0.0
  21.         self.w = None
  22.         self.V = None
  23.  
  24.     def fit(self, X: np.array, Y: np.array, verbose=True):
  25.         self.n = X.shape[1]
  26.         self.w = np.zeros(self.n, np.float64)
  27.         self.V = self.sigma * np.array(np.random.randn(self.n, self.k))
  28.  
  29.         for epoch in range(self.epoch):
  30.             for x, y in zip(X, Y):
  31.                 assert y in (-1, 1)
  32.                 self._update(x=x, y=y, p=self._predict(x))
  33.  
  34.             if verbose:
  35.                 print("epoch:{0} log loss={1}".format(epoch, self.test(X, Y)))
  36.         return self
  37.  
  38.     def predict(self, X: np.array) -> np.array:
  39.         return np.array([self._predict(x) for x in X])
  40.  
  41.     def test(self, X: np.array, Y: np.array) -> float:
  42.         return np.mean([-log(sigmoid(y * p)) for p, y in zip(self.predict(X), Y)])
  43.  
  44.     def _predict(self, x: np.array) -> float:
  45.         wx = np.dot(self.w, x)
  46.         vx = np.zeros((self.k,), dtype=np.float64)
  47.         v2x2 = np.zeros((self.k,), dtype=np.float64)
  48.  
  49.         for f in range(self.k):
  50.             vx[f] = np.dot(self.V[:, f], x)
  51.  
  52.         for i in range(len(x)):
  53.             for f in range(self.k):
  54.                 v2x2[f] += (self.V[i, f] ** 2) * (x[i] ** 2)
  55.  
  56.         c = sum((vx[f] ** 2 - v2x2[f]) for f in range(self.k))
  57.  
  58.         return self.w0 + wx + 0.5 * c
  59.  
  60.     def _update(self, x, y, p) -> None:
  61.         vx = [np.dot(self.V[:, f], x) for f in range(self.k)]
  62.  
  63.         delta = y * (sigmoid(y * p) - 1.0)
  64.         self.w0 -= self.eta * (delta + 2 * self.lamb * self.w0)
  65.         for i in range(len(x)):
  66.             self.w[i] -= self.eta * (delta * x[i] + 2 * self.lamb * self.w[i])
  67.  
  68.             for f in range(self.k):
  69.                 h = x[i] * (vx[f] - x[i] * self.V[i, f])
  70.                 self.V[i, f] -= self.eta * (delta * h + 2 * self.lamb * self.V[i, f])
  71.  
  72.  
  73. def main():
  74.     from sklearn.datasets import load_breast_cancer
  75.     from sklearn.model_selection import train_test_split
  76.     from sklearn.metrics import confusion_matrix
  77.     from sklearn.preprocessing import StandardScaler
  78.  
  79.     data = load_breast_cancer()
  80.     X, y = data["data"], data["target"]
  81.     X_train, X_test, y_train, y_test = train_test_split(X, y)
  82.     y_train = [-1 if y == 0 else 1 for y in y_train]
  83.     y_test = [-1 if y == 0 else 1 for y in y_test]
  84.  
  85.     sc = StandardScaler()
  86.     sc.fit(X_train)
  87.     X_train = sc.transform(X_train)
  88.     X_test = sc.transform(X_test)
  89.  
  90.     model = FactorizationMachines(epoch=100)
  91.     model.fit(X_train, y_train)
  92.     y_pred = model.predict(X_test)
  93.     print(confusion_matrix(y_test, [1 if p > 0.5 else -1 for p in y_pred]))
  94.  
  95.  
  96. if __name__ == '__main__':
  97.     main()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top