# Path: crowdastro/crowd/util.py
# def majority_vote(y):
#     """Computes the majority vote of a set of crowd labels.
# 
#     y: (n_annotators, n_examples) NumPy masked array of labels.
#     -> (n_examples,) NumPy array of labels.
#     """
#     _, n_samples = y.shape
#     mv = numpy.zeros((n_samples,))
#     for i in range(n_samples):
#         labels = y[:, i]
# 
#         if labels.mask is False:
#             counter = collections.Counter(labels)
#         else:
#             counter = collections.Counter(labels[~labels.mask])
# 
#         if counter:
#             mv[i] = max(counter, key=counter.get)
#         else:
#             # No labels for this data point.
#             mv[i] = numpy.random.randint(2)  # ¯\_(ツ)_/¯
#     return mv
# 
# def logistic_regression(w, x):
#     """Logistic regression classifier model.
# 
#     w: Weights w. (n_features,) NumPy array
#     x: Data point x_i. (n_features,) NumPy array
#     -> float in [0, 1]
#     """
#     return scipy.special.expit(numpy.dot(x, w.T))


import logging
import time
import numpy
import scipy.optimize
import sklearn.linear_model
from crowdastro.crowd.util import majority_vote, logistic_regression
        for trial in range(self.n_restarts):
            logging.debug('Trial {}/{}'.format(trial + 1, self.n_restarts))
            a, b, w = self._fit_params(X, Y)
            self.a_, self.b_, self.w_ = a, b, w
            lh = self.score(X, Y)
            results.append((lh, (a, b, w)))

        a, b, w = max(results, key=lambda z: z[0])[1]
        self.a_ = a
        self.b_ = b
        self.w_ = w

    def _fit_params(self, x, y):
        """
        x: (n_samples, n_features) NumPy array of data (with no bias term).
        y: (n_labellers, n_samples) NumPy masked array of crowd labels.
        """
        # Add a bias feature.
        x = numpy.hstack([x, numpy.ones((x.shape[0], 1))])

        n_samples, n_dim = x.shape
        n_labellers, n_samples_ = y.shape
        if n_samples_ != n_samples:
            raise ValueError('x and y have different numbers of samples.')

        self.n_samples_ = n_samples
        self.n_labellers_ = n_labellers
        self.n_dim_ = n_dim

        # Compute majority vote labels for initialisation.

# Path: crowdastro/crowd/util.py
# def majority_vote(y):
#     """Computes the majority vote of a set of crowd labels.
# 
#     y: (n_annotators, n_examples) NumPy masked array of labels.
#     -> (n_examples,) NumPy array of labels.
#     """
#     _, n_samples = y.shape
#     mv = numpy.zeros((n_samples,))
#     for i in range(n_samples):
#         labels = y[:, i]
# 
#         if labels.mask is False:
#             counter = collections.Counter(labels)
#         else:
#             counter = collections.Counter(labels[~labels.mask])
# 
#         if counter:
#             mv[i] = max(counter, key=counter.get)
#         else:
#             # No labels for this data point.
#             mv[i] = numpy.random.randint(2)  # ¯\_(ツ)_/¯
#     return mv
# 
# def logistic_regression(w, x):
#     """Logistic regression classifier model.
# 
#     w: Weights w. (n_features,) NumPy array
#     x: Data point x_i. (n_features,) NumPy array
#     -> float in [0, 1]
#     """
#     return scipy.special.expit(numpy.dot(x, w.T))


# Path: crowdastro/crowd/raykar.py
import logging
import time
import numpy
import scipy.optimize
import sklearn.linear_model
from crowdastro.crowd.util import majority_vote, logistic_regression

        for trial in range(self.n_restarts):
            logging.debug('Trial {}/{}'.format(trial + 1, self.n_restarts))
            a, b, w = self._fit_params(X, Y)
            self.a_, self.b_, self.w_ = a, b, w
            lh = self.score(X, Y)
            results.append((lh, (a, b, w)))

        a, b, w = max(results, key=lambda z: z[0])[1]
        self.a_ = a
        self.b_ = b
        self.w_ = w

    def _fit_params(self, x, y):
        """
        x: (n_samples, n_features) NumPy array of data (with no bias term).
        y: (n_labellers, n_samples) NumPy masked array of crowd labels.
        """
        # Add a bias feature.
        x = numpy.hstack([x, numpy.ones((x.shape[0], 1))])

        n_samples, n_dim = x.shape
        n_labellers, n_samples_ = y.shape
        if n_samples_ != n_samples:
            raise ValueError('x and y have different numbers of samples.')

        self.n_samples_ = n_samples
        self.n_labellers_ = n_labellers
        self.n_dim_ = n_dim

        # Compute majority vote labels for initialisation.

        mv = majority_vote(y)