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
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
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
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