Started work on.
authorilb@NIH.GOV <ilb@NIH.GOV@ba61647d-9d00-f842-95cd-605cb4296b96>
Tue, 17 Apr 2018 22:13:54 +0000 (22:13 +0000)
committerilb@NIH.GOV <ilb@NIH.GOV@ba61647d-9d00-f842-95cd-605cb4296b96>
Tue, 17 Apr 2018 22:13:54 +0000 (22:13 +0000)
git-svn-id: https://citdcbmipav.cit.nih.gov/repos-pub/mipav/trunk@15452 ba61647d-9d00-f842-95cd-605cb4296b96

mipav/src/gov/nih/mipav/model/algorithms/StochasticForests.java [new file with mode: 0644]

diff --git a/mipav/src/gov/nih/mipav/model/algorithms/StochasticForests.java b/mipav/src/gov/nih/mipav/model/algorithms/StochasticForests.java
new file mode 100644 (file)
index 0000000..ce6c13c
--- /dev/null
@@ -0,0 +1,306 @@
+package gov.nih.mipav.model.algorithms;\r
+\r
+\r
+\r
+import gov.nih.mipav.model.structures.*;\r
+import gov.nih.mipav.view.*;\r
+import java.io.*;\r
+import java.util.*;\r
+\r
+public class StochasticForests extends AlgorithmBase {\r
+       // Note that while Random Forests is the name usually applied to this type\r
+       // of algorithm, Random Forests(tm) is a trademark of Leo Breiman and Adele Cutler and is \r
+       // licensed exclusively to Salford Systems for the commercial release of the software.\r
+       // Our trademarks also include RF(tm), RandomForests(tm), RandomForest(tm) and Random Forest(tm).\r
+       \r
+       // This is a port from C++ to Java of the ranger package of version 0.9.7 of A Fast Implementation\r
+       // of Random Forests.  The date of the original code is 3/29/2018.  The authors of the original code\r
+       // are Marvin N. Wright, Stefan Wager, and Philipp Probst.  The maintainer of the original code is\r
+       // Marvin N. Wright at cran@wrig.de.  The license of the C++ core of version 0.9.7 is a MIT license. \r
+       //(The R package which is not used in this port is still a GPL3 license.)\r
+       \r
+       // Copyright <2014-2018> <Marvin N. Wright>\r
+\r
+       // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and\r
+       // associated documentation files (the "Software"), to deal in the Software without restriction, \r
+       // including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
+       // and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,\r
+       // subject to the following conditions:\r
+\r
+       // The above copyright notice and this permission notice shall be included in all copies or substantial\r
+       // portions of the Software.\r
+\r
+       // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+       // NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+       // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r
+       // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\r
+       // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+       \r
+       // ### Introduction\r
+       // ranger is a fast implementation of random forest (Breiman 2001) or recursive partitioning, \r
+       // particularly suited for high dimensional data. Classification, regression, probability estimation\r
+       // and survival forests are supported. Classification and regression forests are implemented as in\r
+       // the original Random Forest (Breiman 2001), survival forests as in Random Survival Forests\r
+       // (Ishwaran et al. 2008). For probability estimation forests see Malley et al. (2012). \r
+       \r
+       // ### References\r
+       // 1.) Wright, M. N. & Ziegler, A. (2017). ranger: A Fast Implementation of Random Forests for High\r
+       // Dimensional Data in C++ and R. Journal of Statistical Software 77:1-17.\r
+       // http://dx.doi.org/10.18637/jss.v077.i01.\r
+       // 2.) Schmid, M., Wright, M. N. & Ziegler, A. (2016). On the use of Harrell's C for clinical risk\r
+       // prediction via random survival forests. Expert Systems with Applications 63:450-459. \r
+       // http://dx.doi.org/10.1016/j.eswa.2016.07.018.\r
+       // 3.) Wright, M. N., Dankowski, T. & Ziegler, A. (2017). Unbiased split variable selection for\r
+       // random survival forests using maximally selected rank statistics. Statistics in Medicine. \r
+       // http://dx.doi.org/10.1002/sim.7212.\r
+       // 4.) Breiman, L. (2001). Random forests. Machine learning 45:5-32.\r
+       // 5.) Ishwaran, H., Kogalur, U. B., Blackstone, E. H., & Lauer, M. S. (2008). \r
+       // Random survival forests. The Annals of Applied Statistics 2:841-860.\r
+       // 6.) Malley, J. D., Kruppa, J., Dasgupta, A., Malley, K. G., & Ziegler, A. (2012). \r
+       // Probability machines: consistent probability estimation using nonparametric learning machines. \r
+       // Methods of Information in Medicine 51:74-81.\r
+\r
+    // Tree types, probability is not selected by ID\r
+       private enum TreeType {\r
+               TREE_CLASSIFICATION,\r
+               TREE_REGRESSION,\r
+           TREE_SURVIVAL,\r
+           TREE_PROBABILITY\r
+       };\r
+       \r
+       // Memory modes\r
+       private enum MemoryMode {\r
+               MEM_DOUBLE,\r
+               MEM_FLOAT,\r
+               MEM_CHAR\r
+       };\r
+       \r
+       // Mask and offset to store 2 bit values in bytes\r
+       static final int mask[] = new int[]{192,48,12,3};\r
+       static final int offset[] = new int[]{6,4,2,0};\r
+       \r
+       // Variable importance\r
+       private enum ImportanceMode {\r
+               IMP_NONE,\r
+               IMP_GINI,\r
+               IMP_PERM_BREIMAN,\r
+               IMP_PERM_LIAW,\r
+               IMP_PERM_RAW,\r
+               IMP_GINI_CORRECTED\r
+       };\r
+       \r
+       // Split mode\r
+       private enum SplitRule {\r
+               LOGRANK,\r
+               AUC,\r
+               AUC_IGNORE_TIES,\r
+               MAXSTAT,\r
+               EXTRATREES\r
+       };\r
+       \r
+       // Prediction type\r
+       private enum PredictionType {\r
+               RESPONSE,\r
+               TERMINALNODES\r
+       };\r
+       \r
+       // Default values\r
+       final int DEFAULT_NUM_TREE = 500;\r
+       final int DEFAULT_NUM_THREADS = 0;\r
+       final ImportanceMode DEFAULT_IMPORTANCE_MODE = ImportanceMode.IMP_NONE;\r
+       \r
+       final int DEFAULT_MIN_NODE_SIZE_CLASSIFICATION = 1;\r
+       final int DEFAULT_MIN_NODE_SIZE_REGRESSION = 5;\r
+       final int DEFAULT_MIN_NODE_SIZE_SURVIVAL = 3;\r
+       final int DEFAULT_MIN_NODE_SIZE_PROBABILITY = 10;\r
+\r
+       final SplitRule DEFAULT_SPLITRULE = SplitRule.LOGRANK;\r
+       final double DEFAULT_ALPHA = 0.5;\r
+       final double DEFAULT_MINPROP = 0.1;\r
+\r
+       final PredictionType DEFAULT_PREDICTIONTYPE = PredictionType.RESPONSE;\r
+       final int DEFAULT_NUM_RANDOM_SPLITS = 1;\r
+\r
+       //const std::vector<double> DEFAULT_SAMPLE_FRACTION = std::vector<double>({1});\r
+\r
+       // Interval to print progress in seconds\r
+       final double STATUS_INTERVAL = 30.0;\r
+\r
+       // Threshold for q value split method switch\r
+       final double Q_THRESHOLD = 0.02;\r
+       \r
+       private class Data {\r
+               protected Vector<String> variable_names;\r
+               protected int num_rows = 0;\r
+               protected int num_rows_rounded = 0;\r
+               protected int num_cols = 0;\r
+               \r
+               protected char snp_data[] = null;\r
+               protected int num_cols_no_snp = 0;\r
+               protected boolean externalData = true;\r
+               \r
+               protected int index_data[] = null;\r
+               protected Vector<Vector<Double>> unique_data_values = null;\r
+               protected int max_num_unique_values = 0;\r
+               int i;\r
+               \r
+               // Variable to not split at (only dependent_varID for non-survival trees)\r
+               protected Vector<Integer> no_split_variables = null;\r
+               \r
+               // For each varID true if ordered\r
+           protected Vector<Boolean> is_ordered_variable = null;\r
+           \r
+           // Permuted samples for corrected impurity importance\r
+           protected Vector<Integer> permuted_sampleIDs = null;\r
+           \r
+           public void dispose() {\r
+               index_data = null;\r
+           }\r
+           \r
+           public int getVariableID(String variable_name) {\r
+                for (i = 0; i < variable_names.size(); i++) {\r
+                        if(variable_names.get(i).equals(variable_name)) {\r
+                                return i;\r
+                        }\r
+                } // for (i = 0; i < variable_names.size(); i++)\r
+                return -1;\r
+           }\r
+           \r
+           public void addSnpData(char snp_data[], int num_cols_snp) {\r
+               num_cols = num_cols_no_snp + num_cols_snp;\r
+               num_rows_rounded = roundToNextMultiple(num_rows, 4);\r
+               this.snp_data = snp_data;\r
+           }\r
+           \r
+           // #nocov start\r
+           /*public boolean loadFromFile(String filename) {\r
+               boolean result;\r
+               \r
+               // Open input file\r
+               File file = new File(filename);\r
+               BufferedReader input_file;\r
+               try {\r
+                   input_file = new BufferedReader(new FileReader(file));\r
+               }\r
+               catch (FileNotFoundException e) {\r
+                       MipavUtil.displayError("Could not find file " + filename);\r
+                       return false;\r
+               }\r
+               \r
+               // Count number of rows\r
+               int line_count = 0;\r
+               String line;\r
+               while (true) {\r
+                       try {\r
+                           line = input_file.readLine();\r
+                       }\r
+                       catch (IOException e) {\r
+                               MipavUtil.displayError("IO exception on readLine of " + filename);\r
+                               return false;\r
+                       }\r
+                       if (line != null) {\r
+                               line_count++;\r
+                       }\r
+                       else {\r
+                               break;\r
+                       }\r
+               } // while (true)\r
+               num_rows = line_count-1;\r
+               try {\r
+                   input_file.close();\r
+               }\r
+               catch (IOException e) {\r
+                       MipavUtil.displayError("IO exception on close of " + filename);\r
+               }\r
+               try {\r
+                   input_file = new BufferedReader(new FileReader(file));\r
+               }\r
+               catch (FileNotFoundException e) {\r
+                       MipavUtil.displayError("Could not find file " + filename);\r
+                       return false;\r
+               }\r
+               \r
+               // Check if comma, semicolon, or whitespace separated\r
+               String header_line;\r
+               try {\r
+                   header_line = input_file.readLine();\r
+               }\r
+               catch (IOException e) {\r
+                       MipavUtil.displayError("IO exception reading header line of " + filename);\r
+                       return false;\r
+               }\r
+               \r
+               // Find out if comma, semicolon, or whitespace separated and call appropriate method\r
+               if (header_line.indexOf(",") != -1) {\r
+                       result = loadFromFileOther(input_file, header_line, ",");\r
+               }\r
+               else if (header_line.indexOf(";") != -1) {\r
+                       result = loadFromFileOther(input_file, header_line, ";");       \r
+               }\r
+               else {\r
+                       result = loadFromFileWhitespace(input_file, header_line);\r
+               }\r
+               \r
+               externalData = false;\r
+               try {\r
+                   input_file.close();\r
+               }\r
+               catch (IOException e) {\r
+                       MipavUtil.displayError("IO exception on close of " + filename);\r
+               }\r
+               return result;\r
+           } // loadFromFile\r
+           \r
+           public boolean loadFromFileWhitespace(BufferedReader input_file, String header_line) {\r
+               // Read header\r
+               String[] header_tokens;\r
+               header_tokens = header_line.split(" ");\r
+               for (i = 0; i < header_tokens.length; i++) {\r
+                       variable_names.add(header_tokens[i]);\r
+               }\r
+               num_cols = variable_names.size();\r
+               num_cols_no_snp = num_cols;\r
+               \r
+               // Read body\r
+               boolean error = false;\r
+               String line;\r
+               int row = 0;\r
+               while (true) {\r
+                       try {\r
+                       line = input_file.readLine();\r
+                       }\r
+                       catch (IOException e) {\r
+                               MipavUtil.displayError("IO exception on readLine from input_file");\r
+                               return false;\r
+                       }\r
+                       if (line == null) {\r
+                               break;\r
+                       }\r
+                       String tokens[];\r
+                       tokens = line.split(" ");\r
+                       for (i = 0; i < tokens.length; i++) {\r
+                               double dValue = Double.valueOf(tokens[i]).doubleValue();\r
+                       }\r
+               } // while true\r
+           } */\r
+           \r
+           \r
+       } // private class Data\r
+       \r
+       private int roundToNextMultiple(int value, int multiple) {\r
+               if (multiple == 0) {\r
+                       return value;\r
+               }\r
+               \r
+               int remainder = value % multiple;\r
+               if (remainder == 0) {\r
+                       return value;\r
+               }\r
+               return value + multiple - remainder;\r
+       }\r
+\r
+       \r
+       public void runAlgorithm() {\r
+               \r
+       }\r
+}
\ No newline at end of file