[[432936]] [51CTO.com クイック翻訳]昨今、ディープラーニング、特に自然言語処理 (NLP) が大きな関心を集めています。少し前に、Kaggle は「Quora Question insincerity Challenge」と呼ばれる自然言語処理 (NLP) コンテストを開始しました。このコンペティションは、テキスト分類問題を解決し、コンペティションと Kaggle の専門家が提供する貴重なカーネルを通じて、問題をより理解しやすくすることを目的としています。 まず、コンテストにおけるテキスト分類問題について説明します。 テキスト分類は自然言語処理における一般的なタスクであり、長さが不明なテキストシーケンスをテキスト カテゴリに変換します。では、テキスト分類では何が行われるのでしょうか? 次のことが可能です。 - コメントの背後にある感情を理解する
- Facebookのようなプラットフォームで有害なコメントを見つける
- Quoraで不誠実な質問を見つけたら、Kaggleで競争が行われている
- サイト上で偽のレビューを見つける
- テキスト広告がクリックされるかどうかを判断する
さて、これらの問題にはすべて共通点があります。機械学習の観点から見ると、これらの問題は本質的に同じであり、ターゲット ラベルのみが変更になり、それ以外は何も変更されていません。そうは言っても、ビジネス知識を追加することでこれらのモデルをより堅牢にすることができ、これはテスト分類のためにデータを前処理するときに含めたいものです。 この記事はディープラーニングを中心とした前処理パイプラインに焦点を当てていますが、その多くは従来の機械学習モデルにも当てはまります。 まず、すべての手順を完了する前に、テキスト データのディープラーニング パイプラインのフローを理解して、プロセス全体をよりよく理解しましょう。 通常は、テキスト データをクリーンアップし、基本的なイベント駆動型アーキテクチャ (EDA) を実行することから始まります。ここでは、データをクリーニングすることでデータ品質の向上を図ります。また、語彙外(OOV)単語を削除することで、Word2Vec 埋め込みの品質を向上させることも試みています。通常、最初の 2 つのステップの間に順序はほとんどなく、その間を行き来するのが一般的です。 次に、ディープラーニング モデルに入力できるテキストの表現を作成します。次に、モデルの作成とトレーニングを開始します。最後に、適切なメトリックを使用してモデルが評価され、リーダーシップからの承認を得てモデルを展開します。これらの用語が今のところあまり意味をなさなくても心配しないでください。この記事で説明したプロセスに沿って説明してみてください。 ここでは、まず単語の埋め込みについてお話ししましょう。これは、ディープラーニング モデル用にデータを前処理するときに考慮する必要があることです。 Word2Vec埋め込みの始め方ここで、語彙内の単語を表現する方法が必要です。 1 つのアプローチは、ワンホットエンコードされた単語ベクトルを使用することですが、これはあまり良い選択ではありません。主な理由の 1 つは、ワンホット ワード ベクトルでは、コサイン類似度などの異なる単語間の類似度を正確に表現できないことです。 ワンホットエンコードされたベクトルの構造を考えると、異なる単語間の類似性は常に 0 になります。もう 1 つの理由は、語彙のサイズが大きくなるにつれて、これらのワンホット エンコードされたベクトルが非常に大きくなることです。 Word2Vec は、単語の固定長のベクトル表現を提供し、異なる単語間の類似点と類推を捉えることで、上記の困難を克服します。 Word2vec 単語ベクトルの学習方法により、さまざまな類推を学習できます。これにより、以前は不可能だった単語に対して代数演算を実行できるようになります。たとえば、キングは男性 + 女性ですか? 結果はクイーンです。 Word2Vec ベクトルは、単語間の類似点を見つけるのにも役立ちます。 「good」に似た言葉を探してみるなら、「awesome」や「great」などが見つかります。 word2vec のこの特性により、テキスト分類に非常に役立ちます。今日のディープラーニング ネットワークは、「良い」と「素晴らしい」が本質的には同様の意味を持つ単語であることを理解できます。 つまり、簡単に言えば、word2vec は単語のベクトルを作成します。したがって、辞書内の各単語には d 次元のベクトルが存在します。通常、Wikipedia や Twitter などの大規模なテキストコーパスでトレーニングした後、他者によって提供される事前トレーニング済みの単語ベクトルを使用します。最も一般的に使用される事前トレーニング済みの単語埋め込みは、300 次元の単語埋め込みを持つ GloVe と Fasttext です。この記事では、Glove を使用します。 テキストデータの基本的な前処理技術ほとんどの場合、観察されるテキスト データは完全にクリーンではありません。異なるソースからのデータには異なる特性があるため、テキストの前処理は分類パイプラインで最も重要なステップの 1 つになります。 たとえば、Twitter のテキスト データは、Quora やニュース/ブログ プラットフォームのテキスト データとはまったく異なるため、別の方法で処理する必要があります。幸いなことに、この記事で説明する手法は、自然言語処理 (NLP) で発生する可能性のあるあらゆる種類のデータに十分適用できる汎用性を備えています。 (1)特殊文字を消去し、句読点を削除する 前処理パイプラインは、分類タスクに使用される word2vec 埋め込みに大きく依存します。原則として、前処理は単語埋め込みをトレーニングする前に使用される前処理と一致する必要があります。ほとんどの埋め込みでは句読点やその他の特殊文字のベクトル値が提供されないため、最初に行うことはテキスト データから特殊文字を削除することです。これらは Quora の不誠実な質問データに存在する特殊文字です。これらの特殊文字を削除するには、置換機能を使用します。 #これから見るすべてのテキスト分類方法で使用されるいくつかの前処理。 パイソン - 1 句読点 = [ ',' 、 '.' 、 '"' 、 ':' 、 ')' 、 '(' 、 '-' 、 '!' 、 '?' 、 '|' 、 ';' 、" '", ' $ '、' & '、' / '、' [ '、' ] '、' > '、' % '、' = '、' # '、' * '、' + '、' \\ '、' • '、' ~ '、' @ '、' £ '、' · '、' _ '、' { '、' } '、' © '、' ^ '、' ® '、' ` '、' < '、' → '、' ° '、' € '、' ™ '、' › '、' ♥ '、' ← '、' × '、' § '、' ″ '、' ′ '、' '、' █ '、' ½ '、' à '、' … '、' “ '、' ★ '、' ” '、' – '、' ● '、' â '、' ► '、' − '、' ¢ '、' ² '、' ¬ '、' ░ '、' ¶ '、' ↑ '、' ± '、' ¿ '、' ▾ '、' ═ '、' ¦ '、' ║ '、' ― '、' ¥ '、' ▓ '、' — '、' ‹ '、' ─ '、' ▒ '、' : '、' ¼ '、' ⊕ '、' ▼ '、' ▪ '、' † '、' ■ '、' ' '、' ▀ '、' ¨ '、' ▄ '、' ♫ '、' ☆ '、' é '、' ¯ '、' ♦ '、' ¤ '、' ▲ '、' è '、' ¸ '、' ¾ '、' Ã '、' ⋅ '、' ' ' 、' ∞ '、' ∙ '、' ) '、' ↓ '、' 、 '、' │ '、' ( '、' » '、' 、 '、' ♪ '、' ╩ '、' ╚ '、' ³ '、'・'、' ╦ '、' ╣ '、' ╔ '、' ╗ '、' ▬ '、' ❤ '、' ï '、' Ø '、' ¹ '、' ≤ '、' ‡ '、' √'、
パイソン - 1def clean_text(x): x = str(x) for punct in puncts: if punct in x: x = x.replace (punct, '' ) return
これは、単純な正規表現を使用して実行することもできます。しかし、データから削除される文字の種類を理解するのに役立つため、一般的には上記の方法が好まれます。 パイソン - 1def clean_numbers(x): if bool(re.search(r '\d' , x)): x = re.sub( '[0-9]{5,}' , '#####' , x) x = re.sub( '[0-9]{4}' , '####' , x) x = re.sub( '[0-9]{3}' , '###' , x) x = re.sub( '[0-9]{2}' , '##' , x) return x
(2)明確な数字 なぜ数字を # に置き換えるのでしょうか? ほとんどの埋め込みでは、テキストをこのように前処理するからです。 Python のヒント: 次のコードの if ステートメントを使用して、テキスト内に数字が存在するかどうかを事前に確認します。同様に、if は常に re.sub コマンドよりも高速であり、テキストのほとんどには数字が含まれていません。 パイソン - 1 def clean_numbers(x): if bool(re.search(r '\d' , x)): x = re.sub( '[0-9]{5,}' , '#####' , x)
(3)スペルミスを削除する データ内のスペルミスを見つけるのに常に役立ちます。これらの単語の埋め込みは word2vec には存在しないため、埋め込みの範囲を広げるには、単語を正しいスペルに置き換える必要があります。 次のコード アーティファクトは、Peter Norvig のスペル チェッカーを改変したものです。 Google word2vec はトレーニング コーパス内で頻度の高い順に単語を並べる傾向があるため、単語の確率を近似するために word2vec の単語順序を使用します。これを使用して、データ内のスペルミスのある単語を見つけることができます。 以下は、Quora の質問類似性チャレンジの CPMP スクリプトです。 パイソン - 1 import re from collections import Counter import gensim import heapq from operator import itemgetter from multiprocessing import Pool
- 2model = gensim.models.KeyedVectors.load_word2vec_format( '../input/embeddings/GoogleNews-vectors-negative300/GoogleNews-vectors-negative300.bin' 、バイナリ= True ) words = model.index2word
- 3 w_rank = {} for i,word in enumerate(words): w_rank[word] = i
- 4 単語 = w_rank
- 5 def words(text): return re.findall(r ' \w+' , text.lower ())
- 6 def P(word): "`word` の確率。" #順位の逆数をプロキシとして使用します#単語が辞書にない場合は 0 を返しますreturn - WORDS.get(word, 0)
- 7 def correction(word): 「単語の最も可能性の高いスペル修正。」 戻る 最大(候補(単語)、キー= P)
- 8 def candidates(word): 「単語のスペル修正候補を生成します。」 (known([word])またはknown(edits1(word))またはknown(edits2(word))または[word])を返します。
- 9 def known(words): 「WORDS の辞書に現れる `words` のサブセット。」 戻る (wが単語の場合、 wがWORDSの場合、wを単語として設定します)
- 10 def edits1(word): "`word` から 1 つ離れた編集すべて。" letters = 'abcdefghijklmnopqrstuvwxyz' splits = [(word[:i], word[i:]) for i in range(len(word) + 1)] deletes = [L + R[1:] for L, R in splits if R] transposes = [L + R[1] + R[0] + R[2:] for L, R in splits if len(R)>1] replaces = [L + c + R[1:] for L, R in splits if R for c in letters] inserts = [L + c + R for L, R in splits for c in letters] return 設定(削除 + 転置 + 置換 + 挿入)
- 11 def edits2(word): "`word` から 2 つ離れたすべての編集。" (e2をe1のedits1(word)で返し、 e2をedits1(e1)で返す)
- 12 def build_vocab(texts): sentences = texts.apply(lambda x: x.split()). values vocab = {} for sentence in sentences: for word in sentence: try: vocab[word] += 1 except KeyError: vocab[word] = 1 return vocab
- 13 語彙 = build_vocab(train.question_text)
- 14 top_90k_words = dict(heapq.nlargest(90000, vocab.items(), key =itemgetter(1)))
- 15 プール = プール(4) 修正された単語 = プール.map(訂正、リスト(top_90k_words.keys()))
- 16 for word,corrected_word in zip(top_90k_words,corrected_words): if word!=corrected_word: print
スペルミスのあるデータを見つけたら、次にスペルミスマップと正規表現関数を使用してそれらを置き換えます。 パイソン - 1 mispell_dict = { 'colour' : 'color' 、 'centre' : 'center' 、 'favourite' : 'favorite' 、 'travelling' : 'traveling' 、 'counselling' : 'counseling' 、 'theatre' : 'theater' 、 'cancelled' : 'canceled' 、 'labour' : 'labor' 、 'organisation' : 'organization' 、 'wwii' : 'world war 2' 、 'citicise' : 'criticize' 、 'youtu ' : 'youtube ' 、 'Qoura' : 'Quora' 、 'sallary' : 'salary' 、 'Whta' : 'What' 、 'narcisist' : , ' how do' : 'どうやって' , 'whatare' : '何が' , 'howcan' : 'どうやって' , 'howmuch' : 'どのくらい' , 'howmany' : 'いくつ' , 'whydo' : 'なぜ' , 'doI' : '私は' , 'theBest' : '最高' , 'howdoes ' : 'どうやって' , 'mastrubation' : 'マスターベーション' , 'mastrubate' : 'マスターベーションする' , "mastrubating" : 'マスターベーションする' , 'pennis' : 'ペニス' , 'Etherium' : 'Etherium' , 'narcissit' : 'ナルシシスト' , 'bigdata' : 'ビッグデータ' 、 '2k17' : '2017' 、 '2k18' : '2018' 、 'qouta' : 'クォータ' 、 'exboyfriend' : '元ボーイフレンド' 、 'airhostess' : 'エアホステス' 、 "whst" : 'what' 、 'watsapp' : 'whatsapp' 、 'demonitisation' : 'demonetization' 、 'demonitization' : 'demonetization' 、 'demonetisation' : 'demonetization'
パイソン - 1def _get_mispell(mispell_dict): mispell_re = re.compile( '(%s)' % '|' . join (mispell_dict.keys()))戻り値mispell_dict, mispell_re
- スペルミスが2つあります。mispellings_re = _get_mispell(mispell_dict) def replace_typical_misspell(text): def replace (match): return mispellings[match.group ( 0)] return mispellings_re.sub( replace , text)
- 3 # 使用法 replace_typical_misspell( "悪魔化とは何か" )
(4)略語を排除する 略語はアポストロフィを使って書かれた単語です。短縮形の例としては、「ain't」や「aren't」などがあります。テキストを標準化したいので、これらの略語を拡張するのは理にかなっています。以下では、圧縮マップと正規表現関数を使用してこれを実現します。 パイソン - 1 収縮辞書 = { "ain't" : "ではない" 、 "aren't" : "ではない" 、 "can't" : "できない" 、 "'cause" : "なぜなら" 、 "could've" : "できたかもしれない" 、 "couldn't" : "できなかった" 、 " didn't" : "しなかった" 、 " does't" : "しない" 、 "don't" : "しない" 、 "hadn't" : "なかった" 、 "hasn't" : "なかった" 、 "haven't" : "持っていない" 、 "he'd" : "彼はするだろう" 、 "he'll" : "彼はするだろう" 、 "he's" : "彼は" 、 "how'd" : "どうやってした" 、 "how'd'y" : "どうやって"持っている" 、 "私は" : "私はだろう" 、 "私はだろう" : "私はだろう"、"私はだろう" 、 "私はだろう":"私は"、"私は":"私は持っている"、 ..."、"私は":"私は持っている"、"私は" 、 "私は" 、"私は":"私は持っている"、"私は"、"私は"、"私は":"私は持っている"、"私は" 、 "私は" 、 "私は":"私は持っている"、"私は" 、 "私は"、"私は":"私は持っている"、"私は" 、 "私は" 、 "私は" 、 "私は" : "私は持っている"、 "私は"、"私は"、"私は" 、 "私は" 、"私は" 、 "私は"、"私は" 、"私は"、"私は"、"私は"、"私は"、"私は"、"私は"、"私は"、"私は"、"私は" 、 "私は" 、"私は"、"私は"、"私は"、"私は" 、 "私は" 、 "私は"、"私は"、"私は" 、 "私は" 、 "私は"、"私は" 、 "私は" 、"私は"、"私は"、 "私は" 、 "私は" 、 "私は「そうなるだろう」 、 「そうなるだろう」 : 「そうなるだろう」 、 「それは」:「そうなるだろう」 、 「しよう」 、 「奥様」 、 「そうかもしれない」、「かもしれない」 、 「かもしれない」、「かもしれない」 、 「かもしれない」、 「かもしれない」 、 「かもしれない」 、 「かもしれない」、「かもしれない」、「かもしれない」、「かもしれない」 、 「かもしれない」、「かもしれない」、「かもしれない」、「かもしれない」、「かもしれない」、「かもしれない」、「かもしれない」、「かもしれない」 、 「かもしれない」 、 「かもしれない」 、「かもしれない」、「かもしれない」、 「しなければならない」、「しなければならない」、「しなければならない」 、 「しなければならない」 、「しなければならない」、「しなければならない」、「しなければならない」、「しなければならない」 、 「しなければならない」 、 「しなければならない」、「しなければならない」 、 「しなければならない」 、 「する必要はない」 、 「する必要はない」 、 「する必要はない」、「する必要はない」 、 「する必要はない」 、 「時の」 、 「すべきではない」 、 「するべき ... 「持ってはいけない」 : 「持ってはいけない」 、 「shan't」 : 「sha't not」 、 「shan't've」 : 「彼女は持っていない」、「彼女は」 、 「彼女は」 「すべきではない」 、 「そうすべきではない」 、 「そうすべきではない」:「持ってはいけない」、「so've」 : " so ' so 's " : " so " 、 " as " : " this is " 、 " that'd " : " that " 、 「that'd've」 : 「それはそうだっただろう」 、 「 that's」 : 「それは」 、 「 there'd 」 : 「そこだろう」 、 「there'd've」 : 「そこがあっただろう」 、 「 there's」 : 「そこがある」 、 「here's」 : 「ここにある」 、 「 they'd」 : 「彼らはそうだろう」 、 「they'd've」 : 「彼らはそうだっただろう」 、 「they'll」 : 「彼らはそうするだろう」 、 「they'll've」 : 「彼らはそうするだろう」 、 「 they're」 : 「彼らはそうである」 、 「they've」 : 「彼らはそうしている」 、 「to've」 : 「持っていた」 、 「wasn't」 : 「なかった」 、 「we'd」 : 「私たちはそうだっただろう」 、 「 we'd've」 : 「私たちはそうだっただろう」 、 「we'll」 : 「私たちはするでしょう」 、 「私たちはするでしょう」 、 「私たちは」 、 「私たちは」 、 「私たちは」 、 「私たちは」 、 「私たちは」 、 「私たちは」 、 「私たちは」 、 「私たちは」 、 「なかった」 、 「何... : 「誰が持っている」 、 「なぜの」 、 「なぜ」 、 「なぜ」 、 「なぜ」 、 「持っている」 、 「だろう」 、 「だろう」 、 「ない」 、 「だろう... , "you'll" : "you will" , "you'll've" : "you will have" , "you're" : "you are" , "you've" : "you have" }
パイソン - 1 def _get_contractions(contraction_dict): contraction_re = re.compile( '(%s)' % '|' . join (contraction_dict.keys())) return contraction_dict, contraction_re
- 2 つの短縮形、contractions_re = _get_contractions(contraction_dict)
- 3 def replace_contractions(text): def replace (match): return contractions[match.group ( 0)] return contractions_re.sub( replace , text)
- 4 # 使用法 replace_contractions( "これは短縮形を含むテキストです" )
上記の手法に加えて、ステミング、レマタイズ、ストップワードの削除などのテキスト前処理手法もあります。これらの手法はディープラーニング NLP モデルでは使用されないため、ここでは説明しません。 意味: シーケンスの作成ディープラーニングが自然言語処理 (NLP) の「頼りになる」選択肢となっている理由の 1 つは、テキスト データから手動で特徴を設計することが実質的に不要であることです。ディープラーニング アルゴリズムは、テキストのシーケンスを入力として受け取り、人間と同じようにテキストの構造を学習します。機械は言葉を理解できないため、データが数値形式で提供されることを期待します。そこで、テキストデータを一連の数字として表現したいと思います。 これがどのように行われるかを理解するには、Keras Tokenizer 関数について少し理解する必要があります。他のトークナイザーも使用できますが、Keras トークナイザーが人気のある選択肢です。 (1)マーカー 簡単に言えば、トークナイザーは文を単語に分割するユーティリティ関数です。 keras.preprocessing.text.Tokenizer は、テキスト コーパス内で最も頻繁に出現する単語のみを保持しながら、テキストをトークン (単語) にトークン化 (分割) します。 パイソン - 1#署名: Tokenizer(num_words=None, フィルター= '!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n' , lower = True , split= ' ' , char_level= False , oov_token=None, document_count=0, **kwargs)
num_words パラメータは、テキスト内の事前に指定された数の単語のみを保持します。これは、めったに出現しない単語を考慮してこのモデルが大量のノイズを生成するのを避けるのに役立ちます。実際のデータでは、num_words パラメータを使用して省略された単語のほとんどはスペルミスであることが多いです。デフォルトでは、トークナイザーは不要なトークンをフィルタリングし、テキストを小文字に変換します。 トークナイザーがデータに適合すると、次の方法でアクセスできる単語インデックス (単語に一意の番号を割り当てるために使用できる単語の辞書) も保持されます。 - トークナイザー.word_index
インデックス辞書内の単語は頻度順に並べられています。 したがって、トークナイザーを使用するコード全体は次のようになります。 パイソン - from keras.preprocessing.text import Tokenizer ## 文をトークン化します tokenizer = Tokenizer(num_words=max_features) tokenizer.fit_on_texts(list(train_X)+list(test_X)) train_X = tokenizer.texts_to_sequences(train_X) test_X = tokenizer.texts_to_sequences(test_X)
ここで、train_X と test_X はコーパス内のドキュメントのリストです。 (2)シーケンス前処理 通常、モデルは各シーケンス (各トレーニング例) が同じ長さ (同じ数の単語/トークン) であることを想定しています。これは maxlen パラメータを使用して制御できます。 例えば: パイソン - train_X = pad_sequences(train_X, maxlen=maxlen) test_X = pad_sequences(test_X, maxlen=maxlen)
これで、トレーニング データは数字のリストで構成されます。各リストの長さは同じです。また、テキストコーパス内で最も多く出現する単語の辞書である word_index もあります。 (3)エンリッチメントの埋め込み 前述のように、エンリッチメントは GLoVE Word2Vec 埋め込みを使用して説明されます。 GLoVE の事前トレーニング済みベクトルは、Wikipedia コーパスでトレーニングされています。 つまり、データに現れる可能性のある一部の単語が埋め込みには現れない可能性があります。それで、どう対処すればいいのでしょうか? まず、Glove Embeddings をロードします。 パイソン - 1 def load_glove_index(): EMBEDDING_FILE = '../input/embeddings/glove.840B.300d/glove.840B.300d.txt' def get_coefs(word,*arr): return word, np.asarray(arr, dtype= 'float32' )[:300] 埋め込みインデックス = dict(get_coefs(*o.split( " " )) for o in 開く(EMBEDDING_FILE))埋め込みインデックスを返す
- 2 グローブ埋め込みインデックス = load_glove_index()
これらの GLoVE ベクターがダウンロードされるフォルダーへのパスを必ず含めてください。 この glove_embedding_index には何が含まれているのでしょうか? これは単なる辞書で、キーは単語、値は単語の埋め込みであり、長さ 300 (約 10 億) の np.array です。 word_index 内の単語の埋め込みのみが必要なので、必要な埋め込みのみを含む行列を作成します。 パイソン - 1 def create_glove(word_index,embeddings_index): emb_mean,emb_std = -0.005838499,0.48782197 all_embs = np.stack(embeddings_index.values ( ))embed_size = all_embs.shape[1] nb_words = min (max_features, len(word_index))embedding_matrix = np.random.normal(emb_mean, emb_std, (nb_words,embed_size))count_found = nb_words for word, i in tqdm(word_index.items()): if i >= max_features: continueembedding_vector =embeddings_index.get(word) ifembedding_vector is Noneでない場合:embedding_matrix[i] =embedding_vectorそれ以外の場合:count_found-=1 print( "" 、count_found、 " 語の埋め込みを取得しました。 " ) returnembedding_matrix
上記のコードは正常に動作しますが、GLoVE の前処理を活用する方法はありますか? はい。著者らは、グローブの前処理時に単語を小文字に変換しませんでした。つまり、「USA」、「usa」、「Usa」という単語の複数のバリエーションが含まれています。これはまた、場合によっては、「Word」のような単語は存在するものの、その小文字の類似語である「word」が存在しないことも意味します。 この状況は次のコードを使用することで解決できます。 パイソン - 1 def create_glove(word_index,embeddings_index): emb_mean,emb_std = -0.005838499,0.48782197 all_embs = np.stack(embeddings_index.values ( ))embed_size = all_embs.shape[1] nb_words = min (max_features, len(word_index))embedding_matrix = np.random.normal(emb_mean, emb_std, (nb_words,embed_size))count_found = nb_words for word, i in tqdm(word_index.items()): if i >= max_features: continueembedding_vector =embeddings_index.get(word) ifembedding_vector is not None:embedding_matrix[i] =embedding_vector else : if word.islower(): #小文字の場合はタイトルケースで単語の埋め込みを取得しようとする 存在しないembedding_vector =embeddings_index.get(word.capitalize()) 埋め込みベクトルが None ではない:embedding_matrix[i] =embedding_vector else : count_found-=1 else : count_found-=1 print( "" 、count_found、 "語の埋め込みを取得しました。" ) returnembedding_matrix
上記は、埋め込み知識を活用してより優れたカバレッジを実現する方法の一例にすぎません。場合によっては、問題に応じて、ドメイン知識と自然言語処理 (NLP) スキルを使用して埋め込みに追加情報を追加することで価値を得られることもあります。 たとえば、Python の TextBlob パッケージで単語の極性と主観性を追加することで、埋め込み自体に外部知識を追加できます。 パイソン - 1 textblobからTextBlob をインポート word_sent = TextBlob( "good" ).sentiment print(word_sent.polarity,word_sent.subjectivity) # 0.7 0.6
TextBlob を使用すると、任意の単語の極性と主観性を取得できます。したがって、この追加情報を埋め込みに追加してみることもできます。 パイソン - 1 def create_glove(word_index,embeddings_index): emb_mean,emb_std = -0.005838499,0.48782197 all_embs = np.stack(embeddings_index.values ( )) embed_size = all_embs.shape[1] nb_words = min (max_features, len(word_index))embedding_matrix = np.random.normal(emb_mean, emb_std, (nb_words,embed_size+4)) count_found = nb_words for word, i in tqdm(word_index.items()): if i >= max_features: continueembedding_vector =embeddings_index.get(word) word_sent = TextBlob(word).sentiment #埋め込みに渡す追加情報extra_embed = [word_sent.polarity,word_sent.subjectivity] 埋め込みベクトルが Noneでない場合:embedding_matrix[i] = np.append(embedding_vector,extra_embed) else : word.islower()の場合:embedding_vector =embeddings_index.get(word.capitalize())embedding_vectorが Noneでない場合:embedding_matrix[i] = np.append(embedding_vector,extra_embed) else :embedding_matrix[i,300:] = extra_embed count_found-=1 else :embedding_matrix[i,300:] = extra_embed count_found-=1 print( "" 、count_found、 " 語の埋め込みを取得しました。 " ) returnembedding_matrix
埋め込みのエンジニアリングは、後の段階でディープラーニング モデルからより優れたパフォーマンスを得るために不可欠な要素です。通常、この部分のコードは、プロジェクトフェーズ中に何度か再検討され、さらに改良されたモデルが試されます。ここでは、word_index のカバレッジを改善し、埋め込みに追加の機能を含めるために多くの創造性を発揮できます。 その他のエンジニアリング機能埋め込み行列を用いたテキスト前処理法 文の長さ、一意の単語の数などの文固有の特徴を別の入力レイヤーとしていつでも追加して、ディープ ニューラル ネットワークに追加情報を提供することができます。 たとえば、これらの追加機能は、Quora Insincerity 分類チャレンジの機能エンジニアリング パイプラインの一部として作成されました。 パイソン - 1 def add_features(df):df [ 'question_text' ] = df [ ' question_text ' ] en)df [ ' capitals ' ] = df [ ' question_text' ] .progress_apply ( lambdaコメント: sum (c for c on c in comtn in c nect in c.isupper( ) ) ) df [ ' caps_vs_lengs axis=1) df[ 'num_words' ] = df.question_text.str. count ( '\S+' ) df[ 'num_unique_words' ] = df[ 'question_text' ].progress_apply(lambda comment: len( set (w for w in comment.split()))) df[ 'words_vs_unique' ] = df[ 'num_unique_words' ] / df[ 'num_words' ] return df
結論は自然言語処理 (NLP) はディープラーニングにおいて依然として非常に興味深い問題であるため、何が機能し、何が機能しないかを調べるために、より多くの人々が多くの実験を行うことを期待しています。ただし、自然言語処理 (NLP) の問題に対するディープラーニング ニューラル ネットワークの前処理手順を調べると、役立つ視点が得られます。 原題: ディープラーニングのためのテキスト前処理方法、著者: Kevin Vu [51CTOによる翻訳。パートナーサイトに転載する場合は、元の翻訳者と出典を51CTO.comとして明記してください] |