Source Code Cross Referenced for MILR.java in  » Science » weka » weka » classifiers » mi » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Science » weka » weka.classifiers.mi 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    This program is free software; you can redistribute it and/or modify
003:         *    it under the terms of the GNU General Public License as published by
004:         *    the Free Software Foundation; either version 2 of the License, or
005:         *    (at your option) any later version.
006:         *
007:         *    This program is distributed in the hope that it will be useful,
008:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
009:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
010:         *    GNU General Public License for more details.
011:         *
012:         *    You should have received a copy of the GNU General Public License
013:         *    along with this program; if not, write to the Free Software
014:         *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
015:         */
016:
017:        /*
018:         * MILR.java
019:         * Copyright (C) 2005 University of Waikato, Hamilton, New Zealand
020:         *
021:         */
022:
023:        package weka.classifiers.mi;
024:
025:        import weka.classifiers.Classifier;
026:        import weka.core.Capabilities;
027:        import weka.core.Instance;
028:        import weka.core.Instances;
029:        import weka.core.MultiInstanceCapabilitiesHandler;
030:        import weka.core.Optimization;
031:        import weka.core.Option;
032:        import weka.core.OptionHandler;
033:        import weka.core.SelectedTag;
034:        import weka.core.Tag;
035:        import weka.core.Utils;
036:        import weka.core.Capabilities.Capability;
037:
038:        import java.util.Enumeration;
039:        import java.util.Vector;
040:
041:        /**
042:         <!-- globalinfo-start -->
043:         * Uses either standard or collective multi-instance assumption, but within linear regression. For the collective assumption, it offers arithmetic or geometric mean for the posteriors.
044:         * <p/>
045:         <!-- globalinfo-end -->
046:         *
047:         <!-- options-start -->
048:         * Valid options are: <p/>
049:         * 
050:         * <pre> -D
051:         *  Turn on debugging output.</pre>
052:         * 
053:         * <pre> -R &lt;ridge&gt;
054:         *  Set the ridge in the log-likelihood.</pre>
055:         * 
056:         * <pre> -A [0|1|2]
057:         *  Defines the type of algorithm:
058:         *   0. standard MI assumption
059:         *   1. collective MI assumption, arithmetic mean for posteriors
060:         *   2. collective MI assumption, geometric mean for posteriors</pre>
061:         * 
062:         <!-- options-end -->
063:         *
064:         * @author Eibe Frank (eibe@cs.waikato.ac.nz)
065:         * @author Xin Xu (xx5@cs.waikato.ac.nz)
066:         * @version $Revision: 1.3 $ 
067:         */
068:        public class MILR extends Classifier implements  OptionHandler,
069:                MultiInstanceCapabilitiesHandler {
070:
071:            /** for serialization */
072:            static final long serialVersionUID = 1996101190172373826L;
073:
074:            protected double[] m_Par;
075:
076:            /** The number of the class labels */
077:            protected int m_NumClasses;
078:
079:            /** The ridge parameter. */
080:            protected double m_Ridge = 1e-6;
081:
082:            /** Class labels for each bag */
083:            protected int[] m_Classes;
084:
085:            /** MI data */
086:            protected double[][][] m_Data;
087:
088:            /** All attribute names */
089:            protected Instances m_Attributes;
090:
091:            protected double[] xMean = null, xSD = null;
092:
093:            /** the type of processing */
094:            protected int m_AlgorithmType = ALGORITHMTYPE_DEFAULT;
095:
096:            /** standard MI assumption */
097:            public static final int ALGORITHMTYPE_DEFAULT = 0;
098:            /** collective MI assumption, arithmetic mean for posteriors */
099:            public static final int ALGORITHMTYPE_ARITHMETIC = 1;
100:            /** collective MI assumption, geometric mean for posteriors */
101:            public static final int ALGORITHMTYPE_GEOMETRIC = 2;
102:            /** the types of algorithms */
103:            public static final Tag[] TAGS_ALGORITHMTYPE = {
104:                    new Tag(ALGORITHMTYPE_DEFAULT, "standard MI assumption"),
105:                    new Tag(ALGORITHMTYPE_ARITHMETIC,
106:                            "collective MI assumption, arithmetic mean for posteriors"),
107:                    new Tag(ALGORITHMTYPE_GEOMETRIC,
108:                            "collective MI assumption, geometric mean for posteriors"), };
109:
110:            /**
111:             * Returns the tip text for this property
112:             *
113:             * @return tip text for this property suitable for
114:             * displaying in the explorer/experimenter gui
115:             */
116:            public String globalInfo() {
117:                return "Uses either standard or collective multi-instance assumption, but "
118:                        + "within linear regression. For the collective assumption, it offers "
119:                        + "arithmetic or geometric mean for the posteriors.";
120:            }
121:
122:            /**
123:             * Returns an enumeration describing the available options
124:             *
125:             * @return an enumeration of all the available options
126:             */
127:            public Enumeration listOptions() {
128:                Vector result = new Vector();
129:
130:                result.addElement(new Option("\tTurn on debugging output.",
131:                        "D", 0, "-D"));
132:
133:                result.addElement(new Option(
134:                        "\tSet the ridge in the log-likelihood.", "R", 1,
135:                        "-R <ridge>"));
136:
137:                result
138:                        .addElement(new Option(
139:                                "\tDefines the type of algorithm:\n"
140:                                        + "\t 0. standard MI assumption\n"
141:                                        + "\t 1. collective MI assumption, arithmetic mean for posteriors\n"
142:                                        + "\t 2. collective MI assumption, geometric mean for posteriors",
143:                                "A", 1, "-A [0|1|2]"));
144:
145:                return result.elements();
146:            }
147:
148:            /**
149:             * Parses a given list of options. 
150:             *
151:             * @param options the list of options as an array of strings
152:             * @throws Exception if an option is not supported
153:             */
154:            public void setOptions(String[] options) throws Exception {
155:                String tmpStr;
156:
157:                setDebug(Utils.getFlag('D', options));
158:
159:                tmpStr = Utils.getOption('R', options);
160:                if (tmpStr.length() != 0)
161:                    setRidge(Double.parseDouble(tmpStr));
162:                else
163:                    setRidge(1.0e-6);
164:
165:                tmpStr = Utils.getOption('A', options);
166:                if (tmpStr.length() != 0) {
167:                    setAlgorithmType(new SelectedTag(Integer.parseInt(tmpStr),
168:                            TAGS_ALGORITHMTYPE));
169:                } else {
170:                    setAlgorithmType(new SelectedTag(ALGORITHMTYPE_DEFAULT,
171:                            TAGS_ALGORITHMTYPE));
172:                }
173:            }
174:
175:            /**
176:             * Gets the current settings of the classifier.
177:             *
178:             * @return an array of strings suitable for passing to setOptions
179:             */
180:            public String[] getOptions() {
181:                Vector result;
182:
183:                result = new Vector();
184:
185:                if (getDebug())
186:                    result.add("-D");
187:
188:                result.add("-R");
189:                result.add("" + getRidge());
190:
191:                result.add("-A");
192:                result.add("" + m_AlgorithmType);
193:
194:                return (String[]) result.toArray(new String[result.size()]);
195:            }
196:
197:            /**
198:             * Returns the tip text for this property
199:             *
200:             * @return tip text for this property suitable for
201:             * displaying in the explorer/experimenter gui
202:             */
203:            public String ridgeTipText() {
204:                return "The ridge in the log-likelihood.";
205:            }
206:
207:            /**
208:             * Sets the ridge in the log-likelihood.
209:             *
210:             * @param ridge the ridge
211:             */
212:            public void setRidge(double ridge) {
213:                m_Ridge = ridge;
214:            }
215:
216:            /**
217:             * Gets the ridge in the log-likelihood.
218:             *
219:             * @return the ridge
220:             */
221:            public double getRidge() {
222:                return m_Ridge;
223:            }
224:
225:            /**
226:             * Returns the tip text for this property
227:             *
228:             * @return tip text for this property suitable for
229:             * displaying in the explorer/experimenter gui
230:             */
231:            public String algorithmTypeTipText() {
232:                return "The mean type for the posteriors.";
233:            }
234:
235:            /**
236:             * Gets the type of algorithm.
237:             *
238:             * @return the algorithm type
239:             */
240:            public SelectedTag getAlgorithmType() {
241:                return new SelectedTag(m_AlgorithmType, TAGS_ALGORITHMTYPE);
242:            }
243:
244:            /**
245:             * Sets the algorithm type.
246:             *
247:             * @param newType the new algorithm type
248:             */
249:            public void setAlgorithmType(SelectedTag newType) {
250:                if (newType.getTags() == TAGS_ALGORITHMTYPE) {
251:                    m_AlgorithmType = newType.getSelectedTag().getID();
252:                }
253:            }
254:
255:            private class OptEng extends Optimization {
256:
257:                /** the type to use 
258:                 * @see MILR#TAGS_ALGORITHMTYPE */
259:                private int m_Type;
260:
261:                /**
262:                 * initializes the object
263:                 * 
264:                 * @param type      the type top use
265:                 * @see MILR#TAGS_ALGORITHMTYPE
266:                 */
267:                public OptEng(int type) {
268:                    super ();
269:
270:                    m_Type = type;
271:                }
272:
273:                /** 
274:                 * Evaluate objective function
275:                 * @param x the current values of variables
276:                 * @return the value of the objective function 
277:                 */
278:                protected double objectiveFunction(double[] x) {
279:                    double nll = 0; // -LogLikelihood
280:
281:                    switch (m_Type) {
282:                    case ALGORITHMTYPE_DEFAULT:
283:                        for (int i = 0; i < m_Classes.length; i++) { // ith bag
284:                            int nI = m_Data[i][0].length; // numInstances in ith bag
285:                            double bag = 0.0, // NLL of each bag 
286:                            prod = 0.0; // Log-prob. 
287:
288:                            for (int j = 0; j < nI; j++) {
289:                                double exp = 0.0;
290:                                for (int k = m_Data[i].length - 1; k >= 0; k--)
291:                                    exp += m_Data[i][k][j] * x[k + 1];
292:                                exp += x[0];
293:                                exp = Math.exp(exp);
294:
295:                                if (m_Classes[i] == 1)
296:                                    prod -= Math.log(1.0 + exp);
297:                                else
298:                                    bag += Math.log(1.0 + exp);
299:                            }
300:
301:                            if (m_Classes[i] == 1)
302:                                bag = -Math.log(1.0 - Math.exp(prod));
303:
304:                            nll += bag;
305:                        }
306:                        break;
307:
308:                    case ALGORITHMTYPE_ARITHMETIC:
309:                        for (int i = 0; i < m_Classes.length; i++) { // ith bag
310:                            int nI = m_Data[i][0].length; // numInstances in ith bag
311:                            double bag = 0; // NLL of each bag
312:
313:                            for (int j = 0; j < nI; j++) {
314:                                double exp = 0.0;
315:                                for (int k = m_Data[i].length - 1; k >= 0; k--)
316:                                    exp += m_Data[i][k][j] * x[k + 1];
317:                                exp += x[0];
318:                                exp = Math.exp(exp);
319:
320:                                if (m_Classes[i] == 1)
321:                                    bag += 1.0 - 1.0 / (1.0 + exp); // To avoid exp infinite
322:                                else
323:                                    bag += 1.0 / (1.0 + exp);
324:                            }
325:                            bag /= (double) nI;
326:
327:                            nll -= Math.log(bag);
328:                        }
329:                        break;
330:
331:                    case ALGORITHMTYPE_GEOMETRIC:
332:                        for (int i = 0; i < m_Classes.length; i++) { // ith bag
333:                            int nI = m_Data[i][0].length; // numInstances in ith bag
334:                            double bag = 0; // Log-prob. 
335:
336:                            for (int j = 0; j < nI; j++) {
337:                                double exp = 0.0;
338:                                for (int k = m_Data[i].length - 1; k >= 0; k--)
339:                                    exp += m_Data[i][k][j] * x[k + 1];
340:                                exp += x[0];
341:
342:                                if (m_Classes[i] == 1)
343:                                    bag -= exp / (double) nI;
344:                                else
345:                                    bag += exp / (double) nI;
346:                            }
347:
348:                            nll += Math.log(1.0 + Math.exp(bag));
349:                        }
350:                        break;
351:                    }
352:
353:                    // ridge: note that intercepts NOT included
354:                    for (int r = 1; r < x.length; r++)
355:                        nll += m_Ridge * x[r] * x[r];
356:
357:                    return nll;
358:                }
359:
360:                /** 
361:                 * Evaluate Jacobian vector
362:                 * @param x the current values of variables
363:                 * @return the gradient vector 
364:                 */
365:                protected double[] evaluateGradient(double[] x) {
366:                    double[] grad = new double[x.length];
367:
368:                    switch (m_Type) {
369:                    case ALGORITHMTYPE_DEFAULT:
370:                        for (int i = 0; i < m_Classes.length; i++) { // ith bag
371:                            int nI = m_Data[i][0].length; // numInstances in ith bag
372:
373:                            double denom = 0.0; // denominator, in log-scale       
374:                            double[] bag = new double[grad.length]; //gradient update with ith bag
375:
376:                            for (int j = 0; j < nI; j++) {
377:                                // Compute exp(b0+b1*Xi1j+...)/[1+exp(b0+b1*Xi1j+...)]
378:                                double exp = 0.0;
379:                                for (int k = m_Data[i].length - 1; k >= 0; k--)
380:                                    exp += m_Data[i][k][j] * x[k + 1];
381:                                exp += x[0];
382:                                exp = Math.exp(exp) / (1.0 + Math.exp(exp));
383:
384:                                if (m_Classes[i] == 1)
385:                                    // Bug fix: it used to be denom += Math.log(1.0+exp);
386:                                    // Fixed 21 Jan 2005 (Eibe)
387:                                    denom -= Math.log(1.0 - exp);
388:
389:                                // Instance-wise update of dNLL/dBk
390:                                for (int p = 0; p < x.length; p++) { // pth variable
391:                                    double m = 1.0;
392:                                    if (p > 0)
393:                                        m = m_Data[i][p - 1][j];
394:                                    bag[p] += m * exp;
395:                                }
396:                            }
397:
398:                            denom = Math.exp(denom);
399:
400:                            // Bag-wise update of dNLL/dBk
401:                            for (int q = 0; q < grad.length; q++) {
402:                                if (m_Classes[i] == 1)
403:                                    grad[q] -= bag[q] / (denom - 1.0);
404:                                else
405:                                    grad[q] += bag[q];
406:                            }
407:                        }
408:                        break;
409:
410:                    case ALGORITHMTYPE_ARITHMETIC:
411:                        for (int i = 0; i < m_Classes.length; i++) { // ith bag
412:                            int nI = m_Data[i][0].length; // numInstances in ith bag 
413:
414:                            double denom = 0.0;
415:                            double[] numrt = new double[x.length];
416:
417:                            for (int j = 0; j < nI; j++) {
418:                                // Compute exp(b0+b1*Xi1j+...)/[1+exp(b0+b1*Xi1j+...)]
419:                                double exp = 0.0;
420:                                for (int k = m_Data[i].length - 1; k >= 0; k--)
421:                                    exp += m_Data[i][k][j] * x[k + 1];
422:                                exp += x[0];
423:                                exp = Math.exp(exp);
424:                                if (m_Classes[i] == 1)
425:                                    denom += exp / (1.0 + exp);
426:                                else
427:                                    denom += 1.0 / (1.0 + exp);
428:
429:                                // Instance-wise update of dNLL/dBk
430:                                for (int p = 0; p < x.length; p++) { // pth variable
431:                                    double m = 1.0;
432:                                    if (p > 0)
433:                                        m = m_Data[i][p - 1][j];
434:                                    numrt[p] += m * exp
435:                                            / ((1.0 + exp) * (1.0 + exp));
436:                                }
437:                            }
438:
439:                            // Bag-wise update of dNLL/dBk
440:                            for (int q = 0; q < grad.length; q++) {
441:                                if (m_Classes[i] == 1)
442:                                    grad[q] -= numrt[q] / denom;
443:                                else
444:                                    grad[q] += numrt[q] / denom;
445:                            }
446:                        }
447:                        break;
448:
449:                    case ALGORITHMTYPE_GEOMETRIC:
450:                        for (int i = 0; i < m_Classes.length; i++) { // ith bag
451:                            int nI = m_Data[i][0].length; // numInstances in ith bag    
452:                            double bag = 0;
453:                            double[] sumX = new double[x.length];
454:                            for (int j = 0; j < nI; j++) {
455:                                // Compute exp(b0+b1*Xi1j+...)/[1+exp(b0+b1*Xi1j+...)]
456:                                double exp = 0.0;
457:                                for (int k = m_Data[i].length - 1; k >= 0; k--)
458:                                    exp += m_Data[i][k][j] * x[k + 1];
459:                                exp += x[0];
460:
461:                                if (m_Classes[i] == 1) {
462:                                    bag -= exp / (double) nI;
463:                                    for (int q = 0; q < grad.length; q++) {
464:                                        double m = 1.0;
465:                                        if (q > 0)
466:                                            m = m_Data[i][q - 1][j];
467:                                        sumX[q] -= m / (double) nI;
468:                                    }
469:                                } else {
470:                                    bag += exp / (double) nI;
471:                                    for (int q = 0; q < grad.length; q++) {
472:                                        double m = 1.0;
473:                                        if (q > 0)
474:                                            m = m_Data[i][q - 1][j];
475:                                        sumX[q] += m / (double) nI;
476:                                    }
477:                                }
478:                            }
479:
480:                            for (int p = 0; p < x.length; p++)
481:                                grad[p] += Math.exp(bag) * sumX[p]
482:                                        / (1.0 + Math.exp(bag));
483:                        }
484:                        break;
485:                    }
486:
487:                    // ridge: note that intercepts NOT included
488:                    for (int r = 1; r < x.length; r++) {
489:                        grad[r] += 2.0 * m_Ridge * x[r];
490:                    }
491:
492:                    return grad;
493:                }
494:            }
495:
496:            /**
497:             * Returns default capabilities of the classifier.
498:             *
499:             * @return      the capabilities of this classifier
500:             */
501:            public Capabilities getCapabilities() {
502:                Capabilities result = super .getCapabilities();
503:
504:                // attributes
505:                result.enable(Capability.NOMINAL_ATTRIBUTES);
506:                result.enable(Capability.RELATIONAL_ATTRIBUTES);
507:                result.enable(Capability.MISSING_VALUES);
508:
509:                // class
510:                result.enable(Capability.BINARY_CLASS);
511:                result.enable(Capability.MISSING_CLASS_VALUES);
512:
513:                // other
514:                result.enable(Capability.ONLY_MULTIINSTANCE);
515:
516:                return result;
517:            }
518:
519:            /**
520:             * Returns the capabilities of this multi-instance classifier for the
521:             * relational data.
522:             *
523:             * @return            the capabilities of this object
524:             * @see               Capabilities
525:             */
526:            public Capabilities getMultiInstanceCapabilities() {
527:                Capabilities result = super .getCapabilities();
528:
529:                // attributes
530:                result.enable(Capability.NOMINAL_ATTRIBUTES);
531:                result.enable(Capability.NUMERIC_ATTRIBUTES);
532:                result.enable(Capability.DATE_ATTRIBUTES);
533:                result.enable(Capability.MISSING_VALUES);
534:
535:                // class
536:                result.disableAllClasses();
537:                result.enable(Capability.NO_CLASS);
538:
539:                return result;
540:            }
541:
542:            /**
543:             * Builds the classifier
544:             *
545:             * @param train the training data to be used for generating the
546:             * boosted classifier.
547:             * @throws Exception if the classifier could not be built successfully
548:             */
549:            public void buildClassifier(Instances train) throws Exception {
550:                // can classifier handle the data?
551:                getCapabilities().testWithFail(train);
552:
553:                // remove instances with missing class
554:                train = new Instances(train);
555:                train.deleteWithMissingClass();
556:
557:                m_NumClasses = train.numClasses();
558:
559:                int nR = train.attribute(1).relation().numAttributes();
560:                int nC = train.numInstances();
561:
562:                m_Data = new double[nC][nR][]; // Data values
563:                m_Classes = new int[nC]; // Class values
564:                m_Attributes = train.attribute(1).relation();
565:
566:                xMean = new double[nR]; // Mean of mean
567:                xSD = new double[nR]; // Mode of stddev
568:
569:                double sY1 = 0, sY0 = 0, totIns = 0; // Number of classes
570:                int[] missingbags = new int[nR];
571:
572:                if (m_Debug) {
573:                    System.out.println("Extracting data...");
574:                }
575:
576:                for (int h = 0; h < m_Data.length; h++) {
577:                    Instance current = train.instance(h);
578:                    m_Classes[h] = (int) current.classValue(); // Class value starts from 0
579:                    Instances currInsts = current.relationalValue(1);
580:                    int nI = currInsts.numInstances();
581:                    totIns += (double) nI;
582:
583:                    for (int i = 0; i < nR; i++) {
584:                        // initialize m_data[][][]		
585:                        m_Data[h][i] = new double[nI];
586:                        double avg = 0, std = 0, num = 0;
587:                        for (int k = 0; k < nI; k++) {
588:                            if (!currInsts.instance(k).isMissing(i)) {
589:                                m_Data[h][i][k] = currInsts.instance(k)
590:                                        .value(i);
591:                                avg += m_Data[h][i][k];
592:                                std += m_Data[h][i][k] * m_Data[h][i][k];
593:                                num++;
594:                            } else
595:                                m_Data[h][i][k] = Double.NaN;
596:                        }
597:
598:                        if (num > 0) {
599:                            xMean[i] += avg / num;
600:                            xSD[i] += std / num;
601:                        } else
602:                            missingbags[i]++;
603:                    }
604:
605:                    // Class count	
606:                    if (m_Classes[h] == 1)
607:                        sY1++;
608:                    else
609:                        sY0++;
610:                }
611:
612:                for (int j = 0; j < nR; j++) {
613:                    xMean[j] = xMean[j] / (double) (nC - missingbags[j]);
614:                    xSD[j] = Math.sqrt(Math.abs(xSD[j]
615:                            / ((double) (nC - missingbags[j]) - 1.0) - xMean[j]
616:                            * xMean[j] * (double) (nC - missingbags[j])
617:                            / ((double) (nC - missingbags[j]) - 1.0)));
618:                }
619:
620:                if (m_Debug) {
621:                    // Output stats about input data
622:                    System.out.println("Descriptives...");
623:                    System.out.println(sY0 + " bags have class 0 and " + sY1
624:                            + " bags have class 1");
625:                    System.out.println("\n Variable     Avg       SD    ");
626:                    for (int j = 0; j < nR; j++)
627:                        System.out.println(Utils.doubleToString(j, 8, 4)
628:                                + Utils.doubleToString(xMean[j], 10, 4)
629:                                + Utils.doubleToString(xSD[j], 10, 4));
630:                }
631:
632:                // Normalise input data and remove ignored attributes
633:                for (int i = 0; i < nC; i++) {
634:                    for (int j = 0; j < nR; j++) {
635:                        for (int k = 0; k < m_Data[i][j].length; k++) {
636:                            if (xSD[j] != 0) {
637:                                if (!Double.isNaN(m_Data[i][j][k]))
638:                                    m_Data[i][j][k] = (m_Data[i][j][k] - xMean[j])
639:                                            / xSD[j];
640:                                else
641:                                    m_Data[i][j][k] = 0;
642:                            }
643:                        }
644:                    }
645:                }
646:
647:                if (m_Debug) {
648:                    System.out.println("\nIteration History...");
649:                }
650:
651:                double x[] = new double[nR + 1];
652:                x[0] = Math.log((sY1 + 1.0) / (sY0 + 1.0));
653:                double[][] b = new double[2][x.length];
654:                b[0][0] = Double.NaN;
655:                b[1][0] = Double.NaN;
656:                for (int q = 1; q < x.length; q++) {
657:                    x[q] = 0.0;
658:                    b[0][q] = Double.NaN;
659:                    b[1][q] = Double.NaN;
660:                }
661:
662:                OptEng opt = new OptEng(m_AlgorithmType);
663:                opt.setDebug(m_Debug);
664:                m_Par = opt.findArgmin(x, b);
665:                while (m_Par == null) {
666:                    m_Par = opt.getVarbValues();
667:                    if (m_Debug)
668:                        System.out
669:                                .println("200 iterations finished, not enough!");
670:                    m_Par = opt.findArgmin(m_Par, b);
671:                }
672:                if (m_Debug)
673:                    System.out
674:                            .println(" -------------<Converged>--------------");
675:
676:                // feature selection use
677:                if (m_AlgorithmType == ALGORITHMTYPE_ARITHMETIC) {
678:                    double[] fs = new double[nR];
679:                    for (int k = 1; k < nR + 1; k++)
680:                        fs[k - 1] = Math.abs(m_Par[k]);
681:                    int[] idx = Utils.sort(fs);
682:                    double max = fs[idx[idx.length - 1]];
683:                    for (int k = idx.length - 1; k >= 0; k--)
684:                        System.out.println(m_Attributes.attribute(idx[k])
685:                                .name()
686:                                + "\t" + (fs[idx[k]] * 100 / max));
687:                }
688:
689:                // Convert coefficients back to non-normalized attribute units
690:                for (int j = 1; j < nR + 1; j++) {
691:                    if (xSD[j - 1] != 0) {
692:                        m_Par[j] /= xSD[j - 1];
693:                        m_Par[0] -= m_Par[j] * xMean[j - 1];
694:                    }
695:                }
696:            }
697:
698:            /**
699:             * Computes the distribution for a given exemplar
700:             *
701:             * @param exmp the exemplar for which distribution is computed
702:             * @return the distribution
703:             * @throws Exception if the distribution can't be computed successfully
704:             */
705:            public double[] distributionForInstance(Instance exmp)
706:                    throws Exception {
707:
708:                // Extract the data
709:                Instances ins = exmp.relationalValue(1);
710:                int nI = ins.numInstances(), nA = ins.numAttributes();
711:                double[][] dat = new double[nI][nA + 1];
712:                for (int j = 0; j < nI; j++) {
713:                    dat[j][0] = 1.0;
714:                    int idx = 1;
715:                    for (int k = 0; k < nA; k++) {
716:                        if (!ins.instance(j).isMissing(k))
717:                            dat[j][idx] = ins.instance(j).value(k);
718:                        else
719:                            dat[j][idx] = xMean[idx - 1];
720:                        idx++;
721:                    }
722:                }
723:
724:                // Compute the probability of the bag
725:                double[] distribution = new double[2];
726:                switch (m_AlgorithmType) {
727:                case ALGORITHMTYPE_DEFAULT:
728:                    distribution[0] = 0.0; // Log-Prob. for class 0
729:
730:                    for (int i = 0; i < nI; i++) {
731:                        double exp = 0.0;
732:                        for (int r = 0; r < m_Par.length; r++)
733:                            exp += m_Par[r] * dat[i][r];
734:                        exp = Math.exp(exp);
735:
736:                        // Prob. updated for one instance
737:                        distribution[0] -= Math.log(1.0 + exp);
738:                    }
739:
740:                    // Prob. for class 0
741:                    distribution[0] = Math.exp(distribution[0]);
742:                    // Prob. for class 1
743:                    distribution[1] = 1.0 - distribution[0];
744:                    break;
745:
746:                case ALGORITHMTYPE_ARITHMETIC:
747:                    distribution[0] = 0.0; // Prob. for class 0
748:
749:                    for (int i = 0; i < nI; i++) {
750:                        double exp = 0.0;
751:                        for (int r = 0; r < m_Par.length; r++)
752:                            exp += m_Par[r] * dat[i][r];
753:                        exp = Math.exp(exp);
754:
755:                        // Prob. updated for one instance
756:                        distribution[0] += 1.0 / (1.0 + exp);
757:                    }
758:
759:                    // Prob. for class 0
760:                    distribution[0] /= (double) nI;
761:                    // Prob. for class 1
762:                    distribution[1] = 1.0 - distribution[0];
763:                    break;
764:
765:                case ALGORITHMTYPE_GEOMETRIC:
766:                    for (int i = 0; i < nI; i++) {
767:                        double exp = 0.0;
768:                        for (int r = 0; r < m_Par.length; r++)
769:                            exp += m_Par[r] * dat[i][r];
770:                        distribution[1] += exp / (double) nI;
771:                    }
772:
773:                    // Prob. for class 1
774:                    distribution[1] = 1.0 / (1.0 + Math.exp(-distribution[1]));
775:                    // Prob. for class 0
776:                    distribution[0] = 1 - distribution[1];
777:                    break;
778:                }
779:
780:                return distribution;
781:            }
782:
783:            /**
784:             * Gets a string describing the classifier.
785:             *
786:             * @return a string describing the classifer built.
787:             */
788:            public String toString() {
789:
790:                String result = "Modified Logistic Regression";
791:                if (m_Par == null) {
792:                    return result + ": No model built yet.";
793:                }
794:
795:                result += "\nMean type: "
796:                        + getAlgorithmType().getSelectedTag().getReadable()
797:                        + "\n";
798:                result += "\nCoefficients...\n" + "Variable      Coeff.\n";
799:                for (int j = 1, idx = 0; j < m_Par.length; j++, idx++) {
800:                    result += m_Attributes.attribute(idx).name();
801:                    result += " " + Utils.doubleToString(m_Par[j], 12, 4);
802:                    result += "\n";
803:                }
804:
805:                result += "Intercept:";
806:                result += " " + Utils.doubleToString(m_Par[0], 10, 4);
807:                result += "\n";
808:
809:                result += "\nOdds Ratios...\n" + "Variable         O.R.\n";
810:                for (int j = 1, idx = 0; j < m_Par.length; j++, idx++) {
811:                    result += " " + m_Attributes.attribute(idx).name();
812:                    double ORc = Math.exp(m_Par[j]);
813:                    result += " "
814:                            + ((ORc > 1e10) ? "" + ORc : Utils.doubleToString(
815:                                    ORc, 12, 4));
816:                }
817:                result += "\n";
818:                return result;
819:            }
820:
821:            /**
822:             * Main method for testing this class.
823:             *
824:             * @param argv should contain the command line arguments to the
825:             * scheme (see Evaluation)
826:             */
827:            public static void main(String[] argv) {
828:                runClassifier(new MILR(), argv);
829:            }
830:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.