Tuesday, May 20, 2008

Giới thiệu về xử lý ngôn ngữ tự nhiên

(lược dịch từ Getting Started on Natural Language Processing with Python)

Những khái niệm cơ bản

Token: trước khi xử lý, dữ liệu text đầu vào cần được phân đoạn thành các đơn vị ngôn ngữ như là từ, dấu chấm câu, số và chữ số. Các đơn vị ngôn ngữ đó được gọi chung là tokens.

Sentence: Một chuỗi có thứ tự các tokens

Tokenization: quá trình phân chia một sent thành các tokens. Với segmented language như tiếng Anh, có thể tokenize dễ dàng với dấu cách (whitespace). Tuy nhiên, với những ngôn ngữ như tiếng Việt, tiếng Trung hay tiếng Ả Rập, tokenization khó hơn nhiều vì không có biên giới rõ rành giữa các từ như tiếng Anh. Hơn thế nữa mọi ký tự trong ngôn ngữ tượng hình như tiếng Trung, tiếng Ả Rập đều có thể tồn tại như một từ đơn ký tự hoặc cũng có thể kết hợp với nhau để tạo thành từ đa ký tự.

Corpus: a body of text, thường chứa rất nhiều sent.

Part-of-speech (POS) tag: một từ có thể được phân loại vào một hay nhiều tập từ vựng (lexical) hoặc lớp từ loại như là danh từ, động từ, tính từ, và giới từ .. Một POS tag là một biểu tượng tượng trưng cho một lớp từ vựng - NN(Noun), VB(Verb), JJ(Adjective), AT(Article). Một trong những tập tags lâu đời và phổ biến nhất là Brow Corpus tag set.

Parse Tree: với mỗi một sent có một tree tương ứng biểu diễn cấu trúc cú pháp của sent đó. Cấu trúc cú pháp được định nghĩa bởi một ngôn ngữ hình thức (formal language).

Những bài toán phổ thông

POS Tagging: cho một câu và một tập POS tags, hãy gán nhãn cho từng từ trong câu. Ví dụ, cho câu “The ball is red”, POS tagger sẽ cho output là “The/AT ball/NN is/VB red/JJ”. POS taggers hiện thời có thể đạt tới độ chính xác 96% (Stanford POS Tagger đạt tới độ chính các trên 97% trong thử nghiệm ở đây). Gán nhãn từ rất hữu dụng cho những bài toán NLP phức tạp hơn như là parsing và machine translation.

Computational Morphology (hình thái học): Ngôn ngữ tự nhiên bao gồm rất nhiều word được xây dựng từ morphemes hay stems (thân từ) - đơn vị ngôn ngữ nhỏ nhất mà còn mang ý nghĩa. Computational Morphology sử dụng máy tính để phát hiện và phân tích cấu trúc bên trong của các words.

Parsing: trong bài toán phân tích câu, một parser sẽ tạo ra một parse tree với đầu vào là một sent. Một vài parsers giả sử có sự tồn tại của một tập luật cú pháp (grammar rules) để dựa trên đó mà phân tích. Các parsers gần đây đã đủ thông minh để suy diễn (deduce) parse trees trực tiếp từ các dữ liệu sử dụng các mô hình thống kê phức tạp. Hầu hết parses đều hoạt động có giám sát (operate in supervised setting) và yêu cầu sent phải được gán nhãn từ loại trước khi phân tích ngữ pháp (parse).

Machine Translation (MT): mục đích của MT là dùng máy tính để dịch một đoạn text từ một ngôn ngữ tự nhiên này sang một ngôn ngữ tự nhiên khác mà không cần sự tham gia của con người. Đây là một trong những bài toán khó nhất của NLP và đã được giải theo nhiều hướng khác nhau trong nhiều năm liền. Hầu hết các cách tiếp cận đều sử dụng POS taggingparsing như là các bước cơ bản.

Viết tắt:
doc => document
sent => sentence
pos => part-of-speech (từ loại như là danh từ, động từ, tính từ .. )

Friday, May 16, 2008

Bánh Big Macs vs. người đầu bếp tài năng

(lược dịch từ http://www.joelonsoftware.com/articles/fog0000000024.html)

Tại sao một số công ty IT lớn nhất lại trở nên dở nhất?

Có sự liên hệ gì nữa MacDonal’s (dây chuyền sản xuất Hamburger tệ nhất) và sự kiện trên?

Bí mật của bánh Big Macs là mọi chiếc bánh đều dở giống hệt như nhau. Một bí mật nữa là chỉ cần IQ của anh đần là đủ để tạo ra bánh Big Macs “dở giống hệt nhau trên toàn thế giới”. Nếu một chiếc Big Macs được rán 37 giây ở Mỹ, nó cũng được rán đúng 37 giây ở Singapore (đúng 37 giây, không hơn, không kém). Để tạo bánh Big Macs bạn chỉ cần tuân theo những luật cứng nhắc đó.

Những luật đó đã được thiết kế một cách cẩn thận bởi những con người thông minh (ở trường đại học McDonald’s Hamburger) sao cho những người bình thường nhất cũng có thể làm theo được. Những luật đó bao gồm tất cả quy trình tránh lỗi (failsafes) như là rung chuông nếu bạn rán bánh quá 37 giây. Hệ thống đó về cơ bản luôn giả sử rằng mọi người sẽ mắc phải rất nhiều lỗi.

Hãy so sánh một đầu bếp của McDonal’s, người luôn tuân theo luật một cách tuyệt đối với một đầu bếp tài năng. Đầu bếp tài năng không dập khuôn theo một cuốn cẩm nang nấu ăn nào hết. Anh ta không đo lường (rán đúng trong 37 giây chẳng hạn). Khi nấu ăn, bạn sẽ thấy thức ăn như nhảy múa dưới bàn tay người đầu bếp tài năng. “Chúng ta chỉ cần cho thêm một ít bột nêm vào đảo đều”, anh ta nói. “Hãy dải đều rau thơm lên trên món ăn nào”. Thế là xong, chúng ta có một món ăn tuyệt hảo!

Hiển nhiên là thức ăn của người đầu bếp tài năng ngon hơn rất nhiều so với bánh Big Macs. Có vẻ như là ngu xuẩn nhưng sẽ rất đáng giá nếu bạn đặt câu hỏi “tại sao?”. Tại sao một công ty nhiều tiền của, đa chi nhánh, có thể thuê những đầu bếp tài năng nhất lại không thể tạo được một bữa ăn ngon miệng?

Hãy tưởng tượng người đầu bếp tài năng quyết định mở cửa hàng ăn. Vì thức ăn của anh rất ngon nên cửa hàng vô cùng đông khách. Công việc kinh doanh hết sức thuận lợi nhưng cũng rất nhanh, anh ta nhận ra rằng nguồn thu nhập của cửa hàng không tăng hơn được nữa bởi một mình anh không thể tạo ra nhiều thức ăn. Vì vậy anh ta quyết định thuê thêm đầu bếp và mở thêm nhiều chi nhánh ở các thành phố khác.

Lúc này, vấn đề bắt đầu nảy sinh. Dân kỹ thuật chúng ta gọi là bài toán mở rộng (scalability problem). Khi bạn cố nhân bản một nhà hàng, bạn phải quyết định giữa việc thuê một đầu bếp tài năng (trong trường hợp này người đầu bếp được thuê sẽ muốn giữ phần lớn lợi nhuận của cửa hàng mới do anh ta tạo ra) và một đầu bếp trẻ tay nghề chưa cao và khách hàng của cửa hàng mới sẽ sớm phát hiện ra chất lượng thức ăn không tốt và không tới cửa hàng đó nữa.

Cách thông thường để giải quyết bài toán mở rộng là thuê một đầu bếp rẻ tiền và đưa cho anh ta một tập các luật cứng nhắc để anh ta có thể tạo ra thức ăn đủ tốt.

Vấn đề là nó không hoạt động như ta mong muốn. Có hàng ngàn thứ mà một đầu bếp nhàng nhàng không thể bắp chước hoặc làm giống hệt như một đầu bếp tài năng được.

Tổng kết

* Để làm được một việc thật tốt, chúng ta cần tài năng thực sự
* Nhân bản tài năng là cực khó
* Một cách để nhân bản tài năng là để cho những người tài tạo ra những luật mà người bình thường có thể làm theo
* Chất lượng của việc nhân bài tài năng như trên thường là thấp (big macs)

Bạn có thể thấy điều tương tự ở những công ty tư vấn IT. Bạn đã bao nhiêu lần từng nghe câu như thế này:

Tuấn rất không vui. Anh vừa thuê một công ty IT lớn xây dựng hệ thống hỗ trợ bán hàng. Những nhà tư vấn IT mà anh vừa thuê cứ mải mê nói chuyện về “Methodology” và tiêu tốn hết hàng trăm triệu đồng mà chẳng làm nên trò trống gì hết.

May mắn thay, Tuấn tìm được một lập trình viên trẻ và tài năng. Tay lập trình viên này xây dựng xong hệ thống trong một ngày với thù lao 200 nghìn và một tô phở. Tuấn rất vui. Anh giới thiệu tay lập trình viên này cho bạn bè của mình.

Chàng trình viên trẻ bắt đầu kiếm bộn tiền và nhanh chóng nhận ra rằng anh không thể làm hết khối lượng công việc được đặt hàng và liền thuê nhiều người để giúp việc. Những người giỏi có thể đòi quá nhiều cổ phiếu vì thế anh ta quyết định thuê cả những lập trình viên trẻ mới tốt nghiệp và đào tạo họ trong vòng 6 tuần.

Vấn đề là khóa đào tạo ngắn hạn không tạo ra những lập trình viên đủ tốt để giữ cho chất lượng sản phẩm đủ tốt. Vì thế, chàng lập trình viên liền tạo ra một tập các luật với mục đích là để giúp tạo giữ cho chất lượng sản phẩm không đổi. Sau 6 năm, tập luật ngày càng nhiều lên và nó trở thành 6 tập sách dầy được gọi là Methodology.

Sau vài chục năm, công ty nhỏ bé ngày nào đã trở thành một tập đoàn lớn. Rất nhiều nhân viên của tập đoàn này hằng ngày vẫn răm rắp tuân theo Methodology cho dù nó đã lỗi thời hoặc có một vài chỗ hoạt động không hiệu quả bởi vì họ không có thể nghĩ ra cách khác để hoàn thành công việc — vì họ không phải là những lập trình viên tài năng. Họ được thuê hàng loạt với giá thị trường. Đến lúc này, một lập trình viên trẻ tài năng khác xuất hiện và một chu kỳ mới lại bắt đầu.

Mọi công ty tin học đều muốn phát triển thật nhanh, nhanh hơn khả năng tuyển dụng được người tài. Các công ty đó phát triển dựa trên tầng tầng lớp lớp những luật và quy trình nhằm đảm bảo chất lượng đồng nhất. Nhưng hãy nhớ rằng, những luật đó chỉ hoạt động khi không có biến cố.

Bài học rút ra

* Người tài không muốn làm bánh Big Macs
* Hãy thận trọng với Methodologies
* Chỉ mở rộng khi tìm được người tài

Saturday, May 10, 2008

Để thành công trong lập trình

(Lược dịch từ “Teach Yourself Programming in Ten Years” của Peter Norvig)
Công thức để thành công trong lập trình là:

- Yêu thích lập trình vì cảm thấy lập trình rất thú vị. Chắc chắn rằng lập trình đủ thú vị để bạn có thể tiếp tục luyện tập trong 10 năm

- Trao đổi (với những lập trình viên khác) và đọc mã nguồn quan trọng hơn nhiều so với bất kỳ cuốn sách hoặc khóa học lập trình nào.

- Chương trình là trọng tâm. Cách học tốt nhất là “vừa làm vừa học” (learning by doing). Ngưỡng cao nhất mà con người có thể đạt được trong một lĩnh vực không phụ thuộc vào kinh nghiệm tích lũy được (có quan điểm cho rằng khi một người làm việc quá lâu trong một lĩnh vực, họ không thể nâng cao trình độ hơn được nữa). Ngưỡng đó có thể được nâng lên kể cả với những người giàu kinh nghiệm bằng cách luôn cố gắng cải tiến. “Cách hiệu quả nhất để nâng cao trình độ là có một đề bài được định nghĩa tốt với mức độ khó phù hợp cho từng cá nhân, thông tin phản hồi, và cơ hội lặp lại và sửa chữa lỗi” (opportunities for repetition and corrections of errors).

- Học đại học (thường là 4 năm) hoặc học cao hơn nữa sẽ giúp bạn tìm được công việc đòi hỏi bằng cấp, và học tập còn giúp bạn hiểu sâu hơn về lĩnh vực theo học. Nhưng nếu bạn không thích trường học, bạn có thể đạt được kinh nghiệm cần thiết cần thiết cho công việc (bằng cách tự học). “Giáo dục về khoa học máy tính không giúp cho ai đó có thể trở thành lập trình viên lão luyện, nó giống như việc nghiên cứu cây cọ và màu vẽ không giúp cho ai đó trở thành một họa sỹ tài năng”. Tôi (Peter Norvig) đã từng thuê một lập trình viên chỉ học hết cấp 3, anh ta đã làm ra những phần mềm lớn và có đủ tiền để mua một hộp đêm cho riêng anh ta.

- Làm việc nhóm với các lập trình viên khác. Là người “giỏi nhất” trong một số dự án, là người “dở nhất” trong một số dự án khác. Khi bạn là người giỏi nhất, bạn thực hành khả năng lãnh đạo và truyền cảm hứng cho người khác bằng tầm nhìn của bạn. Khi bạn là người dở nhất, bạn học hỏi cách những người giỏi làm việc, và học cả những việc mà người giỏi không muốn làm (vì họ sẽ bắt bạn làm những việc đó).

- Tham gia những dự án với tư cách là người đến sau. Hãy hiểu chương trình viết bởi những lập trình viên khác. Hãy ngẫm nghĩ xem để hiểu chương trình do người khác viết thì cần có những thông tin gì và bổ xung thông tin đó (nếu thiếu). Suy nghĩ xem nên thiết kế chương trình thế nào để thuận tiện cho những người sẽ tiếp tục phát triển chương trình của bạn.

- Học ít nhất 6 ngôn ngữ lập trình. Bao gồm một ngôn ngữ hỗ trợ trừa tượng hóa lớp (class abstraction) như là Java hoặc C++, một ngôn ngữ hỗ trợ trừa tượng hóa hàm (funtional abstraction) như là Lisp hoặc ML, một ngôn ngữ hỗ trợ declarative specifiaction như là Prolog hoặc C++ templates, một ngôn ngữ hỗ trợ coroutines như là Icon hoặc Scheme, một ngôn ngữ hỗ trợ lập trình song song như là Sisal.

- Hãy nhớ từ “máy tính” trong cụm từ “khoa học máy tính”. Phải biết cần bao nhiêu thời gian để máy tính thực hiện một lệnh, đọc một word vào bộ nhớ (khi có hoặc ko có cache miss), đọc những words liên tiếp từ đĩa cứng, và tìm kiếm vị trí mới trên đĩa.

- Tham gia chuẩn hóa ngôn ngữ. Như là tham gia ANSI C++ committee, hoặc đơn giản hơn là quyết định xem coding style của bạn để lề (indentation) theo kiểu 2 ô trắng hay 4 ô trắng. Hãy học xem cái gì làm người khác lại thích ở một ngôn ngữ lập trình, họ thích đến mức nào và nếu có thể tìm hiểu vì sao mà họ thích.

- Hãy sử dụng những chuẩn bạn học được (một cách thích hợp) càm sớm càng tốt.

Tuesday, May 6, 2008

Good jQuery cheat sheets and API lookup

  • www.cheat-sheets.org/saved-copy/Jquery-Cheat-Sheet-1.2.pdf
  • http://labs.colorcharge.com/jquery/jquery12_colorcharge.png
  • http://www.gscottolson.com/weblog/2008/01/11/jquery-cheat-sheet/
  • http://remysharp.com/jquery-api/

Fun with JavaScript Chainability

want to show all string properties of an object in JavaScript?


function showAllStringPropertiesOf( object ) {
for (var property in object) {
if (typeof object[property] == "string") {
console.log(property, ":", object[property]);
}
}
}

var object1 = {
name: "Spiragram",
address: "87 Beach Road",
vision: "Spiragram will liberate, lead and inspire programmers to realize their full potential ..."
},
object2 = {
name: "Tien Dung",
age: 26,
saySomething: function () { alert("hello from " + this.name); }
};

showAllStringPropertiesOf(object1);
showAllStringPropertiesOf(object2);

is it nice if we do not have to duplicate the function name? We can write:


forEach([object1, object2], showAllStringPropertiesOf );

where forEach is a funtion:


function forEach( a, fn ) {
var i, l = a.length;
for (i = 0; i < l; i+=1) {
fn(a[i]);
}
end

is there a better way (because we have only two objects)? The answer is making the function chainable by adding a return itself command to the end of the function.


function showAllStringPropertiesOf ( ... ) {
...
...
return arguments.callee;
}

now we can call:

showAllStringPropertiesOf( object1 )( object2 );

still want to make it more readable? Let make more fun with “and” keyword.

showAllStringPropertiesOf( object1 ).and( object2 );

by adding some code below

function showAllStringPropertiesOf ( ... ) {
...
...
return addAndMagicTo(arguments.callee);
}

function addAndMagicTo( fn ) {
fn.and = fn;
return fn;
}

Monday, May 5, 2008

Phật giáo thời đại Internet

http://www.giacngo.vn: Một trang tin mới tinh về phật và thiền vừa mới go live tháng trước. Trang web tổng hợp tin tức từ khá nhiều nguồn. Có nhiều bài thú vị. Tớ thích mấy bài pháp thoại cuả thiền sư Nhất Hạnh, gần gũi, dễ hiểu mà sâu sắc:
Có lẽ tớ thích tên miền tinhthuc hơn là giacngo. Giác ngộ nghe hơi có vẻ cao siêu. Tỉnh thức thì ai cũng làm được, chỉ cần có ý thức là mình sống trong mơ là bắt đầu có tỉnh thức rồi. Từ Bụt (hay Buddhism trong tiếng Anh) cũng có nghĩa là tỉnh thức.