def log1p(expr): # Use trick to compute log1p for small values more accurate # https://www.johndcook.com/blog/2012/07/25/trick-for-computing-log1x/ expr = ast.IdExpr(expr, to_reuse=True) expr1p = utils.add(ast.NumVal(1.0), expr, to_reuse=True) expr1pm1 = utils.sub(expr1p, ast.NumVal(1.0), to_reuse=True) return ast.IfExpr( utils.eq(expr1pm1, ast.NumVal(0.0)), expr, utils.div(utils.mul(expr, ast.LogExpr(expr1p)), expr1pm1))
def _cosine_kernel(self, support_vector): support_vector_norm = np.linalg.norm(support_vector) if support_vector_norm == 0.0: support_vector_norm = 1.0 feature_norm = ast.SqrtExpr(utils.apply_op_to_expressions( ast.BinNumOpType.ADD, *[ utils.mul(ast.FeatureRef(i), ast.FeatureRef(i)) for i in range(len(support_vector)) ]), to_reuse=True) safe_feature_norm = ast.IfExpr(utils.eq(feature_norm, ast.NumVal(0.0)), ast.NumVal(1.0), feature_norm) kernel = self._linear_kernel(support_vector / support_vector_norm) kernel = utils.div(kernel, safe_feature_norm) return kernel