protected GLM refitClassifier(int p, int[][] groups, boolean[] selected, double[][][] x, double[] y, double[][] w, int maxNumIters) {
		List<double[]> xList = new ArrayList<>();
		for (int g = 0; g < selected.length; g++) {
			if (selected[g]) {
				double[][] t = x[g];
				for (int j = 0; j < t.length; j++) {
					xList.add(t[j]);
				}
			}
		}

		double[][] xNew = new double[xList.size()][];
		for (int i = 0; i < xNew.length; i++) {
			xNew[i] = xList.get(i);
		}

		int[] attrs = new int[xNew.length];
		for (int i = 0; i < attrs.length; i++) {
			attrs[i] = i;
		}

		RidgeLearner ridgeLearner = new RidgeLearner();
		ridgeLearner.setVerbose(verbose);
		ridgeLearner.setEpsilon(epsilon);
		ridgeLearner.fitIntercept(fitIntercept);
		// A ridge regression with very small regularization parameter
		// This often improves stability a lot
		GLM glm = ridgeLearner.buildBinaryClassifier(attrs, xNew, y, maxNumIters, 1e-8);
		return getGLM(p, groups, selected, glm.coefficients(0), glm.intercept(0), LinkFunction.LOGIT);
	}