Infragistics ASP.NET controls

numl - a machine learning library for .NET developers

In one of my previous posts called Machine learning resources for .NET developers, I introduced a machine learning library called numl.net.  numl.net is a machine learning library for .NET created by Seth Juarez.  You can find the library here and Seth's blog here.  When I began resea... [更多...]


Xamarin 2.0 Product Review - Android and iOS development in C# just got easier

Xamarin 2.0 : The prayers of mobile developers have been answered   Hello, and welcome to my latest article on refactorthis.net.  This article is a product review of the latest release by Xamarin called Xamarin 2.0. The state of mobile development We are experiencing a revolution unlik... [更多...]


Assistant Professor receives $518,434 to apply Machine Learning to network analysis

The University of Illinois at Urbana-Champaign - College of Engineering has awarded $518,434 to Assistant Professor Maxim Raginsky to use to apply Machine Learning techniques to network analysis to try and discover how to make networks more efficient. From the article http://csl.illinois.edu/news/... [更多...]


Machine learning: bitly can do a lot more for you than shrink your URLs..

bitly's contributions to BigData and Machine learning Greetings to all of my fellow technologists.  I wanted to write an article to let you know about some very interesting resources that bitly has made available to developers and data lovers alike.  Just in case you've been liv... [更多...]


About the author

My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

Related links

Month List

tegory/Bragisoft.aspx" title="分类: Bragisoft">Bragisoft (2)
  • RSS feed for c#c# (27)
  • RSS feed for C# 5.0C# 5.0 (1)
  • RSS feed for Code CompleteCode Complete (5)
  • RSS feed for Data AnalyticsData Analytics (3)
  • RSS feed for Data MiningData Mining (3)
  • RSS feed for Decision TreesDecision Trees (3)
  • RSS feed for Dependency InjectionDependency Injection (2)
  • RSS feed for Design PatternsDesign Patterns (10)
  • RSS feed for DevelopmentDevelopment (20)
  • RSS feed for dot42dot42 (2)
  • RSS feed for F#F# (1)
  • RSS feed for Functional ProgrammingFunctional Programming (1)
  • RSS feed for ILIL (1)
  • RSS feed for ILAsmILAsm (1)
  • RSS feed for INFRAGISTICSINFRAGISTICS (1)
  • RSS feed for IoCIoC (1)
  • RSS feed for iOSiOS (2)
  • RSS feed for iPadiPad (5)
  • RSS feed for iPhoneiPhone (5)
  • RSS feed for LinqLinq (1)
  • RSS feed for Machine learningMachine learning (8)
  • RSS feed for MathMath (3)
  • RSS feed for MicrosoftMicrosoft (5)
  • RSS feed for Microsoft ExcelMicrosoft Excel (1)
  • RSS feed for Microsoft OfficeMicrosoft Office (1)
  • RSS feed for Microsoft Patterns And PracticesMicrosoft Patterns And Practices (2)
  • RSS feed for Microsoft WordMicrosoft Word (1)
  • RSS feed for Mobile developmentMobile development (4)
  • RSS feed for Mobile sitesMobile sites (5)
  • RSS feed for monomono (8)
  • RSS feed for MonoDroidMonoDroid (5)
  • RSS feed for MonoTouchMonoTouch (2)
  • RSS feed for MSILMSIL (3)
  • RSS feed for MVVMMVVM (8)
  • RSS feed for NETADVANTAGENETADVANTAGE (1)
  • RSS feed for Neural NetworksNeural Networks (4)
  • RSS feed for NoSQLNoSQL (1)
  • RSS feed for numl.netnuml.net (1)
  • RSS feed for PDLPDL (1)
  • RSS feed for Prediction algorithmsPrediction algorithms (7)
  • RSS feed for PrismPrism (1)
  • RSS feed for Product ReviewProduct Review (9)
  • RSS feed for Pseudo CodePseudo Code (1)
  • RSS feed for Published booksPublished books (1)
  • RSS feed for RapidMinerRapidMiner (3)
  • RSS feed for RavenDBRavenDB (1)
  • RSS feed for ReviewsReviews (3)
  • RSS feed for RobotsRobots (1)
  • RSS feed for SecuritySecurity (1)
  • RSS feed for SilverlightSilverlight (3)
  • RSS feed for Simulated EvolutionSimulated Evolution (3)
  • RSS feed for Software DesignSoftware Design (12)
  • RSS feed for SQLSQL (1)
  • RSS feed for Structured learningStructured learning (3)
  • RSS feed for SyncfusionSyncfusion (3)
  • RSS feed for TDDTDD (1)
  • RSS feed for Tech NewsTech News (3)
  • RSS feed for TwitterTwitter (2)
  • RSS feed for UnityUnity (2)
  • RSS feed for ValidationValidation (1)
  • RSS feed for Visual Basic .NETVisual Basic .NET (2)
  • RSS feed for Visual StudioVisual Studio (8)
  • RSS feed for Visual Studio 2012Visual Studio 2012 (4)
  • RSS feed for WebHierarchicalDataGrid WebHierarchicalDataGrid (1)
  • RSS feed for WebUltraGridWebUltraGrid (1)
  • RSS feed for Windows 8Windows 8 (7)
  • RSS feed for Windows App StoreWindows App Store (6)
  • RSS feed for Windows Phone 7Windows Phone 7 (1)
  • RSS feed for Windows Phone 8Windows Phone 8 (1)
  • RSS feed for WinRTWinRT (5)
  • RSS feed for WPFWPF (11)
  • RSS feed for WPF Extended ToolkitWPF Extended Toolkit (1)
  • RSS feed for WPF SuccinctlyWPF Succinctly (2)
  • RSS feed for XamarianXamarian (1)
  • RSS feed for XamarinXamarin (4)
  • RSS feed for XAMLXAML (10)
  • refactorthis.net | All posts tagged 'Mobile Development'
    Infragistics JQuery controls

    dot42 Android development with C#. All the best parts with less restrictions!

    Check out dot42 and Xamarin 2.0 forr developing Android applications using the .NET framework.
    Check out dot42 and Xamarin 2.0 forr developing Android applications using the .NET framework. [More]


    dot42: an alternative to MonoDroid

    Android development in Visual Studio I'm sure a lot of you have heard of the MonoDroid product by Xamarin which allows .NET developers to write android applications using your favorite .NET tools.  I find this option awesome because I'm a .NET developer and because I find native android development tedious.  It's not that Java is difficult, especially when compared to iOS development using objective-C (ughh).  My main problem with android development in Java is once you use Visual Studio for a few years, it's really hard to use anything else.   Enter Xamarin's MonoDroid I was really excited when MonoDroid was released.  That excitement faded quickly when I learned that i couldn't deploy my applications to my Android phone for testing without a license.  Instead, you are forced you use the Android emulator.  I've tried many times with many configurations to use the emulator.  It's simply not feasible for me.  The emulator is INCREDIBLY slow, when it works.  Other times I would wait for 20+ mins before giving up.  I'm not the only developer to express disdain for the Android emulator.  Just google Android emulator slow and you will find a lot of people have this problem. dot42: An alternative Let me start by saying that I ran across dot42 http://www.dot42.com/ only 10 minutes ago, so I don't claim to have experience with the product.  What I can say is that like MonoDroid, they offer a free version of their product for personal (no commercial development).  Unlike MonoDroid, I see no news on their site to suggest that you can't deploy your application on your phone for testing with the free version.  If this is in fact true, this makes all the difference to me as a developer. (Update: I've verified that dot42 does NOT restrict deployment to your device of choice.  They even allow you to publish free applications to the Android app market!  Be on the look out for  a follow up article dedicated 100% to dot42 very soon!) I think MonoDroid is a great product and it is certainly a much more mature product that dot42.  I will be sure to write a follow up to this article once I've tested the product. What about you?  Anyone out there want to speak out about their problems with the android emulator?  Does anyone else wish that MonoDroid would allow us to test the product on our own devices?  Please feel free to comment and let us know what you think! Happy Coding! kick it on DotNetKicks.com


    About the author

    My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

    Related links

    Month List

    refactorthis.net | Validation
    Infragistics JQuery controls

    WPF Validation tutorial for the rest of us. Learn to use IDataErrorInfo to automatically validate your views.

        WPF Validation for mere mortals I've recently jumped on the WPF bandwagon and I've fallen in love with this technology.  XAML is a fascinating animal indeed.  The declarative nature of the language leaves much to be explored.  There are many ways to solve the same problem.  On my quest for knowledge, I've been researching the intrinsic validation functionality of WPF.  Unfortunately, most every example I've ran across on blog posts and codeproject.com have been a bit too complex for my blood.  I find often that you need learn other subjects before you can begin to understand how the validation works.  Don't get me wrong, the examples are really nice.  However, when I'm learning something, I want a straight to the point example of the topic at hand.  It's with this idea in mind that I bring you a simple tutorial on WPF validation. I will be illustrating this example using the MVVM (Model-View-ViewModel) Pattern.   Click here to download the entire source WPFMVVMValidation.zip (74.08 kb)  Consider the following code  The view MainWindow.xaml <Window x:Class="ExceptionValidation.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:viewModel="clr-namespace:ExceptionValidation" Title="MainWindow" Height="350" Width="525" > <Window.Resources> <viewModel:MainWindowViewModel x:Key="mainViewModel"/> </Window.Resources> <StackPanel DataContext="{Binding Source={StaticResource mainViewModel }}"> <TextBlock>Enter total amount</TextBlock> <TextBox Width="200" Name="txtTotalAmount" > <Binding Path="[0].TotalAmount" ValidatesOnDataErrors="True"> <Binding.ValidationRules> <ExceptionValidationRule></ExceptionValidationRule> </Binding.ValidationRules> </Binding> </TextBox> <Button Content="Button" Height="28" Name="button1" Width="84" /> </StackPanel> </Window>     The viewmodel MainWindowViewModel.cs using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.ComponentModel; namespace ExceptionValidation { class MainWindowViewModel : ObservableCollection<Product> { public MainWindowViewModel() { Add(new Product { TotalAmount = 3 }); } } }   The model Product.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; namespace ExceptionValidation { public class Product : INotifyPropertyChanged , IDataErrorInfo { public event PropertyChangedEventHandler PropertyChanged; private int _totalAmount = 5; public int TotalAmount { get { return _totalAmount; } set { _totalAmount = value; OnPropertyChanged("TotalAmount"); } } public void OnPropertyChanged(string info) { PropertyChangedEventHandler handler = PropertyChanged; if (PropertyChanged != null) { handler(this, new PropertyChangedEventArgs(info)); } } public string Error { get { throw new NotImplementedException(); } } public string this[string columnName] { get { if (columnName == "TotalAmount") { bool valid = true; if (_totalAmount > 10) { valid = false; } if (!valid) { return "The total amount cannot exceed 10!"; } } return null; } } } } A brief introduction to MVVM  As you can see, we have a XAML view, a viewmodel class, and a model.  The Model is a representation of an object's data.  In this instance, we are modeling a Product.  The viewmodel is an object that handles the change notification between properties in the model and elements on the view.  XAML properties, events, and bindings have the ability to tunnel (down the tree) as well as bubble (up the tree).   Binding the ViewModel to the view. In order to bind the ViewModel to the view, we must make it accessible to the view via XAML.  To accomplish this, we first have to import the namespace in which the viewmodel exists.  Examine the following code. xmlns:viewModel="clr-namespace:ExceptionValidation" Here is the equivalent in c# using ExceptionValidation; Once we've imported the namespace for use, we then need to define our MainWindowViewModel as a Resource of the current window. <Window.Resources> <viewModel:MainWindowViewModel x:Key="mainViewModel"/> </Window.Resources> This allows us to declare an instance of the MainWindowViewModel class by using the associated Key "mainViewModel". Binding the ViewModel As stated before the ViewModel acts as a "go between" for the View and the Model.  In order for the view model to communicate with our XAML view, we will bind the ViewModel to the StackPanel's DataContext. <StackPanel DataContext="{Binding Source={StaticResource mainViewModel }}"> XAML's ability to tunnel properties down from parent to child will allow each element inside the stack panel to make use of the DataContext binding that we've just setup using the Window resource's key mainViewModel. ObservableCollection<T> The viewmodel inherits from ObservableCollection<Product>.  The ObservableCollection<T> generic class represents a collection that can be utilized by WPF databinding.  This is possible because the ObservableCollection<T> class raises an event when items are added and removed from the collection. INotifyPropertyChanged The model implements the INotifyPropertyChanged interface.  This interface provides an event in which to fire any time a model property is changed.  This event notifies the bound element in the view that the property has changed. public event PropertyChangedEventHandler PropertyChanged;   public void OnPropertyChanged(string info) { PropertyChangedEventHandler handler = PropertyChanged; if (PropertyChanged != null) { handler(this, new PropertyChangedEventArgs(info)); } }   IDataErrorInfo The magic behind WPF validation comes from the implementation of the IDataErrrorInfo interface.  The interface implements the following members.  The this[columnName] indexer implements the logic of the validation rule. //Not used by WPF public string Error { get { throw new NotImplementedException(); } } public string this[string columnName] { get { if (columnName == "TotalAmount") { bool valid = true; if (_totalAmount > 10) { valid = false; } if (!valid) { return "The total amount cannot exceed 10!"; } } return null; } } The following XAML code binds the TotalAmount property of the first Product in the viewmodel's internal collection to the Text property of the TextBox element.  The ValidatesOnDataErrors attribute tells the textbox binding to raise an event when there is a valadation error.  When the event is raised, the bound element's template is changed to a new visual style that places a Red rectangle around the border of the TextBox.  When the error is corrected, the original template is restored.  Binding.ValidatesOnDataErrors <TextBox Width="200" Name="txtTotalAmount" > <Binding Path="[0].TotalAmount" ValidatesOnDataErrors="True"> </Binding> </TextBox> In the provided example, if you enter a value greater than 10 into the text box and tab out of the textbox, you will see that an error is raised causing the red outline around the textbox.  If you correct the error by replacing the value with a number less than 10, the red outline will disappear. This concludes my tutorial on WPF validation.  This is the very basic of validation methods.  There are many other advanced tutorials on the subject.  My next tutorial will involve utilizing custom validation attributes from the System.ComponentModel namespace to handle WPF view validation. Thanks for reading! ~/Buddy James kick it on DotNetKicks.com  


    About the author

    My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

    Related links

    Month List

    Category list

    • RSS feed for .NET.NET (37)
    • RSS feed for .NET 4.5.NET 4.5 (9)
    • RSS feed for AndroidAndroid (5)
    • RSS feed for Artificial IntelligenceArtificial Intelligence (6)
    • RSS feed for ASP.NET MVCASP.NET MVC (5)
    • RSS feed for ASP.NET WebFormsASP.NET WebForms (4)
    • RSS feed for AssemblerAssembler (3)
    • RSS feed for AssemblyAssembly (3)
    • RSS feed for Asynchronous ProgrammingAsynchronous Programming (3)
    • RSS feed for Big DataBig Data (7)
    • RSS feed for bit.lybit.ly (1)
    • RSS feed for BlogBlog (9)
    • RSS feed for BlogEngine.NETBlogEngine.NET (2)
    • RSS feed for BragisoftBragisoft (2)
    • RSS feed for c#c# (27)
    • RSS feed for C# 5.0C# 5.0 (1)
    • RSS feed for Code CompleteCode Complete (5)
    • RSS feed for Data AnalyticsData Analytics (3)
    • RSS feed for Data MiningData Mining (3)
    • RSS feed for Decision TreesDecision Trees (3)
    • RSS feed for Dependency InjectionDependency Injection (2)
    • RSS feed for Design PatternsDesign Patterns (10)
    • RSS feed for DevelopmentDevelopment (20)
    • RSS feed for dot42dot42 (2)
    • RSS feed for F#F# (1)
    • RSS feed for Functional ProgrammingFunctional Programming (1)
    • RSS feed for ILIL (1)
    • RSS feed for ILAsmILAsm (1)
    • RSS feed for INFRAGISTICSINFRAGISTICS (1)
    • RSS feed for IoCIoC (1)
    • RSS feed for iOSiOS (2)
    • RSS feed for iPadiPad (5)
    • RSS feed for iPhoneiPhone (5)
    • RSS feed for LinqLinq (1)
    • RSS feed for Machine learningMachine learning (8)
    • RSS feed for MathMath (3)
    • RSS feed for MicrosoftMicrosoft (5)
    • RSS feed for Microsoft ExcelMicrosoft Excel (1)
    • RSS feed for Microsoft OfficeMicrosoft Office (1)
    • RSS feed for Microsoft Patterns And PracticesMicrosoft Patterns And Practices (2)
    • RSS feed for Microsoft WordMicrosoft Word (1)
    • RSS feed for Mobile developmentMobile development (4)
    • RSS feed for Mobile sitesMobile sites (5)
    • RSS feed for monomono (8)
    • RSS feed for MonoDroidMonoDroid (5)
    • RSS feed for MonoTouchMonoTouch (2)
    • RSS feed for MSILMSIL (3)
    • RSS feed for MVVMMVVM (8)
    • RSS feed for NETADVANTAGENETADVANTAGE (1)
    • RSS feed for Neural NetworksNeural Networks (4)
    • RSS feed for NoSQLNoSQL (1)
    • RSS feed for numl.netnuml.net (1)
    • RSS feed for PDLPDL (1)
    • RSS feed for Prediction algorithmsPrediction algorithms (7)
    • RSS feed for PrismPrism (1)
    • RSS feed for Product ReviewProduct Review (9)
    • RSS feed for Pseudo CodePseudo Code (1)
    • RSS feed for Published booksPublished books (1)
    • RSS feed for RapidMinerRapidMiner (3)
    • RSS feed for RavenDBRavenDB (1)
    • RSS feed for ReviewsReviews (3)
    • RSS feed for RobotsRobots (1)
    • RSS feed for Security refactorthis.net | All posts tagged 'code comments'
      Infragistics WPF controls

      Design and Document your Code using PDL (Programming Design Language)

      Introduction Many of us underestimate the importance of proper code documentation through comments. Comments, when used correctly, can greatly increase the maintainability of your functions and routines, especially if there is any chance that another developer will ever need to look at your code. It's hard enough for you to remember what your intentions were for a routine you wrote 5 years ago. Imagine what it's like for someone that has no clue what you meant to do in the first place. Background While reading "Code Complete" (every developer, regardless of skill level, age, or programming language should own this book), I discovered a method used to comment your routines that provides so much more than just code comments. Using the Code This method is called PDL (Programming Design Language). The basic idea behind PDL is that you write all of the comments for your method before writing any code. Once the comments are finished, you then fill in the blanks with the implementation. Here is an example: Public Function CanUserBuyAlchohol(ByVal Age As Integer, ByVal HasLicense As Boolean) As Boolean      'If the user is of the legal drinking age          If Age > 21 Then          'If the user has a drivers license                  If HasLicense Then                  'Return success to the caller                          Return True                  'Otherwise the user does not have a drivers license                   Else                     'Return Failure to the caller                          Return False         End If       'Otherwise the user is too young          Else               'Return Failure to the caller                  Return False       End If  End Function     A few things to note here: All of the comments are formatted logically (indentation) When using this method, you write the comments first in a high level format (plain English) This allows you to design the routine at a high level of abstraction The requirements are in English so the routine is designed such that it can be ported to any language very easily All of the thinking work is done up front All that's left is to fill in the code under each comment The comments written in English explain exactly what you need, so implementation is a breeze Since comments are written first, you can be rest assured that all of your methods will be well documented If another developer is reading through your code, he can simply read your high level comments until he finds the code he needs. Points of Interest So as you can see, using PDL has several advantages: Assures code is always documented Allows for high level design of routine that does not rely on a specific programming language implementation (remember the comments are plain English) Once the comments are complete, coding is a snap because the logic has already been documented in plain English in the comments. I hope you find PDL as beneficial to learn as I have. Don't forget to buy Code Complete! Until next time.   kick it on DotNetKicks.com  


      About the author

      My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

      Related links

      Month List

      None

      refactorthis.net | All posts tagged 'documentation'
      Infragistics WPF controls

      Design and Document your Code using PDL (Programming Design Language)

      Introduction Many of us underestimate the importance of proper code documentation through comments. Comments, when used correctly, can greatly increase the maintainability of your functions and routines, especially if there is any chance that another developer will ever need to look at your code. It's hard enough for you to remember what your intentions were for a routine you wrote 5 years ago. Imagine what it's like for someone that has no clue what you meant to do in the first place. Background While reading "Code Complete" (every developer, regardless of skill level, age, or programming language should own this book), I discovered a method used to comment your routines that provides so much more than just code comments. Using the Code This method is called PDL (Programming Design Language). The basic idea behind PDL is that you write all of the comments for your method before writing any code. Once the comments are finished, you then fill in the blanks with the implementation. Here is an example: Public Function CanUserBuyAlchohol(ByVal Age As Integer, ByVal HasLicense As Boolean) As Boolean      'If the user is of the legal drinking age          If Age > 21 Then          'If the user has a drivers license                  If HasLicense Then                  'Return success to the caller                          Return True                  'Otherwise the user does not have a drivers license                   Else                     'Return Failure to the caller                          Return False         End If       'Otherwise the user is too young          Else               'Return Failure to the caller                  Return False       End If  End Function     A few things to note here: All of the comments are formatted logically (indentation) When using this method, you write the comments first in a high level format (plain English) This allows you to design the routine at a high level of abstraction The requirements are in English so the routine is designed such that it can be ported to any language very easily All of the thinking work is done up front All that's left is to fill in the code under each comment The comments written in English explain exactly what you need, so implementation is a breeze Since comments are written first, you can be rest assured that all of your methods will be well documented If another developer is reading through your code, he can simply read your high level comments until he finds the code he needs. Points of Interest So as you can see, using PDL has several advantages: Assures code is always documented Allows for high level design of routine that does not rely on a specific programming language implementation (remember the comments are plain English) Once the comments are complete, coding is a snap because the logic has already been documented in plain English in the comments. I hope you find PDL as beneficial to learn as I have. Don't forget to buy Code Complete! Until next time.   kick it on DotNetKicks.com  


      About the author

      My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

      Related links

      Month List

      None

      Category list

      About the author

      My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

      Related links

      Month List

      None

      refactorthis.net | numl - a machine learning library for .NET developers
      Infragistics JQuery controls

      numl - a machine learning library for .NET developers

      In one of my previous posts called Machine learning resources for .NET developers, I introduced a machine learning library called numl.net.  numl.net is a machine learning library for .NET created by Seth Juarez.  You can find the library here and Seth's blog here.  When I began researching the library, I learned quickly that one of Seth's goals in writing numl.net was to abstract away the complexities that stops many software developers from trying their hand at machine learning.  I must say that in my opinion, he has done a wonderful job in accomplishing this goal!

      Tutorial

      I've decided to throw together a small tutorial to show you just how easy it is to use numl.net to perform predictions.  This tutorial will use structured learning by way of a decision tree to perform predictions.  I will use the infamous Iris Data set which contains data 3 different types of Iris flowers and the data that defines them.  Before we get into code, let's look at some basic terminology first.

      With numl.net you create a POCO (plain old CLR object) to use for training as well as predictions.  There will be properties that you will specify known values (features) so that you can predict the value of an unknown property value (label).  numl.net makes identifying features and labels easy, you simply mark your properties with the [Feature] attribute or the [Label] attribute (there is also a [StringLabel] attribute as well).  Here is an example of the Iris class that we will use in this tutorial.

      using numl.Model;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      
      namespace NumlDemo
      {
          /// <summary>
          /// Represents an Iris in the infamous Iris classification dataset (Fisher, 1936)
          /// Each feature property will be used for training as well as prediction.  The label
          /// property is the value to be predicted.  In this case, it's which type of Iris we are dealing with.
          /// </summary>
          public class Iris
          {
              //Length in centimeters
              [Feature]
              public double SepalLength { get; set; }
      
              //Width in centimeters
              [Feature]
              public double SepalWidth { get; set; }
      
              //Length in centimeters
              [Feature]
              public double PetalLength { get; set; }
      
              //Width in centimeters
              [Feature]
              public double PetalWidth { get; set; }
      
              
              //-- Iris Setosa 
              //-- Iris Versicolour 
              //-- Iris Virginica
              
              public enum IrisTypes
              {
                  IrisSetosa,
                  IrisVersicolour,
                  IrisVirginica
              }
      
              [Label]
              public IrisTypes IrisClass { get; set; } //This is the label or value that we wish to predict based on the supplied features
          }
      }

      As you can see, we have a simple POCO Iris class, which defines four features and one label.  The Iris training data can be found here .  Here is an example of the data found in the file.

       

      5.1,3.5,1.4,0.2,Iris-setosa

      6.3,2.5,4.9,1.5,Iris-versicolor

      6.0,3.0,4.8,1.8,Iris-virginica
       
       
      The first four values are doubles which represent the features Sepal Length, Sepal Width, Petal Length, Petal Width.  The final value is an enum that represents the label that we will predict which is the class of Iris.
       
      We have the Iris class, so now we need a method to parse the training data file and generate a static List<Iris> collection.  Here is the code:
       
      using System;
      using System.Collections.Generic;
      using System.IO;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      
      namespace NumlDemo
      {
          /// <summary>
          /// Provides the services to parse the training data files 
          /// </summary>
          public static class IrisDataParserService
          {
              //provides the training data to create the predictive model
              public static List<Iris> TrainingIrisData { get; set; }
      
              /// <summary>
              /// Reads the trainingDataFile and populates the TrainingIrisData list
              /// </summary>
              /// <param name="trainingDataFile">File full of Iris data</param>
              /// <returns></returns>
              public static void LoadIrisTrainingData(string trainingDataFile)
              {
                  //if we don't have a training data file
                  if (string.IsNullOrEmpty(trainingDataFile))
                      throw new ArgumentNullException("trainingDataFile");
      
                  //if the file doesn't exist on the file system
                  if (!File.Exists(trainingDataFile))
                      throw new FileNotFoundException();
      
                  if (TrainingIrisData == null)
                      //initialize the return training data set
                      TrainingIrisData = new List<Iris>();
      
                  //read the entire file contents into a string
                  using (var fileReader = new StreamReader(new FileStream(trainingDataFile, FileMode.Open)))
                  {
                      string fileLineContents;
                      while ((fileLineContents = fileReader.ReadLine()) != null)
                      {
                          //split the current line into an array of values
                          var irisValues = fileLineContents.Split(',');
      
                          double sepalLength = 0.0;
                          double sepalWidth = 0.0;
      
                          double petalLength = 0.0;
                          double petalWidth = 0.0;
      
                          if (irisValues.Length == 5)
                          {
                              Iris currentIris = new Iris();
      
                              double.TryParse(irisValues[0], out sepalLength);
                              currentIris.SepalLength = sepalLength;
      
                              double.TryParse(irisValues[1], out sepalWidth);
                              currentIris.SepalWidth = sepalWidth;
      
                              double.TryParse(irisValues[2], out petalLength);
                              currentIris.PetalLength = petalLength;
      
                              double.TryParse(irisValues[3], out petalWidth);
                              currentIris.PetalWidth = petalWidth;
      
                              if (irisValues[4] == "Iris-setosa")
                                  currentIris.IrisClass = Iris.IrisTypes.IrisSetosa;
                              else if (irisValues[4] == "Iris-versicolor")
                                  currentIris.IrisClass = Iris.IrisTypes.IrisVersicolour;
                              else
                                  currentIris.IrisClass = Iris.IrisTypes.IrisVirginica;
      
                              IrisDataParserService.TrainingIrisData.Add(currentIris);
                          }
                      }
                  }
              }
          }
      }
      This code is pretty standard.  We simply read each line in the file, split the values out into an array, and populate a List<Iris> collection of Iris objects based on the data found in the file.
       

      Now the magic

      Using the numl.net library, we need only use three classes to perform a prediction based on the Iris data set.  We start with a Descriptor, which identifies the class in which we will learn and predict.  Next, we will instantiate a DecisionTreeGenerator, passing the descriptor to the constructor.  Finally, we will create our prediction model by calling the Generate method of the DecisionTreeGenerator, passing the training data (IEnumerable<Iris>) to the Generate method.  The generate method will provide us with a model in which we can perform our prediction.

      Here is the code:

      using numl;
      using numl.Model;
      using numl.Supervised;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      
      namespace NumlDemo
      {
          class Program
          {
              public static void Main(string[] args)
              {
                  //get the descriptor that describes the features and label from the Iris training objects
                  var irisDescriptor = Descriptor.Create<Iris>();
      
                  //create a decision tree generator and teach it about the Iris descriptor
                  var decisionTreeGenerator = new DecisionTreeGenerator(irisDescriptor);
      
                  //load the training data
                  IrisDataParserService.LoadIrisTrainingData(@"D:\Development\machinelearning\Iris Dataset\bezdekIris.data");
      
                  //create a model based on our training data using the decision tree generator
                  var decisionTreeModel = decisionTreeGenerator.Generate(IrisDataParserService.TrainingIrisData);
      
                  //create an iris that should be an Iris Setosa
                  var irisSetosa = new Iris
                  {
                      SepalLength = 5.1,
                      SepalWidth = 3.5,
                      PetalLength = 1.4,
                      PetalWidth = 0.2
                  };
      
                  //create an iris that should be an Iris Versicolor
                  var irisVersiColor = new Iris
                  {
                      SepalLength = 6.1,
                      SepalWidth = 2.8,
                      PetalLength = 4.0,
                      PetalWidth = 1.3
                  };
      
                  //create an iris that should be an Iris Virginica
                  var irisVirginica = new Iris
                  {
                      SepalLength = 7.7,
                      SepalWidth = 2.8,
                      PetalLength = 6.7,
                      PetalWidth = 2.0
                  };
      
                  var irisSetosaClass = decisionTreeModel.Predict<Iris>(irisSetosa);
                  var irisVersiColorClass = decisionTreeModel.Predict<Iris>(irisVersiColor);
                  var irisVirginicaClass = decisionTreeModel.Predict<Iris>(irisVirginica);
      
                  Console.WriteLine("The Iris Setosa was predicted as {0}",
                      irisSetosaClass.IrisClass.ToString());
      
                  Console.WriteLine("The Iris Versicolor was predicted as {0}",
                      irisVersiColorClass.IrisClass.ToString());
      
                  Console.WriteLine("The Iris Virginica was predicted as {0}",
                      irisVirginicaClass.IrisClass.ToString());
      
                  Console.ReadKey();
              }
          }
      }

      And that's all there is to it.  As you can see, you can use the prediction model accurately and there's no math, only simple abstractions.

      I hope this has peaked your interest in the numl.net library for machine learning in .NET.  

      Feel free to post any questions or opinions.

      Thanks for reading!

      Buddy James

       



      Comments (9) -

      sam
      sam
      3/27/2013 11:47:06 PM #

      Hi , nice stuff, but I am getting error "Invalid descriptor: Empty feature set!"

      var data = Value.GetData();
                  var description = Descriptor.Create<Value>();
                  var generator = new DecisionTreeGenerator(50);
                  var model = generator.Generate(description, data);

      where value :
      public class Value
          {
              public int V1 { get; set; }
              public int V2 { get; set; }
              public int R { get ;set; }
      }

      Buddy James
      Buddy James
      3/28/2013 7:25:41 AM #

      Sam,

      You need to mark some of your properties with the [Feature] attribute.. That would be my first guess.. give that a shot and see if that doesn't take care of your problem.

      Thanks for reading!

      Buddy James

      sam
      sam
      3/28/2013 7:56:47 AM #

      Thanks Buddy , will try it today . it look good , but there is no documentation at all .

      Buddy James
      Buddy James
      3/28/2013 2:40:01 PM #

      Sam,

      I've forked the GitHub repository and I'm working to help provide some documentation as I learn the library.

      Buddy James
      Buddy James
      3/28/2013 2:40:01 PM #

      Sam,

      I've forked the GitHub repository and I'm working to help provide some documentation as I learn the library.

      sam
      sam
      3/28/2013 5:50:47 PM #

      I just posed an issue , it seem it cant handle big date , it only works when the sample data is less than 10 and the data somehow consistent , for example if you feed it from this it will  error    :
      public static IEnumerable<Value>  GetData()
              {

                 for ( int i=0  ; i<1000; i++)
                 {
                     yield return new Value { V1 =1 , V2 = i , R= (i>50 ) ?"l":"s"  };

                 }
              }

      Buddy James
      Buddy James
      3/29/2013 1:31:30 AM #

      Sam,

      I appreciate the heads up.

      I've submitted the bug and I'll let you know when it's been fixed.

      Thanks,

      Buddy James

      sam
      sam
      3/30/2013 2:22:55 PM #

      Hi Buddy ,
      really thank you for your help , but it seem numl is not what I am looking for , also its developer confirmed that . I was trying to make it predict the level of student from his degrees which supposed to be easy job .
      I advise you to do some deep test before consider using it to any real life project .
      I a mgoing to try :
      www.codeproject.com/.../AForge-NET-open-source-framework

      Buddy James
      Buddy James
      3/31/2013 1:07:24 AM #

      Sam,

      I appreciate your feedback.

      The library is a young work in progress.  It's on github and I feel it's worth the time.  I'm having a lot of fun working on it and I'm learning a lot in the process.

      I suggest trying all libraries and pick the one that calls out to you.  NND is another project that I'm involved in that is more geared toward neural networks, however, it's vast... Maybe you should give it a try.  Be sure to stop by and let me know what works for you.  Thanks for reading!

      Add comment

        Country flag


      • Comment
      • Preview
      Loading

      About the author

      My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

      Related links

      Month List

      refactorthis.net | numl - a machine learning library for .NET developers
      Argument; theForm.submit(); } } //]]>
      Infragistics WPF controls

      numl - a machine learning library for .NET developers

      In one of my previous posts called Machine learning resources for .NET developers, I introduced a machine learning library called numl.net.  numl.net is a machine learning library for .NET created by Seth Juarez.  You can find the library here and Seth's blog here.  When I began researching the library, I learned quickly that one of Seth's goals in writing numl.net was to abstract away the complexities that stops many software developers from trying their hand at machine learning.  I must say that in my opinion, he has done a wonderful job in accomplishing this goal!

      Tutorial

      I've decided to throw together a small tutorial to show you just how easy it is to use numl.net to perform predictions.  This tutorial will use structured learning by way of a decision tree to perform predictions.  I will use the infamous Iris Data set which contains data 3 different types of Iris flowers and the data that defines them.  Before we get into code, let's look at some basic terminology first.

      With numl.net you create a POCO (plain old CLR object) to use for training as well as predictions.  There will be properties that you will specify known values (features) so that you can predict the value of an unknown property value (label).  numl.net makes identifying features and labels easy, you simply mark your properties with the [Feature] attribute or the [Label] attribute (there is also a [StringLabel] attribute as well).  Here is an example of the Iris class that we will use in this tutorial.

      using numl.Model;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      
      namespace NumlDemo
      {
          /// <summary>
          /// Represents an Iris in the infamous Iris classification dataset (Fisher, 1936)
          /// Each feature property will be used for training as well as prediction.  The label
          /// property is the value to be predicted.  In this case, it's which type of Iris we are dealing with.
          /// </summary>
          public class Iris
          {
              //Length in centimeters
              [Feature]
              public double SepalLength { get; set; }
      
              //Width in centimeters
              [Feature]
              public double SepalWidth { get; set; }
      
              //Length in centimeters
              [Feature]
              public double PetalLength { get; set; }
      
              //Width in centimeters
              [Feature]
              public double PetalWidth { get; set; }
      
              
              //-- Iris Setosa 
              //-- Iris Versicolour 
              //-- Iris Virginica
              
              public enum IrisTypes
              {
                  IrisSetosa,
                  IrisVersicolour,
                  IrisVirginica
              }
      
              [Label]
              public IrisTypes IrisClass { get; set; } //This is the label or value that we wish to predict based on the supplied features
          }
      }

      As you can see, we have a simple POCO Iris class, which defines four features and one label.  The Iris training data can be found here .  Here is an example of the data found in the file.

       

      5.1,3.5,1.4,0.2,Iris-setosa

      6.3,2.5,4.9,1.5,Iris-versicolor

      6.0,3.0,4.8,1.8,Iris-virginica
       
       
      The first four values are doubles which represent the features Sepal Length, Sepal Width, Petal Length, Petal Width.  The final value is an enum that represents the label that we will predict which is the class of Iris.
       
      We have the Iris class, so now we need a method to parse the training data file and generate a static List<Iris> collection.  Here is the code:
       
      using System;
      using System.Collections.Generic;
      using System.IO;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      
      namespace NumlDemo
      {
          /// <summary>
          /// Provides the services to parse the training data files 
          /// </summary>
          public static class IrisDataParserService
          {
              //provides the training data to create the predictive model
              public static List<Iris> TrainingIrisData { get; set; }
      
              /// <summary>
              /// Reads the trainingDataFile and populates the TrainingIrisData list
              /// </summary>
              /// <param name="trainingDataFile">File full of Iris data</param>
              /// <returns></returns>
              public static void LoadIrisTrainingData(string trainingDataFile)
              {
                  //if we don't have a training data file
                  if (string.IsNullOrEmpty(trainingDataFile))
                      throw new ArgumentNullException("trainingDataFile");
      
                  //if the file doesn't exist on the file system
                  if (!File.Exists(trainingDataFile))
                      throw new FileNotFoundException();
      
                  if (TrainingIrisData == null)
                      //initialize the return training data set
                      TrainingIrisData = new List<Iris>();
      
                  //read the entire file contents into a string
                  using (var fileReader = new StreamReader(new FileStream(trainingDataFile, FileMode.Open)))
                  {
                      string fileLineContents;
                      while ((fileLineContents = fileReader.ReadLine()) != null)
                      {
                          //split the current line into an array of values
                          var irisValues = fileLineContents.Split(',');
      
                          double sepalLength = 0.0;
                          double sepalWidth = 0.0;
      
                          double petalLength = 0.0;
                          double petalWidth = 0.0;
      
                          if (irisValues.Length == 5)
                          {
                              Iris currentIris = new Iris();
      
                              double.TryParse(irisValues[0], out sepalLength);
                              currentIris.SepalLength = sepalLength;
      
                              double.TryParse(irisValues[1], out sepalWidth);
                              currentIris.SepalWidth = sepalWidth;
      
                              double.TryParse(irisValues[2], out petalLength);
                              currentIris.PetalLength = petalLength;
      
                              double.TryParse(irisValues[3], out petalWidth);
                              currentIris.PetalWidth = petalWidth;
      
                              if (irisValues[4] == "Iris-setosa")
                                  currentIris.IrisClass = Iris.IrisTypes.IrisSetosa;
                              else if (irisValues[4] == "Iris-versicolor")
                                  currentIris.IrisClass = Iris.IrisTypes.IrisVersicolour;
                              else
                                  currentIris.IrisClass = Iris.IrisTypes.IrisVirginica;
      
                              IrisDataParserService.TrainingIrisData.Add(currentIris);
                          }
                      }
                  }
              }
          }
      }
      This code is pretty standard.  We simply read each line in the file, split the values out into an array, and populate a List<Iris> collection of Iris objects based on the data found in the file.
       

      Now the magic

      Using the numl.net library, we need only use three classes to perform a prediction based on the Iris data set.  We start with a Descriptor, which identifies the class in which we will learn and predict.  Next, we will instantiate a DecisionTreeGenerator, passing the descriptor to the constructor.  Finally, we will create our prediction model by calling the Generate method of the DecisionTreeGenerator, passing the training data (IEnumerable<Iris>) to the Generate method.  The generate method will provide us with a model in which we can perform our prediction.

      Here is the code:

      using numl;
      using numl.Model;
      using numl.Supervised;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      
      namespace NumlDemo
      {
          class Program
          {
              public static void Main(string[] args)
              {
                  //get the descriptor that describes the features and label from the Iris training objects
                  var irisDescriptor = Descriptor.Create<Iris>();
      
                  //create a decision tree generator and teach it about the Iris descriptor
                  var decisionTreeGenerator = new DecisionTreeGenerator(irisDescriptor);
      
                  //load the training data
                  IrisDataParserService.LoadIrisTrainingData(@"D:\Development\machinelearning\Iris Dataset\bezdekIris.data");
      
                  //create a model based on our training data using the decision tree generator
                  var decisionTreeModel = decisionTreeGenerator.Generate(IrisDataParserService.TrainingIrisData);
      
                  //create an iris that should be an Iris Setosa
                  var irisSetosa = new Iris
                  {
                      SepalLength = 5.1,
                      SepalWidth = 3.5,
                      PetalLength = 1.4,
                      PetalWidth = 0.2
                  };
      
                  //create an iris that should be an Iris Versicolor
                  var irisVersiColor = new Iris
                  {
                      SepalLength = 6.1,
                      SepalWidth = 2.8,
                      PetalLength = 4.0,
                      PetalWidth = 1.3
                  };
      
                  //create an iris that should be an Iris Virginica
                  var irisVirginica = new Iris
                  {
                      SepalLength = 7.7,
                      SepalWidth = 2.8,
                      PetalLength = 6.7,
                      PetalWidth = 2.0
                  };
      
                  var irisSetosaClass = decisionTreeModel.Predict<Iris>(irisSetosa);
                  var irisVersiColorClass = decisionTreeModel.Predict<Iris>(irisVersiColor);
                  var irisVirginicaClass = decisionTreeModel.Predict<Iris>(irisVirginica);
      
                  Console.WriteLine("The Iris Setosa was predicted as {0}",
                      irisSetosaClass.IrisClass.ToString());
      
                  Console.WriteLine("The Iris Versicolor was predicted as {0}",
                      irisVersiColorClass.IrisClass.ToString());
      
                  Console.WriteLine("The Iris Virginica was predicted as {0}",
                      irisVirginicaClass.IrisClass.ToString());
      
                  Console.ReadKey();
              }
          }
      }

      And that's all there is to it.  As you can see, you can use the prediction model accurately and there's no math, only simple abstractions.

      I hope this has peaked your interest in the numl.net library for machine learning in .NET.  

      Feel free to post any questions or opinions.

      Thanks for reading!

      Buddy James

       



      Comments (9) -

      sam
      sam
      3/27/2013 11:47:06 PM #

      Hi , nice stuff, but I am getting error "Invalid descriptor: Empty feature set!"

      var data = Value.GetData();
                  var description = Descriptor.Create<Value>();
                  var generator = new DecisionTreeGenerator(50);
                  var model = generator.Generate(description, data);

      where value :
      public class Value
          {
              public int V1 { get; set; }
              public int V2 { get; set; }
              public int R { get ;set; }
      }

      Buddy James
      Buddy James
      3/28/2013 7:25:41 AM #

      Sam,

      You need to mark some of your properties with the [Feature] attribute.. That would be my first guess.. give that a shot and see if that doesn't take care of your problem.

      Thanks for reading!

      Buddy James

      sam
      sam
      3/28/2013 7:56:47 AM #

      Thanks Buddy , will try it today . it look good , but there is no documentation at all .

      Buddy James
      Buddy James
      3/28/2013 2:40:01 PM #

      Sam,

      I've forked the GitHub repository and I'm working to help provide some documentation as I learn the library.

      Buddy James
      Buddy James
      3/28/2013 2:40:01 PM #

      Sam,

      I've forked the GitHub repository and I'm working to help provide some documentation as I learn the library.

      sam
      sam
      3/28/2013 5:50:47 PM #

      I just posed an issue , it seem it cant handle big date , it only works when the sample data is less than 10 and the data somehow consistent , for example if you feed it from this it will  error    :
      public static IEnumerable<Value>  GetData()
              {

                 for ( int i=0  ; i<1000; i++)
                 {
                     yield return new Value { V1 =1 , V2 = i , R= (i>50 ) ?"l":"s"  };

                 }
              }

      Buddy James
      Buddy James
      3/29/2013 1:31:30 AM #

      Sam,

      I appreciate the heads up.

      I've submitted the bug and I'll let you know when it's been fixed.

      Thanks,

      Buddy James

      sam
      sam
      3/30/2013 2:22:55 PM #

      Hi Buddy ,
      really thank you for your help , but it seem numl is not what I am looking for , also its developer confirmed that . I was trying to make it predict the level of student from his degrees which supposed to be easy job .
      I advise you to do some deep test before consider using it to any real life project .
      I a mgoing to try :
      www.codeproject.com/.../AForge-NET-open-source-framework

      Buddy James
      Buddy James
      3/31/2013 1:07:24 AM #

      Sam,

      I appreciate your feedback.

      The library is a young work in progress.  It's on github and I feel it's worth the time.  I'm having a lot of fun working on it and I'm learning a lot in the process.

      I suggest trying all libraries and pick the one that calls out to you.  NND is another project that I'm involved in that is more geared toward neural networks, however, it's vast... Maybe you should give it a try.  Be sure to stop by and let me know what works for you.  Thanks for reading!

      Add comment

        Country flag


      • Comment
      • Preview
      Loading

      About the author

      My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

      Related links

      Month List

      refactorthis.net | numl - a machine learning library for .NET developers
      Infragistics JQuery controls

      numl - a machine learning library for .NET developers

      In one of my previous posts called Machine learning resources for .NET developers, I introduced a machine learning library called numl.net.  numl.net is a machine learning library for .NET created by Seth Juarez.  You can find the library here and Seth's blog here.  When I began researching the library, I learned quickly that one of Seth's goals in writing numl.net was to abstract away the complexities that stops many software developers from trying their hand at machine learning.  I must say that in my opinion, he has done a wonderful job in accomplishing this goal!

      Tutorial

      I've decided to throw together a small tutorial to show you just how easy it is to use numl.net to perform predictions.  This tutorial will use structured learning by way of a decision tree to perform predictions.  I will use the infamous Iris Data set which contains data 3 different types of Iris flowers and the data that defines them.  Before we get into code, let's look at some basic terminology first.

      With numl.net you create a POCO (plain old CLR object) to use for training as well as predictions.  There will be properties that you will specify known values (features) so that you can predict the value of an unknown property value (label).  numl.net makes identifying features and labels easy, you simply mark your properties with the [Feature] attribute or the [Label] attribute (there is also a [StringLabel] attribute as well).  Here is an example of the Iris class that we will use in this tutorial.

      using numl.Model;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      
      namespace NumlDemo
      {
          /// <summary>
          /// Represents an Iris in the infamous Iris classification dataset (Fisher, 1936)
          /// Each feature property will be used for training as well as prediction.  The label
          /// property is the value to be predicted.  In this case, it's which type of Iris we are dealing with.
          /// </summary>
          public class Iris
          {
              //Length in centimeters
              [Feature]
              public double SepalLength { get; set; }
      
              //Width in centimeters
              [Feature]
              public double SepalWidth { get; set; }
      
              //Length in centimeters
              [Feature]
              public double PetalLength { get; set; }
      
              //Width in centimeters
              [Feature]
              public double PetalWidth { get; set; }
      
              
              //-- Iris Setosa 
              //-- Iris Versicolour 
              //-- Iris Virginica
              
              public enum IrisTypes
              {
                  IrisSetosa,
                  IrisVersicolour,
                  IrisVirginica
              }
      
              [Label]
              public IrisTypes IrisClass { get; set; } //This is the label or value that we wish to predict based on the supplied features
          }
      }

      As you can see, we have a simple POCO Iris class, which defines four features and one label.  The Iris training data can be found here .  Here is an example of the data found in the file.

       

      5.1,3.5,1.4,0.2,Iris-setosa

      6.3,2.5,4.9,1.5,Iris-versicolor

      6.0,3.0,4.8,1.8,Iris-virginica
       
       
      The first four values are doubles which represent the features Sepal Length, Sepal Width, Petal Length, Petal Width.  The final value is an enum that represents the label that we will predict which is the class of Iris.
       
      We have the Iris class, so now we need a method to parse the training data file and generate a static List<Iris> collection.  Here is the code:
       
      using System;
      using System.Collections.Generic;
      using System.IO;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      
      namespace NumlDemo
      {
          /// <summary>
          /// Provides the services to parse the training data files 
          /// </summary>
          public static class IrisDataParserService
          {
              //provides the training data to create the predictive model
              public static List<Iris> TrainingIrisData { get; set; }
      
              /// <summary>
              /// Reads the trainingDataFile and populates the TrainingIrisData list
              /// </summary>
              /// <param name="trainingDataFile">File full of Iris data</param>
              /// <returns></returns>
              public static void LoadIrisTrainingData(string trainingDataFile)
              {
                  //if we don't have a training data file
                  if (string.IsNullOrEmpty(trainingDataFile))
                      throw new ArgumentNullException("trainingDataFile");
      
                  //if the file doesn't exist on the file system
                  if (!File.Exists(trainingDataFile))
                      throw new FileNotFoundException();
      
                  if (TrainingIrisData == null)
                      //initialize the return training data set
                      TrainingIrisData = new List<Iris>();
      
                  //read the entire file contents into a string
                  using (var fileReader = new StreamReader(new FileStream(trainingDataFile, FileMode.Open)))
                  {
                      string fileLineContents;
                      while ((fileLineContents = fileReader.ReadLine()) != null)
                      {
                          //split the current line into an array of values
                          var irisValues = fileLineContents.Split(',');
      
                          double sepalLength = 0.0;
                          double sepalWidth = 0.0;
      
                          double petalLength = 0.0;
                          double petalWidth = 0.0;
      
                          if (irisValues.Length == 5)
                          {
                              Iris currentIris = new Iris();
      
                              double.TryParse(irisValues[0], out sepalLength);
                              currentIris.SepalLength = sepalLength;
      
                              double.TryParse(irisValues[1], out sepalWidth);
                              currentIris.SepalWidth = sepalWidth;
      
                              double.TryParse(irisValues[2], out petalLength);
                              currentIris.PetalLength = petalLength;
      
                              double.TryParse(irisValues[3], out petalWidth);
                              currentIris.PetalWidth = petalWidth;
      
                              if (irisValues[4] == "Iris-setosa")
                                  currentIris.IrisClass = Iris.IrisTypes.IrisSetosa;
                              else if (irisValues[4] == "Iris-versicolor")
                                  currentIris.IrisClass = Iris.IrisTypes.IrisVersicolour;
                              else
                                  currentIris.IrisClass = Iris.IrisTypes.IrisVirginica;
      
                              IrisDataParserService.TrainingIrisData.Add(currentIris);
                          }
                      }
                  }
              }
          }
      }
      This code is pretty standard.  We simply read each line in the file, split the values out into an array, and populate a List<Iris> collection of Iris objects based on the data found in the file.
       

      Now the magic

      Using the numl.net library, we need only use three classes to perform a prediction based on the Iris data set.  We start with a Descriptor, which identifies the class in which we will learn and predict.  Next, we will instantiate a DecisionTreeGenerator, passing the descriptor to the constructor.  Finally, we will create our prediction model by calling the Generate method of the DecisionTreeGenerator, passing the training data (IEnumerable<Iris>) to the Generate method.  The generate method will provide us with a model in which we can perform our prediction.

      Here is the code:

      using numl;
      using numl.Model;
      using numl.Supervised;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      
      namespace NumlDemo
      {
          class Program
          {
              public static void Main(string[] args)
              {
                  //get the descriptor that describes the features and label from the Iris training objects
                  var irisDescriptor = Descriptor.Create<Iris>();
      
                  //create a decision tree generator and teach it about the Iris descriptor
                  var decisionTreeGenerator = new DecisionTreeGenerator(irisDescriptor);
      
                  //load the training data
                  IrisDataParserService.LoadIrisTrainingData(@"D:\Development\machinelearning\Iris Dataset\bezdekIris.data");
      
                  //create a model based on our training data using the decision tree generator
                  var decisionTreeModel = decisionTreeGenerator.Generate(IrisDataParserService.TrainingIrisData);
      
                  //create an iris that should be an Iris Setosa
                  var irisSetosa = new Iris
                  {
                      SepalLength = 5.1,
                      SepalWidth = 3.5,
                      PetalLength = 1.4,
                      PetalWidth = 0.2
                  };
      
                  //create an iris that should be an Iris Versicolor
                  var irisVersiColor = new Iris
                  {
                      SepalLength = 6.1,
                      SepalWidth = 2.8,
                      PetalLength = 4.0,
                      PetalWidth = 1.3
                  };
      
                  //create an iris that should be an Iris Virginica
                  var irisVirginica = new Iris
                  {
                      SepalLength = 7.7,
                      SepalWidth = 2.8,
                      PetalLength = 6.7,
                      PetalWidth = 2.0
                  };
      
                  var irisSetosaClass = decisionTreeModel.Predict<Iris>(irisSetosa);
                  var irisVersiColorClass = decisionTreeModel.Predict<Iris>(irisVersiColor);
                  var irisVirginicaClass = decisionTreeModel.Predict<Iris>(irisVirginica);
      
                  Console.WriteLine("The Iris Setosa was predicted as {0}",
                      irisSetosaClass.IrisClass.ToString());
      
                  Console.WriteLine("The Iris Versicolor was predicted as {0}",
                      irisVersiColorClass.IrisClass.ToString());
      
                  Console.WriteLine("The Iris Virginica was predicted as {0}",
                      irisVirginicaClass.IrisClass.ToString());
      
                  Console.ReadKey();
              }
          }
      }

      And that's all there is to it.  As you can see, you can use the prediction model accurately and there's no math, only simple abstractions.

      I hope this has peaked your interest in the numl.net library for machine learning in .NET.  

      Feel free to post any questions or opinions.

      Thanks for reading!

      Buddy James

       



      Comments (9) -

      sam
      sam
      3/27/2013 11:47:06 PM #

      Hi , nice stuff, but I am getting error "Invalid descriptor: Empty feature set!"

      var data = Value.GetData();
                  var description = Descriptor.Create<Value>();
                  var generator = new DecisionTreeGenerator(50);
                  var model = generator.Generate(description, data);

      where value :
      public class Value
          {
              public int V1 { get; set; }
              public int V2 { get; set; }
              public int R { get ;set; }
      }

      Buddy James
      Buddy James
      3/28/2013 7:25:41 AM #

      Sam,

      You need to mark some of your properties with the [Feature] attribute.. That would be my first guess.. give that a shot and see if that doesn't take care of your problem.

      Thanks for reading!

      Buddy James

      sam
      sam
      3/28/2013 7:56:47 AM #

      Thanks Buddy , will try it today . it look good , but there is no documentation at all .

      Buddy James
      Buddy James
      3/28/2013 2:40:01 PM #

      Sam,

      I've forked the GitHub repository and I'm working to help provide some documentation as I learn the library.

      Buddy James
      Buddy James
      3/28/2013 2:40:01 PM #

      Sam,

      I've forked the GitHub repository and I'm working to help provide some documentation as I learn the library.

      sam
      sam
      3/28/2013 5:50:47 PM #

      I just posed an issue , it seem it cant handle big date , it only works when the sample data is less than 10 and the data somehow consistent , for example if you feed it from this it will  error    :
      public static IEnumerable<Value>  GetData()
              {

                 for ( int i=0  ; i<1000; i++)
                 {
                     yield return new Value { V1 =1 , V2 = i , R= (i>50 ) ?"l":"s"  };

                 }
              }

      Buddy James
      Buddy James
      3/29/2013 1:31:30 AM #

      Sam,

      I appreciate the heads up.

      I've submitted the bug and I'll let you know when it's been fixed.

      Thanks,

      Buddy James

      sam
      sam
      3/30/2013 2:22:55 PM #

      Hi Buddy ,
      really thank you for your help , but it seem numl is not what I am looking for , also its developer confirmed that . I was trying to make it predict the level of student from his degrees which supposed to be easy job .
      I advise you to do some deep test before consider using it to any real life project .
      I a mgoing to try :
      www.codeproject.com/.../AForge-NET-open-source-framework

      Buddy James
      Buddy James
      3/31/2013 1:07:24 AM #

      Sam,

      I appreciate your feedback.

      The library is a young work in progress.  It's on github and I feel it's worth the time.  I'm having a lot of fun working on it and I'm learning a lot in the process.

      I suggest trying all libraries and pick the one that calls out to you.  NND is another project that I'm involved in that is more geared toward neural networks, however, it's vast... Maybe you should give it a try.  Be sure to stop by and let me know what works for you.  Thanks for reading!

      Add comment

        Country flag


      • Comment
      • Preview
      Loading

      About the author

      My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

      Related links

      Month List

      refactorthis.net | Machine learning resources for .NET developers
      Infragistics JQuery controls

      Machine learning resources for .NET developers

      Machine learning for .NET

      Greetings friends and welcome to this article on Machine learning libraries for .NET developers.  Machine learning is a hot topic right now and for good reason.  Personally, I haven't been so excited about a technology since my computer used my 2800 baud modem to dial into a BBS over 17 years ago.  The thought that my computer could communicate with another computer was so fascinating to me.  That moment was the very moment that would forever change my life.  I learned a lot about DOS by writing batch scripts and running other programs that allowed me to visit and then run a BBS system.  It eventually lead me to QBasic.  I wanted to learn to write BBS door games and QBasic was included as a part of a standard DOS installation back then.

      Fast forward 17 years and I'm still in love with computers, programming, and the concept of communication between machines.  The magic never disappeared.  So when i first learned about the concept of Machine learning, I felt like that 13 year old kid again.  The idea that a machine can learn to do things that it has not been programmed to do is now a passion of mine.  The concepts of Machine learning have an extreme learning curve, however, I believe that we as humans can do anything that we put our mind to.  So I began looking around for tutorials on machine learning.  I found many great tutorials and books, however, most of them involved using python.  I have nothing against python.  As a matter of fact, I find it ironic that I started with BASIC and now in this moment of "rebirth" I'm beginning to use python which looks a lot like BASIC in many ways.  The fact of the matter remains, I'm a .NET developer.  I've spent the last 9 years in the .NET framework and I love the technology.  C# is an awesome programming language and it's hard to imagine life without Visual Studio.  What can I say, the IDE has spoiled me.

      While I scoured the internet looking for tutorials related to Machine learning resources for .NET developers, I wished that there was a one resource that would assist me in my search for resources to help me achieve my goal.

      Well that's what this article is all about.  In this article, I will introduce you to some .NET libraries that will assist you in your quest to learn about Machine learning.

      NND Neural Network Designer by Bragisoft

      The Neural Network Designer project (NND) is a DBMS management system for neural networks that was created by Jan Bogaerts.  The designer application is developed using WPF, and is a user interface which allows you to design your neural network, query the network, create and configure chat bots that are capable of asking questions and learning from your feed back.  The chat bots can even scrape the internet for information to return in their output as well as to use for learning.  The project includes a custom language syntax called NNL (neural network language) that you can use in configuring your machine learning project.  The source code is designed so that the libraries can be used in your own custom applications so you don't have to start from scratch with such a complex set of technologies.  The project is actually an open source project in which I am a part of.  Some of the possibilities offered by this awesome project include predictions, image and pattern recognition, value inspection, memory profiling and much more.  Stop by the Bragisoft NND website and download the application to give it a try

       Screen shots of the neural network designer by Bragisoft

      A DBMS for neural networks

      A DBMS for neural networks

       

      Mind map rand forrest

      Machine learning

      The chat bot designer and other tools

      GUIs and debuggers

      Accord.net

      Here is a description from the Accord.NET project website 

      Accord.NET is a framework for scientific computing in .NET. The framework builds upon AForge.NET, an also popular framework for image processing, supplying new tools and libraries. Those libraries encompass a wide range of scientific computing applications, such as statistical data processing, machine learning, pattern recognition, including but not limited to, computer vision and computer audition. The framework offers a large number of probability distributions, hypothesis tests, kernel functions and support for most popular performance measurements techniques.

       The most impressive parts of this library has got to be the documentation and sample applications that are distributed with the project.  This makes the library easy to get started using.  I also like the ability to perform operations like Audio processing (beat detection and more), Video processing (easy integration with your web cam, vision capabilities and object recognition).  This is an excellent place to start with approaching Machine learning with the .NET framework.  Here are a two videos that should whet your appetite.

      Hand writing recognition with Accord.NET

       

      Here is an example of head tracking with Accord.NET (super cool)

       

      AIMLBot Program# AILM Chat bot library

      AIMLBot (Program#) is a small, fast, standards-compliant yet easily customizable implementation of an AIML (Artificial Intelligence Markup Language) based chatter bot in C#. AIMLBot has been tested on both Microsoft's runtime environment and Mono. Put simply, it will allow you to chat (by entering text) with your computer using natural language.  The project is located here.

      Math.NET

      Machine learning algorithms are extremely math heavy.  Math.NET is a library  that can assist with the math that is required to solve machine learning related problems.

      Math.NET Numerics aims to provide methods and algorithms for numerical computations in science, engineering and every day use. Covered topics include special functions, linear algebra, probability models, random numbers, interpolation, integral transforms and more.

      DotNumerics

      DotNumerics is a website dedicated to numerical computing for .NET. DotNumerics includes a Numerical Library for .NET. The library is written in pure C# and has more than 100,000 lines of code with the most advanced algorithms for Linear Algebra, Differential Equations and Optimization problems. The Linear Algebra library includes CSLapack, CSBlas and CSEispack, these libraries are the translation from Fortran to C# of LAPACK, BLAS and EISPACK, respectively.

      You can find the library here. 

      ALGLIB

      ALGLIB is a cross-platform numerical analysis and data processing library. It supports several programming languages (C++, C#, Pascal, VBA) and several operating systems (Windows, Linux, Solaris). ALGLIB features include:

      Accessing ‘R’ from C#–Lessons learned

      Here are instructions to use the R statistical framework from within c#

      ILNumerics

      You can check out the library at http://www.ilnumerics.net

      NuML.net http://numl.net

      A nice site about the basics of machine learning in c# by Seth Juarez . NuML.NET is a machine learning library for .NET developers written by Seth Juarez.  I've recently tried this library and I'm impressed!  Seth has stated publicly that his intention behind the numl.net library is to abstract the scary math away from machine learning to provide tools that are more approachable by software developers and boy did he deliver!  I've been working with this library for a little more than an hour and I've written a prediction app in c#.  You can find his numl.net library source on github.

      Encog Machine Learning Framework

      Here is what the official Heaton Research website has to say about Encog:

      Encog is an advanced machine learning framework that supports a variety of advanced algorithms, as well as support classes to normalize and process data. Machine learning algorithms such as Support Vector Machines, Artificial Neural Networks, Genetic Programming, Bayesian Networks, Hidden Markov Models and Genetic Algorithms are supported. Most Encog training algoritms are multi-threaded and scale well to multicore hardware. Encog can also make use of a GPU to further speed processing time. A GUI based workbench is also provided to help model and train machine learning algorithms. Encog has been in active development since 2008.

      Encog is available for Java, .Net and C/C++.

      Jeff Heaton knows a great deal about machine learning algorithms and he's created a wonderful library called Encog.  I was able to write a neural network application that solved the classic XOR problem in 20 minutes after installing the library.  What really amazes me is that he has an Encog Library for JavaScript which includes live samples on his website of Javascript + encog solving problems like the Traveling Salesman Problem and Conway's game of life, all in a browser!  This library can even use your GPU for the heavy lifting if that's your choice.  I would highly recommend that you at least check out his site and download the library to look at the examples.  You can find the Encog library here

       

      Conclusion

      This concludes my article on Machine learning resources for the .NET developer.  If you have any suggestions regarding a project that you know of or you are working on related to Machine learning in .NET, please don't hesitate to leave a comment and I will update the article to mention the project.  This article has shown that we as .NET developers have many resources available to us to use to implement Machine learning based solutions.  I appreciate your time in reading this article and I hope you found it useful.  Please subscribe to my RSS feed.  Until next time..

      Buddy James



      Comments (6) -

      Seth Juarez
      Seth Juarez
      3/4/2013 11:11:59 AM #

      Hey! I also made something: http://numl.net.

      Buddy James
      Buddy James
      3/9/2013 4:22:53 AM #

      Seth,

      Thank you for contributing.  I'm going to add your project to my list.

      The code looks great.  The site design is really awesome too!  Kudos!

      Buddy James

      terrell26
      terrell26
      3/21/2013 12:44:32 PM #

      You seem to know a great deal about this subject

      Buddy James
      Buddy James
      3/21/2013 5:33:28 PM #

      I appreciate the compliment.  I'm very passionate about machine learning and I'm constantly learning.

      Thanks again!

      Buddy James

      Don Syme
      Don Syme
      7/2/2013 4:46:37 AM #

      Great links!

      For F# developers (or C# developers adding an F# project to their solution) see also  

          http://fsharp.org/machine-learning

      Buddy James
      Buddy James
      7/4/2013 8:37:45 PM #

      Thanks for reading @Don.  I hear great things about F# and machine learning.  F# is on my list of languages to learn.  Thanks again!

      Buddy

      Pingbacks and trackbacks (1)+

      Add comment

        Country flag


      • Comment
      • Preview
      Loading

      About the author

      My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

      Related links

      Month List

      refactorthis.net | numl - a machine learning library for .NET developers
      Infragistics WPF controls

      numl - a machine learning library for .NET developers

      In one of my previous posts called Machine learning resources for .NET developers, I introduced a machine learning library called numl.net.  numl.net is a machine learning library for .NET created by Seth Juarez.  You can find the library here and Seth's blog here.  When I began researching the library, I learned quickly that one of Seth's goals in writing numl.net was to abstract away the complexities that stops many software developers from trying their hand at machine learning.  I must say that in my opinion, he has done a wonderful job in accomplishing this goal!

      Tutorial

      I've decided to throw together a small tutorial to show you just how easy it is to use numl.net to perform predictions.  This tutorial will use structured learning by way of a decision tree to perform predictions.  I will use the infamous Iris Data set which contains data 3 different types of Iris flowers and the data that defines them.  Before we get into code, let's look at some basic terminology first.

      With numl.net you create a POCO (plain old CLR object) to use for training as well as predictions.  There will be properties that you will specify known values (features) so that you can predict the value of an unknown property value (label).  numl.net makes identifying features and labels easy, you simply mark your properties with the [Feature] attribute or the [Label] attribute (there is also a [StringLabel] attribute as well).  Here is an example of the Iris class that we will use in this tutorial.

      using numl.Model;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      
      namespace NumlDemo
      {
          /// <summary>
          /// Represents an Iris in the infamous Iris classification dataset (Fisher, 1936)
          /// Each feature property will be used for training as well as prediction.  The label
          /// property is the value to be predicted.  In this case, it's which type of Iris we are dealing with.
          /// </summary>
          public class Iris
          {
              //Length in centimeters
              [Feature]
              public double SepalLength { get; set; }
      
              //Width in centimeters
              [Feature]
              public double SepalWidth { get; set; }
      
              //Length in centimeters
              [Feature]
              public double PetalLength { get; set; }
      
              //Width in centimeters
              [Feature]
              public double PetalWidth { get; set; }
      
              
              //-- Iris Setosa 
              //-- Iris Versicolour 
              //-- Iris Virginica
              
              public enum IrisTypes
              {
                  IrisSetosa,
                  IrisVersicolour,
                  IrisVirginica
              }
      
              [Label]
              public IrisTypes IrisClass { get; set; } //This is the label or value that we wish to predict based on the supplied features
          }
      }

      As you can see, we have a simple POCO Iris class, which defines four features and one label.  The Iris training data can be found here .  Here is an example of the data found in the file.

       

      5.1,3.5,1.4,0.2,Iris-setosa

      6.3,2.5,4.9,1.5,Iris-versicolor

      6.0,3.0,4.8,1.8,Iris-virginica
       
       
      The first four values are doubles which represent the features Sepal Length, Sepal Width, Petal Length, Petal Width.  The final value is an enum that represents the label that we will predict which is the class of Iris.
       
      We have the Iris class, so now we need a method to parse the training data file and generate a static List<Iris> collection.  Here is the code:
       
      using System;
      using System.Collections.Generic;
      using System.IO;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      
      namespace NumlDemo
      {
          /// <summary>
          /// Provides the services to parse the training data files 
          /// </summary>
          public static class IrisDataParserService
          {
              //provides the training data to create the predictive model
              public static List<Iris> TrainingIrisData { get; set; }
      
              /// <summary>
              /// Reads the trainingDataFile and populates the TrainingIrisData list
              /// </summary>
              /// <param name="trainingDataFile">File full of Iris data</param>
              /// <returns></returns>
              public static void LoadIrisTrainingData(string trainingDataFile)
              {
                  //if we don't have a training data file
                  if (string.IsNullOrEmpty(trainingDataFile))
                      throw new ArgumentNullException("trainingDataFile");
      
                  //if the file doesn't exist on the file system
                  if (!File.Exists(trainingDataFile))
                      throw new FileNotFoundException();
      
                  if (TrainingIrisData == null)
                      //initialize the return training data set
                      TrainingIrisData = new List<Iris>();
      
                  //read the entire file contents into a string
                  using (var fileReader = new StreamReader(new FileStream(trainingDataFile, FileMode.Open)))
                  {
                      string fileLineContents;
                      while ((fileLineContents = fileReader.ReadLine()) != null)
                      {
                          //split the current line into an array of values
                          var irisValues = fileLineContents.Split(',');
      
                          double sepalLength = 0.0;
                          double sepalWidth = 0.0;
      
                          double petalLength = 0.0;
                          double petalWidth = 0.0;
      
                          if (irisValues.Length == 5)
                          {
                              Iris currentIris = new Iris();
      
                              double.TryParse(irisValues[0], out sepalLength);
                              currentIris.SepalLength = sepalLength;
      
                              double.TryParse(irisValues[1], out sepalWidth);
                              currentIris.SepalWidth = sepalWidth;
      
                              double.TryParse(irisValues[2], out petalLength);
                              currentIris.PetalLength = petalLength;
      
                              double.TryParse(irisValues[3], out petalWidth);
                              currentIris.PetalWidth = petalWidth;
      
                              if (irisValues[4] == "Iris-setosa")
                                  currentIris.IrisClass = Iris.IrisTypes.IrisSetosa;
                              else if (irisValues[4] == "Iris-versicolor")
                                  currentIris.IrisClass = Iris.IrisTypes.IrisVersicolour;
                              else
                                  currentIris.IrisClass = Iris.IrisTypes.IrisVirginica;
      
                              IrisDataParserService.TrainingIrisData.Add(currentIris);
                          }
                      }
                  }
              }
          }
      }
      This code is pretty standard.  We simply read each line in the file, split the values out into an array, and populate a List<Iris> collection of Iris objects based on the data found in the file.
       

      Now the magic

      Using the numl.net library, we need only use three classes to perform a prediction based on the Iris data set.  We start with a Descriptor, which identifies the class in which we will learn and predict.  Next, we will instantiate a DecisionTreeGenerator, passing the descriptor to the constructor.  Finally, we will create our prediction model by calling the Generate method of the DecisionTreeGenerator, passing the training data (IEnumerable<Iris>) to the Generate method.  The generate method will provide us with a model in which we can perform our prediction.

      Here is the code:

      using numl;
      using numl.Model;
      using numl.Supervised;
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      
      namespace NumlDemo
      {
          class Program
          {
              public static void Main(string[] args)
              {
                  //get the descriptor that describes the features and label from the Iris training objects
                  var irisDescriptor = Descriptor.Create<Iris>();
      
                  //create a decision tree generator and teach it about the Iris descriptor
                  var decisionTreeGenerator = new DecisionTreeGenerator(irisDescriptor);
      
                  //load the training data
                  IrisDataParserService.LoadIrisTrainingData(@"D:\Development\machinelearning\Iris Dataset\bezdekIris.data");
      
                  //create a model based on our training data using the decision tree generator
                  var decisionTreeModel = decisionTreeGenerator.Generate(IrisDataParserService.TrainingIrisData);
      
                  //create an iris that should be an Iris Setosa
                  var irisSetosa = new Iris
                  {
                      SepalLength = 5.1,
                      SepalWidth = 3.5,
                      PetalLength = 1.4,
                      PetalWidth = 0.2
                  };
      
                  //create an iris that should be an Iris Versicolor
                  var irisVersiColor = new Iris
                  {
                      SepalLength = 6.1,
                      SepalWidth = 2.8,
                      PetalLength = 4.0,
                      PetalWidth = 1.3
                  };
      
                  //create an iris that should be an Iris Virginica
                  var irisVirginica = new Iris
                  {
                      SepalLength = 7.7,
                      SepalWidth = 2.8,
                      PetalLength = 6.7,
                      PetalWidth = 2.0
                  };
      
                  var irisSetosaClass = decisionTreeModel.Predict<Iris>(irisSetosa);
                  var irisVersiColorClass = decisionTreeModel.Predict<Iris>(irisVersiColor);
                  var irisVirginicaClass = decisionTreeModel.Predict<Iris>(irisVirginica);
      
                  Console.WriteLine("The Iris Setosa was predicted as {0}",
                      irisSetosaClass.IrisClass.ToString());
      
                  Console.WriteLine("The Iris Versicolor was predicted as {0}",
                      irisVersiColorClass.IrisClass.ToString());
      
                  Console.WriteLine("The Iris Virginica was predicted as {0}",
                      irisVirginicaClass.IrisClass.ToString());
      
                  Console.ReadKey();
              }
          }
      }

      And that's all there is to it.  As you can see, you can use the prediction model accurately and there's no math, only simple abstractions.

      I hope this has peaked your interest in the numl.net library for machine learning in .NET.  

      Feel free to post any questions or opinions.

      Thanks for reading!

      Buddy James

       



      Comments (9) -

      sam
      sam
      3/27/2013 11:47:06 PM #

      Hi , nice stuff, but I am getting error "Invalid descriptor: Empty feature set!"

      var data = Value.GetData();
                  var description = Descriptor.Create<Value>();
                  var generator = new DecisionTreeGenerator(50);
                  var model = generator.Generate(description, data);

      where value :
      public class Value
          {
              public int V1 { get; set; }
              public int V2 { get; set; }
              public int R { get ;set; }
      }

      Buddy James
      Buddy James
      3/28/2013 7:25:41 AM #

      Sam,

      You need to mark some of your properties with the [Feature] attribute.. That would be my first guess.. give that a shot and see if that doesn't take care of your problem.

      Thanks for reading!

      Buddy James

      sam
      sam
      3/28/2013 7:56:47 AM #

      Thanks Buddy , will try it today . it look good , but there is no documentation at all .

      Buddy James
      Buddy James
      3/28/2013 2:40:01 PM #

      Sam,

      I've forked the GitHub repository and I'm working to help provide some documentation as I learn the library.

      Buddy James
      Buddy James
      3/28/2013 2:40:01 PM #

      Sam,

      I've forked the GitHub repository and I'm working to help provide some documentation as I learn the library.

      sam
      sam
      3/28/2013 5:50:47 PM #

      I just posed an issue , it seem it cant handle big date , it only works when the sample data is less than 10 and the data somehow consistent , for example if you feed it from this it will  error    :
      public static IEnumerable<Value>  GetData()
              {

                 for ( int i=0  ; i<1000; i++)
                 {
                     yield return new Value { V1 =1 , V2 = i , R= (i>50 ) ?"l":"s"  };

                 }
              }

      Buddy James
      Buddy James
      3/29/2013 1:31:30 AM #

      Sam,

      I appreciate the heads up.

      I've submitted the bug and I'll let you know when it's been fixed.

      Thanks,

      Buddy James

      sam
      sam
      3/30/2013 2:22:55 PM #

      Hi Buddy ,
      really thank you for your help , but it seem numl is not what I am looking for , also its developer confirmed that . I was trying to make it predict the level of student from his degrees which supposed to be easy job .
      I advise you to do some deep test before consider using it to any real life project .
      I a mgoing to try :
      www.codeproject.com/.../AForge-NET-open-source-framework

      Buddy James
      Buddy James
      3/31/2013 1:07:24 AM #

      Sam,

      I appreciate your feedback.

      The library is a young work in progress.  It's on github and I feel it's worth the time.  I'm having a lot of fun working on it and I'm learning a lot in the process.

      I suggest trying all libraries and pick the one that calls out to you.  NND is another project that I'm involved in that is more geared toward neural networks, however, it's vast... Maybe you should give it a try.  Be sure to stop by and let me know what works for you.  Thanks for reading!

      Add comment

        Country flag


      • Comment
      • Preview
      Loading

      About the author

      My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

      Related links

      Month List

      refactorthis.net | dot42: an alternative to MonoDroid
      Infragistics ASP.NET controls

      dot42: an alternative to MonoDroid

      Android development in Visual Studio

      I'm sure a lot of you have heard of the MonoDroid product by Xamarin which allows .NET developers to write android applications using your favorite .NET tools.  I find this option awesome because I'm a .NET developer and because I find native android development tedious.  It's not that Java is difficult, especially when compared to iOS development using objective-C (ughh).  My main problem with android development in Java is once you use Visual Studio for a few years, it's really hard to use anything else.  

      Enter Xamarin's MonoDroid

      I was really excited when MonoDroid was released.  That excitement faded quickly when I learned that i couldn't deploy my applications to my Android phone for testing without a license.  Instead, you are forced you use the Android emulator.  I've tried many times with many configurations to use the emulator.  It's simply not feasible for me.  The emulator is INCREDIBLY slow, when it works.  Other times I would wait for 20+ mins before giving up.  I'm not the only developer to express disdain for the Android emulator.  Just google Android emulator slow and you will find a lot of people have this problem.

      dot42: An alternative

      Let me start by saying that I ran across dot42 http://www.dot42.com/ only 10 minutes ago, so I don't claim to have experience with the product.  What I can say is that like MonoDroid, they offer a free version of their product for personal (no commercial development).  Unlike MonoDroid, I see no news on their site to suggest that you can't deploy your application on your phone for testing with the free version.  If this is in fact true, this makes all the difference to me as a developer. (Update: I've verified that dot42 does NOT restrict deployment to your device of choice.  They even allow you to publish free applications to the Android app market!  Be on the look out for  a follow up article dedicated 100% to dot42 very soon!)

      I think MonoDroid is a great product and it is certainly a much more mature product that dot42.  I will be sure to write a follow up to this article once I've tested the product.

      What about you?  Anyone out there want to speak out about their problems with the android emulator?  Does anyone else wish that MonoDroid would allow us to test the product on our own devices?  Please feel free to comment and let us know what you think!

      Happy Coding!

      kick it on DotNetKicks.com



      Comments (10) -

      Bragi
      Bragi
      1/20/2013 3:18:42 AM #

      Yes, I've also had varying experiences with the emulator. I prefer working on the device itself cause it gives better results, but it can be clumsy sometimes, always switching between dev-machine and phone to do a single key-press.

      Buddy James
      Buddy James
      1/20/2013 1:59:53 PM #

      I can totally relate.  As tedious as the whole process of testing on a device is, I still find it  a better option than trying to use the emulator.  I can't understand why the emulators perform so poorly (when they work at all).  Thanks for reading!

      sam
      sam
      1/21/2013 9:48:18 AM #

      mono app will have initialization time , I comes to conclusion that if you want to do android app for commercial use just use Java . it is a good long run solution .

      Buddy James
      Buddy James
      1/21/2013 2:30:03 PM #

      @sam Thanks for your input!  I agree that native development takes some of the steps out of the way.

      I personally love C#.  Even more so, I'm deeply in love with Visual Studio.  It's such a great IDE.  Once you are spoiled with Visual Studio, it's hard to switch to something like Eclipse.

      Maybe someone will develop a solution that integrates native Java development with Visual Studio.  That would be a most attractive option!

      Thanks again for your thoughts on the subject.

      Roger Heim
      Roger Heim
      2/5/2013 2:23:38 PM #

      @Buddy Try IntelliJ for Android dev (especially if you use R# in Visual Studio.) The free community edition has everything you need for Android dev (commercial too.)

      Buddy James
      Buddy James
      2/5/2013 7:31:16 PM #

      @Roger, Thank you for reading!  I looked at the IntelliJ website and I must say, it looks like a very nice product.  My only issue is that although I can write Java, I'm a .NET developer at heart.  At the same time, the fact that this product has an Android UI designer has me considering giving it a shot!  If the free IDE allows for deploying to my phone (and not the crummy emulator!), then this just might be the IDE that I use on the occasions in which I do choose Java as my weapon of choice.  Thanks again for the comment and the great suggestion!

      Buddy James

      Frank Rem
      Frank Rem
      2/17/2013 3:28:58 AM #

      @Sam Regarding the initialization, this is not a consequence of the language but of the extra runtime. Note that dot42 compiles c# to Dex (dalvik executable code) just like Eclipse compiles your Java to Dex. There is no runtime penalty when developing your app with dot42.

      Admin
      Admin
      2/17/2013 4:45:16 AM #

      @Frank Thanks for the extra info!  I've written a new, more detailed post on dot42 www.refactorthis.net/.../dot42-Android-development-with-C-All-the-best-parts-with-less-restrictions!.aspx

      Read, comment..

      Thanks for reading!!

      Buddy

      Marco
      Marco
      3/21/2013 12:38:20 PM #

      I tried dot42....i dont like....
      It s like developing in java for android and it has not a ide :'(
      Though i dont like eclipse coz i ve been using for many years visual studio, i started to develop in java on eclipse....tired of trying new products or alternatives...i tried also phonegap, i wanted to die

      Buddy James
      Buddy James
      3/21/2013 5:41:49 PM #

      I'm sorry to hear that.

      Have you tried Mono for Android?

      Thanks for reading!

      Buddy James

      Pingbacks and trackbacks (2)+

      Add comment

        Country flag


      • Comment
      • Preview
      Loading

      About the author

      My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

      Related links

      Month List

      refactorthis.net | How to keep your WPF UI responsive and report progress during a long running task. C# and asynchronous multithreading.
      Infragistics JQuery controls

      How to keep your WPF UI responsive and report progress during a long running task. C# and asynchronous multithreading.

      WPF Succinctly Download

       

       

      The problem

      Have you ever had to execute a bit of code that took an extremely long time to complete?  If so, I'm sure you've noticed that your user interface becomes unresponsive.  You can't use any controls on the form until the process completes.  This is extremely problematic and makes for a poor user experience.

      The cause

      This problem is because you have executed a synchronous block of code on the same thread as the user interface.  The user interface will not be able to respond to any user action until the synchronous method has completed.

      Let's look at an example that illustrates the execution of a synchronous method executing on the user interface thread.

      The example

       

      This example is very simple.  It's a WPF application with two buttons.  

      One of the buttons will start a long running for loop and the other button opens a MessageBox and

      displays a message to let you know that the UI is active.

      When you click the button to start the long running process, try to click the other button.  

      You will notice that you are unable to click the button to show the message box.

       

      Here's the MainWindow.xaml markup

      <Window x:Class="SynchronousExecution.MainWindow"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              Title="MainWindow" Height="350" Width="525">
          <Grid Width="111" Height="118">
              <Button Content="Start Process" Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="btnStartProcess" VerticalAlignment="Top" Width="89" Click="btnStartProcess_Click" />
              <Button Content="Try to click me" Height="23" HorizontalAlignment="Left" Margin="10,43,0,0" Name="btnTryMe" VerticalAlignment="Top" Width="89" Click="btnTryMe_Click" />
          </Grid>
      </Window>

       

      And here is the code behind MainWindow.xaml.cs

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Data;
      using System.Windows.Documents;
      using System.Windows.Input;
      using System.Windows.Media;
      using System.Windows.Media.Imaging;
      using System.Windows.Navigation;
      using System.Windows.Shapes;
      using System.Threading;
      
      namespace SynchronousExecution
      {
          /// <summary>
          /// Interaction logic for MainWindow.xaml
          /// </summary>
          public partial class MainWindow : Window
          {
              public MainWindow()
              {
                  InitializeComponent();
              }
      
              private void btnStartProcess_Click(object sender, RoutedEventArgs e)
              {
                  MessageBox.Show("Starting the long process.  Try to click the button below.");
                  for (var loopCounter = 0; loopCounter < 500; loopCounter++)
                  {
                      Thread.Sleep(100);
                  }
                  MessageBox.Show("The process has ended.");
              }
      
              private void btnTryMe_Click(object sender, RoutedEventArgs e)
              {
                  MessageBox.Show("User interface is responding!");
              }
          }
      }

      Download  SynchronousExecution.zip (52.38 kb)

      The solution

      The solution to this problem is to spawn a new thread to execute the long running task.  By placing the execution on a seperate thread, this leaves the main UI thread free to interact with the user's input.

      Reporting progress 

      If you execute a long running task, you usually want to let your users know about the progress of the task.  A control to assist with this is the progressbar control.  

      The WPF progress bar control inherits from the RangeBase class.  The control contains the following properties to control how the progress is displayed to the user.

      Minimum The minimum value of the Value property.
      Maximum The maximum value of the Value property.
      SmallChange The value in which the Value property is incremented.
      Value The current value position between the Minimum and Maximum property.

      Multithreading concerns

      Multithreading is a complex topic and is beyond the scope of this article.  However, there are a few concerns that you must be aware of if you plan to access values on the UI thread from the worker thread.

      The System.Windows.Threading.Dispatcher object is used to execute code on the UI thread from the executing worker thread.  The Dispatcher object has the BeginInvoke method which will execute an asynchronous delegate on the thread in which the dispatcher object was created.  So by using the dispatcher object from the user interface code you are able to access the user interface controls from your worker thread.

      We'll take a look at another example that will bring all of these concepts together to illustrate executing a long running task on a seperate thread with a progress bar that updates the user interface via the Dispatcher object.

      The example

      The example is a WPF application.  The main window contains the following controls;

      lstRandomValues A ListBox control that will hold random values that are generated during the long running process. The pupose of this control is to illustrate the responsiveness of the user interface during the long running process.
      prgProgress A ProgressBar control that will illustrate the progress of the long running task. The ProgressBar is hidden by default. It's shown when the long running process begins and is hidden again when the process has ended or is canceled.
      txtProgress A TextBox control that displays the long running process percentage of completion.
      btnCancel A Button control that will cancel the long running process and in turn hide the progress bar and progress textbox.
      btnInteract A Button control that will launch a MessageBox to illustrate the responsiveness of the UI while the long running process is executing.
      btnBegin A Button control that will begin the long running process.

      And here is the code 

      Window1.xaml

      <Window x:Class="RandomNameSpace.ViewModels.Window1"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          Title="Window1" Height="400" Width="400">    
              <!-- Parent Grid -->
              <Grid>
                  <Grid.RowDefinitions>
                      <RowDefinition />
                      <RowDefinition />
                  </Grid.RowDefinitions>
                  <Grid.ColumnDefinitions>
                      <ColumnDefinition />
                      <ColumnDefinition />
                  </Grid.ColumnDefinitions>
                  <ListBox Grid.Row="0" Grid.Column="0" Name="lstRandomValues" Grid.ColumnSpan="2" />
              
                  <Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
                      <Grid.RowDefinitions>
                          <RowDefinition />
                          <RowDefinition />
                      </Grid.RowDefinitions>
                      <Grid.ColumnDefinitions>
                          <ColumnDefinition />
                          <ColumnDefinition />
                      </Grid.ColumnDefinitions>
                      
                      <Border Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" x:Name="bdrProgress" Visibility="Hidden" Background="Azure" CornerRadius="10" BorderBrush="DarkGray" BorderThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center">
                          <StackPanel>
                              <Grid Margin="5">
                                  <ProgressBar x:Name="prgProgress" Width="200" Height="20" Minimum="0" Maximum="1" />
                                  <TextBlock x:Name="txtProgress" HorizontalAlignment="Center" VerticalAlignment="Center" />
                              </Grid>
                              <Button x:Name="btnCancel" Content="Cancel" HorizontalAlignment="Right" Margin="3" Click="btnCancel_Click" />
                          </StackPanel>
                      </Border>
                      
                      <Button Grid.Row="1" Grid.Column="1" x:Name="btnInteract" HorizontalAlignment="Center"  Content="Interact with UI" Click="btnInteract_Click" Height="23.96" />
                      <Button Grid.Row="1" Grid.Column="0" x:Name="btnBegin" HorizontalAlignment="Left"  Content="Start Long Process" Click="btnBegin_Click"  Height="23.96" Margin="35,33.27,0,33.27" />
                  </Grid>
              </Grid>
      </Window>

      Window1.xaml.cs

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Data;
      using System.Windows.Documents;
      using System.Windows.Input;
      using System.Windows.Media;
      using System.Windows.Media.Imaging;
      using System.Windows.Navigation;
      using System.Windows.Shapes;
      using System.Threading;
      using System.Windows.Threading;
      
      
      namespace RandomNameSpace.ViewModels
      {
      	/// <summary>
      	/// Interaction logic for Window1.xaml
      	/// </summary>
      	public partial class Window1 : Window 
      	{
              private bool IsCanceled = false;
      
              private RandomViewModel _viewModel;
      
              public RandomViewModel ViewModel
              {
                  get { return _viewModel; }
                  set { _viewModel = value; }
              }
      
      		public Window1()
      		{
      			InitializeComponent();
                  PrepareViewModel();
      		}
      
              private void PrepareViewModel()
              {
                  ViewModel = new RandomViewModel();
      
                  this.lstRandomValues.DisplayMemberPath = "Value";
                  this.lstRandomValues.DataContext = ViewModel;
                  this.lstRandomValues.ItemsSource = ViewModel;
              }
      
      		private void btnBegin_Click(object sender, RoutedEventArgs e)
      		{
                  BeginProcess();
      		}
      
      		private void btnInteract_Click(object sender, RoutedEventArgs e)
      		{
                  MessageBox.Show("Interaction!");
      		}
      
      		private void btnCancel_Click(object sender, RoutedEventArgs e)
      		{
                  CancelProcess();
      		}
      
              public void BeginProcess()
              {
                  bdrProgress.Visibility = System.Windows.Visibility.Visible;
                  DisableBeginButton();
                  Action StartLoop;
                  StartLoop = () => DoLongRunningProcess();
      
                  Thread t;
      
                  t = new Thread(StartLoop.Invoke);
                  t.Start();
              }
      
              public void CancelProcess()
              {
                  this.IsCanceled = true;
                  Thread.Sleep(1500);
                  ClearListBox();
                  EnableBeginButton();
              }
      
              private void ClearListBox()
              {
                  Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.ViewModel.Clear(); }, null);
              }
      
              private void DoLongRunningProcess()
              {
                  for (var loopCounter = 0.0; loopCounter < 1.0; loopCounter = loopCounter + .1)
                  {
                      if (!IsCanceled)
                      {
                          //add a random number to the viewmodel collection to be bound to the listview
                          Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.ViewModel.AddValue(1564); }, null);
      
                          UpdateProgressBar(loopCounter);
                          Thread.Sleep(2000);
                      }
                      else
                      {
                          break;
                      }
                  }
      
                  IsCanceled = false;
      
                  ClearListBox();
      
                  MessageBox.Show("Completed");
      
                  EnableBeginButton();
                  HideProgressBar();
      
              }
      
              private void EnableBeginButton()
              {
                  Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.btnBegin.SetValue(Button.IsEnabledProperty, true); }, null);
              }
      
              private void DisableBeginButton()
              {
                  Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.btnBegin.SetValue(Button.IsEnabledProperty, false); }, null);
              }
      
              private void UpdateProgressBar(double value)
              {
                  Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.prgProgress.SetValue(ProgressBar.ValueProperty, value); }, null);
                  Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.txtProgress.SetValue(TextBlock.TextProperty, (value * 100).ToString()); }, null);
              }
      
              private void HideProgressBar()
              {
                  Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.bdrProgress.SetValue(Border.VisibilityProperty, Visibility.Collapsed); }, null);
              }
      	}
      }

       

      RandomValue.cs
      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Linq;
      using System.Text;
      
      namespace RandomNameSpace.ViewModels
      {
          public class RandomValue : INotifyPropertyChanged
          {
              private int _value;
      
              public int Value
              {
                  get
                  {
                      return _value;
                  }
                  set
                  {
                      if (_value != value)
                          _value = value;
      
                      OnPropertyChanged("Value");
                  }
              }
      
      
              public event PropertyChangedEventHandler PropertyChanged;
      
              public void OnPropertyChanged(string propertyName)
              {
                  var handler = PropertyChanged;
                  if (handler != null)
                  {
                      handler(this, new PropertyChangedEventArgs(propertyName));
                  }
              }
          }
      }

      RandomViewModel.cs

      using System;
      using System.Collections.Generic;
      using System.Collections.ObjectModel;
      using System.Linq;
      using System.Text;
      using System.Threading;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Threading;
      
      namespace RandomNameSpace.ViewModels
      {
          public class RandomViewModel : ObservableCollection<RandomValue>
          {
              public RandomViewModel() : base() {}
      
              public void AddValue(int value)
              {
                  Random rnd = new Random();
                  var calculatedValue = (value * rnd.Next(3000));
      
                  this.Add(new RandomValue { Value = (calculatedValue) });
              }
          }
      }

      Here is the entire solution for download. 

      WPFAsyncProgressBarMVVM.zip (77.39 kb)  

      This concludes the article.  Thank you for taking the time to read it!

      Until next time...

      ~/Buddy James

      kick it on DotNetKicks.com

       

       



      Pingbacks and trackbacks (1)+

      Add comment

        Country flag


      • Comment
      • Preview
      Loading

      About the author

      My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

      Related links

      Month List

      refactorthis.net | How to keep your WPF UI responsive and report progress during a long running task. C# and asynchronous multithreading.
      Infragistics WPF controls

      How to keep your WPF UI responsive and report progress during a long running task. C# and asynchronous multithreading.

      WPF Succinctly Download

       

       

      The problem

      Have you ever had to execute a bit of code that took an extremely long time to complete?  If so, I'm sure you've noticed that your user interface becomes unresponsive.  You can't use any controls on the form until the process completes.  This is extremely problematic and makes for a poor user experience.

      The cause

      This problem is because you have executed a synchronous block of code on the same thread as the user interface.  The user interface will not be able to respond to any user action until the synchronous method has completed.

      Let's look at an example that illustrates the execution of a synchronous method executing on the user interface thread.

      The example

       

      This example is very simple.  It's a WPF application with two buttons.  

      One of the buttons will start a long running for loop and the other button opens a MessageBox and

      displays a message to let you know that the UI is active.

      When you click the button to start the long running process, try to click the other button.  

      You will notice that you are unable to click the button to show the message box.

       

      Here's the MainWindow.xaml markup

      <Window x:Class="SynchronousExecution.MainWindow"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              Title="MainWindow" Height="350" Width="525">
          <Grid Width="111" Height="118">
              <Button Content="Start Process" Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="btnStartProcess" VerticalAlignment="Top" Width="89" Click="btnStartProcess_Click" />
              <Button Content="Try to click me" Height="23" HorizontalAlignment="Left" Margin="10,43,0,0" Name="btnTryMe" VerticalAlignment="Top" Width="89" Click="btnTryMe_Click" />
          </Grid>
      </Window>

       

      And here is the code behind MainWindow.xaml.cs

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Data;
      using System.Windows.Documents;
      using System.Windows.Input;
      using System.Windows.Media;
      using System.Windows.Media.Imaging;
      using System.Windows.Navigation;
      using System.Windows.Shapes;
      using System.Threading;
      
      namespace SynchronousExecution
      {
          /// <summary>
          /// Interaction logic for MainWindow.xaml
          /// </summary>
          public partial class MainWindow : Window
          {
              public MainWindow()
              {
                  InitializeComponent();
              }
      
              private void btnStartProcess_Click(object sender, RoutedEventArgs e)
              {
                  MessageBox.Show("Starting the long process.  Try to click the button below.");
                  for (var loopCounter = 0; loopCounter < 500; loopCounter++)
                  {
                      Thread.Sleep(100);
                  }
                  MessageBox.Show("The process has ended.");
              }
      
              private void btnTryMe_Click(object sender, RoutedEventArgs e)
              {
                  MessageBox.Show("User interface is responding!");
              }
          }
      }

      Download  SynchronousExecution.zip (52.38 kb)

      The solution

      The solution to this problem is to spawn a new thread to execute the long running task.  By placing the execution on a seperate thread, this leaves the main UI thread free to interact with the user's input.

      Reporting progress 

      If you execute a long running task, you usually want to let your users know about the progress of the task.  A control to assist with this is the progressbar control.  

      The WPF progress bar control inherits from the RangeBase class.  The control contains the following properties to control how the progress is displayed to the user.

      Minimum The minimum value of the Value property.
      Maximum The maximum value of the Value property.
      SmallChange The value in which the Value property is incremented.
      Value The current value position between the Minimum and Maximum property.

      Multithreading concerns

      Multithreading is a complex topic and is beyond the scope of this article.  However, there are a few concerns that you must be aware of if you plan to access values on the UI thread from the worker thread.

      The System.Windows.Threading.Dispatcher object is used to execute code on the UI thread from the executing worker thread.  The Dispatcher object has the BeginInvoke method which will execute an asynchronous delegate on the thread in which the dispatcher object was created.  So by using the dispatcher object from the user interface code you are able to access the user interface controls from your worker thread.

      We'll take a look at another example that will bring all of these concepts together to illustrate executing a long running task on a seperate thread with a progress bar that updates the user interface via the Dispatcher object.

      The example

      The example is a WPF application.  The main window contains the following controls;

      lstRandomValues A ListBox control that will hold random values that are generated during the long running process. The pupose of this control is to illustrate the responsiveness of the user interface during the long running process.
      prgProgress A ProgressBar control that will illustrate the progress of the long running task. The ProgressBar is hidden by default. It's shown when the long running process begins and is hidden again when the process has ended or is canceled.
      txtProgress A TextBox control that displays the long running process percentage of completion.
      btnCancel A Button control that will cancel the long running process and in turn hide the progress bar and progress textbox.
      btnInteract A Button control that will launch a MessageBox to illustrate the responsiveness of the UI while the long running process is executing.
      btnBegin A Button control that will begin the long running process.

      And here is the code 

      Window1.xaml

      <Window x:Class="RandomNameSpace.ViewModels.Window1"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          Title="Window1" Height="400" Width="400">    
              <!-- Parent Grid -->
              <Grid>
                  <Grid.RowDefinitions>
                      <RowDefinition />
                      <RowDefinition />
                  </Grid.RowDefinitions>
                  <Grid.ColumnDefinitions>
                      <ColumnDefinition />
                      <ColumnDefinition />
                  </Grid.ColumnDefinitions>
                  <ListBox Grid.Row="0" Grid.Column="0" Name="lstRandomValues" Grid.ColumnSpan="2" />
              
                  <Grid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
                      <Grid.RowDefinitions>
                          <RowDefinition />
                          <RowDefinition />
                      </Grid.RowDefinitions>
                      <Grid.ColumnDefinitions>
                          <ColumnDefinition />
                          <ColumnDefinition />
                      </Grid.ColumnDefinitions>
                      
                      <Border Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" x:Name="bdrProgress" Visibility="Hidden" Background="Azure" CornerRadius="10" BorderBrush="DarkGray" BorderThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center">
                          <StackPanel>
                              <Grid Margin="5">
                                  <ProgressBar x:Name="prgProgress" Width="200" Height="20" Minimum="0" Maximum="1" />
                                  <TextBlock x:Name="txtProgress" HorizontalAlignment="Center" VerticalAlignment="Center" />
                              </Grid>
                              <Button x:Name="btnCancel" Content="Cancel" HorizontalAlignment="Right" Margin="3" Click="btnCancel_Click" />
                          </StackPanel>
                      </Border>
                      
                      <Button Grid.Row="1" Grid.Column="1" x:Name="btnInteract" HorizontalAlignment="Center"  Content="Interact with UI" Click="btnInteract_Click" Height="23.96" />
                      <Button Grid.Row="1" Grid.Column="0" x:Name="btnBegin" HorizontalAlignment="Left"  Content="Start Long Process" Click="btnBegin_Click"  Height="23.96" Margin="35,33.27,0,33.27" />
                  </Grid>
              </Grid>
      </Window>

      Window1.xaml.cs

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Data;
      using System.Windows.Documents;
      using System.Windows.Input;
      using System.Windows.Media;
      using System.Windows.Media.Imaging;
      using System.Windows.Navigation;
      using System.Windows.Shapes;
      using System.Threading;
      using System.Windows.Threading;
      
      
      namespace RandomNameSpace.ViewModels
      {
      	/// <summary>
      	/// Interaction logic for Window1.xaml
      	/// </summary>
      	public partial class Window1 : Window 
      	{
              private bool IsCanceled = false;
      
              private RandomViewModel _viewModel;
      
              public RandomViewModel ViewModel
              {
                  get { return _viewModel; }
                  set { _viewModel = value; }
              }
      
      		public Window1()
      		{
      			InitializeComponent();
                  PrepareViewModel();
      		}
      
              private void PrepareViewModel()
              {
                  ViewModel = new RandomViewModel();
      
                  this.lstRandomValues.DisplayMemberPath = "Value";
                  this.lstRandomValues.DataContext = ViewModel;
                  this.lstRandomValues.ItemsSource = ViewModel;
              }
      
      		private void btnBegin_Click(object sender, RoutedEventArgs e)
      		{
                  BeginProcess();
      		}
      
      		private void btnInteract_Click(object sender, RoutedEventArgs e)
      		{
                  MessageBox.Show("Interaction!");
      		}
      
      		private void btnCancel_Click(object sender, RoutedEventArgs e)
      		{
                  CancelProcess();
      		}
      
              public void BeginProcess()
              {
                  bdrProgress.Visibility = System.Windows.Visibility.Visible;
                  DisableBeginButton();
                  Action StartLoop;
                  StartLoop = () => DoLongRunningProcess();
      
                  Thread t;
      
                  t = new Thread(StartLoop.Invoke);
                  t.Start();
              }
      
              public void CancelProcess()
              {
                  this.IsCanceled = true;
                  Thread.Sleep(1500);
                  ClearListBox();
                  EnableBeginButton();
              }
      
              private void ClearListBox()
              {
                  Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.ViewModel.Clear(); }, null);
              }
      
              private void DoLongRunningProcess()
              {
                  for (var loopCounter = 0.0; loopCounter < 1.0; loopCounter = loopCounter + .1)
                  {
                      if (!IsCanceled)
                      {
                          //add a random number to the viewmodel collection to be bound to the listview
                          Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.ViewModel.AddValue(1564); }, null);
      
                          UpdateProgressBar(loopCounter);
                          Thread.Sleep(2000);
                      }
                      else
                      {
                          break;
                      }
                  }
      
                  IsCanceled = false;
      
                  ClearListBox();
      
                  MessageBox.Show("Completed");
      
                  EnableBeginButton();
                  HideProgressBar();
      
              }
      
              private void EnableBeginButton()
              {
                  Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.btnBegin.SetValue(Button.IsEnabledProperty, true); }, null);
              }
      
              private void DisableBeginButton()
              {
                  Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.btnBegin.SetValue(Button.IsEnabledProperty, false); }, null);
              }
      
              private void UpdateProgressBar(double value)
              {
                  Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.prgProgress.SetValue(ProgressBar.ValueProperty, value); }, null);
                  Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.txtProgress.SetValue(TextBlock.TextProperty, (value * 100).ToString()); }, null);
              }
      
              private void HideProgressBar()
              {
                  Dispatcher.BeginInvoke(DispatcherPriority.Background, (SendOrPostCallback)delegate { this.bdrProgress.SetValue(Border.VisibilityProperty, Visibility.Collapsed); }, null);
              }
      	}
      }

       

      RandomValue.cs
      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Linq;
      using System.Text;
      
      namespace RandomNameSpace.ViewModels
      {
          public class RandomValue : INotifyPropertyChanged
          {
              private int _value;
      
              public int Value
              {
                  get
                  {
                      return _value;
                  }
                  set
                  {
                      if (_value != value)
                          _value = value;
      
                      OnPropertyChanged("Value");
                  }
              }
      
      
              public event PropertyChangedEventHandler PropertyChanged;
      
              public void OnPropertyChanged(string propertyName)
              {
                  var handler = PropertyChanged;
                  if (handler != null)
                  {
                      handler(this, new PropertyChangedEventArgs(propertyName));
                  }
              }
          }
      }

      RandomViewModel.cs

      using System;
      using System.Collections.Generic;
      using System.Collections.ObjectModel;
      using System.Linq;
      using System.Text;
      using System.Threading;
      using System.Windows;
      using System.Windows.Controls;
      using System.Windows.Threading;
      
      namespace RandomNameSpace.ViewModels
      {
          public class RandomViewModel : ObservableCollection<RandomValue>
          {
              public RandomViewModel() : base() {}
      
              public void AddValue(int value)
              {
                  Random rnd = new Random();
                  var calculatedValue = (value * rnd.Next(3000));
      
                  this.Add(new RandomValue { Value = (calculatedValue) });
              }
          }
      }

      Here is the entire solution for download. 

      WPFAsyncProgressBarMVVM.zip (77.39 kb)  

      This concludes the article.  Thank you for taking the time to read it!

      Until next time...

      ~/Buddy James

      kick it on DotNetKicks.com

       

       



      Pingbacks and trackbacks (1)+

      Add comment

        Country flag


      • Comment
      • Preview
      Loading

      About the author

      My name is Buddy James.  I'm a Microsoft Certified Solutions Developer from the Nashville, TN area.  I'm a Software Engineer, an author, a blogger (http://www.refactorthis.net), a mentor, a thought leader, a technologist, a data scientist, and a husband.  I enjoy working with design patterns, data mining, c#, WPF, Silverlight, WinRT, XAML, ASP.NET, python, CouchDB, RavenDB, Hadoop, Android(MonoDroid), iOS (MonoTouch), and Machine Learning. I love technology and I love to develop software, collect data, analyze the data, and learn from the data.  When I'm not coding,  I'm determined to make a difference in the world by using data and machine learning techniques. (follow me at @budbjames).  

      Related links

      Month List