Xamarin 日本語情報

Xamarin(ザマリン) の代理店だったエクセルソフト田淵のブログです。主に Xamarin に関するエントリーをアップしていきます。(なるべく正しい有益な情報を掲載していきたいと考えていますが、このブログのエントリーは所属組織の公式見解ではありませんのでご注意ください)

Xamarin で Microsoft Cognitive Services を使うには - その2

こんにちは。エクセルソフトの田淵です。

この記事は Cogbot Advent Calendar 2018 の 22日目のエントリーです。遅れてしまい、すみません!

先日は Xamarin で Microsoft Cognitive Services を使うには - その1 として、Cognitive ServicesVision(視覚) を使ってみました。

今日は Language(言語)を使ってみます。

サンプルは以下にアップしてあります。

github.com

Cognitive Services - Language(言語)

Language の中にもいくつかサービスがあります。

azure.microsoft.com

アプリとサービスが構造化されていないテキストの意味を解釈したり、話者の発言の裏にある意味を認識したりできる言語サービスについて、詳細をご覧ください。

とのこと。これも非常に AI っぽいサービスですね。

Translator Text

文章の翻訳をしてくれるサービスです。

60以上の言語をサポートしていて、注目すべきは入力された文章の言語を自動判別できることだと思います。

対応言語は以下をご参照ください。

docs.microsoft.com

サービス作成

「Translator」で検索して、「Translator Text」を F0 の価格プランで作成しましょう。Translator Text は Global なのでリージョンの指定はありません。

余談ですが、いくつかのドキュメントに Cognitive Services の All-in-One キーを使う。というような記述があるのですが、@BEACH_SIDE さんがいくつかのサービスでは All-In-One キーはなぜか使えないって言っていたので、なるべくそれぞれのサービスのキーを作成して使っていきたいと思います。

beachside.hatenablog.com

ドキュメント

以下のサンプルを元に実装していきましょう。

docs.microsoft.com

NuGet パッケージとコード

NuGet パッケージマネージャーで、恐らく一番上に表示されている「Newtonsoft.Json」をインストールします。

(カンの良い方は気づいたはず。そう。SDK がありませんでしたw)

コードの説明

HttpClient で普通にアクセスして JSON をデシリアライズするだけなので難しいところはないかと思います。いくつかポイントを解説します。

To の言語

RequestUri にエンドポイント https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=de&to=it と渡すと、to= の部分に翻訳してくれます。

今回は英語と日本語だけなので、EnumToLanguage を用意して、TranslateTextAsync の引数に渡すようにしました。

public enum ToLanguage
{
    en,
    ja
}
JsonConvert.DeserializeObject<T> の型

レスポンスのサンプル にもありますが、以下のような JSON が返ってきます。

[
  {
    "detectedLanguage": {
      "language": "en",
      "score": 1.0
    },
    "translations": [
      {
        "text": "Hallo Welt!",
        "to": "de"
      },
      {
        "text": "Salve, mondo!",
        "to": "it"
      }
    ]
  }
]

一番外側が [] になっているので、以下の TranslatedObject の List でデシリアライズします。

JsonConvert.DeserializeObject<List<TranslatedObject>>(jsonResponse)

です。

JsonProperty

アッパーキャメルでプロパティを設定しなおしています。

public class DetectedLanguage
{
    [JsonProperty("language")]
    public string Language { get; set; }
    [JsonProperty("score")]
    public double Score { get; set; }
}

public class Translation
{
    [JsonProperty("text")]
    public string Text { get; set; }
    [JsonProperty("to")]
    public string To { get; set; }
}

public class TranslatedObject
{
    [JsonProperty("detectedLanguage")]
    public DetectedLanguage DetectedLanguage { get; set; }
    [JsonProperty("translations")]
    public List<Translation> Translations { get; set; }
}

f:id:ytabuchi:20181225183805p:plain:w300

良いですね!

コードの説明

Text Analytics

いくつかサービスがありますが、今回は「テキストの感情分析」を使ってみます。

以下のデモをみてみましょう。文章の感情を読み取り、ポジティブなのかネガティブなのかを返します。

azure.microsoft.com

2018年12月時点では、残念ながら日本語はキーワード抽出しか対応していません。

docs.microsoft.com

そのため、上記の TranslatorText と組み合わせて英語に翻訳してから Sentiment(感情)を分析してみたいと思います。

サービス作成

「Text Analytics」または「テキスト分析」で検索して、「テキスト分析」を F0 の価格プランで作成しましょう。どのリージョンに作ったか?を覚えておいてください。

f:id:ytabuchi:20181225184041p:plain:w600

ドキュメント

以下のサンプルを元に実装していきましょう。

docs.microsoft.com

NuGet パッケージとコード

NuGet パッケージマネージャーで、Windows の場合は「プレリリースを含める」、macOS の場合は「プレリリースパッケージを表示する」のチェックボックスをオンにして、「Microsoft.Azure.CognitiveServices.Language.TextAnalytics」を検索してインストールします。2018年12月時点の SDK のバージョンは 2.8.0-preview です。

2018/12/20 時点では、インストールする Microsoft.Azure.CognitiveServices.Language.TextAnalytics の 2.8.0-preview の依存パッケージである Microsoft.Rest.ClientRuntime の 2.3.17 に以下のバグがあるようで、「Darwin17.7.0DarwinKernelVersion17.7.0FriNov2204316PDT2018rootxnu-4570.71.171/RELEASE_X86_64' is invalid.」というエラーが出てました。個別に Microsoft.Rest.ClientRuntime の最新版 2.3.18 をインストールすることで回避可能です。

github.com

f:id:ytabuchi:20181225185521p:plain:w450

DetectLanguageAsync

テキスト分析を行う前に、TextAnalyticsClientDetectLanguageAsync メソッドで認識した言語が英語かどうかを判定しています。

第一引数の BatchInput は引数 IList<Input> をとり、Input の引数は [string id = null], [string text = null] なので、

new Input(null, text)

を指定すると正しい結果が取れないようでした。そのため、ID を new Input("0", text), と指定してあげる必要があるようです。

戻り値の DetectedLanguages には NameIso6391Name がありますので、今回は Iso6391Name"en" を取得できれば OK ということにしました。

言語検出の詳細は以下をご参照ください。

docs.microsoft.com

SentimentAsync

英語であることを確認したら、TextAnalyticsClientSentimentAsync メソッドで感情を分析します。

こちらも、DetectLanguageAsync と同様に、第一引数の MultiLanguageBatchInput は引数 IList<MultiLanguageInput> をとり、MultiLanguageInput の引数は [string language = null], [string id = null], [string text = null] なのですが、new MultiLanguageInput("en", "0", text) と ID を指定してあげます。

あとは戻り値の Documents[0].Score をみてあげれば結果が取得できます。

f:id:ytabuchi:20181225193030p:plain:w300

うん、こちらも良い感じ。

.NET Core のコンソール

今回も同様に、まずはコンソールアプリで確認してみましょう。

Console.WriteLine("Cognitive Services - Language - Translator Text");

var ja = "今日は人生で一番良い日です。";
var en = "I had a wonderful trip to Seattle and enjoyed seeing the Space Needle!";

var translationClient = new TranslatorTextService();
var ja2en = translationClient.TranslateTextAsync(ja, TranslatorTextService.ToLanguage.en).Result;
var en2ja = translationClient.TranslateTextAsync(en, TranslatorTextService.ToLanguage.ja).Result;

Console.WriteLine($"Source: {ja}\n" +
    $"Translated: {ja2en}");
Console.WriteLine($"Source: {en}\n" +
    $"Translated: {en2ja}");


Console.WriteLine("Cognitive Services - Language - Text Analytics");

var textAnalysisClient = new TextAnalyticsService();
var sentiment1 = textAnalysisClient.AnalyzeSentimentAsync(en).Result;
var sentiment2 = textAnalysisClient.AnalyzeSentimentAsync(ja2en).Result;

Console.WriteLine($"Source: {en}\n" +
    $"Sentiment(Happiness): {sentiment1*100:00}%");
Console.WriteLine($"Source: {ja2en}\n" +
    $"Sentiment(Happiness): {sentiment2*100:00}%");

問題なさそうです!

Xamarin.Forms の実装

こちらも最後は Xamarin.Forms の実装です。今回からページを複数使うので、TabbedPage を使用しました。

TabbedPage
<?xml version="1.0" encoding="UTF-8"?>
<TabbedPage
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:XFCognitiveServices"
    xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
    ios:Page.UseSafeArea="true"
    xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
    BarBackgroundColor="#F1F1F1"
    android:TabbedPage.ToolbarPlacement="Bottom"
    android:TabbedPage.BarItemColor="#999999"
    android:TabbedPage.BarSelectedItemColor="#303F9F"
    x:Class="XFCognitiveServices.MainTabPage">
    <TabbedPage.Children>
        <local:VisionPage Title="Vision"
                          Icon="vision.png"/>
        <local:LanguagePage Title="Language"
                            Icon="language.png"/>
  </TabbedPage.Children>
</TabbedPage>

各ページ内で別のページを呼び出すこと(Navigation.PushAsync(new SomePage()))がある場合は、<local:VisionPage/> の代わりに、以下のように NavigationPage で包んで表示してください。

<NavigationPage Title="Vision"
                Icon="vision.png">
    <x:Arguments>
        <local:VisionPage />
    </x:Arguments>
</NavigationPage>

Tabbed Page の詳細は以下です。

docs.microsoft.com

Android で Bottom Tab を使う

Xamarin.Forms 3.1 以降では、Android に Bottom Tab を使用できるようになりました。

上記 TabbedPage の以下のオプションの部分です。

xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
BarBackgroundColor="#F1F1F1"
android:TabbedPage.ToolbarPlacement="Bottom"
android:TabbedPage.BarItemColor="#999999"
android:TabbedPage.BarSelectedItemColor="#303F9F"

docs.microsoft.com

Bottom Tab は @Santea3173 くんXamarin Advent Calendar 2018 の 18日目の 最近の Xamarin.Forms のアップデートを試してみる で触れてますね。非常に良いです。

TabbedPage のアイコン

Android でも Bottom Tab を使うことで、iOSAndroid 両方にアイコンが必要になります。色は上書きされますので、表示したい部分「以外」を透過に設定した画像を用意します。

iOS はアイコンのファイル名に倍率を付ける必要があります。@1x30x30@2x60x60@3x90x90 のサイズで用意してプロジェクトの Resource フォルダに追加して、ビルドアクションを BundleResource にしておけば表示されます。

f:id:ytabuchi:20181225175051p:plain:w300

AndroidAndroid プロジェクトの Resources/drawable フォルダにファイルを追加して、ビルドアクションを AndroidResource にしておけば表示されます。サイズはいい感じにしてくれるので(多分)問いません。(私は 120x120 のファイルを追加しました。)

f:id:ytabuchi:20181225174507p:plain:w300

ちなみに、Android の Bottom Tab では、4個以上から非選択タブのテキストが隠れていい感じに表示してくれるようになります。便利w (iOS はそのままでした。)

f:id:ytabuchi:20181225180036p:plain:w450

f:id:ytabuchi:20181225180050p:plain:w450

UseSafeArea

iPhone X のノッチ用の設定です。以下を各ページの XAML に付けます。

xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:Page.UseSafeArea="true"

以下のドキュメントにもありますが、注意点として Page.Padding を強制的に上書きするだけなので、他で設定している場合は注意してください。とのことです。

docs.microsoft.com

IsSwipePagingEnabled

AndroidTabbedPage でスワイプで各タブページを遷移できるオプションです。が、なんか、標準でオンになっているっぽくて設定しなくてもスワイプできましたw

android:TabbedPage.OffscreenPageLimit="2"
android:TabbedPage.IsSwipePagingEnabled="true"

一応ドキュメントへのリンクです。

docs.microsoft.com

まとめ

今日は 言語 Language のサービスをいくつか使ってみました。

入力した言語を自動認識するというのに驚きました。こちらも簡単に翻訳機能をアプリに追加できるので魅力的ですね。

サンプルは以下にアップしてあります。興味があればビルドしてみてください。

github.com

チャットアプリとかはみんな使えばいいのに!と思いましたが、ローカルにエンジンが無いと無限にお金が掛かってしまうかw

今後も触っていって、「そのXX」まで書いていきたいです。

Xamarin 気になった方は

Visual Studio 2017 をインストールして触ってみてください。手順書は こちらのエントリー をご覧ください。 学習用リソースJXUG リンクページ に参考資料を纏めてますので併せてどうぞ。

Xamarin の導入支援サービスを始めました。ベースは基本的なアプリを一緒に作ることで Xamarin を使えるようになって頂く内容ですが、ご要望に応じて講習内容のカスタマイズも可能です。詳しくは田淵までお問い合わせください(^^)

Xamarin 有償トレーニング : XLsoft エクセルソフト

Xamarin の情報が欲しい方はこのブログも購読いただいたり、私のTwitterアカウントをフォローいただいたりすると嬉しいです。

私が所属している エクセルソフト の宣伝を少しさせてください。弊社は開発者向けの様々なソフトウェアを扱っています。Office/PDF ファイルを .NET/Java で操作するライブラリ Aspose(アスポーズ)Windows アプリ、Web ページ、iOS/Android アプリの UI テストができる TestComplete などお勧めです(^^) また、Visual Studio Professional/Enterprise with MSDN も販売してますし、日本で売っていない海外のソフトウェア、開発ツールなどを弊社経由で日本円で購入頂くことも可能です。ご興味あれば 弊社ページ を覗いてみてください。

以上です。

エクセルソフト | ダウンロード | 学習用リソース | JXUG リンクページ | ブログ購読