Skip to content

IFormatProvider in TextLoader #126

Closed

Description

@ddobric

Want to know how TextLoader deals with files in different cultures.
For example, if you are running on OS with culture like "de-de" such files might be loaded incorrectly:

CMT,1,1,1267,6.9,CRD,23
CMT,1,1,1267,6.8,CRD,24

With such cultures (none-invariant) would require files formatted in following way (separator = ';')

CMT;1;1;1267;6,9,CRD;23
CMT;1;1;1267;6,8,CRD;23

Activity

  1. veikkoeeva commented on May 11, 2018

    @veikkoeeva
    Contributor

    Cross-referencing since related: #74 and #109. And since this is a real problem, feeding thoughts: https://www.nuget.org/packages?q=CSV.

  2. veikkoeeva commented on May 11, 2018

    @veikkoeeva
    Contributor

    @ddobric You can see it at

    public class TextLoader<TInput> : ILearningPipelineLoader
    .

    I wonder if it were possible to do something like this

        /// <summary>
        /// A canonical interface for deserializer.
        /// </summary>
        public interface IDeserializer
        {
           /// <summary>
           /// Can this provider stream data.
           /// </summary>
           bool CanStream { get; }
    
           /// <summary>
           /// Deserializes the given data.
           /// </summary>
           /// <param name="data">The data to be serialized.</param>
           /// <param name="destination">The destination type.</param>
           /// <returns>The deserialized object.</returns>
           object Deserialize(object data, Type destination);
    
    /// <summary>
    /// Deserializes the given data from a stream.
    /// </summary>
    /// <param name="dataStream">The stream from which to serialize.</param>
    /// <param name="destination">The destination type.</param>
    /// <returns>The deserialized object.</returns>
    object Deserialize(Stream dataStream, Type destination);
    
    /// <summary>
    /// Deserializes the given data from a text stream.
    /// </summary>
    /// <param name="reader">The text stream from which to serialize.</param>
    /// <param name="destination">The destination type.</param>
    /// <returns>The deserialized object.</returns>
    object Deserialize(TextReader reader, Type destination);
    }
    
    /// <summary>
        /// A default JSON deserializer.
        /// </summary>
        [DebuggerDisplay("CanStream = {CanStream}")]
        public class DefaultJsonDeserializer: IDeserializer
        {
            public JsonSerializer Deserializer { get; }
            public JsonSerializerSettings Settings { get; }
            public bool CanStream { get; } = true;
    
            public DefaultJsonDeserializer(JsonSerializerSettings settings)
            {
                if(settings == null)
                {
                    throw new ArgumentNullException(nameof(settings));
                }
                Deserializer = JsonSerializer.Create(settings);
                Settings = settings;
            }
    
            public object Deserialize(Stream dataStream, Type destination)
            {
                using(var streamReader = new StreamReader(dataStream))
                {
                    using(var reader = new JsonTextReader(streamReader))
                    {
                        return Deserializer.Deserialize(reader, destination);
                    }
                }
            }
    
            public object Deserialize(object data, Type destination)
            {
                return JsonConvert.DeserializeObject((string)data, destination, Settings);
            }
    
            public object Deserialize(TextReader reader, Type destination)
            {
                using(var jsonReader = new JsonTextReader(reader))
                {
                    return Deserializer.Deserialize(jsonReader, destination);
                }
            }
        }
    }
    

    The real case would be more complicated and the interface could support, say IAsyncEnumerable<T>. The intention would be to make canonical interfaces for input (and output) and make concrete implementations in arbitrary ways, users could bring their own (de)serializers. This might be possible in the current system. I don't know what is schema, for instance, in MachineLearning.NET. :)

  3. sfilipi commented on Nov 27, 2018

    @sfilipi
    Member

    @ddobric you can specify the column separator in the TextLoader, in ML.Net.
    The TextLoader's default separator is ' \t'.

    The culture does not play a factor.

  4. codemzs commented on Jun 30, 2019

    @codemzs
    Member

    Please try with the new API in post 1.0 release and let me know if you still see this issue.

  5. ghost locked as resolved and limited conversation to collaborators on Mar 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions