| 15 | |
| 16 | |
| 17 | class SVM(BaseEstimator): |
| 18 | def __init__(self, C=1.0, kernel=None, tol=1e-3, max_iter=100): |
| 19 | """Support vector machines implementation using simplified SMO optimization. |
| 20 | |
| 21 | Parameters |
| 22 | ---------- |
| 23 | C : float, default 1.0 |
| 24 | kernel : Kernel object |
| 25 | tol : float , default 1e-3 |
| 26 | max_iter : int, default 100 |
| 27 | """ |
| 28 | self.C = C |
| 29 | self.tol = tol |
| 30 | self.max_iter = max_iter |
| 31 | if kernel is None: |
| 32 | self.kernel = Linear() |
| 33 | else: |
| 34 | self.kernel = kernel |
| 35 | |
| 36 | self.b = 0 |
| 37 | self.alpha = None |
| 38 | self.K = None |
| 39 | |
| 40 | def fit(self, X, y=None): |
| 41 | self._setup_input(X, y) |
| 42 | self.K = np.zeros((self.n_samples, self.n_samples)) |
| 43 | for i in range(self.n_samples): |
| 44 | self.K[:, i] = self.kernel(self.X, self.X[i, :]) |
| 45 | self.alpha = np.zeros(self.n_samples) |
| 46 | self.sv_idx = np.arange(0, self.n_samples) |
| 47 | return self._train() |
| 48 | |
| 49 | def _train(self): |
| 50 | iters = 0 |
| 51 | while iters < self.max_iter: |
| 52 | iters += 1 |
| 53 | alpha_prev = np.copy(self.alpha) |
| 54 | |
| 55 | for j in range(self.n_samples): |
| 56 | # Pick random i |
| 57 | i = self.random_index(j) |
| 58 | |
| 59 | eta = 2.0 * self.K[i, j] - self.K[i, i] - self.K[j, j] |
| 60 | if eta >= 0: |
| 61 | continue |
| 62 | L, H = self._find_bounds(i, j) |
| 63 | |
| 64 | # Error for current examples |
| 65 | e_i, e_j = self._error(i), self._error(j) |
| 66 | |
| 67 | # Save old alphas |
| 68 | alpha_io, alpha_jo = self.alpha[i], self.alpha[j] |
| 69 | |
| 70 | # Update alpha |
| 71 | self.alpha[j] -= (self.y[j] * (e_i - e_j)) / eta |
| 72 | self.alpha[j] = self.clip(self.alpha[j], H, L) |
| 73 | |
| 74 | self.alpha[i] = self.alpha[i] + self.y[i] * self.y[j] * ( |
no outgoing calls