Changeset 2415 for trunk/sources/LibSVM/Model.cs
- Timestamp:
- 10/07/09 11:58:21 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/LibSVM/Model.cs
r2411 r2415 21 21 using System; 22 22 using System.IO; 23 24 namespace SVM { 25 /// <remarks> 26 /// Encapsulates an SVM Model. 27 /// </remarks> 28 [Serializable] 29 public class Model { 30 private Parameter _parameter; 31 private int _numberOfClasses; 32 private int _supportVectorCount; 33 private Node[][] _supportVectors; 34 private double[][] _supportVectorCoefficients; 35 private double[] _rho; 36 private double[] _pairwiseProbabilityA; 37 private double[] _pairwiseProbabilityB; 38 39 private int[] _classLabels; 40 private int[] _numberOfSVPerClass; 41 42 internal Model() { 43 } 44 23 using System.Threading; 24 using System.Globalization; 25 26 namespace SVM 27 { 45 28 /// <summary> 46 /// Parameter object.29 /// Encapsulates an SVM Model. 47 30 /// </summary> 48 public Parameter Parameter { 49 get { 50 return _parameter; 51 } 52 set { 53 _parameter = value; 54 } 55 } 56 57 /// <summary> 58 /// Number of classes in the model. 59 /// </summary> 60 public int NumberOfClasses { 61 get { 62 return _numberOfClasses; 63 } 64 set { 65 _numberOfClasses = value; 66 } 67 } 68 69 /// <summary> 70 /// Total number of support vectors. 71 /// </summary> 72 public int SupportVectorCount { 73 get { 74 return _supportVectorCount; 75 } 76 set { 77 _supportVectorCount = value; 78 } 79 } 80 81 /// <summary> 82 /// The support vectors. 83 /// </summary> 84 public Node[][] SupportVectors { 85 get { 86 return _supportVectors; 87 } 88 set { 89 _supportVectors = value; 90 } 91 } 92 93 /// <summary> 94 /// The coefficients for the support vectors. 95 /// </summary> 96 public double[][] SupportVectorCoefficients { 97 get { 98 return _supportVectorCoefficients; 99 } 100 set { 101 _supportVectorCoefficients = value; 102 } 103 } 104 105 /// <summary> 106 /// Rho values. 107 /// </summary> 108 public double[] Rho { 109 get { 110 return _rho; 111 } 112 set { 113 _rho = value; 114 } 115 } 116 117 /// <summary> 118 /// First pairwise probability. 119 /// </summary> 120 public double[] PairwiseProbabilityA { 121 get { 122 return _pairwiseProbabilityA; 123 } 124 set { 125 _pairwiseProbabilityA = value; 126 } 127 } 128 129 /// <summary> 130 /// Second pairwise probability. 131 /// </summary> 132 public double[] PairwiseProbabilityB { 133 get { 134 return _pairwiseProbabilityB; 135 } 136 set { 137 _pairwiseProbabilityB = value; 138 } 139 } 140 141 // for classification only 142 143 /// <summary> 144 /// Class labels. 145 /// </summary> 146 public int[] ClassLabels { 147 get { 148 return _classLabels; 149 } 150 set { 151 _classLabels = value; 152 } 153 } 154 155 /// <summary> 156 /// Number of support vectors per class. 157 /// </summary> 158 public int[] NumberOfSVPerClass { 159 get { 160 return _numberOfSVPerClass; 161 } 162 set { 163 _numberOfSVPerClass = value; 164 } 165 } 166 167 /// <summary> 168 /// Reads a Model from the provided file. 169 /// </summary> 170 /// <param name="filename">The name of the file containing the Model</param> 171 /// <returns>the Model</returns> 172 public static Model Read(string filename) { 173 FileStream input = File.OpenRead(filename); 174 try { 175 return Read(input); 176 } 177 finally { 178 input.Close(); 179 } 180 } 181 182 /// <summary> 183 /// Reads a Model from the provided stream. 184 /// </summary> 185 /// <param name="stream">The stream from which to read the Model.</param> 186 /// <returns>the Model</returns> 187 public static Model Read(Stream stream) { 188 StreamReader input = new StreamReader(stream); 189 190 // read parameters 191 192 Model model = new Model(); 193 Parameter param = new Parameter(); 194 model.Parameter = param; 195 model.Rho = null; 196 model.PairwiseProbabilityA = null; 197 model.PairwiseProbabilityB = null; 198 model.ClassLabels = null; 199 model.NumberOfSVPerClass = null; 200 201 bool headerFinished = false; 202 while (!headerFinished) { 203 string line = input.ReadLine(); 204 string cmd, arg; 205 int splitIndex = line.IndexOf(' '); 206 if (splitIndex >= 0) { 207 cmd = line.Substring(0, splitIndex); 208 arg = line.Substring(splitIndex + 1); 209 } else { 210 cmd = line; 211 arg = ""; 212 } 213 arg = arg.ToLower(); 214 215 int i, n; 216 switch (cmd) { 217 case "svm_type": 218 param.SvmType = (SvmType)Enum.Parse(typeof(SvmType), arg.ToUpper()); 219 break; 220 221 case "kernel_type": 222 param.KernelType = (KernelType)Enum.Parse(typeof(KernelType), arg.ToUpper()); 223 break; 224 225 case "degree": 226 param.Degree = int.Parse(arg); 227 break; 228 229 case "gamma": 230 param.Gamma = double.Parse(arg); 231 break; 232 233 case "coef0": 234 param.Coefficient0 = double.Parse(arg); 235 break; 236 237 case "nr_class": 238 model.NumberOfClasses = int.Parse(arg); 239 break; 240 241 case "total_sv": 242 model.SupportVectorCount = int.Parse(arg); 243 break; 244 245 case "rho": 246 n = model.NumberOfClasses * (model.NumberOfClasses - 1) / 2; 247 model.Rho = new double[n]; 248 string[] rhoParts = arg.Split(); 249 for (i = 0; i < n; i++) 250 model.Rho[i] = double.Parse(rhoParts[i]); 251 break; 252 253 case "label": 254 n = model.NumberOfClasses; 255 model.ClassLabels = new int[n]; 256 string[] labelParts = arg.Split(); 257 for (i = 0; i < n; i++) 258 model.ClassLabels[i] = int.Parse(labelParts[i]); 259 break; 260 261 case "probA": 262 n = model.NumberOfClasses * (model.NumberOfClasses - 1) / 2; 263 model.PairwiseProbabilityA = new double[n]; 264 string[] probAParts = arg.Split(); 265 for (i = 0; i < n; i++) 266 model.PairwiseProbabilityA[i] = double.Parse(probAParts[i]); 267 break; 268 269 case "probB": 270 n = model.NumberOfClasses * (model.NumberOfClasses - 1) / 2; 271 model.PairwiseProbabilityB = new double[n]; 272 string[] probBParts = arg.Split(); 273 for (i = 0; i < n; i++) 274 model.PairwiseProbabilityB[i] = double.Parse(probBParts[i]); 275 break; 276 277 case "nr_sv": 278 n = model.NumberOfClasses; 279 model.NumberOfSVPerClass = new int[n]; 280 string[] nrsvParts = arg.Split(); 281 for (i = 0; i < n; i++) 282 model.NumberOfSVPerClass[i] = int.Parse(nrsvParts[i]); 283 break; 284 285 case "SV": 286 headerFinished = true; 287 break; 288 289 default: 290 throw new Exception("Unknown text in model file"); 291 } 292 } 293 294 // read sv_coef and SV 295 296 int m = model.NumberOfClasses - 1; 297 int l = model.SupportVectorCount; 298 model.SupportVectorCoefficients = new double[m][]; 299 for (int i = 0; i < m; i++) { 300 model.SupportVectorCoefficients[i] = new double[l]; 301 } 302 model.SupportVectors = new Node[l][]; 303 304 for (int i = 0; i < l; i++) { 305 string[] parts = input.ReadLine().Trim().Split(); 306 307 for (int k = 0; k < m; k++) 308 model.SupportVectorCoefficients[k][i] = double.Parse(parts[k]); 309 int n = parts.Length - m; 310 model.SupportVectors[i] = new Node[n]; 311 for (int j = 0; j < n; j++) { 312 string[] nodeParts = parts[m + j].Split(':'); 313 model.SupportVectors[i][j] = new Node(); 314 model.SupportVectors[i][j].Index = int.Parse(nodeParts[0]); 315 model.SupportVectors[i][j].Value = double.Parse(nodeParts[1]); 316 } 317 } 318 319 return model; 320 } 321 322 /// <summary> 323 /// Writes a model to the provided filename. This will overwrite any previous data in the file. 324 /// </summary> 325 /// <param name="filename">The desired file</param> 326 /// <param name="model">The Model to write</param> 327 public static void Write(string filename, Model model) { 328 FileStream stream = File.Open(filename, FileMode.Create); 329 try { 330 Write(stream, model); 331 } 332 finally { 333 stream.Close(); 334 } 335 } 336 337 /// <summary> 338 /// Writes a model to the provided stream. 339 /// </summary> 340 /// <param name="stream">The output stream</param> 341 /// <param name="model">The model to write</param> 342 public static void Write(Stream stream, Model model) { 343 StreamWriter output = new StreamWriter(stream); 344 345 Parameter param = model.Parameter; 346 347 output.Write("svm_type " + param.SvmType + Environment.NewLine); 348 output.Write("kernel_type " + param.KernelType + Environment.NewLine); 349 350 if (param.KernelType == KernelType.POLY) 351 output.Write("degree " + param.Degree + Environment.NewLine); 352 353 if (param.KernelType == KernelType.POLY || param.KernelType == KernelType.RBF || param.KernelType == KernelType.SIGMOID) 354 output.Write("gamma " + param.Gamma + Environment.NewLine); 355 356 if (param.KernelType == KernelType.POLY || param.KernelType == KernelType.SIGMOID) 357 output.Write("coef0 " + param.Coefficient0 + Environment.NewLine); 358 359 int nr_class = model.NumberOfClasses; 360 int l = model.SupportVectorCount; 361 output.Write("nr_class " + nr_class + Environment.NewLine); 362 output.Write("total_sv " + l + Environment.NewLine); 363 364 { 365 output.Write("rho"); 366 for (int i = 0; i < nr_class * (nr_class - 1) / 2; i++) 367 output.Write(" " + model.Rho[i]); 368 output.Write(Environment.NewLine); 369 } 370 371 if (model.ClassLabels != null) { 372 output.Write("label"); 373 for (int i = 0; i < nr_class; i++) 374 output.Write(" " + model.ClassLabels[i]); 375 output.Write(Environment.NewLine); 376 } 377 378 if (model.PairwiseProbabilityA != null) 379 // regression has probA only 380 { 381 output.Write("probA"); 382 for (int i = 0; i < nr_class * (nr_class - 1) / 2; i++) 383 output.Write(" " + model.PairwiseProbabilityA[i]); 384 output.Write(Environment.NewLine); 385 } 386 if (model.PairwiseProbabilityB != null) { 387 output.Write("probB"); 388 for (int i = 0; i < nr_class * (nr_class - 1) / 2; i++) 389 output.Write(" " + model.PairwiseProbabilityB[i]); 390 output.Write(Environment.NewLine); 391 } 392 393 if (model.NumberOfSVPerClass != null) { 394 output.Write("nr_sv"); 395 for (int i = 0; i < nr_class; i++) 396 output.Write(" " + model.NumberOfSVPerClass[i]); 397 output.Write(Environment.NewLine); 398 } 399 400 output.Write("SV\n"); 401 double[][] sv_coef = model.SupportVectorCoefficients; 402 Node[][] SV = model.SupportVectors; 403 404 for (int i = 0; i < l; i++) { 405 for (int j = 0; j < nr_class - 1; j++) 406 output.Write(sv_coef[j][i] + " "); 407 408 Node[] p = SV[i]; 409 if (p.Length == 0) { 410 output.WriteLine(); 411 continue; 412 } 413 if (param.KernelType == KernelType.PRECOMPUTED) 414 output.Write("0:{0}", (int)p[0].Value); 415 else { 416 output.Write("{0}:{1}", p[0].Index, p[0].Value); 417 for (int j = 1; j < p.Length; j++) 418 output.Write(" {0}:{1}", p[j].Index, p[j].Value); 419 } 420 output.WriteLine(); 421 } 422 423 output.Flush(); 424 } 425 } 31 [Serializable] 32 public class Model 33 { 34 private Parameter _parameter; 35 private int _numberOfClasses; 36 private int _supportVectorCount; 37 private Node[][] _supportVectors; 38 private double[][] _supportVectorCoefficients; 39 private double[] _rho; 40 private double[] _pairwiseProbabilityA; 41 private double[] _pairwiseProbabilityB; 42 43 private int[] _classLabels; 44 private int[] _numberOfSVPerClass; 45 46 internal Model() 47 { 48 } 49 50 /// <summary> 51 /// Parameter object. 52 /// </summary> 53 public Parameter Parameter 54 { 55 get 56 { 57 return _parameter; 58 } 59 set 60 { 61 _parameter = value; 62 } 63 } 64 65 /// <summary> 66 /// Number of classes in the model. 67 /// </summary> 68 public int NumberOfClasses 69 { 70 get 71 { 72 return _numberOfClasses; 73 } 74 set 75 { 76 _numberOfClasses = value; 77 } 78 } 79 80 /// <summary> 81 /// Total number of support vectors. 82 /// </summary> 83 public int SupportVectorCount 84 { 85 get 86 { 87 return _supportVectorCount; 88 } 89 set 90 { 91 _supportVectorCount = value; 92 } 93 } 94 95 /// <summary> 96 /// The support vectors. 97 /// </summary> 98 public Node[][] SupportVectors 99 { 100 get 101 { 102 return _supportVectors; 103 } 104 set 105 { 106 _supportVectors = value; 107 } 108 } 109 110 /// <summary> 111 /// The coefficients for the support vectors. 112 /// </summary> 113 public double[][] SupportVectorCoefficients 114 { 115 get 116 { 117 return _supportVectorCoefficients; 118 } 119 set 120 { 121 _supportVectorCoefficients = value; 122 } 123 } 124 125 /// <summary> 126 /// Rho values. 127 /// </summary> 128 public double[] Rho 129 { 130 get 131 { 132 return _rho; 133 } 134 set 135 { 136 _rho = value; 137 } 138 } 139 140 /// <summary> 141 /// First pairwise probability. 142 /// </summary> 143 public double[] PairwiseProbabilityA 144 { 145 get 146 { 147 return _pairwiseProbabilityA; 148 } 149 set 150 { 151 _pairwiseProbabilityA = value; 152 } 153 } 154 155 /// <summary> 156 /// Second pairwise probability. 157 /// </summary> 158 public double[] PairwiseProbabilityB 159 { 160 get 161 { 162 return _pairwiseProbabilityB; 163 } 164 set 165 { 166 _pairwiseProbabilityB = value; 167 } 168 } 169 170 // for classification only 171 172 /// <summary> 173 /// Class labels. 174 /// </summary> 175 public int[] ClassLabels 176 { 177 get 178 { 179 return _classLabels; 180 } 181 set 182 { 183 _classLabels = value; 184 } 185 } 186 187 /// <summary> 188 /// Number of support vectors per class. 189 /// </summary> 190 public int[] NumberOfSVPerClass 191 { 192 get 193 { 194 return _numberOfSVPerClass; 195 } 196 set 197 { 198 _numberOfSVPerClass = value; 199 } 200 } 201 202 /// <summary> 203 /// Reads a Model from the provided file. 204 /// </summary> 205 /// <param name="filename">The name of the file containing the Model</param> 206 /// <returns>the Model</returns> 207 public static Model Read(string filename) 208 { 209 FileStream input = File.OpenRead(filename); 210 try 211 { 212 return Read(input); 213 } 214 finally 215 { 216 input.Close(); 217 } 218 } 219 220 /// <summary> 221 /// Reads a Model from the provided stream. 222 /// </summary> 223 /// <param name="stream">The stream from which to read the Model.</param> 224 /// <returns>the Model</returns> 225 public static Model Read(Stream stream) 226 { 227 TemporaryCulture.Start(); 228 229 StreamReader input = new StreamReader(stream); 230 231 // read parameters 232 233 Model model = new Model(); 234 Parameter param = new Parameter(); 235 model.Parameter = param; 236 model.Rho = null; 237 model.PairwiseProbabilityA = null; 238 model.PairwiseProbabilityB = null; 239 model.ClassLabels = null; 240 model.NumberOfSVPerClass = null; 241 242 bool headerFinished = false; 243 while (!headerFinished) 244 { 245 string line = input.ReadLine(); 246 string cmd, arg; 247 int splitIndex = line.IndexOf(' '); 248 if (splitIndex >= 0) 249 { 250 cmd = line.Substring(0, splitIndex); 251 arg = line.Substring(splitIndex + 1); 252 } 253 else 254 { 255 cmd = line; 256 arg = ""; 257 } 258 arg = arg.ToLower(); 259 260 int i,n; 261 switch(cmd){ 262 case "svm_type": 263 param.SvmType = (SvmType)Enum.Parse(typeof(SvmType), arg.ToUpper()); 264 break; 265 266 case "kernel_type": 267 param.KernelType = (KernelType)Enum.Parse(typeof(KernelType), arg.ToUpper()); 268 break; 269 270 case "degree": 271 param.Degree = int.Parse(arg); 272 break; 273 274 case "gamma": 275 param.Gamma = double.Parse(arg); 276 break; 277 278 case "coef0": 279 param.Coefficient0 = double.Parse(arg); 280 break; 281 282 case "nr_class": 283 model.NumberOfClasses = int.Parse(arg); 284 break; 285 286 case "total_sv": 287 model.SupportVectorCount = int.Parse(arg); 288 break; 289 290 case "rho": 291 n = model.NumberOfClasses * (model.NumberOfClasses - 1) / 2; 292 model.Rho = new double[n]; 293 string[] rhoParts = arg.Split(); 294 for(i=0; i<n; i++) 295 model.Rho[i] = double.Parse(rhoParts[i]); 296 break; 297 298 case "label": 299 n = model.NumberOfClasses; 300 model.ClassLabels = new int[n]; 301 string[] labelParts = arg.Split(); 302 for (i = 0; i < n; i++) 303 model.ClassLabels[i] = int.Parse(labelParts[i]); 304 break; 305 306 case "probA": 307 n = model.NumberOfClasses * (model.NumberOfClasses - 1) / 2; 308 model.PairwiseProbabilityA = new double[n]; 309 string[] probAParts = arg.Split(); 310 for (i = 0; i < n; i++) 311 model.PairwiseProbabilityA[i] = double.Parse(probAParts[i]); 312 break; 313 314 case "probB": 315 n = model.NumberOfClasses * (model.NumberOfClasses - 1) / 2; 316 model.PairwiseProbabilityB = new double[n]; 317 string[] probBParts = arg.Split(); 318 for (i = 0; i < n; i++) 319 model.PairwiseProbabilityB[i] = double.Parse(probBParts[i]); 320 break; 321 322 case "nr_sv": 323 n = model.NumberOfClasses; 324 model.NumberOfSVPerClass = new int[n]; 325 string[] nrsvParts = arg.Split(); 326 for (i = 0; i < n; i++) 327 model.NumberOfSVPerClass[i] = int.Parse(nrsvParts[i]); 328 break; 329 330 case "SV": 331 headerFinished = true; 332 break; 333 334 default: 335 throw new Exception("Unknown text in model file"); 336 } 337 } 338 339 // read sv_coef and SV 340 341 int m = model.NumberOfClasses - 1; 342 int l = model.SupportVectorCount; 343 model.SupportVectorCoefficients = new double[m][]; 344 for (int i = 0; i < m; i++) 345 { 346 model.SupportVectorCoefficients[i] = new double[l]; 347 } 348 model.SupportVectors = new Node[l][]; 349 350 for (int i = 0; i < l; i++) 351 { 352 string[] parts = input.ReadLine().Trim().Split(); 353 354 for (int k = 0; k < m; k++) 355 model.SupportVectorCoefficients[k][i] = double.Parse(parts[k]); 356 int n = parts.Length-m; 357 model.SupportVectors[i] = new Node[n]; 358 for (int j = 0; j < n; j++) 359 { 360 string[] nodeParts = parts[m + j].Split(':'); 361 model.SupportVectors[i][j] = new Node(); 362 model.SupportVectors[i][j].Index = int.Parse(nodeParts[0]); 363 model.SupportVectors[i][j].Value = double.Parse(nodeParts[1]); 364 } 365 } 366 367 TemporaryCulture.Stop(); 368 369 return model; 370 } 371 372 /// <summary> 373 /// Writes a model to the provided filename. This will overwrite any previous data in the file. 374 /// </summary> 375 /// <param name="filename">The desired file</param> 376 /// <param name="model">The Model to write</param> 377 public static void Write(string filename, Model model) 378 { 379 FileStream stream = File.Open(filename, FileMode.Create); 380 try 381 { 382 Write(stream, model); 383 } 384 finally 385 { 386 stream.Close(); 387 } 388 } 389 390 /// <summary> 391 /// Writes a model to the provided stream. 392 /// </summary> 393 /// <param name="stream">The output stream</param> 394 /// <param name="model">The model to write</param> 395 public static void Write(Stream stream, Model model) 396 { 397 TemporaryCulture.Start(); 398 399 StreamWriter output = new StreamWriter(stream); 400 401 Parameter param = model.Parameter; 402 403 output.Write("svm_type " + param.SvmType + "\n"); 404 output.Write("kernel_type " + param.KernelType + "\n"); 405 406 if (param.KernelType == KernelType.POLY) 407 output.Write("degree " + param.Degree + "\n"); 408 409 if (param.KernelType == KernelType.POLY || param.KernelType == KernelType.RBF || param.KernelType == KernelType.SIGMOID) 410 output.Write("gamma " + param.Gamma + "\n"); 411 412 if (param.KernelType == KernelType.POLY || param.KernelType == KernelType.SIGMOID) 413 output.Write("coef0 " + param.Coefficient0 + "\n"); 414 415 int nr_class = model.NumberOfClasses; 416 int l = model.SupportVectorCount; 417 output.Write("nr_class " + nr_class + "\n"); 418 output.Write("total_sv " + l + "\n"); 419 420 { 421 output.Write("rho"); 422 for (int i = 0; i < nr_class * (nr_class - 1) / 2; i++) 423 output.Write(" " + model.Rho[i]); 424 output.Write("\n"); 425 } 426 427 if (model.ClassLabels != null) 428 { 429 output.Write("label"); 430 for (int i = 0; i < nr_class; i++) 431 output.Write(" " + model.ClassLabels[i]); 432 output.Write("\n"); 433 } 434 435 if (model.PairwiseProbabilityA != null) 436 // regression has probA only 437 { 438 output.Write("probA"); 439 for (int i = 0; i < nr_class * (nr_class - 1) / 2; i++) 440 output.Write(" " + model.PairwiseProbabilityA[i]); 441 output.Write("\n"); 442 } 443 if (model.PairwiseProbabilityB != null) 444 { 445 output.Write("probB"); 446 for (int i = 0; i < nr_class * (nr_class - 1) / 2; i++) 447 output.Write(" " + model.PairwiseProbabilityB[i]); 448 output.Write("\n"); 449 } 450 451 if (model.NumberOfSVPerClass != null) 452 { 453 output.Write("nr_sv"); 454 for (int i = 0; i < nr_class; i++) 455 output.Write(" " + model.NumberOfSVPerClass[i]); 456 output.Write("\n"); 457 } 458 459 output.Write("SV\n"); 460 double[][] sv_coef = model.SupportVectorCoefficients; 461 Node[][] SV = model.SupportVectors; 462 463 for (int i = 0; i < l; i++) 464 { 465 for (int j = 0; j < nr_class - 1; j++) 466 output.Write(sv_coef[j][i] + " "); 467 468 Node[] p = SV[i]; 469 if (p.Length == 0) 470 { 471 output.WriteLine(); 472 continue; 473 } 474 if (param.KernelType == KernelType.PRECOMPUTED) 475 output.Write("0:{0}", (int)p[0].Value); 476 else 477 { 478 output.Write("{0}:{1}", p[0].Index, p[0].Value); 479 for (int j = 1; j < p.Length; j++) 480 output.Write(" {0}:{1}", p[j].Index, p[j].Value); 481 } 482 output.WriteLine(); 483 } 484 485 output.Flush(); 486 487 TemporaryCulture.Stop(); 488 } 489 } 426 490 }
Note: See TracChangeset
for help on using the changeset viewer.