class_docstr: Twin multi-Label Support Vector Machines
  
  Parameters
  ----------
  c_k : int
      the empirical risk penalty parameter that determines the trade-off between the loss terms
  sor_omega: float (default is 1.0)
      the smoothing parameter
  threshold : int (default is 1e-6)
          threshold above which a label should be assigned
  lambda_param : float (default is 1.0)
          the regularization parameter
  max_iteration : int (default is 500)
          maximum number of iterations to use in successive overrelaxation
  
  
  References
  ----------
  
  If you use this classifier please cite the original paper introducing the method:
  
  .. code :: bibtex
  
      @article{chen2016mltsvm,
        title={MLTSVM: a novel twin support vector machine to multi-label learning},
        author={Chen, Wei-Jie and Shao, Yuan-Hai and Li, Chun-Na and Deng, Nai-Yang},
        journal={Pattern Recognition},
        volume={52},
        pages={61--74},
        year={2016},
        publisher={Elsevier}
      }
  
  
  Examples
  --------
  
  Here's a very simple example of using MLTSVM with a fixed number of neighbors:
  
  .. code :: python
  
      from skmultilearn.adapt import MLTSVM
  
      classifier = MLTSVM(c_k = 2**-1)
  
      # train
      classifier.fit(X_train, y_train)
  
      # predict
      predictions = classifier.predict(X_test)
  
  
  You can also use :class:`~sklearn.model_selection.GridSearchCV` to find an optimal set of parameters:
  
  .. code :: python
  
      from skmultilearn.adapt import MLTSVM
      from sklearn.model_selection import GridSearchCV
  
      parameters = {'c_k': [2**i for i in range(-5, 5, 2)]}
      score = 'f1-macro
  
      clf = GridSearchCV(MLTSVM(), parameters, scoring=score)
      clf.fit(X, y)
  
      print (clf.best_params_, clf.best_score_)
  
      # output
      {'c_k': 0.03125} 0.347518217573
code: def _successive_overrelaxation(self, omegaW, Q):
      # Initialization
      D = np.diag(Q)  # Only one dimension vector - is enough
      D_inv = 1.0 / D  # D-1 simplify form
      small_l = Q.shape[1]
      oldnew_alpha = np.zeros([small_l, 1])  # buffer
  
      is_not_enough = True
      was_going_down = False
      last_alfa_norm_change = -1
  
      nr_iter = 0
      while is_not_enough:  # do while
          oldAlpha = oldnew_alpha
          for j in range(0, small_l):  # It's from last alpha to first
              oldnew_alpha[j] = oldAlpha[j] - omegaW * D_inv[j] * (
                  Q[j, :].T.dot(oldnew_alpha) - 1
              )
          oldnew_alpha = oldnew_alpha.clip(0.0, self.c_k)
          alfa_norm_change = norm(oldnew_alpha - oldAlpha)
  
          if (
              not was_going_down
              and last_alfa_norm_change > alfa_norm_change
          ):
              was_going_down = True
          is_not_enough = (
              alfa_norm_change > self.threshold
              and nr_iter < self.max_iteration
              and (
                  (not was_going_down)
                  or last_alfa_norm_change > alfa_norm_change
              )
          )
          # TODO: maybe add any(oldnew_alpha != oldAlpha)
  
          last_alfa_norm_change = alfa_norm_change
          nr_iter += 1
      self.iteration_count.append(nr_iter)
      return oldnew_alpha
  
file_path: scikit-multilearn/skmultilearn/adapt/mltsvm.py
imports: from skmultilearn.base import MLClassifierBase
  import numpy
  import scipy.sparse
  from scipy.linalg import norm
  from scipy.sparse.linalg import inv
  from scipy.linalg import inv
label_desc: Use image node_id 4 for calling the MLTSVM obj's underlying member method code with example usage: obj._successive_overrelaxation(omegaW, Q) and returns: oldnew_alpha