Example #1
0
    def probability(self, x_mat: ndarray) -> Union[ndarray, float]:
        """
        返回对应于 x_mat 的预测概率。如果是二分类问题,那么返回一个行向量;如果是多分类问题,返回一个
        m*num_labels 的矩阵,其中每一行表示样本在每个类上的概率。

        :param x_mat: 特征向量组,行数 m 表示样本数,列数 n 表示特征数
        :return: 预测概率。
        """

        if self._theta is None:
            raise StateError('not trained yet')

        self._theta, x_mat = _t.match_theta_x(self._theta, x_mat)

        return _mf.sigmoid(x_mat @ self._theta)
Example #2
0
    def __cost(self, theta_row: ndarray, x_mat: ndarray,
               y_row: ndarray) -> float:
        """
        计算代价值。

        :param theta_row: 参数
        :param x_mat: 特征向量组,行数 m 表示样本数,列数 n 表示特征数
        :param y_row: 输出行向量,每一个值代表 x_mat 中对应行的输出
        :return: 代价值
        """

        m = x_mat.shape[0]
        hx = _mf.sigmoid(x_mat @ theta_row)
        thetan = theta_row[1:]
        # FIXME: 当 hx 中包含 0 或 1 时,会导致 log 出现警告并终止迭代
        cost = -(y_row @ np.log(hx) +
                 (1 - y_row) @ np.log(1 - hx)) / m + self.lamb * sum(
                     thetan**2) / (2 * m)

        return cost
Example #3
0
    def __feedforward(thetas: Union[List[ndarray], Tuple[ndarray]],
                      x_mat: ndarray) -> list:
        """
        正向传播,计算分类问题的预测概率。

        :param x_mat: 特征向量组,行数 m 表示样本数,列数 n 表示特征数
        :param thetas: 参数向量组。每一个 theta 表示对应层的参数
        :return: 一个 list,存有每一层计算后的 ai 和 zi(除了 an,其他 ai 都加上了一列偏置列)
        """

        r = []
        a = x_mat
        for i, theta in enumerate(thetas):
            z = a @ theta.T
            r.append(z)
            a = _mf.sigmoid(z)
            if i != len(thetas) - 1:
                a = np.hstack((np.ones((a.shape[0], 1)), a))
            r.append(a)

        return r
Example #4
0
    def __gradient(self, theta_row: ndarray, x_mat: ndarray,
                   y_row: ndarray) -> ndarray:
        """
        计算梯度。

        :param theta_row: 参数
        :param x_mat: 特征向量组,行数 m 表示样本数,列数 n 表示特征数
        :param y_row: 输出行向量,每一个值代表 x_mat 中对应行的输出
        :return: 梯度,是一个行向量
        """

        m = x_mat.shape[0]
        thetan = theta_row[1:]
        xn = x_mat[:, 1:]
        hx = _mf.sigmoid(x_mat @ theta_row)

        # 如果不展开的话,就是个只有一个元素的二维数组
        grad0 = ((x_mat[:, :1].T @ (hx - y_row)) / m).ravel()
        gradn = ((xn.T @ (hx - y_row)) / m + self.lamb * thetan / m).ravel()

        return np.hstack((grad0, gradn))
Example #5
0
    def predict(self, x_mat: ndarray) -> Union[ndarray, int]:
        """
        返回预测值,是对应于 x_mat 的标记。

        :param x_mat: 特征向量组,行数 m 表示样本数,列数 n 表示特征数
        :return: 预测标记
        """

        if self._theta is None:
            raise StateError('not trained yet')

        self._theta, x_mat = _t.match_theta_x(self._theta, x_mat)
        prob = x_mat @ self._theta

        if len(self.labels) == 2:
            return _t.ret(
                _t.convert_y(self.labels,
                             _mf.sigmoid(prob) >= self.threshold,
                             to=False))
        else:
            return _t.ret(self.labels[np.argmax(prob, axis=1)])