歡迎光臨
每天分享高質量文章

.NET Core使用微軟AI認知服務識別文字語言

點選上方藍字關註“汪宇傑部落格”

識別一段文字的語言有多種途徑,在這個以AI為熱點的時代,我們也可以給自己的應用強行加上AI,然後就能加上“智慧”的名字“自主研發成功”後去吹牛逼。今天我帶大家來看看如何使用微軟智慧雲Azure提供的AI認知服務來識別一段文字的語言。

本文的前提條件是你得有一個Azure國際版的訂閱,免費試用的也行。

新建Azure認知服務賬戶

點選”Create a resouce“,然後搜尋”Translator“,選擇”Translator Text“,這是Azure認知服務的其中一種應用,主要用途是做翻譯,但我們也能用來識別文字的語言。

Name中指定一個名稱,可以任意,不影響程式開發。選擇一個Pricing tier,這裡我選的F0是免費的。Resource group也可以任意指定,不會影響程式開發。

建立完成後,到Keys中複製一個Key,Key1Key2都可以使用,作用是完全一樣的,沒有什麼講究。

.NET Core 呼叫認知服務

Azure認知服務提供了REST介面,所以我們在.NET Core裡可以像使用任何REST API一樣,構造請求,並解析傳回的JSON字串。

TextLanguageDetector

新建一個名為TextLanguageDetector的類。用來封裝呼叫Azure認知服務的操作。定義屬性HostRouteSubscriptionKey。其中SubscriptionKey就是之前從Azure Portal裡複製的那個Key。這個需要讓呼叫者根據自己的Azure賬戶自由調整,所以留在建構式引數裡。HostRoute是固定的,因此可以寫死在程式裡。

public class TextLanguageDetector

{

    public string Host { get; } = “https://api.cognitive.microsofttranslator.com”;

    public string Route { get; } = “/detect?api-version=3.0”;

    public string SubscriptionKey { get; }

    public TextLanguageDetector(string subscriptionKey)

    {

        SubscriptionKey = subscriptionKey;

    }

    public async Task DetectAsync(string text)

    {

        // …

    }

}

DetectAsync方法接受的是需要識別的文字,傳回的DetectResult型別也是我們自己定義的,它的定義稍後再看。我們先看看該方法的具體實現:

if (string.IsNullOrWhiteSpace(text))

{

    throw new ArgumentNullException(nameof(text));

}

object[] body = { new { Text = text } };

var requestBody = JsonConvert.SerializeObject(body);

using (var client = new HttpClient())

using (var request = new HttpRequestMessage())

{

    request.Method = HttpMethod.Post;

    request.RequestUri = new Uri(Host + Route);

    request.Content = new StringContent(requestBody, Encoding.UTF8, “application/json”);

    request.Headers.Add(“Ocp-Apim-Subscription-Key”, SubscriptionKey);

    var response = await client.SendAsync(request);

    var jsonResponse = await response.Content.ReadAsStringAsync();

    return new DetectResult(jsonResponse);

}

非常簡明直接。使用POST動作向認知服務的終端地址提交一個構造的Body,內容Text為方法的輸入引數,即要識別的文字。API的認證方式使用SubscriptionKey。最終拿到的jsonResponse是識別結果,轉為DetectResult型別。

假設識別的是簡體中文,並且沒有發生異常,那麼Azure認知服務的傳回Json會是這樣:

[

    {

        “language”: “zh-Hans”,

        “score”: 1.0,

        “isTranslationSupported”: true,

        “isTransliterationSupported”: true,

        “alternatives”: [

            {

                “language”: “ja”,

                “score”: 1.0,

                “isTranslationSupported”: true,

                “isTransliterationSupported”: true

            }

        ]

    }

]

language是語言程式碼,zh-Hans就是簡體中文。score表示AI認為有多大的可能性是該語言,1.0就是非常確信。對於文字“予力地球上每一人、每一組織,成就不凡”的識別結果,出現了兩種確信的語言:簡體中文和日語。但日語是alternatives的,所以AI基本斷定,該語言為簡體中文。具體的語言程式碼和語言名稱對應關係可以從這裡找到:

var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);

構造DetectResult

為了讓我們程式對呼叫者更加友好,我們不會只傳回Json。我根據Azure認知服務可能傳回的兩種情況:成功、失敗,構造了DetectResult型別:

public class DetectResult

{

    public string RawJson { get; set; }

    public bool IsSuccess => !RawJson.Contains(“\”error\””);

    public string ErrorMessage

    {

        get

        {

            var obj = JsonConvert.DeserializeObject(RawJson);

            return obj.error.message.ToString();

        }

    }

    public DetectResult(string rawJson)

    {

        RawJson = rawJson;

    }

    public List ToCogResults()

    {

        return IsSuccess ? JsonConvert.DeserializeObject>(RawJson) : null;

    }

}

RawJson用來存放認知服務傳回的Json本身,可以讓呼叫者去做一些更加高階的自定義解析。IsSuccess表示呼叫是否有成功,如果不成功的話使用者可以檢查ErrorMessage獲得具體錯誤訊息。成功的話可以呼叫ToCogResults()方法把結果解析到TextCogResult型別裡去。這個方法傳回的是一個List,因為輸入的文字不一定只有一種語言。

public class TextCogResult

{

    public string Language { get; set; }

    public float Score { get; set; }

    //public bool IsTranslationSupported { get; set; }

    //public bool IsTransliterationSupported { get; set; }

    public Alternative[] Alternatives { get; set; }

}

public class Alternative

{

    public string Language { get; set; }

    public float Score { get; set; }

    //public bool IsTranslationSupported { get; set; }

    //public bool IsTransliterationSupported { get; set; }

}

以上的所有程式碼都可以封裝到一個.NET Standard類庫裡,這樣就可以跨.NET Framework, .NET Core或者Xamarin使用了。

為了方便大家,我已經釋出了可以直接使用的NuGet包

https://www.nuget.org/packages/AzureAILanguageDetector

應用程式

以.NET Core控制檯應用為例,呼叫TextLanguageDetector並輸出語言的本地名稱和英語名稱:

var texts = new[]

{

    “Empower every person and every organization on the planet to achieve more”,

    “予力地球上每一人、每一組織,成就不凡”

};

var dt = new TextLanguageDetector(“你的Key”);

foreach (var text in texts)

{

    var result = dt.DetectAsync(text).Result;

    if (result.IsSuccess)

    {

        var r = result.ToCogResults();

        var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);

        var ctr = cultures.FirstOrDefault(c => c.Name == r.First().Language);

        if (ctr != null) Console.WriteLine($”{ctr.EnglishName} – {ctr.NativeName}”);

    }

    else

    {

        Console.WriteLine(result.ErrorMessage);

    }

}

本文示例程式碼:https://github.com/EdiWang/DotNet-Samples/tree/master/CogSvcLngDetect

參考資料:https://docs.microsoft.com/en-us/azure/cognitive-services/translator/quickstart-csharp-detect

    贊(0)

    分享創造快樂