PaddlePaddle を使い始める: 対話システムにおける感情分析から始める

PaddlePaddle を使い始める: 対話システムにおける感情分析から始める

1. 背景

人工知能の時代では、さまざまなディープラーニングフレームワークが普及しており、フレームワークを習得することは、この時代のアルゴリズムエンジニアにとって標準となっています。しかし、どのようなフレームワークやツールを学んだとしても、それがどのように特定の問題を解決し、ビジネスの改善に役立つかを理解していなければ、木を見て森を見ずということになります。

この記事では、インテリジェントな対話システムにおける基本的な問題である感情分析から始め、Baidu のオープンソースのディープラーニング フレームワーク (PaddlePaddle) を使用して感情分析を「段階的に」解決する方法、そして最終的に対話システム全体の品質を向上させる方法について詳しく説明します。

1.1 ケーススタディ

次のようなシナリオを想像してください。親になったばかりの若い男性が、おむつの専門サプライヤー(Ding Ding the Deer など)を訪れ、生まれたばかりの赤ちゃん用のおむつを買いだめしたいと考えています。その後の交渉の後、この若者は、自分の接客を担当していたのがロボットであり、無関係な質問に答えていたことに気づいた。彼は激怒し、ロボットを直接侮辱した。もしあなたがこのスマートショッピングガイドロボットを開発しているアルゴリズムエンジニアだったら、この状況にどう対処すべきでしょうか?

(画像出典: Xiaolu Dingding 向けに開発されたスマート ショッピング ガイド ロボットの Smart One のテスト アカウント)

対話システムの分野では、現在の人工知能は弱い人工知能に過ぎないため、人間の介入は避けられず、いつ介入するかが問題となります。ユーザーの現在の感情(ポジティブな感情、ネガティブな感情)を正確に識別し、ユーザーがネガティブな感情を示したときにタイムリーに手動の支援に引き継ぐことができれば、効率が向上し、コストが節約され、企業にとって可能な限り正確な推奨事項が提供されるだけでなく、弱い人工知能が状況に対処できない場合にタイムリーにユーザーを安心させ、顧客離れを減らすことができます。これは、インテリジェントな対話システムにおける感情分析の典型的な応用例です。

1.2 対話システムにおける感情分析の重要性

人と直接コミュニケーションをとるシステムとして、対話システムがユーザーの感情をリアルタイムに認識できれば、対話システム全体の品質向上に大きな意義があります。上記のシナリオは、対話システムにおけるその応用例の 1 つにすぎません。

まず、感情分析は企業に定量的な顧客サービス品質評価を直接提供することができます。優れたカスタマー サービス担当者は、顧客とのやり取り中に顧客を不快にさせないように注意するため、感情分析を使用して、各カスタマー サービスやり取りログから顧客の感情の変動や、どのような応答が顧客を不快にさせる可能性があるかを明らかにすることができ、企業の効率を改善し、対話システムの品質を高めるのに役立ちます。

さらに、現在のタスク指向の対話システムのほとんどは、有限状態オートマトン (FSA ベース) またはフレームベースのアーキテクチャを使用しています。このようなアーキテクチャでは、意図の認識が特に重要です。ユーザーの感情的傾向は、意図認識の精度を向上させるのに役立ちます。

最後に、対話システム分野における最先端の研究では、強化学習を組み合わせて会話型ロボットを設計しています[2]。強化学習では、ロボットが環境からフィードバックを受け取り、報酬を定量化してより適切なアクションを選択する必要があります。正確な感情分析は強力な環境フィードバックであり、強化学習が対話システムで役割を果たすための基本的なコンポーネントです。

2. 感情分析とPaddlePaddle

感情分析[1]は、オピニオンマイニングとも呼ばれ、一般的には計算技術を使用してテキストの主観性、客観性、意見、感情をマイニングして分析し、テキストの感情的傾向に基づいて分類判断を行うことを指します。テキストは、文、段落、または文書のいずれかになります。感情的な傾向は、(ポジティブ、ネガティブ)、(幸せ、悲しい) などの 2 つのカテゴリ、または (ポジティブ、ネガティブ、中立) などの 3 つのカテゴリに分けられます。この問題は通常、テキスト分類問題としてモデル化されます。この記事では、Baidu のオープンソースのディープラーニング フレームワーク PaddlePaddle を使用して感情分析を解決してみます。

PaddlePaddle は、Baidu 傘下のオープンソースのディープラーニング プラットフォームです。 PaddleはParallel Distributed Deep Learning[3]の略称です。説明の便宜上、以下の文章ではPaddleをPaddlePaddleと表記します。

3. Paddleを使用して感情分析を解決する

3.1 インストール

以前にも TensorFlow をインストールしようとしましたが、TF のインストールに必要な依存関係の多さと面倒なプロセスに今でも驚いています。 Paddleはインストールが非常に簡単で、公式ウェブサイト[4]には豊富なドキュメントが掲載されています。この記事では CPU バージョンのみを使用します。読者は Linux/Mac で次のコマンドを実行するだけです。

pip インストール paddlepaddle

Python スクリプトで paddle をインポートします。

paddle.v2をpaddleとしてインポートする

インポートが成功した場合、インストールは成功です。おめでとうございます。

3.2 データ

開発者が実験を迅速に実行できるようにするために、Paddle は、古典的な MNIST や Movielens など、多くのインターフェースと既製のデータを提供します。ただし、データを取得するためにこれらのインターフェースを呼び出すだけでは、データ処理は開発者にとってブラックボックスになります。そこで、この記事では外部データを使って感情分析実験を行っていきます。まずはデータの構成を見てみましょう。

(1)データの説明

データは中国語のテキストデータを使用します。各データは 1 行を占め、各データはインスタンス (単語に分割された中国語の文) とラベルで構成されます。ラベルには 0 (負)、1 (中立)、2 (正) の 3 つの値があります。例:

インスタンス:あなたの/自宅/顧客/オンライン/タイムラベル:1

インスタンス:役に立つ場合は、次回にもっと写真を撮ることができますラベル:2

インスタンス:what/garbage/yolabel:0

データ ファイルでは、1 つのインスタンスとラベルが 1 行を占め、タブで区切られます。

(2)パドルのデータサポート

Paddle は次の 4 つのデータ型をサポートします。

密なベクトル

高密度浮動小数点ベクトル

スパースバイナリベクトル

スパース01ベクトル、つまり、ほとんどの値は0ですが、値がある場所は1である必要があります

スパース浮動小数点ベクトル

スパースベクトル、つまりほとんどの値は0ですが、値がある場所は任意の浮動小数点数になることができます

整数

整数

3 つのシーケンス モード:

シーケンスなし

シーケンスではありません

順序

時系列

サブシーケンス

時系列であり、各要素もシーケンスである

(3)パドル内のデータリーダー

トレーニングおよびテストのフェーズでは、Paddle はデータを読み取る必要があります。便宜上、Paddle では次の定義が行われます。

リーダー: リーダーはデータを読み取り、トラバース可能なデータ項目を提供する関数です。

リーダーは Python ジェネレーターである必要はなく、次の 2 つの条件を満たすだけでよいことに注意してください。

まず、パラメータなし、次に反復可能

公式コードに何度も登場する reader.shuffle と batch は、実際には Python デコレータです。Shuffle はリーダーを受け取り、リーダー内のデータをシャッフルしたリーダーを返します。batch もリーダーを受け取り、batch_size サイズのミニバッチを返します。通常の使用方法は次のとおりです。

train_reader = パドル.batch(

パドル.リーダー.シャッフル(

オリジンリーダー、

バッファサイズ=1000)、

バッチサイズ=100)

独自のリーダーを定義するときは、 origin_reader が関数オブジェクトであることに注意してください。

この記事では、最も単純なワンホットエンコーディングを使用して文を表します。単語空間を表す辞書が既に存在し、辞書が空間内の各単語のインデックスを保持していると仮定すると、リーダーを次のように定義できます (トレーニングリーダーを例に挙げます)。

def train(wd):

ファイルリーダー()を定義します:

open(training_file_location) を f として指定します:

真の場合:

行 = f.readline()

行の場合:

アイテム = 行を分割します('\t')

単語 = items[0].split('/')

ラベル = アイテム[1]

yield [[wd[word] for word in words], int(label)]

それ以外:

戻る

ファイルリーダーを返す

3.3 モデル

3.3.1 モデルの選択

パドルの柔軟性と利便性を示すために、この記事では 3 つのモデルを使用して感情分析を解決します。これらは、LogisticRegression、LogisticRegression-FM、および TextCNN です。以下では、これら 3 つのモデルの概要を説明します。

(1)ロジスティック回帰

バイナリ分類問題を解決する場合、ロジスティック回帰 (LR) は次の式を使用して、インスタンスが正のクラスとして分類される確率を表します。

多重分類ロジスティック回帰の場合、インスタンスがカテゴリiに分類される確率は

(2)ロジスティック回帰-FM

(1)から、LRはxの線形部分のみを考慮していることがわかります。因数分解マシン[5]に触発されて、以下に示すように、線形部分をxの対話型部分を含むように拡張することができます。

(3)テキストCNN

CNNは画像の分野で大きな進歩を遂げており、TextCNN[6]はそれをNLPに導入してテキスト分類を処理し、良好な結果を達成しました。その構造を以下に示します。

3.3.2 モデル構築

Paddle でモデルを構築するには、データから出力までのネットワーク全体を定義する必要があります。この記事で選択した 3 つのモデルはすべてニューラル ネットワーク モデルで表現できますが、隠し層と完全接続層が異なります。

(1)データ層

上記の reader の定義から、reader 内のデータは実際にはインスタンスとラベルの 2 つの要素を含むリストであることがわかります。インスタンスの型は integer_value_sequence です (セクション 3.2 の paddle でサポートされるデータ型を参照)。ラベルの型は整数です。例:

[[10, 201, 332, 103, 88], 1]

したがって、次のデータ レイヤーを定義できます。

データ = paddle.layer.data("インスタンス", paddle.data_type.integer_value_sequence(input_dim))

lbl = paddle.layer.data("ラベル", paddle.data_type.integer_value(3))

このうち、インスタンスとラベルはデータ レイヤーの名前です。トレーニング中は、フィーディング パラメータを使用して、トレーニング データ内の要素を対応するデータ レイヤーにマッピングできます。次に、埋め込みレイヤーを次のように定義します。

emb = paddle.layer.embedding(入力 = データ、サイズ = emb_dim)

埋め込み後のデータは次のようになります。

[[vect_10, vect_201, vect_332, vect_103, vect_88], 1]

vect_i は、このベクトル内で添え字 i の要素のみに値があり、その他はすべて 0 であることを意味します。

(2)モデル層

まず、最も単純なロジスティック回帰を構築します。

プール = paddle.layer.pooling(入力 = emb、pooling_type = paddle.pooling.Sum())

出力 = paddle.layer.fc(入力 = pool、サイズ = class_dim、動作 = paddle.activation.Softmax())

これは非常に簡単です。まず、pooling.Sum を使用して単語埋め込みの各次元を追加し、文全体の埋め込みを取得し、次に完全接続層を使用してサイズ class_dim のソフトマックス結果を取得します。 Paddle では、最初にプーリングが実行されないと、トレーニング中にインスタンスの数がラベルの数と等しくないという例外がスローされることに注意してください。これは、emb の結果が単語埋め込みのリストであり、Paddle がこのリスト内の各要素をインスタンスとして扱い、pooling.Sum を使用してリストを文の埋め込みに変換するためです。

次に、FM を使用してロジスティック回帰を構築します。

プール = paddle.layer.pooling(入力 = emb、pooling_type = paddle.pooling.Sum())

linear_part = paddle.layer.fc(入力=プール、サイズ=1、動作=paddle.activation.Linear())

相互作用部分 = paddle.layer.factorization_machine(入力=プール、

係数サイズ=係数サイズ、

アクティベーション = パドル.アクティベーション.リニア())

出力 = paddle.layer.fc(入力=[linear_part, interaction_part], サイズ=class_dim,

行為 = パドル.活性化.Softmax())

ロジスティック回帰との唯一の違いは、x の線形性だけでなく、x の次元間の相互作用も利用することです。ここでは、linear_part を使用して線形部分を取得し、interaction_part を使用してサイズ factor_size の相互作用部分を取得します。完全接続層では、linear_part と interaction_part が結合されてソフトマックス出力が取得されます。

最後に、畳み込みニューラル ネットワーク (CNN) を構築します。

pool_1 = conv_pool_layer(入力=emb,

emb_dim=emb_dim、

hid_dim=hid_dim、

コンテキスト長さ=2、

act=paddle.activation.Relu(),

pooling_type = paddle.pooling.Max())

pool_2 = conv_pool_layer(入力=emb,

emb_dim=emb_dim、

hid_dim=hid_dim、

コンテキスト長さ=3,

act=paddle.activation.Relu(),

pooling_type = paddle.pooling.Max())

出力 = paddle.layer.fc(入力=[pool_1, pool_2], サイズ=class_dim,

行為 = パドル.活性化.Softmax())

conv_pool_layer の定義は次のとおりです。

conv_pool_layer を定義します(入力、emb_dim、hid_dim、context_len、act、pooling_type):

paddle.layer.mixed(size=emb_dim * context_len) を m として:

m += paddle.layer.context_projection(入力=入力、コンテキスト長=コンテキスト長)

fc = パドル.レイヤー.fc(m、サイズ=hid_dim、act=act)

paddle.layer.pooling(入力=fc、pooling_type=pooling_type) を返します

ここでは、隣接する 2 つの単語 (Bi-Gram) と隣接する 3 つの単語 (Tri-Gram) に対してのみ畳み込みを実行し、ReLU 活性化関数と最大プーリング操作を使用します。利便性のため、Paddle は畳み込みとプーリングを行うときに直接呼び出すことができる多くのインターフェースをカプセル化しています (paddle.v2.networks.sequence_conv_pool など)。読者は Paddle の公式ドキュメントを参照できます。

(3)損失層

これは多重分類タスクなので、損失は最も一般的に使用されるクロスエントロピーを使用して定義できます。

lbl = paddle.layer.data("ラベル", paddle.data_type.integer_value(3))

コスト = paddle.layer.cross_entropy_cost(入力 = 出力、ラベル = lbl)

データ層、モデル層、損失層の定義後、ネットワーク構造全体が構築されます。以下は、上記のロジスティック回帰のコード例です。

ロジスティック回帰(input_dim,

クラス_dim、

emb_dim=128,

is_predict=False):

データ = paddle.layer.data("インスタンス", paddle.data_type.integer_value_sequence(input_dim))

emb = paddle.layer.embedding(入力 = データ、サイズ = emb_dim)

プール = paddle.layer.pooling(入力 = emb、pooling_type = paddle.pooling.Sum())

出力 = paddle.layer.fc(入力 = pool,

サイズ=クラス_dim、

行為 = パドル.活性化.Softmax())

そうでない場合 is_predict:

lbl = paddle.layer.data("ラベル", paddle.data_type.integer_value(3))

コスト = paddle.layer.cross_entropy_cost(入力 = 出力、ラベル = lbl)

返品費用

それ以外:

出力を返す

テストの便宜上、テストかどうかを識別するために is_predict が追加されています。トレーニング中は、トレーニング データに対するモデルの損失を返します。テスト中は、softmax 後の出力を直接返します。

3.3.3 モデルのトレーニングと保存

上記で定義した損失に応じて、モデル全体のパラメータを直接作成する

コスト = ロジスティック回帰(dict_dim、class_dim=class_dim)

パラメータ = paddle.parameters.create(コスト)

パラメータは、トレーニングまたはテストフェーズ中にネットワーク構造内のモデル全体のパラメータ、つまりネットワーク構造内のすべての w を維持する役割を果たします。 Paddle では、目的関数の最適化はオプティマイザーを通じて実行されます。ユーザーの操作を容易にするために、Paddle はユーザーが選択できるさまざまな最適化アルゴリズムをカプセル化しています。この記事では、例として Adam アルゴリズムを使用します。オプティマイザーを定義した後、トレーナーを直接定義できます。

adam_optimizer = paddle.optimizer.Adam( 学習率=2e-3,

正規化=paddle.optimizer.L2Regularization(レート=8e-4)、

model_average = paddle.optimizer.ModelAverage(average_window=0.5))

トレーナー = paddle.trainer.SGD(コスト = コスト、パラメータ = パラメータ、

update_equation = adam_optimizer)

ユーザーがトレーニング プロセス全体を監視できるように、Paddle はトレーニングのステータスを反映するさまざまなイベントを定義します。ユーザーは特定のイベントから現在の出力や失われた値などのさまざまな情報を取得し、独自の event_handler をカスタマイズできます。event_handler では次の 6 つのイベントを処理できます。

終了反復

反復の終了を示す

反復開始

反復の開始をマークします

ビギンパス

時代の始まりを示す

エンドパス

時代の終わりを告げる

テスト結果

trainer.test によって返された結果

終了前へ後へ

ForwardBackwardのラウンドの終了を示します

以下は、この記事で定義した event_handler の例です。各ミニバッチの終了時にコストなどの情報を出力し、各パスの後にパラメータをファイルに保存します。

イベントハンドラを定義します。

インスタンスの場合(イベント、paddle.event.EndIteration):

event.batch_id % 100 == 0 の場合:

print "\nパス %d、バッチ %d、コスト %f、%s" % (

イベント.pass_id、イベント.batch_id、イベント.cost、イベント.metrics)

それ以外:

sys.stdout.write('.')

sys.stdout.flush()

if isinstance(event, paddle.event.EndPass):

open('./params_pass_%d.tar' % event.pass_id, 'w') を f として実行します:

トレーナー.save_parameter_to_tar(f)

すべての設定が完了したら、モデルのトレーニングを開始できます。

trainer.train( リーダー=train_reader, イベントハンドラ=イベントハンドラ,

給餌=給餌、num_passes=10)

このうち、feeding はデータ レイヤーのマッピングを定義します: feeding={'instance': 0, 'label': 1}。これは、データの最初の要素が instance という名前のデータ レイヤーにマッピングされ、2 番目の要素が label という名前のデータ レイヤーにマッピングされることを意味します。これが、データ レイヤーの名前の理由でもあります。

3.4 テストと結果分析

テストフェーズでは、トレーニングフェーズで保存したパラメータファイルを読み込み、paddle の infer を使用して出力を取得します。

open("./params_pass_9.tar") を f として実行します:

パラメータ = paddle.parameters.Parameters.from_tar(f)

出力 = cn_sentiment.logistic_regression(dict_dim、class_dim=class_dim、is_predict=True)

probs = paddle.infer(出力レイヤー = out、パラメータ = パラメータ、入力 = x)

この記事では、probs は各テストインスタンスが 3 つのカテゴリのいずれかに属する確率を格納し、最も確率の高いカテゴリがモデルの予測結果となります。テスト結果は次のように要約され、報告されます。

モデル

アクセ

ロジスティック回帰

0.932857991682

ロジスティック回帰-FM

0.933143264763

CNN_シグモイド

0.935828877005

CNN_レル

0.953060011884

結果から、LR-FM は特徴間の相互作用を考慮しており、LR よりも優れたパフォーマンスを発揮することがわかります。しかし、より強力な表現力により、CNN は LR と比較して結果を大幅に改善しました。実験では、シグモイドよりも ReLU 活性化関数の利点も検証されました。これは、ReLU がトレーニング中に発生する勾配飽和効果 (Saturation Effect) を解決できるためです。

4. まとめと展望

この記事では、具体的な例を挙げて、対話システムにおける感情分析の応用について紹介します。感情分析は、対話システムにとって、少なくとも次の 4 つの意味を持ちます。手作業への移行の基盤を提供すること、意図認識を最適化すること、顧客サービスの品質を向上させるために対話データをマイニングすること、強化学習を支援することです。私は現在、「Smarter」で会話型ロボットの開発に取り組んでいます。NLP技術を活用して会話の質を高め、お客様のコスト削減や効率化に貢献したいと考えているため、この思いはより一層強く感じています。

さらに、この記事では、パドルを使用して感情分析の問題を段階的に解決する方法を示し、実験でパドルを使用して実装されたいくつかのモデルの結果を簡単に比較します。この記事の目的は、ディープラーニングに参入する開発者に、開発にパドルを使用する方法についての直感的な体験を提供し、さらなる議論の出発点となることです。

もちろん、この記事は表面的な部分しか触れていません。 Paddle の公式 Web サイトのスローガン「簡単に学習して使用できる分散型ディープラーニング プラットフォーム」のとおり、Paddle はインストールと使用が非常に便利です。古典的なタスク用の基本的なデータ セットも用意されているため、ディープラーニングを初めて使用する人には特に適しています。しかし、Paddle がそれほど単純だと思っているなら、それは間違いです。人気のディープラーニング フレームワークと同様に、Paddle は GPU をサポートするだけでなく、ファブリック クラスター、OpenMPI クラスター、Kubernetes スタンドアロン、Kubernetes 分散など、複数の分散クラスターの展開と操作もサポートします。これらの機能は読者が探索できるように残されています。

5. 参考文献

[1] Yang Ligong、Zhu Jian、Tang Shiping。テキスト感情分析のレビュー[J]。Journal of Computer Applications、2013、33(6):1574-1578。

[2] Serban IV、Sankar C、Germain M、他「深層強化学習チャットボット[J]」2017年。

[3] http://ai.baidu.com/paddlepaddle

[4] http://staging.paddlepaddle.org/docs/develop/documentation/zh/getstarted/index_cn.html

[5] Rendle S. 因数分解マシン[C]// IEEE、データマイニングに関する国際会議。IEEE、2011:995-1000。

[6] Kim Y. 文分類のための畳み込みニューラルネットワーク[J]. Eprint Arxiv、2014年。

<<:  人工知能と機械学習がもたらす劇的な変化を示す6つの事例

>>:  テキストからキーワードを抽出するにはどうすればいいですか? Daguan Dataが使用する3つのアルゴリズムから始めましょう

ブログ    
ブログ    

推薦する

2020年の人工知能の時代へようこそ

2019 年は AI にとって非常に素晴らしい年でしたが、これはすべて 2020 年にさらに大きな影...

製造業の発展は新たな課題に直面しており、人工知能が重要な役割を果たすだろう

[[245913]]現在、製造業の発展は新たな歴史的時期を迎えており、世界各国間の競争の焦点となって...

すべてのプログラマーが知っておくべきソートアルゴリズムトップ10

導入プログラマーとして、上位 10 のソート アルゴリズムは必須であり、すべての資格のあるプログラマ...

異種族の創造、AIがキリンの写真を鳥に変換し、人間と機械を欺く

この記事はLeiphone.comから転載したものです。転載する場合は、Leiphone.com公式...

ショック!自動運転車が人をはねたが、救助活動は失敗し、死亡が確認された。

太平洋標準時3月18日午後10時、米国アリゾナ州で、ウーバーが路上試験中に自転車に乗った女性と衝突し...

Python vs R: 機械学習とデータ分析の比較

[[187351]]新しいツールの出現を促すために、機械学習やデータ分析の分野は「オープンソース」の...

Mathematica が Big Language Model を導入しました。ネットユーザー:買う、買う、買う

Mathematica Wolfram の最新バージョンでは、大規模言語モデル (LLM) が正式に...

95歳のハーバード大学出身者が、機械学習をゼロから始めるための必読書を執筆しました。本のリソースは現在公開されています。

機械学習を始める最も簡単な方法は何ですか?今年ハーバード大学で統計学の学位を取得したばかりのダニー・...

...

機械学習のテストセットをスケールアップする方法

[[385223]]テスト セットのヒル クライミングは、トレーニング セットに影響を与えたり、予測...

年次レビュー:人工知能業界は2021年後半に突入

[[443324]] 2015年に人工知能が普及して以来、人工知能業界は7年間の発展を経て後半期に突...

...

サイバーセキュリティにおける機械学習:課題と比較

デジタルでつながった時代において、サイバーセキュリティ防御における機械学習 (ML) の役割は不可欠...

A* 検索アルゴリズム (実行可能なソース コード付き)

最近、少し時間ができたので、Java で A* 検索を作成し、表示に swing を使用しました。ア...