1.はじめに
textCNNを使って特許文献を分類してみました。
結構いい感じに分類してくれました。
2.textCNNについて
textCNNとは、畳み込みニューラルネットワーク(CNN)をテキスト分類に応用した手法です。論文に記載されている構造を真似してtensorflowで層を作成しました。(Convolutional Neural Networks for Sentence Classification,2014)
textCNNは次の四つの層からなります。
embedding layer: 入力された単語ベクトルを分散表現(単語埋め込み)に変換する層です。事前学習済みのword2vecやランダムな値を初期値として使うことができます。
convolutional layer: 複数のフィルター(カーネル)を用意し、フィルターサイズ分の単語に対して畳み込み処理(内積計算)を行って新しい特徴量ベクトルを生成する層です。
max-over-time pooling layer: 各フィルターで生成された特徴量ベクトルから最大値だけ抽出する層です。これにより、入力文書の長さに依存しない固定長の特徴量ベクトルが得られます。
output layer: pooling layerの出力に全結合層とsoftmax関数を適用して分類結果(確率値)を出力する層です。
3.作成した構造
こんな感じです。このレポジトリの構造を参考に、「こんな感じに書けばいいのかな?」と書いてみました。
ソースコードはこちら。
#@title モデル作成
from tensorflow.keras import layers
import math
#Functionalな書き方。
# A text input.
text_input = tf.keras.Input(shape=(1,), dtype=tf.string, name='text')
#embedding layer:
x = vectorize_layer(text_input)
x = layers.Embedding(max_features + 1, embedding_dim)(x)
x = layers.Dropout(0.5)(x)
x1 = layers.Reshape((vocab_size,embedding_dim,1))(x)
#convolutional layer
x_3 = layers.Conv2D(100,(3,embedding_dim), padding='valid', activation='relu', strides=3)(x1)
x_4 = layers.Conv2D(100,(4,embedding_dim) , padding='valid', activation='relu', strides=4)(x1)
x_5 = layers.Conv2D(100,(5,embedding_dim), padding='valid', activation='relu', strides=5)(x1)
#max-over-time pooling layer
x_3 = layers.MaxPooling2D((math.floor(vocab_size /3),1))(x_3)
x_4 = layers.MaxPooling2D((math.floor(vocab_size /4),1))(x_4)
x_5 = layers.MaxPooling2D((math.floor(vocab_size /5),1))(x_5)
#output layer
x_all = layers.concatenate([x_3,x_4,x_5])
x = layers.Flatten()(x_all)
x = layers.Dropout(0.5)(x)
predictions = layers.Dense(1, activation='sigmoid', name='predictions')(x)
#comple
model = tf.keras.Model(text_input, predictions)
model.compile(
loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']
)
#visualize
model.summary()
dot_img_file = 'model_1.png'
tf.keras.utils.plot_model(model, to_file=dot_img_file, show_shapes=True)
4.工夫した点
上記のvectrization層。tf.keras.layers.TextVectorization。TokenizationからID変換(分かち書き、n-gram、正規化、outputの変更)までを一気にやってくれます。最初からテキストを投入できるので素敵。コードはこんな感じです。⇓
max_features = 3000
embedding_dim = 200
max_len = 200
vectorize_layer = TextVectorization(
standardize=custom_standardization,
#split="character",
split=segment_by_spm,
max_tokens=max_features,
ngrams=(1,1),
#output_mode='tf-idf',
#output_mode='int',
output_mode = 'count',
#output_sequence_length=max_len
#output_mode = 'multi_hot',
#pad_to_max_tokens=True,
#sparse=True,
)
分かち書きは今回はsentencepieceを使いましたが、分かち書きは入れ替えればginzaもmecabもできると思います。
textCNNなのでoutput_modeはcount(multi-hot)で処理しましたが、BERTならばintのモードで出せば、paddingもしてくれた上でIDに対応させて出力してくれます。
あと、3,4,5の畳み込みってどうやればいいの?状態でしたが、tensorflowのFunctionalな書き方をした時の引数?の部分を分裂(x_3、x_4、x_5)させて、layers.concatenateで連結してまたもとに戻す(x_all)という操作でできるのが分かりました。
結果
その後、特許調査に使う母集団を作成し、要約と請求項をもとに、関連性をスコアで出力してもらいました。
学習にかかった時間はgoogle colaboratoryでGPUを使い5分ほど。精度は0.980程度でした。
こんな感じに出してくれます⇓便利だなあ。streamlitをかませて、リアルタイムでy_trainを修正して、スコア更新をしてみたいと思いました。
Комментарии