Пример #1
0
    def _calculate_scores_for_binary(self, X, Y):
        """
        Вычисляет полезность для бинарных признаков

        Аргументы:
        ----------
        X: array-like, shape=(nobj, self.nfeatures)
            массив с обучающими данными
        Y: array-like, shape=(nobj, nclasses)
            массив значений классов, закодированных с помощью двоичных векторов

        Возвращает:
        -----------
        scores: array-like, shape=(self.nfeatures, nclasses)
            scores[i][j] показывает полезность i-го признака для j-го класса
        """
        classes_counts = Y.sum(axis=0)  # встречаемость классов
        counts = np.ravel(X.sum(axis=0))  # встречаемость признаков
        # совместная встречаемость признаков и классов
        counts_by_classes = safe_sparse_dot(Y.T, X)

        # обнуляем редко встречающиеся признаки
        # rare_indices = np.where(counts < self.min_count)
        # counts[rare_indices] = 0
        # counts_by_classes[:, rare_indices] = 0

        if self.method in self._CONTINGENCY_METHODS:
            # вычисляем таблицы сопряжённости
            nclasses = Y.shape[1]
            contingency_table = np.zeros(shape=(nclasses, self._ndata_features,
                                                2, 2),
                                         dtype=np.float64)
            for i in range(nclasses):
                for j in range(self._ndata_features):
                    count = counts_by_classes[i, j]
                    feature_count, class_count = counts[j], classes_counts[i]
                    rest = self._N - count - feature_count + count
                    contingency_table[i, j] = [[rest, feature_count - count],
                                               [class_count - count, count]]
            if self.method == 'log_odds':
                func = (lambda x: odds_ratio(x, alpha=0.1))
            elif self.method == 'information_gain':
                func = information_gain
            elif self.method == 'bns':
                func = bns
            # КАК СДЕЛАТЬ БЕЗ ПРЕОБРАЗОВАНИЙ
            scores = np.array([[
                func(contingency_table[i][j])
                for j in range(self._ndata_features)
            ] for i in range(nclasses)])
        elif self.method == 'ambiguity':
            scores = counts_by_classes / counts
        else:
            raise ValueError(
                "Wrong feature selection method: {0}, "
                "only the following methods are available: {1}".format(
                    self.method, self._CONTINGENCY_METHODS))
        scores[np.isnan(scores)] = 0.0
        return scores
Пример #2
0
    def _calculate_scores_for_binary(self, X, Y):
        """
        Вычисляет полезность для бинарных признаков

        Аргументы:
        ----------
        X: array-like, shape=(nobj, self.nfeatures)
            массив с обучающими данными
        Y: array-like, shape=(nobj, nclasses)
            массив значений классов, закодированных с помощью двоичных векторов

        Возвращает:
        -----------
        scores: array-like, shape=(self.nfeatures, nclasses)
            scores[i][j] показывает полезность i-го признака для j-го класса
        """
        classes_counts = Y.sum(axis=0)  # встречаемость классов
        counts = np.ravel(X.sum(axis=0))  # встречаемость признаков
        # совместная встречаемость признаков и классов
        counts_by_classes = safe_sparse_dot(Y.T, X)

        # обнуляем редко встречающиеся признаки
        # rare_indices = np.where(counts < self.min_count)
        # counts[rare_indices] = 0
        # counts_by_classes[:, rare_indices] = 0

        if self.method in self._CONTINGENCY_METHODS:
            # вычисляем таблицы сопряжённости
            nclasses = Y.shape[1]
            contingency_table = np.zeros(shape=(nclasses, self._ndata_features, 2, 2),
                                         dtype=np.float64)
            for i in range(nclasses):
                for j in range(self._ndata_features):
                    count = counts_by_classes[i, j]
                    feature_count, class_count = counts[j], classes_counts[i]
                    rest = self._N - count - feature_count + count
                    contingency_table[i, j] = [[rest, feature_count - count],
                                               [class_count - count, count]]
            if self.method == 'log_odds':
                func = (lambda x: odds_ratio(x, alpha=0.1))
            elif self.method == 'information_gain':
                func = information_gain
            elif self.method == 'bns':
                func = bns
            # КАК СДЕЛАТЬ БЕЗ ПРЕОБРАЗОВАНИЙ
            scores = np.array([[func(contingency_table[i][j])
                                for j in range(self._ndata_features)]
                               for i in range(nclasses)])
        elif self.method == 'ambiguity':
            scores = counts_by_classes / counts
        else:
            raise ValueError("Wrong feature selection method: {0}, "
                             "only the following methods are available: {1}".format(
                                self.method, self._CONTINGENCY_METHODS))
        scores[np.isnan(scores)] = 0.0
        return scores
Пример #3
0
    def _find_optimal_thresholds(self, column, y):
        """
        Вычисляет пороги для бинаризации

        Аргументы:
        ----------
        column: array-like, shape=(nobj,), колонка значений признаков
        y: array-like, shape=(nobj, nclasses), 0/1-матрица классов
        """
        classes_number = y.shape[1]
        # вычисляем частоты встречаемости признаков для разных классов
        values, counts = \
            _collect_column_statistics(column, y, classes_number=classes_number, precision=6)
        if self.method in Binarizer._CONTINGENCY_METHODS:
            # бинарная классификация
            if classes_number <= 2:
                counts = [counts]
            else:
                summary_counts = np.sum(counts, axis=1)
                counts = [
                    np.array((summary_counts - counts[:, i], counts[:, i])).T
                    for i in np.arange(classes_number)
                ]
            best_thresholds = [None] * len(counts)
            best_scores = [None] * len(counts)
            for i in np.arange(len(counts)):
                current_thresholds, current_tables = \
                    _collect_contingency_tables(values, counts[i])
                if self.method == "log_odds":
                    func = (lambda x: odds_ratio(x, alpha=0.1))
                elif self.method == 'information_gain':
                    func = information_gain
                elif self.method == 'bns':
                    func = bns
                else:
                    raise ValueError("Wrong binarization method: {0}".format(
                        self.method))
                scores = [func(table) for table in current_tables]
                best_score_index = np.argmax(scores)
                best_thresholds[i] = current_thresholds[best_score_index]
                best_scores[i] = scores[best_score_index]
        return best_thresholds, best_scores
Пример #4
0
    def _find_optimal_thresholds(self, column, y):
        """
        Вычисляет пороги для бинаризации

        Аргументы:
        ----------
        column: array-like, shape=(nobj,), колонка значений признаков
        y: array-like, shape=(nobj, nclasses), 0/1-матрица классов
        """
        classes_number = y.shape[1]
        # вычисляем частоты встречаемости признаков для разных классов
        values, counts = \
            _collect_column_statistics(column, y, classes_number=classes_number, precision=6)
        if self.method in Binarizer._CONTINGENCY_METHODS:
            # бинарная классификация
            if classes_number <= 2:
                counts = [counts]
            else:
                summary_counts = np.sum(counts, axis=1)
                counts = [np.array((summary_counts - counts[:, i], counts[:, i])).T
                          for i in np.arange(classes_number)]
            best_thresholds = [None] * len(counts)
            best_scores = [None] * len(counts)
            for i in np.arange(len(counts)):
                current_thresholds, current_tables = \
                    _collect_contingency_tables(values, counts[i])
                if self.method == "log_odds":
                    func = (lambda x: odds_ratio(x, alpha=0.1))
                elif self.method == 'information_gain':
                    func = information_gain
                elif self.method == 'bns':
                    func = bns
                else:
                    raise ValueError("Wrong binarization method: {0}".format(self.method))
                scores = [func(table) for table in current_tables]
                best_score_index = np.argmax(scores)
                best_thresholds[i] = current_thresholds[best_score_index]
                best_scores[i] = scores[best_score_index]
        return best_thresholds, best_scores