2

I am developing a dot net core 1.1 app in which I am trying to use Accord.Net. According to examples in this page (Naive Bayes) I need to convert data retrieved from DB to DataTable.

The thing is that while using DataTable I got this error:

The type 'DataTable' exists in both 'Shim, ...' and 'System.Data.Common, ...'

Even if I use this:

DataTable learningDataNotCodifiedAsDataTable = new DataTable();

or this:

System.Data.DataTable learningDataNotCodifiedAsDataTable = new System.Data.DataTable();

TG.

ConductedClever
  • 4,175
  • 2
  • 35
  • 69
  • You don't actually need to convert the data retrieved from the DB to a data table. What you really need to is to convert the data to a double[][] or int[][] array which you can then pass to the .Learn method of NaiveBayesLearning. Please check the second example in the page you linked, in case it helps! – Cesar Aug 17 '17 at 17:29

2 Answers2

1

If you have System.Data assembly in Assemblies and don't want or can't delete it, then you can bypass it by using extern alias, but when I bypassed this error using it I got 'DataTable' does not contain a constructor that takes 0/1 arguments error, and if believe this discussion the reason is:

System.Data.DataTable is present in .Net core(1.0,1.1) as an empty class to complete the interfaces implementation. This issue is to track the work needed to bring in an API to provide DataTable like API in .Net Core.

And it changed only in .NET Core 2.0, see this SO post. I tried you code in .NET Core 2.0 project (in VS 2017 15.3) and only then it worked fine.

UPDATE: I meant this assemblies.

enter image description here

But as you say you have only NUGET packages, then you also can use aliases in you csproj file for Nuget packages like below(I used System.Data.Common you can replace it with your Shim package if needed) :

 <Target Name="DataAlias" BeforeTargets="FindReferenceAssembliesForReferences;ResolveReferences">
    <ItemGroup>
      <ReferencePath Condition="'%(FileName)' == 'System.Data.Common'">
        <Aliases>MyData</Aliases>
      </ReferencePath>
    </ItemGroup>
  </Target>

and then reference it in C# like this:

extern alias MyData; //1st line in .cs file
...
using MyData::System.Data;
...
DataTable datatable = new DataTable();

But still you won't be able to use because you will get the error about constructor I wrote above. Here you has 2 options how to solve this:

  1. Switch to .NET Core 2.0
  2. Try to use workaround solution from this post using DbDataReader if it suits you
user2771704
  • 5,994
  • 6
  • 37
  • 38
  • What do you mean by 'If you have System.Data assembly in Assemblies'? Neither in NuGet packages nor in SDK packages I don't have even System package. Is there another place to search? After that, you mean that in dot net core 1.1 there are no solutions? – ConductedClever Aug 17 '17 at 10:19
  • @ConductedClever Please check updated answer. Yes, unfortunately there is no solution, just like were several posts about DbSet and .NET Core here and on GitHub. And there were also just 2 options: 1) Wait .NET Core 2.0; 2) Write your own implementation (sounded almost like a joke) – user2771704 Aug 17 '17 at 11:33
  • I am very happy to hear .net core 2.0 is in final version but by now I am trying to keep the dot net core version to keep the costs low. As soon as the other solutions ended up, I will mark your answer as accepted. Thanks. – ConductedClever Aug 17 '17 at 18:57
1

While the DataTable is not available in .NET Core 1.1, it is now available in .NET Core 2.0. If you can upgrade your project to .NET Core 2.0, then you will be able to use it in your code.

However, if you cannot switch to .NET Core 2.0 right now, then please note that you are not required to use DataTables with any of the methods in Accord.NET framework. They are given or shown just because they can give some extra convenience, but they are not really required, as shown in the example below:

string[] columnNames = { "Outlook", "Temperature", "Humidity", "Wind", "PlayTennis" };

string[][] data =
{
    new string[] { "Sunny", "Hot", "High", "Weak", "No" },
    new string[] { "Sunny", "Hot", "High", "Strong", "No" },
    new string[] { "Overcast", "Hot", "High", "Weak", "Yes" },
    new string[] { "Rain", "Mild", "High", "Weak", "Yes" },
    new string[] { "Rain", "Cool", "Normal", "Weak", "Yes" },
    new string[] { "Rain", "Cool", "Normal", "Strong", "No" },
    new string[] { "Overcast", "Cool", "Normal", "Strong", "Yes" },
    new string[] { "Sunny", "Mild", "High", "Weak", "No" },
    new string[] { "Sunny", "Cool", "Normal", "Weak", "Yes" },
    new string[] {  "Rain", "Mild", "Normal", "Weak", "Yes" },
    new string[] {  "Sunny", "Mild", "Normal", "Strong", "Yes" },
    new string[] {  "Overcast", "Mild", "High", "Strong", "Yes" },
    new string[] {  "Overcast", "Hot", "Normal", "Weak", "Yes" },
    new string[] {  "Rain", "Mild", "High", "Strong", "No" },
};

// Create a new codification codebook to
// convert strings into discrete symbols
Codification codebook = new Codification(columnNames, data);

// Extract input and output pairs to train
int[][] symbols = codebook.Transform(data);
int[][] inputs = symbols.Get(null, 0, -1); // Gets all rows, from 0 to the last (but not the last)
int[] outputs = symbols.GetColumn(-1);     // Gets only the last column

// Create a new Naive Bayes learning
var learner = new NaiveBayesLearning();

NaiveBayes nb = learner.Learn(inputs, outputs);

// Consider we would like to know whether one should play tennis at a
// sunny, cool, humid and windy day. Let us first encode this instance
int[] instance = codebook.Translate("Sunny", "Cool", "High", "Strong");

// Let us obtain the numeric output that represents the answer
int c = nb.Decide(instance); // answer will be 0

// Now let us convert the numeric output to an actual "Yes" or "No" answer
string result = codebook.Translate("PlayTennis", c); // answer will be "No"

// We can also extract the probabilities for each possible answer
double[] probs = nb.Probabilities(instance); // { 0.795, 0.205 }
Cesar
  • 2,059
  • 25
  • 30
  • you are right about `DataTable` not be necessary but after I totally builded the project, the problem expanded. Now `Directory`, `File`, and `Process` are common between `shim` and `System.IO.FileSystem` and `System.Diagnostics.Process`. Any further solutions for these three and any similar? – ConductedClever Aug 17 '17 at 18:54
  • Since you are having errors with Shim, my guess is that you are using the "Portable Accord.NET" version from NuGet. If you have updated to Net Core 2.0, you can use the official Accord.NET libraries from NuGet instead. – Cesar Aug 17 '17 at 19:03
  • Ok, I've just seen you cannot upgrade right now. Please try to install the latest pre-release package of Accord.NET currently on NuGet - I am almost sure that version should work with NET Core 1.1. – Cesar Aug 17 '17 at 19:05
  • @ConductedClever You can use *extern alias* to choose which library to use for `Directory`,`File` and `Process`. See Update in my answer for reference, just replace `System.Data.Common` with namespace you need both in `csproj` and `cs` files. – user2771704 Aug 17 '17 at 19:07
  • @Cesar I have added the 3.1.0-pre (current version) but the problem stays. You know, in a simple example of using portable.accord we don't need `Directory`, `File`, and `Process` but in mine I need them. I think this is a special situation from your tests. – ConductedClever Aug 17 '17 at 19:18
  • @user2771704 I will try the way you mentioned and inform you. Thanks. – ConductedClever Aug 17 '17 at 19:19
  • The latest version is 3.6.4-alpha: https://www.nuget.org/packages/Accord.MachineLearning/3.6.4-alpha, as I mentioned, this version should be compatible with .NET Core 1.1 (.NET Standard 1.4) – Cesar Aug 17 '17 at 19:20
  • Sorry, I should have added: But it might not have all the features, such as for example support for DataTable and Bitmaps. – Cesar Aug 17 '17 at 19:24
  • 1
    @Cesar I was checking the pre-releases of portable.accord! You are completely right. Thank you for great Accord and greater support. – ConductedClever Aug 17 '17 at 19:28
  • Thanks! Being a pre-release, this version might still have some issues to be ironed out. If you find something, please register at the project's issue tracker! https://github.com/accord-net/framework/issues – Cesar Aug 17 '17 at 19:33