Jak poprawnie przekazać Typ i wykonać konwersję obiektu?

0

Mam problem z przekonwertowaniem object na KeyValuePair.Key. Podpis metody wygląda następująco:

public EstimatorChain<RegressionPredictionTransformer<PoissonRegressionModelParameters>> GetRegressionPipeline(MLContext context, KeyValuePair<Type, object> algorithm)

A konwersja: (algorithm.Key)algorithm.Value or algorithm.Value as algorithm.Key rzuca wyjątkiem:

algorithm is a variable but is used like a type

Jak poprawnie przekonwertować na typ klucza Key? Zakładając (dla przykładu) że Value to LbfgsPoissonRegressionTrainer something = new LbfgsPoissonRegressionTrainer();

Czy powinienem użyć refleksji? Jeśli tak, to jak?

0

WTF 😁
Nie możesz zrobić (algorithm.Key)algorithm.Value. To nie są typy (klasy). Myślę, że powinno się to zrobić tak

(LbfgsPoissonRegressionTrainer)algorithm.Value;

PS.
Dlaczego typ klucza ma narzucać typ na wartość? Co chcesz tym osiągnąć? Wydaje mi się, że słownik w tym momencie nie ma sensu.

0
AdamWox napisał(a):

(...) Myślę, że powinno się to zrobić tak

(LbfgsPoissonRegressionTrainer)algorithm.Value;

A co jeśli chcę przekazać typ generycznie?

1

A co później chcesz zrobić z tym obiektem algorithm.Value? Bo ja tu widzę trzy możliwości w zależności od tego co chcesz potem zrobić: stworzenie interfejsu IAlgorithm, skorzystanie z refleksji, użycie czegoś w rodzaju strategii.

0
maszrum napisał(a):

A co później chcesz zrobić z tym obiektem algorithm.Value? Bo ja tu widzę trzy możliwości w zależności od tego co chcesz potem zrobić: stworzenie interfejsu IAlgorithm, skorzystanie z refleksji, użycie czegoś w rodzaju strategii.

Chcę wykorzystać do tworzenia generycznego pipeline dla modeli ML, żeby przetestować kilka jednocześnie:

return context.Transforms.CopyColumns(outputColumnName: "Label", inputColumnName: "Item")
                .Append(context.Transforms.Concatenate("Features", "Item"))
                .AppendCacheCheckpoint(context)
                .Append((algorithm.Key)algorithm.Value);
1

Nie znam ML, ale mi to wygląda jakby algorithm.Value zawsze było typu IEstimator<RegressionPredictionTransformer<PoissonRegressionModelParameters>>. Mam rację?

0

@maszrum: Kurde fajans, w sumie racja. Tyle razy zmieniałem sygnaturę tej metody, że przeoczyłem taką oczywistość :)

Bądź co bądź, będzie mnie teraz nurtować jak to zrobić generycznie, więc nie zamykam wątku :)

0

Ale co jeszcze generycznie? Bo nie rozumiem za bardzo.

Skoro wiesz jaki jest typ algorytmu, to możesz go użyć od razu.

public EstimatorChain<RegressionPredictionTransformer<PoissonRegressionModelParameters>> GetRegressionPipeline(
             MLContext context, 
             IEstimator<RegressionPredictionTransformer<PoissonRegressionModelParameters>> algorithm)
0

@maszrum: Niekoniecznie w tym przypadku, ale generalnie, czy da się jakoś przekazać typ na który da się rzutować.

Ostatecznie szukałem rozwiązania: var value = Convert.ChangeType(item.Value, item.Key); Choć Twój post rozwiązauje konkretnie mój problem. Dzięki.

return context.Transforms.CopyColumns(outputColumnName: "Label", inputColumnName: "Item")
                .Append(context.Transforms.Concatenate("Features", "Item")
                .AppendCacheCheckpoint(context)
                .Append((dynamic)Convert.ChangeType(algorithm.Value, algorithm.Key));
0
var value = 5;
var obj = (object)value;

Takie coś jest jednokierunkowe. Odwrócenie tego jest możliwe jedynie poprzez "zgadywanie" czym jest obj. Takie zgadywanie odbywa się poprzez rzutowanie (czy tam operator is/as). Nie da się tego zrobić inaczej, nawet mając typ obiektu jako System.Type.

if (obj is float valueFloat)
{
    // something
}
else if (obj is int valueInt)
{
    // something
}
0
maszrum napisał(a):

Nie da się tego zrobić inaczej, nawet mając typ obiektu jako System.Type.

Nie wiem, u mnie działa.

1 użytkowników online, w tym zalogowanych: 0, gości: 1