自然言語処理におけるテキスト表現手法の概要

テキストデータのコンピュータ表現

画像データがRGBやYUVなどの形式で表されるように、自然言語処理(NLP)では文字列をコンピュータで処理可能な数値形式に変換する必要があります。画像処理で扱うピクセル行列と同様に、テキストデータも行列形式で表現されます。

分かち書き処理

日本語などの連続文字言語では、文章を意味のある単位に分割する処理が必要です。最大マッチングアルゴリズム(正向・逆向・双方向)を用いた例を示します。

def forward_max_match(text, max_length=6):
    result = []
    while text:
        matched = False
        for i in range(max_length, 0, -1):
            if len(text) >= i:
                word = text[:i]
                if is_valid_word(word):  # 辞書に存在するか確認
                    result.append(word)
                    text = text[i:]
                    matched = True
                    break
        if not matched:
            result.append(text[0])
            text = text[1:]
    return result

# 実行例
sentence = "今日の夕食はとても美味しかった"
tokens = forward_max_match(sentence)
print(tokens)  # ["今日", "の", "夕食", "は", "とても", "美味しかった"]

one-hotエンコーディング

最も基本的なベクトル表現方法で、語彙数と同じ次元を持ちます。

vocab = {"私": 0, "今日": 1, "朝": 2, "食事": 3, "美味": 4, "かった": 5}

def one_hot_encode(word):
    vector = [0] * len(vocab)
    vector[vocab[word]] = 1
    return vector

# 例
print(one_hot_encode("朝"))  # [0, 0, 1, 0, 0, 0]

TF-IDFによる重み付け

単語の重要度を考慮した表現方法で、文書内での出現頻度と語彙全体での重要度を組み合わせます。

def calculate_tf_idf(term, doc, corpus):
    # TFの計算
    tf = doc.count(term) / len(doc)
    
    # IDFの計算
    doc_count = sum(1 for d in corpus if term in d)
    idf = math.log(len(corpus) / (doc_count + 1))
    
    return tf * idf

# 例
document = ["今日", "天気", "良い"]
corpus = [["今日", "天気", "良い"], ["昨日", "雨", "降った"]]
weight = calculate_tf_idf("天気", document, corpus)
print(f"TF-IDF: {weight:.3f}")

word2vecによる分散表現

ニューロンネットワークを用いた次元削減表現で、語義の類似性をベクトル空間で表現します。

word_vectors = {
    "朝": [0.15, 0.22, 0.37],
    "今日": [0.53, 0.11, 0.18],
    "食事": [0.42, 0.92, 0.0]
}

def cosine_similarity(v1, v2):
    return sum(a*b for a,b in zip(v1,v2)) / (math.sqrt(sum(x*x for x in v1)) * math.sqrt(sum(y*y for y in v2)))

# 類似度計算
similarity = cosine_similarity(word_vectors["朝"], word_vectors["今日"])
print(f"朝と今日の類似度: {similarity:.2f}")

word2vecの学習プロセス

CBOW(Continuous Bag of Words)とSkip-gramの2つのモデル構造があります。CBOWは周辺語から中心語を予測し、Skip-gramは中心語から周辺語を予測します。

  • 語彙数1000、隠れ層ノード数150の場合は1000×150の重み行列が生成される
  • 訓練後、左側の行列が最終的な単語ベクトルとして利用される
  • 150~300次元が一般的なベクトルサイズ

タグ: NLP word-embedding tf-idf word2vec text-representation

5月15日 22:51 投稿