C# 自训练算法

C# 自训练算法,c#,.net,algorithm,neural-network,training-data,C#,.net,Algorithm,Neural Network,Training Data,我想为一个特定的问题开发一个自我训练算法。为了简单起见,我将把它归结为一个简单的例子 更新:我已经添加了一个有效的解决方案,作为下面这个问题的答案。 假设我有一个来自数据库的大量实体列表。每个实体的类型相同,有4个byte类型的属性 public class Entity { public byte Prop1 { get; set; } public byte Prop2 { get; set; } public byte Prop3 { get; set; }

我想为一个特定的问题开发一个自我训练算法。为了简单起见,我将把它归结为一个简单的例子

更新:我已经添加了一个有效的解决方案,作为下面这个问题的答案。

假设我有一个来自数据库的大量实体列表。每个实体的类型相同,有4个byte类型的属性

public class Entity
{
    public byte Prop1 { get; set; }
    public byte Prop2 { get; set; }
    public byte Prop3 { get; set; }
    public byte Prop4 { get; set; }
}
现在,我想根据一个简单的条件动态测试每个实体的一个或多个属性。这基本上意味着,我想测试所有属性的所有可能组合,在这个条件下

为了做到这一点,我为属性创建了一个位掩码

[Flags]
public enum EEntityValues
{
    Undefined = 0,
    Prop1 = 1,
    Prop2 = 2,
    Prop3 = 4,
    Prop4 = 8,
}
并添加了一个方法来获取位掩码的最大值。对于本例,返回15(1+2+4+8)

public static int GetMaxValue<T>() where T : struct
{
    return Enum.GetValues( typeof(T) ).Cast<int>().Sum();
}
public static int GetMaxValue(),其中T:struct
{
返回Enum.GetValues(typeof(T)).Cast().Sum();
}
在这个阶段,我能够用一个简单的循环迭代所有属性组合。在示例中,在第一次迭代中测试属性Prop1,在第二次迭代中测试Prop2,在第三次迭代中测试Prop1和Prop2,依此类推

for(int i = 1; i <= GetMaxValue<EEntityValues>(); i++)
{
     EEntityValues flags = (EEntityValues)i;

     if(flags.HasSet(EEntityValues.Prop1))
     {
         ....
     }
}

for(int i=1;i休息后,我想出了一个似乎符合我要求的解决方案。限制是所有测试的属性都应该是具有相同值范围的相同类型,这对我来说很好,因为所有属性都是抽象的百分比值

顺便说一下,我不确定主题“自我训练算法”这里有点误导。有几种方法可以实现这种解决方案,但如果您不知道数据的行为以及值的影响,最简单的解决方案是强制所有可能的组合以确定最佳拟合结果。这就是我在这里展示的

无论如何,出于测试目的,我在实体类中添加了一个随机数生成器

public class Entity
{
    public byte Prop1 { get; set; }
    public byte Prop2 { get; set; }
    public byte Prop3 { get; set; }
    public byte Prop4 { get; set; }

    public Entity()
    {
        Random random = new Random( Guid.NewGuid().GetHashCode() );
        byte[] bytes = new byte[ 4 ];

        random.NextBytes( bytes );

        this.Prop1 = bytes[0];
        this.Prop2 = bytes[1];
        this.Prop3 = bytes[2];
        this.Prop4 = bytes[3];
    }
}
我的比特面具保持不变

[Flags]
public enum EProperty
{
    Undefined = 0,
    Prop1 = 1,
    Prop2 = 1 << 1,
    Prop3 = 1 << 2,
    Prop4 = 1 << 3
}
[标志]
公共枚举属性
{
未定义=0,
Prop1=1,
Prop2=1e);
对于(int index=0;index Math.Abs(e.Prop1)>=value);
打破
案例EProperty.Prop2:
结果=结果,其中(e=>Math.Abs(e.Prop2)>=值);
打破
案例EProperty.Prop3:
结果=结果,其中(e=>Math.Abs(e.Prop3)>=值);
打破
案例EProperty.Prop4:
结果=结果,其中(e=>Math.Abs(e.Prop4)>=值);
打破
}
}
返回结果;
}
}
最后我准备好开始训练了

    private const int maxThreads = 10;

    private const int minValue = 0;
    private const int maxValue = 100;

    private static IEnumerable<Entity> entities;

    public static void Main(string[] args)
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString());

        entities = Enumerable.Repeat(new Entity(), 10).ToList();

        Action<EProperty[], int[]> testCase = RunTestCase;
        RunSelfTraining( testCase );

        Console.WriteLine(DateTime.Now.ToLongTimeString());
        Console.WriteLine("Done.");

        Console.Read();
    }

    private static void RunTestCase( EProperty[] properties, int[] values ) 
    {         
        foreach( Entity entity in entities.Where( properties, values ) )
        {

        }
    }

    private static void RunSelfTraining<T>( Action<T[], int[]> testCase ) where T : struct
    {
        ParallelOptions parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = maxThreads };

        for (int maskValue = 1; maskValue <= BitMask.GetMaxValue<T>(); maskValue++)
        {
            T mask = ( T ) (object)maskValue;
            T[] properties = mask.Split().ToArray();         

            int variations = (int) Math.Pow(maxValue - minValue + 1, properties.Length);

            Parallel.For(1, variations, parallelOptions, variation =>
            {
                int[] values = GetVariation(variation, minValue, maxValue, properties.Length).ToArray();   
                testCase.Invoke(properties, values);        
            } );
        }
    }

    public static IEnumerable<int> GetVariation( int index, int minValue, int maxValue, int count )
    {
        index = index - 1; 
        int range = maxValue - minValue + 1;

        for( int j = 0; j < count; j++ )
        {
            yield return index % range + minValue;
            index = index / range;
        }
    }
}
private const int maxThreads=10;
私有常量int minValue=0;
private const int maxValue=100;
私有静态可数实体;
公共静态void Main(字符串[]args)
{
Console.WriteLine(DateTime.Now.ToLongTimeString());
entities=Enumerable.Repeat(新实体(),10.ToList();
Action testCase=RunTestCase;
RunSelfTraining(testCase);
Console.WriteLine(DateTime.Now.ToLongTimeString());
控制台。WriteLine(“完成”);
Console.Read();
}
私有静态void RunTestCase(EProperty[]属性,int[]值)
{         
foreach(实体中的实体。其中(属性、值))
{
}
}
私有静态void RunSelfTraining(Action testCase),其中T:struct
{
ParallelOptions ParallelOptions=new ParallelOptions{MaxDegreeOfParallelism=maxThreads};
对于(int maskValue=1;maskValue)
{
int[]values=GetVariation(variation,minValue,maxValue,properties.Length).ToArray();
调用(属性、值);
} );
}
}
公共静态IEnumerable GetVariation(int索引、int最小值、int最大值、int计数)
{
指数=指数-1;
int range=maxValue-minValue+1;
对于(int j=0;j
我不确定我是否遵循了。。你是说你想要一种方法来测试(例如)
prop1
prop2
的组合,而不是同时测试所有4个属性吗?你是否意识到这四个属性有
4228250625
组合?所以你的意思是你想要能够检查
prop1和prop2
组合,但也可以检查
prop1和prop3
,(等等等等)以及一次完成所有任务?我不完全理解。您希望获得多少最小值?每个属性一个或每个组合一个4元组?@endeffects为什么不在
EEntityValues
中创建一个条目,如下所示:
All=Prop1 | Prop2 | Prop3 | Prop4
。此外,我将使用二进制操作而不是幻数来声明标志:
None=0
Prop1=1
Prop2=1
public class Entity
{
    public byte Prop1 { get; set; }
    public byte Prop2 { get; set; }
    public byte Prop3 { get; set; }
    public byte Prop4 { get; set; }

    public Entity()
    {
        Random random = new Random( Guid.NewGuid().GetHashCode() );
        byte[] bytes = new byte[ 4 ];

        random.NextBytes( bytes );

        this.Prop1 = bytes[0];
        this.Prop2 = bytes[1];
        this.Prop3 = bytes[2];
        this.Prop4 = bytes[3];
    }
}
[Flags]
public enum EProperty
{
    Undefined = 0,
    Prop1 = 1,
    Prop2 = 1 << 1,
    Prop3 = 1 << 2,
    Prop4 = 1 << 3
}
public static class BitMask
{
    public static int GetMaxValue<T>() where T : struct
    {
        return Enum.GetValues(typeof (T)).Cast<int>().Sum();
    }

    public static int GetTotalCount<T>() where T : struct
    {
        return Enum.GetValues(typeof (T)).Cast<int>().Count(e => e > 0);
    }

    public static int GetFlagCount<T>(this T mask) where T : struct
    {
        int result = 0, value = (int) (object) mask;

        while (value != 0)
        {
            value = value & (value - 1);
            result++;
        }

        return result;
    }

    public static IEnumerable<T> Split<T>(this T mask)
    {
        int maskValue = (int) (object) mask;

        foreach (T flag in Enum.GetValues(typeof (T)))
        {
            int flagValue = (int) (object) flag;

            if (0 != (flagValue & maskValue))
            {
                yield return flag;
            }
        }
    }
}
public static class QueryBuilder
{
    public static IEnumerable<Entity> Where(this IEnumerable<Entity> entities, EProperty[] properties, int[] values)
    {
        IEnumerable<Entity> result = entities.Select(e => e);

        for (int index = 0; index <= properties.Length - 1; index++)
        {
            EProperty property = properties[index];
            int value = values[index];

            switch (property)
            {
                case EProperty.Prop1:
                    result = result.Where(e => Math.Abs(e.Prop1) >= value);
                    break;
                case EProperty.Prop2:
                    result = result.Where(e => Math.Abs(e.Prop2) >= value);
                    break;
                case EProperty.Prop3:
                    result = result.Where(e => Math.Abs(e.Prop3) >= value);
                    break;              
                case EProperty.Prop4:
                    result = result.Where(e => Math.Abs(e.Prop4) >= value);
                    break;   
            }
        }

        return result;
    }
}
    private const int maxThreads = 10;

    private const int minValue = 0;
    private const int maxValue = 100;

    private static IEnumerable<Entity> entities;

    public static void Main(string[] args)
    {
        Console.WriteLine(DateTime.Now.ToLongTimeString());

        entities = Enumerable.Repeat(new Entity(), 10).ToList();

        Action<EProperty[], int[]> testCase = RunTestCase;
        RunSelfTraining( testCase );

        Console.WriteLine(DateTime.Now.ToLongTimeString());
        Console.WriteLine("Done.");

        Console.Read();
    }

    private static void RunTestCase( EProperty[] properties, int[] values ) 
    {         
        foreach( Entity entity in entities.Where( properties, values ) )
        {

        }
    }

    private static void RunSelfTraining<T>( Action<T[], int[]> testCase ) where T : struct
    {
        ParallelOptions parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = maxThreads };

        for (int maskValue = 1; maskValue <= BitMask.GetMaxValue<T>(); maskValue++)
        {
            T mask = ( T ) (object)maskValue;
            T[] properties = mask.Split().ToArray();         

            int variations = (int) Math.Pow(maxValue - minValue + 1, properties.Length);

            Parallel.For(1, variations, parallelOptions, variation =>
            {
                int[] values = GetVariation(variation, minValue, maxValue, properties.Length).ToArray();   
                testCase.Invoke(properties, values);        
            } );
        }
    }

    public static IEnumerable<int> GetVariation( int index, int minValue, int maxValue, int count )
    {
        index = index - 1; 
        int range = maxValue - minValue + 1;

        for( int j = 0; j < count; j++ )
        {
            yield return index % range + minValue;
            index = index / range;
        }
    }
}