Natural language processing with ruby - part 1, Data pre-processing

Xử lý ngôn ngữ là một kĩ thuật quan trọng nhằm giúp máy tính hiểu được ngôn ngữ của con người, qua đó hướng dẫn máy tính thực hiện và giúp đỡ con người trong những công việc có liên quan đến ngôn ngữ như nhận dạng chữ viết, dịch máy, khai phá quan điểm ...

Có thể bạn đã biết, Google chính là một hệ thống lớn và nổi tiếng trong lĩnh vực xử lý ngôn ngữ tự nhiên trong việc áp dụng các kỹ thuật như dịch máy (google stranslate), hay information retrieval đối với máy tìm kiếm google. Nếu biết và nắm chắc kiến thức về xử lý ngôn ngữ tự nhiên biết đâu một ngày đẹp trời nào đó sản phẩm của bạn sẽ thay thế hoàn toàn Google 😄 =))

Khi thực hiện các project lớn về xử lý ngôn ngữ tự nhiên chắc hẳn các bạn thường liên tưởng đến python, Java hoặc C/C++ bởi sự hỗ trợ mạnh mẽ. Bạn đã bao giờ đặt ra những câu hỏi như: "Tại sao Python được tích hợp riêng một bộ công cụ phục vụ cho việc xử lý ngôn ngữ tự nhiên như NLTK vậy còn đối với ruby thì sao?" Đừng lo, với ruby xử lý ngôn ngữ tự nhiên cũng không hề khó.

Bài viết này tôi sẽ hướng dẫn các bạn một số bước cơ bản và quan trọng trong quá trình xử lý dữ liệu trước khi dữ liệu của bạn áp dụng các thuật toán học máy để giải quyết các bài toán trong lĩnh vực xử lý ngôn ngữ tự nhiên.

Tokenization

Tokenization là một quá trình xử lý nhằm mục đích xác định ranh giới của các từ trong câu văn.

Ví dụ "Framgia Vietnam là công ty IT Nhật Bản số 1 tại Việt Nam."

Sau khi được phân tách từ chúng ta sẽ nhận được output như sau:

["Framgia", "Vietnam", "là", "công", "ty", "IT", "Nhật", "Bản", "số", "1", "tại", "Việt", "Nam", "."]

Nếu là người làm xử lý ngữ tự nhiên tại Việt Nam, chắc hẳn bạn chẳng còn xa lạ gì với bộ vnTokenizer - một công cụ viết bằng java, được phát triển bởi thầy Lê Hồng Phương cùng cộng sự.

Với ruby bạn cũng có thể thực hiện tokenization rất dễ dàng thông qua việc sử dụng gem Tokenizer

Để cài đặt bộ công cụ này, hãy thêm vào Gemfile của bạn như sau

gem "tokenizer"

Hoặc sử dụng dòng lệnh

$ gem install tokenizer

Bạn có thể sử dụng bộ công cụ này bằng 2 cách

Command line tool:

$ echo 'Hi, ich gehe in die Schule!. | tokenize

Tích hợp thư viện tokenizer

require 'tokenizer'
de_tokenizer = Tokenizer::WhitespaceTokenizer.new
de_tokenizer.tokenize('Ich gehe in die Schule!')
# => ["Ich", "gehe", "in", "die", "Schule", "!"]

Word Segmentation

Word Segmentation là một bài toán vô cùng quan trọng để nâng cao độ chính xác trong qúa trình xử lý ngôn ngữ tự nhiên của bạn.

Một từ có thể có một, hai hoặc nhiều âm tiết tạo nên, nên có rất nhiều cách phân chia các âm tiết thành các từ, gây ra nhập nhằng. Việc phân giải nhập nhằng này gọi là bài toán tách từ.

Ví dụ với một câu input: "Học sinh học sinh học"

Kết qủa trả về sau quá trình thực hiện word segmentation như sau:

["Học sinh", "học", "sinh học"]

'srx-english' Là một thư viện Ruby chứa các quy luật của một câu tiếng anh và word segmentation.

Để cài đặt bộ công cụ này bạn có thể dùng lệnh

gem install srx-english

Bộ công cụ này cung cấp cho bạn 2 lựa chọn đó là: Sentences Segmentation và Word Segmentation

Đối với Sentences Segmentation bạn có thể sử dụng như sau:

require 'srx/english/sentence_splitter'

text =<<-END
  This is e.g. Mr. Smith, who talks slowly... And this is another sentence.
END

splitter = SRX::English::SentenceSplitter.new(text)
splitter.each do |sentence|
  puts sentence.gsub(/\n|\r/,"")
end
#=> This is e.g. Mr. Smith, who talks slowly...
#=> And this is another sentence.

Như vậy đối với 1 đoạn văn đầu vào "This is e.g. Mr. Smith, who talks slowly... And this is another sentence." bộ công cụ trên sẽ phân tích cho chúng ta đoạn văn này được cấu tạo từ 2 câu là "This is e.g. Mr. Smith, who talks slowly..." và "And this is another sentence."

Một cách dùng thứ hai là Word Segmentation

require 'srx/english/word_splitter'

sentence = 'My home is my castle.'
splitter = SRX::English::WordSplitter.new(sentence)
splitter.each do |word,type,start_offset,end_offset|
  puts "'#{word}' #{type}"
end
# => 'My' word
# => ' ' other
# => 'home' word
# => ' ' other
# => 'is' word
# => ' ' other
# => 'my' word
# => ' ' other
# => 'castle' word
# => '.' punct

N-gram Langguage Model

Mô hình ngôn ngữ được áp dụng trong rất nhiều lĩnh vực của xử lý ngôn ngữ tự nhiên như: kiểm lỗi chính tả, dịch máy hay phân đoạn từ... Chính vì vậy, nghiên cứu mô hình ngôn ngữ chính là tiền đề để nghiên cứu các lĩnh vực tiếp theo.

Mô hình ngôn ngữ có nhiều hướng tiếp cận, nhưng chủ yếu được xây dựng theo mô hình N-gram.

Xét trong một văn bản, N-gram là một cụm từ gồm N từ liên tiếp cùng xuất hiện trong văn bản đó. Nếu độ dài tính theo từ của một văn bản là L, thì số N-gram sinh ra là (L * (L - N + 1)) / 2. Như vậy N càng lớn thì số lượng N-gram sinh ra càng lớn.

Ví dụ với một câu input: "chiếc điện thoại này đẹp giá tốt". N-gram sinh ra như sau:

  • Unigram: ["chiếc", "điện", "thoại", "này", "đẹp", "giá", "tốt"]
  • Bigram: ["start chiếc", "chiếc điện", "điện thoại", "thoại này", "này đẹp", "đẹp giá", "giá tốt", "tốt end"]
  • ...........

ruby_nlp là một bộ công cụ đơn giản, cho phép bạn có thể sinh ra n-gram như ví dụ tôi đã nêu trên.

Bạn có thể sử dụng bộ công cụ này như sau:

install gem ruby_nlp

gem install ruby_nlp

Cách sử dụng:

require 'ruby_nlp/ngram'
ngram = Ngram.new("foo bar lux win")

ngram.unigrams # => [["foo"], ["bar"], ["lux"], ["win"]]
ngram.bigrams # => [["foo", "bar"], ["bar", "lux"], ["lux", "win"]]
ngram.trigrams # => [["foo", "bar", "lux"], ["bar", "lux", "win"]]
ngram.ngrams(4) # => [["foo", "bar", "lux", "win"]]

ngram = Ngram.new("abcde", regex: //)
ngram.unigrams # => [["a"], ["b"], ["c"], ["d"], ["e"]]

POS tagger

Part-Of-Speech tagging hay còn gọi là gán nhãn từ loại là một công việc quan trọng và bắt buộc phải có đối với mọi hệ xử lý ngôn ngữ tự nhiên. Công việc gán nhãn từ loại cho một văn bản là xác định từ loại của mỗi từ trong phạm vi văn bản đó, tức là phân loại các từ thành các lớp từ loại dựa trên thực tiễn hoạt động ngôn ngữ trong đó:

Ví dụ

input: Một chuỗi các từ và tập nhãn từ loại (Ví dụ đối với tiếng Anh: “Book that flight.”, và tập thẻ Penn Treebank)

output: Một nhãn tốt nhất cho từng từ trong câu (Ví dụ: Book/VB that/DT flight/NN ./.)

Đối với dữ liệu input là tiếng anh, bạn có thể sử dụng bộ công cụ EngTagger

cài đặt:

gem install engtagger

Bạn có thể sử dụng bộ công cụ này như sau:

require 'rubygems'
require 'engtagger'

# Create a parser object
tgr = EngTagger.new

# Sample text
text = "Alice chased the big fat cat."

# Add part-of-speech tags to text
tagged = tgr.add_tags(text)

#=> "<nnp>Alice</nnp> <vbd>chased</vbd> <det>the</det> <jj>big</jj> <jj>fat</jj><nn>cat</nn> <pp>.</pp>"

Tập nhãn POS tags được sử dụng ở đây là một phiên bản đã được sửa đổi từ tập nhãn Penn Treebank

dưới đây là tập nhãn được sử dụng cho mục đích gán nhãn từ loại (part-Of-Speech tagging) trong bộ công cụ này.

CC      Conjunction, coordinating               and, or
CD      Adjective, cardinal number              3, fifteen
DET     Determiner                              this, each, some
EX      Pronoun, existential there              there
FW      Foreign words
IN      Preposition / Conjunction               for, of, although, that
JJ      Adjective                               happy, bad
JJR     Adjective, comparative                  happier, worse
JJS     Adjective, superlative                  happiest, worst
LS      Symbol, list item                       A, A.
MD      Verb, modal                             can, could, 'll
NN      Noun                                    aircraft, data
NNP     Noun, proper                            London, Michael
NNPS    Noun, proper, plural                    Australians, Methodists
NNS     Noun, plural                            women, books
PDT     Determiner, prequalifier                quite, all, half
POS     Possessive                              's, '
PRP     Determiner, possessive second           mine, yours
PRPS    Determiner, possessive                  their, your
RB      Adverb                                  often, not, very, here
RBR     Adverb, comparative                     faster
RBS     Adverb, superlative                     fastest
RP      Adverb, particle                        up, off, out
SYM     Symbol                                  *
TO      Preposition                             to
UH      Interjection                            oh, yes, mmm
VB      Verb, infinitive                        take, live
VBD     Verb, past tense                        took, lived
VBG     Verb, gerund                            taking, living
VBN     Verb, past/passive participle           taken, lived
VBP     Verb, base present form                 take, live
VBZ     Verb, present 3SG -s form               takes, lives
WDT     Determiner, question                    which, whatever
WP      Pronoun, question                       who, whoever
WPS     Determiner, possessive & question       whose
WRB     Adverb, question                        when, how, however

PP      Punctuation, sentence ender             ., !, ?
PPC     Punctuation, comma                      ,
PPD     Punctuation, dollar sign                $
PPL     Punctuation, quotation mark left        ``
PPR     Punctuation, quotation mark right       ''
PPS     Punctuation, colon, semicolon, elipsis  :, ..., -
LRB     Punctuation, left bracket               (, {, [
RRB     Punctuation, right bracket              ), }, ]

Tổng Kết

Bài viết này tôi đã giới thiệu cho bạn một số công cụ hỗ trợ trong quá trình xử lý ngôn ngữ tự nhiên. Hy vọng những điều trên sẽ giúp ích được nhiều cho bạn trong công việc, học tập và nghiên cứu lĩnh vực này. Tuy nhiên, xử lý ngôn ngữ tự nhiên là một lĩnh vực rất rộng và khó trong Công Nghệ Thông Tin, Nhưng nếu như chỉ dừng lại ở mức tiền xử lý dữ liệu thì sẽ không còn là bài toán xử lý ngôn ngữ tự nhiên nữa. Ở bài viết sau tôi sẽ giới thiệu một số phương pháp học máy thường được áp dụng để giải quyết một số bài toán của NLP. Hy vọng sẽ nhận được sự quan tâm từ các bạn.

tài liệu tham khảo