当サイトを最適な状態で閲覧していただくにはブラウザのJavaScriptを有効にしてご利用下さい。
JavaScriptを無効のままご覧いただいた場合には一部機能がご利用頂けない場合や正しい情報を取得できない場合がございます。
承知しました
本サイトではWebサイトのエクスペリエンスを向上させるために、Cookieを使用しています。Cookieはブラウザの設定から無効にできます。本サイトで使用するCookieについては、プライバシーポリシーをご確認ください。

Blog

ブログ

開発者向け

機械学習:ラベルが幸運ではなくスマートであることを確認する方法

By Michael Berry  

私たちの生活を整理するラベルやカテゴリーがなければ、世界は混乱するでしょう。ただし、何かの「賢明なラベル」と見なすものは、他の人が使用する用語ではない場合があり、「正しい」用語を選択することは運が左右するゲームになります。では、プロジェクトのコンテンツが適切で一貫性のあるカテゴリで編成されていることをどのように保証できますか?

この記事では、 ML.NETKentico Kontent .NET SDKを使用して、 コンテンツアイテムへの分類用語の追加を自動化する方法を示します。機械学習によるデータ駆動型の分類を使用して、分類用語の一貫性を確保すると同時に、コンテンツ編集者の肩から適切なラベルを選択する負担を取り除きます。

その「ラッキーラベリング」のゲームをよりスマートなソリューションに変えましょう!

データサイエンスや機械学習の学位は必要ありません

最初は、機械学習モデルの作成を取り巻くアルゴリズム、統計、その他の数学的複雑さに恐れを感じていましたが、MicrosoftのVisualStudio用ML.NETModel Builder Extensionを発見したとき、その恐れはすぐに解消されました。この拡張機能は、自動機械学習を使用して、シナリオとデータセットに最適な機械学習アルゴリズムを見つけます。最適なアルゴリズムを選択すると、そのアルゴリズムを選択し、モデルをトレーニングして、グラフィカルユーザーインターフェイス内ですべてを評価できます。大きな持ち帰り:それはゼロ機械学習/データ科学の経験が必要です。

KontentプロジェクトでML.NETの分類が役立つのはいつですか?

コンテンツの分類に機械学習を適用すると、次の場合に役立ちます。

  1. プロジェクトに同様の分類用語があり、編集者はどの用語がコンテンツに最適かを判断するのに苦労しています。
  2. プロジェクトには多くの分類用語があり、どれを削除できるかを特定する必要があります。
  3. 大規模なデータセットがあり、プロジェクトに追加する必要のある用語を特定する必要があります。

機械学習が役立つシナリオは他にもたくさんあると思われますが、これらは、この概念実証を開始したときに頭に浮かんだアイデアでした。以下のデモンストレーションと記事の残りの部分では、シナリオ#1に焦点を当てます。プロジェクトに同様の分類用語があり、編集者はどの用語がコンテンツに最適かを判断するのに苦労しています。

デモンストレーション

ML.NETがKenticoKontentでコンテンツの分類を自動化する方法を示すために、タイトル、説明、評価に基づいて映画をリストするNetflixカテゴリを提案する.NET Core3.1コンソールアプリケーションを作成しました。簡単にするために、1つの分類用語が映画に割り当てられる非階層的なラベル付け構造に焦点を当てました。プロジェクトを作成する手順は次の段階に分かれており、VisualStudioでコンソールアプリケーションを作成する方法を知っていることを前提としています。

  1. ML.NETモデルの確立
  2. KenticoKontentの準備
  3. モデルに対してコンテンツを実行する
  4. 提案された分類用語のインポート


ML.NETモデルの確立

ML.NETモデルを作成するための最初のステップは、サポートされているSQLデータベース、CSV、またはTSV形式で適切なデータセットを見つけることでした。 CSVファイルを使用することを選択しましたが、値をサニタイズして有効なCSVにし、データから一部のASCII文字を削除する必要がありました。 次に、MicrosoftのML.NET Model Builder Extension for VisualStudioをダウンロードしてインストールしました。完了したら、Visual Studioでコンソールアプリケーションを開き、プロジェクトを右クリックし、[追加]を使用して「機械学習」をプロジェクトに追加しました。

機械学習が追加された後、拡張機能は「カスタムシナリオ」オプションを含む6つの機械学習テンプレートから選択できるようにします。 Microsoftのシナリオの例と説明によると、「問題の分類」が私のシナリオに最も適しているので、それを選択しました。

Kentico Kontent

次のステップはモデルをトレーニングするためのものなので、サニタイズされたCSVを選択し、プログラムで予測する列を特定し、モデルが提案の基にする列を選択しました。

Kentico Kontent

画面下部の「トレーニング」ボタンをクリックすると、モデルのトレーニング時間を指定できる画面が開きました。 Microsoftには、ここにいくつかのトレーニングの推奨事項があります: https ://docs.microsoft.com/en-us/dotnet/machine-learning/automate-training-with-model-builder#how-long-should-i-train-for。 120秒で、57.44%の精度を管理しました。 [評価]をクリックすると、CSV内の一部のデータに対してモデルをテストし、上位5つの予測結果を分析することができました。

Kentico Kontent

いくつかのテストの後、57%の精度の結果に満足できませんでした。これは、Microsoftのトレーニング時間の推奨が17の異なる分類カテゴリに対して短すぎることを示唆しています。そのため、トレーニングを1時間再実行するようになり、精度が約66%向上しました。 次に、2つの機械学習プロジェクトを生成してソリューションに追加する[コード]ボタンをクリックすると、次のコマンドを使用してモデルを使用できました。

 // Add input datavar input = new ModelInput();input.Title = 'The Nightmare Before Christmas';input.Description = 'Jack Skellington, king of Halloween Town, ' + 'discovers Christmas Town, but his attempts to bring Christmas to his home causes confusion.';input.Rating = 'PG';// Load model and predict output of sample dataModelOutput result = ConsumeModel.Predict(input);Console.WriteLine(result.Prediction);

コンソールアプリケーションを実行すると、「Children&Family Movies」という出力が正しく生成され、ML.NETモデルをKontentプロジェクトにリンクする準備ができていることがわかりました。

Kentico Kontent

KenticoKontentの準備

次に、コンソールアプリケーションを使用するKenticoKontentプロジェクトを準備する必要がありました。実際のシナリオでは、「スマート」ラベリングの必要性が生じる前にプロジェクトが存在する可能性がありますが、私の概念実証では、機械学習の需要は、Kontentプロジェクトではなく、データセットによって推進されていました。

Kontentを設定するには、私はに記載されている作品という単一のコンテンツタイプと呼ばれる単一の分類グループを含んでいるでしょう、私のサブスクリプションで新しいプロジェクトを作成しました。コンテンツタイプと分類グループは、機械学習モデルの構築に使用したCSVの要素と用語で構成されていました。

  • タイトル:単純なテキスト要素
  • レーティング:CSV内の11のコンテンツレーティング(TV-GレーティングからRレーティング)すべてを含む複数選択要素
  • リリース日:日付と時刻の要素
  • 説明:リッチテキスト要素
  • リストされている:CSV内の「リストされている」用語の17個すべてを含む分類グループ
Kentico Kontent
Kentico Kontent

コンテンツタイプと分類法の用語が表示されたら、まだリリースされていない映画のタイトル、評価、説明を使用して、サンプルコンテンツアイテムのバリエーションを作成し始めました。コンソールアプリケーションからアイテムにデータをアップサートできるように、「ドラフト」ワークフローステップにそれらを残しました。

Kentico Kontent

モデルに対してコンテンツを実行する

次に、Kentico Kontentからそのコンテンツを取得し、生成したML.NETモデルコードにフィードして、予測を行えるようにしました。このために、 Kentico Kontent .NET SDK NuGetパッケージをインストールし、強く型付けされたムービーを返すMovieListingクラスを作成しました。

 //file location: MLNET-kontent-taxonomy-app/MovieListing.csclass MovieListing { IDeliveryClient client; public MovieListing(KontentKeys keys) { client = DeliveryClientBuilder .WithOptions(builder => builder .WithProjectId(keys.ProjectId) .UsePreviewApi(keys.PreviewApiKey) .Build()) .Build(); } public async Task> GetMovies() { DeliveryItemListingResponse response = await client.GetItemsAsync( new EqualsFilter('system.type', 'movie'), new ElementsParameter('title', 'rating', 'description', 'listed_in') ); return response; } }
 //file location: MLNET-kontent-taxonomy-app/Models/Movie.cspublic partial class Movie { public const string Codename = 'movie'; public const string DescriptionCodename = 'description'; public const string ListedInCodename = 'listed_in'; public const string RatingCodename = 'rating'; public const string ReleaseDateCodename = 'release_date'; public const string TitleCodename = 'title'; public string Description { get; set; } [JsonProperty('listed_in')] public IEnumerable ListedIn { get; set; } [JsonProperty('rating')] public IEnumerable Rating { get; set; } [JsonProperty('release_date')] public DateTime? ReleaseDate { get; set; } public ContentItemSystemAttributes System { get; set; } [JsonProperty('title')] public string Title { get; set; } }

メインのProgram.csからこのクラスをインスタンス化し、APIキーを渡し、ループできるDeliveryItemListingResponseを返しました。 ML.NET消費ロジックを別のクラスに設定して、保守性を高め、メインプログラムをクリーンにしました。

 //file location: MLNET-kontent-taxonomy-app/TaxonomyPredictor.cs//generated using: https://github.com/Kentico/kontent-generators-netclass TaxonomyPredictor { public string GetTaxonomy(Movie movie) { // Add input data var input = new ModelInput(); input.Title = movie.Title; input.Rating = movie.Rating.ToList().First().Name; input.Description = movie.Description; // Load model and predict output of sample data ModelOutput result = ConsumeModel.Predict(input); Console.WriteLine('Listing best match: ' + result.Prediction); //formatting to meet Kontent codename requirements //ex: Children & Family Movies => children___family_movies var formatted_prediction = result.Prediction.Replace(' ', '_').Replace('&', '_').ToLower(); return formatted_prediction; } }

そして、Program.csからインスタンス化しました。次に、TaxonomyPredictor.GetTaxonomy(Movie)メソッドを使用して、MovieListing.GetMovies()メソッドによって返された映画のリストをループするときに「リストされた」用語を提案できます。

//file location: MLNET-kontent-taxonomy-app/Program.csMovieListing movieListing = new MovieListing(keys);TaxonomyPredictor predictor = new TaxonomyPredictor();var movies = movieListing.GetMovies();foreach (Movie movie in movies.Result.Items){ if (movie.ListedIn.Count() < 1) { string formatted_prediction = predictor.GetTaxonomy(movie); Console.WriteLine(formatted_prediction); }}

これにより、アプリケーションを実行したときに、コンソールに「ベストマッチ」の分類用語が生成されました。

提案された分類用語のインポート

最後に、提案された分類用語を、KenticoKontentプロジェクトにあるコンテンツアイテムのバリエーションに自動化するときが来ました。これは、TaxonomyImporterという別のクラスでKentico Kontent .NET ManagementSDKを使用して実現しました。

 //file location: MLNET-kontent-taxonomy-app/TaxonomyImporter.csclass TaxonomyImporter { ManagementClient client; public TaxonomyImporter(KontentKeys keys) { ManagementOptions options = new ManagementOptions { ProjectId = keys.ProjectId, ApiKey = keys.ManagementApiKey, }; // Initializes an instance of the ManagementClient client client = new ManagementClient(options); } public async Task UpsertTaxonomy(Movie movie, string listing_prediction) { MovieImport stronglyTypedElements = new MovieImport { ListedIn = new[] { TaxonomyTermIdentifier.ByCodename(listing_prediction) } }; // Specifies the content item and the language variant ContentItemIdentifier itemIdentifier = ContentItemIdentifier.ByCodename(movie.System.Codename); LanguageIdentifier languageIdentifier = LanguageIdentifier.ByCodename(movie.System.Language); ContentItemVariantIdentifier identifier = new ContentItemVariantIdentifier(itemIdentifier, languageIdentifier); // Upserts a language variant of your content item ContentItemVariantModel response = await client.UpsertContentItemVariantAsync(identifier, stronglyTypedElements); return response.Elements.Title + ' updated.'; } }

Program.csでインポーターをインスタンス化したので、映画のリストをループするときにUpsertTaxonomyメソッドを使用できました。次に、コンテンツアイテムのバリエーションをアップサートするときにKentico Kontent Management SDKが期待するものに対応するために、Movieから継承する強く型付けされたMovieImportモデルを作成する必要がありました。

 //file location: MLNET-kontent-taxonomy-app/Models/MovieImport.cspublic partial class MovieImport : Movie { [JsonProperty('listed_in')] public new IEnumerable ListedIn { get; set; } [JsonProperty('rating')] public new IEnumerable Rating { get; set; } }

これが完了し、環境変数、appsettings.json、および.NET Core構成オプションの組み合わせを使用した構成バインディングを使用するロジックを追加すると、アプリケーションは完成しました。以下は、完成したProgram.csファイル、構成ファイル、およびプログラムの実行結果です。

//file location: MLNET-kontent-taxonomy-app/Program.csclass Program{ static void Main(string[] args) { Console.WriteLine('Starting program...'); var environmentName = Environment.GetEnvironmentVariable('ASPNETCORE_ENVIRONMENT'); var configuration = new ConfigurationBuilder() .AddJsonFile('appsettings.json', optional: true, reloadOnChange: true) .AddJsonFile($'appsettings.{environmentName}.json', optional: true, reloadOnChange: true) .Build(); //file location: MLNET-kontent-taxonomy-app/Configuration/KontentKeys.cs var keys = new KontentKeys(); ConfigurationBinder.Bind(configuration.GetSection('KontentKeys'), keys); MovieListing movieListing = new MovieListing(keys); TaxonomyPredictor predictor = new TaxonomyPredictor(); TaxonomyImporter importer = new TaxonomyImporter(keys); var movies = movieListing.GetMovies(); foreach (Movie movie in movies.Result.Items) { if (movie.ListedIn.Count() < 1) { string formatted_prediction = predictor.GetTaxonomy(movie); var upsertResponse = importer.UpsertTaxonomy(movie, formatted_prediction).Result; Console.WriteLine(upsertResponse); } } Console.WriteLine('Program finished.'); } }
 //file location: MLNET-kontent-taxonomy-app/Configuration/KontentKeys.cspublic class KontentKeys { public string ProjectId { get; set; } public string PreviewApiKey { get; set; } public string ManagementApiKey { get; set; } }
 //file location: MLNET-kontent-taxonomy-app/appsettings.json{ 'KontentKeys': { 'ProjectId': '', 'PreviewApiKey': '', 'ManagementApiKey': '' }}
Kentico Kontent

可能性を想像してみてください

この記事では、ML.NET ModelBuilderを.NETCoreコンソールアプリケーションとKenticoKontentプロジェクトで使用して、コンテンツへの分類用語の割り当てを自動化する方法を説明しました。私のデモンストレーションでは、フラットな分類構造と単純な分類シナリオに焦点を当てましたが、これはほぼ無限の機械学習の可能性の1つにすぎません。これを次のレベルに引き上げて、Kentico Kontent Webhookに接続するとどうなりますか?画像分類を使用して、アセットの説明を自動的に書き込むのはどうですか?機械学習に飛び込み、独自のカスタムモデルを作成して、業界固有のより複雑な分類を実行したいと思うかもしれません。適切なツールと考え方があれば、何でも可能だと思います。

私のアプリケーションの完全なソースコード、サポートデータファイル、およびプロジェクトの独自のコピーをテストする方法の説明は、次の場所にあります。

コードを取得する

Headless CMSの導入をお考えでしょうか?

クラウドとマルチデバイスに最適化されたKentico Kontentをお試しください