/** * Constructor. The Gaussian mixture model will be learned from the given data with the EM * algorithm. The number of components will be selected by BIC. * * @param data the training data. */ @SuppressWarnings("unchecked") public GaussianMixture(double[] data) { if (data.length < 20) throw new IllegalArgumentException("Too few samples."); ArrayList<Component> mixture = new ArrayList<Component>(); Component c = new Component(); c.priori = 1.0; c.distribution = new GaussianDistribution(data); mixture.add(c); int freedom = 0; for (int i = 0; i < mixture.size(); i++) freedom += mixture.get(i).distribution.npara(); double bic = 0.0; for (double x : data) { double p = c.distribution.p(x); if (p > 0) bic += Math.log(p); } bic -= 0.5 * freedom * Math.log(data.length); double b = Double.NEGATIVE_INFINITY; while (bic > b) { b = bic; components = (ArrayList<Component>) mixture.clone(); split(mixture); bic = EM(mixture, data); freedom = 0; for (int i = 0; i < mixture.size(); i++) freedom += mixture.get(i).distribution.npara(); bic -= 0.5 * freedom * Math.log(data.length); } }
/** Round the bounds for axis i. */ public void extendBound(int i) { if (i < 0 || i >= dimension) { throw new IllegalArgumentException("Invalid bound index: " + i); } extendBound[i] = true; lowerBound[i] = precisionUnit[i] * (Math.floor(originalLowerBound[i] / precisionUnit[i])); upperBound[i] = precisionUnit[i] * (Math.ceil(originalUpperBound[i] / precisionUnit[i])); }
/** * Constructor. The Gaussian mixture model will be learned from the given data with the EM * algorithm. * * @param data the training data. * @param k the number of components. */ public GaussianMixture(double[] data, int k) { if (k < 2) throw new IllegalArgumentException("Invalid number of components in the mixture."); double min = Math.min(data); double max = Math.max(data); double step = (max - min) / (k + 1); for (int i = 0; i < k; i++) { Component c = new Component(); c.priori = 1.0 / k; c.distribution = new GaussianDistribution(min += step, step); components.add(c); } EM(components, data); }
public ExponentialDistributionDemo() { super(new BorderLayout()); Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer, JLabel>(); for (int i = 0; i <= 50; i += 10) { labelTable.put(new Integer(i), new JLabel(String.valueOf(i / 10))); } lambdaSlider = new JSlider(0, 50, (int) Math.round(lambda * 10)); lambdaSlider.addChangeListener(this); lambdaSlider.setLabelTable(labelTable); lambdaSlider.setMajorTickSpacing(10); lambdaSlider.setMinorTickSpacing(2); lambdaSlider.setPaintTicks(true); lambdaSlider.setPaintLabels(true); optionPane = new JPanel(new FlowLayout(FlowLayout.LEFT)); optionPane.setBorder(BorderFactory.createRaisedBevelBorder()); optionPane.add(new JLabel("\u03BB:")); optionPane.add(lambdaSlider); add(optionPane, BorderLayout.NORTH); canvas = new JPanel(new GridLayout(2, 2)); add(canvas, BorderLayout.CENTER); ExponentialDistribution dist = new ExponentialDistribution(lambda); double[][] p = new double[100][2]; double[][] q = new double[100][2]; for (int i = 0; i < p.length; i++) { p[i][0] = i / 20.0; p[i][1] = dist.p(p[i][0]); q[i][0] = i / 20.0; q[i][1] = dist.cdf(p[i][0]); } pdf = LinePlot.plot(p, Line.Style.SOLID, Color.BLUE); pdf.setTitle("PDF"); canvas.add(pdf); cdf = LinePlot.plot(q, Line.Style.SOLID, Color.BLUE); cdf.setTitle("CDF"); canvas.add(cdf); double[] data = new double[500]; for (int i = 0; i < data.length; i++) { data[i] = dist.rand(); } histogram = Histogram.plot(data, 20); histogram.setTitle("Histogram"); canvas.add(histogram); qqplot = QQPlot.plot(data, dist); qqplot.setTitle("Q-Q Plot"); canvas.add(qqplot); }
/** Set the precision unit for axis i. */ void setPrecisionUnit(int i) { if (upperBound[i] > lowerBound[i]) { double digits = Math.log10(Math.abs(upperBound[i] - lowerBound[i])); double residual = digits - Math.floor(digits); if (residual < 0.2) { // If the range is less than 15 units, we reduce one level. digits -= 1.0; } precisionDigits[i] = (int) Math.floor(digits); precisionUnit[i] = Math.pow(10, precisionDigits[i]); if (residual >= 0.2 && residual <= 0.7) { // In case of too few grids, we use a half of precision unit. precisionUnit[i] /= 2; precisionDigits[i] -= 1; } } else { precisionUnit[i] = 0.1; } }