Guest User

Untitled

a guest
Jan 23rd, 2019
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.92 KB | None | 0 0
  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()
Add Comment
Please, Sign In to add comment