How to use LinearSvm? - ml.net

Currently I'm using FastTree for binary classification, but I would like to give SVM a try and compare metrics.
All the docs mention LinearSvm, but I can't find code example anywhere.
mlContext.BinaryClassification.Trainers does not have public SVM trainers. There is LinearSvm class and LinearSvm.TrainLinearSvm static method, but they seem to be intended for different things.
What am I missing?
Version: 0.7

For some reason there is no trainer in the runtime API but there is a linear SVM trainer in the Legacy API (for v0.7) found here. They might be generating a new one for the upcoming API, so my advice is to either use the legacy one, or wait for a newer API.
At this stage, ML.Net is very much in development.

Copy pasting the response I got on Github:
I have two answers for you: What the status of the API is, and how to use the LinearSVM in the meantime.
First, we have LinearSVM in the ML.NET codebase, but we do not yet have samples or the API extensions to place it in mlContext.BinaryClassification.Trainers. This is being worked through in issue #1318. I'll link this to that issue, and mark it as a bug.
In the meantime, you can use direct instantiation to get access to LinearSVM:
var arguments = new LinearSvm.Arguments()
{
NumIterations = 20
};
var linearSvm = new LinearSvm(mlContext, arguments);
var svmTransformer = linearSvm.Fit(trainSet);
var scoredTest = svmTransformer.Transform(testSet);
This will give you an ITransformer, here called svmTransformer that you can use to operate on IDataView objects.

Related

Reverse engineering the checksum algorithm

I have an IP camera that receives commands using POST HTTP requests(for example to call PTZ commands or set various camera settings). The standard way of controlling it is through it's own web interface which is partially an ActiveX plugin and partially standard html+js. Of course because of the ActiveX part it only works in IE under Windows.
I'm attempting to change that by figuring out all the commands and writing a small python or javascript code to do the same, so that it is more cross platform.
I have one major problem. Each POST request contains a calculated "cc" field which I assume is a checksum. The JS code in the cam interface points out that it is calculated by calling a function inside the plugin:
tt = new Date().Format("yyyyMMddhhmmss");
jo_header["tt"] = tt;
if (getCpPlugin() != null && getCpPlugin().valid) {
jo_header["cc"] = getCpPlugin().nsstpGetCC(tt, session_id);
}
nsstpGetCC function obviously calculates the checksum from two parameters the timestamp and session_id. Real example(captured with Wireshark):
tt = "20171018231918"
session_id = "30303532646561302D623434612D3131"
cc = "849e586524385e1071caa4023a3df75401e5bb82"
Checksum seems to be 160bit. I tried both sha-1 and ripemd-160 and all combinations of concatenating tt and session_id I could think of. But I can't seem to get the same hash as the one the original plugin gets. The plugin dll seems to be written in c++. And I have almost no experience with decompilation to dive into this problem from that angle.
So my question basically is can someone figure out how they calculated that cc, or at least give me an idea in which direction to research further. Maybe I'm looking at wrong hash algorithms or something... Or give me some idea how I could somehow figure out what the original ActiveX function nsstpGetCC is doing for example by decompilation or maybe by monitoring it's operation in memory while running. What tools should I use?

AWS and Changes in Swift 3

After the Swift 3 update, I'm having some trouble getting my app to compile. Most of the errors are pretty simple to fix, but I'm running into a few in particular with AWS. Is there some sort of updated AWS SDK for Swift 3? I've tried to look it up, but haven't found one. In any case, the two main errors I'm having trouble resolving are as follows:
"Type 'IdentityProviderManager' does not conform to protocol AWSIdentityProviderManager." This is for a class I created following a tutorial to set up logins through AWS Cognito. The code is:
class IdentityProviderManager: NSObject, AWSIdentityProviderManager{
var tokens : [NSString : NSString]?
init(tokens: [NSString : NSString]) {
self.tokens = tokens
}
#objc func logins() -> AWSTask<AnyObject> {
return AWSTask(result: tokens as AnyObject)
}
}
In the AWS documentation for AWSIdentityProviderManager, it says that the only required function is logins, which I have. Is there a simple way to resolve this that I'm missing?
The other error is in my LoginViewController class: "Type 'LoginViewController' does not conform to protocol 'AWSCognitoIdentityPasswordAuthentication'." Here the issue seems a bit more clear, since the documentation says that getPasswordAuthenticationDetails() is a required method and XCode seems to have changed this method to getDetails() when updating to Swift 3, unless I'm mistaken and it wasn't there to begin with or something. In any case, autocomplete doesn't give me the original method and I can't seem to make the class conform to the protocol.
Apologies if the answer is already in documentation somewhere, but as far as I can tell it seems like the AWS SDK (at least the version that I have) is somehow incompatible with Swift 3. Is there something I can do to resolve these errors?
Nevermind, it turned out XCode just wasn't showing me the option to make the changes I needed. The automatic fix implemented slightly different versions of the required functions and everything ended up working.

Sitecore: Glass Mapper Code First

It is possible to automatically generate Sitecore templates just coding models? I'm using Sitecore 8.0 and I saw Glass Mapper Code First approach but I cant find more information about that.
Not sure why there isn't much info about it, but you can definitely model/code first!. I do it alot using the attribute configuration approach like so:
[SitecoreType(true, "{generated guid}")]
public class ExampleModel
{
[SitecoreField("{generated guid}", SitecoreFieldType.SingleLineText)]
public virtual string Title { get; set; }
}
Now how this works. The SitecoreType 'true' value for the first parameter indicates it may be used for codefirst. There is a GlassCodeFirstDataprovider which has an Initialize method, executed in Sitecore's Initialize pipeline. This method will collect all configurations marked for codefirst and create it in the sql dataprovider. The sections and fields are stored in memory. It also takes inheritance into account (base templates).
I think you first need to uncomment some code in the GlassMapperScCustom class you get when you install the project via Nuget. The PostLoad method contains the few lines that execute the Initialize method of each CodeFirstDataprovider.
var dbs = global::Sitecore.Configuration.Factory.GetDatabases();
foreach (var db in dbs)
{
var provider = db.GetDataProviders().FirstOrDefault(x => x is GlassDataProvider) as GlassDataProvider;
if (provider != null)
{
using (new SecurityDisabler())
{
provider.Initialise(db);
}
}
}
Furthermore I would advise to use code first on development only. You can create packages or serialize the templates as usual and deploy them to other environment so you dont need the dataprovider (and potential risks) there.
You can. But it's not going to be Glass related.
Code first is exactly what Sitecore.PathFinder is looking to achieve. There's not a lot of info publicly available on this yet however.
Get started here: https://github.com/JakobChristensen/Sitecore.Pathfinder

Enumerate Upgrade Codes of installed products?

I'd like to get list of all Upgrade codes of all installed products on Windows box. The question is: is there a dedicated MSI function to address this request?
There is MsiEnumProducts() that enumerates all installed products and MsiEnumRelatedProducts() to enumerate all products for the given Upgrade code. But I can't find a function to get all Upgrade codes in the system.
The workaround I can imagine is use MsiEnumProducts() to get list of all installed products, open each with MsiOpenProduct() function and read "UpgradeCode" property with MsiGetProductProperty(). But this should be very slow due to multiple MsiOpenProduct() calls.
I believe MsiEnumProducts loop with MsiOpenProduct and then MsiGetProductProperty is the correct official sequence. If you really need faster and are willing to bypass the API's you could read the registry directly at HKCR\Installer\UpgradeCodes. You'll have to reverse the Darwin Descriptors though. This isn't technically supported but the reality is these keys have been there for 16 years and MSFT has been doing ZERO development on The Windows Installer. Ok, maybe they updated the version number and removed ARM support in Windows 10 LOL.
FWIW, I like to use C# not C++ but the concept is the same. The following snippet ran on my developer machine in about 2 seconds.
using System;
using Microsoft.Deployment.WindowsInstaller;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
foreach (var productInstallation in ProductInstallation.AllProducts)
{
using(var database = new Database(productInstallation.LocalPackage, DatabaseOpenMode.ReadOnly))
{
Console.WriteLine(database.ExecutePropertyQuery("UpgradeCode"));
}
}
}
}
}
According to the DTF documentation, ProductInstallation.AllProducts uses MsiEnumProducts. The Database class constructor is using MsiOpenDatabase and ExecutePropertyQuery is a higher level call that basically abstracts doing a SELECT Value from Property WHERE Property = '%s'. So it'll be calling APIs to create, execute and fetch results from views. All these classes implement IDisposable to call the correct APIs to free resources also.
Ya... that's why I love managed code. :)

Sitecore Glass Mapper always null

I am using Sitecore Glass Mapper for a new project I'm setting up.
We are using Sitecore 7.2, latest version of Team Development for Sitecore (TDS) code generation and the latest version of glass.
The code I am trying to execute:
var b = new SitecoreContext();
var c = b.GetCurrentItem<T01_Homepage>();
b is not null. c is null.
var d = b.GetItem<T01_Homepage>("path")
d is null.
I added my assembly in GlassMapperScCustom:
public static IConfigurationLoader[] GlassLoaders(){
var attributes = new AttributeConfigurationLoader(new[] { "Company.Framework.Websites.Corporate", "Company.Framework.Core", "Company.Framework.Common" });
return new IConfigurationLoader[] { attributes };
}
When I look into b.GlassContext.TypeConfigurations all my models are there.
I figured it could be a language issue because the site is in dutch and maybe the wrong language would be resolved incorrectly. This was also not the case.
I disabled WebActivator and added the GlassMapperSc.Start() in my Global.asax Application_Start method.
We are also using Autofac as DI framework. But without it, it still isn't working as you can see above. Also when I create my own custom models without TDS code generation the result of GetCurrentItem<T> is null.
Does anyone have an idea how I can fix this?
Did you check your Sites.config and the default language for this website? There could be a difference between the language which is defined in your Sitecore languages folder and your configuration.
I had a similar problem with one of my projects where I changed the Sitecore.Context.Language to "nl" instead of "nl-NL". The glass mapper will return null, but Sitecore.Context.Database.GetItem will return an object in this case.
Most of the times it is a language issue. The mapper returns a null object when you do not have versions in the current or given language.
What can be confusing is that Sitecore.Context.Database.GetItem returns an object, even if it does not have a version in the current language. Be sure to check that item.Versions has any.
Some things you may try (this didn't fit in the comments field)
1) Confirm that the related fields in the Sitecore Item object contain values (so Sitecore.Context.Item for your "c" var and Sitecore.Context.Database.GetItem("path") for your "d" var)
2) Try to encapsulate the GetItem/GetCurrentItem call in a VersionCountDisabler, like this:
T01_Homepage model = null;
using (new VersionCountDisabler())
{
var context = new SitecoreContext();
model = context.GetItem<T01_Homepage>("path");
}
// Do you have data in model now?
3) Try to encapsulate the same call with a SecurityDisabler. Just to confirm it's not a security issue.
4) If you still don't know what it is, please update your question with some (simplified) code for your model.