Khai phá dữ liệu dưới dạng văn bản tài liệu

Phân tích dự đoán, kinh doanh thông minh, và khai phá dữ liệu nói chung tất cả các nhu cầu lưu trữ và xử lý các cấu trúc dữ liệu phức tạp và thường rất khác nhau như thông tin được xử lý, phân tích, và tổng kết. Nó rất được coi trọng, đặc biệt là trong thông tin tài chính doanh nghiệp, mà đa số các dữ liệu xuất phát từ cơ sở dữ liệu quan hệ. Theo đó là một cấu trúc chặt chẽ và yêu cầu một phần lớn của việc chuẩn bị trước về mặt thiết kế lược đồ của bạn và các mô hình dữ liệu. Các thế hệ mới của NoSQL và cơ sở dữ liệu dựa trên văn bản (document-based databases) làm cho quá trình này đơn giản hơn bởi vì bạn có thể tạo và kết xuất thông tin theo một định dạng linh hoạt. Ngoài ra, bạn có thể làm việc dựa trên các phương pháp để trích xuất dữ liệu theo các định dạng cố định mà bạn cần. Trong bài viết này, tôi tìm hiểu làm thế nào để sử dụng cơ sở dữ liệu dựa trên văn bản cho việc phân tích và xử lý dữ liệu như là một phần của giải pháp tổng quan về cơ sở dữ liệu của bạn.

Martin Brown, Phó chủ tịch của Technical Publications, Couchbase

Ảnh của Martin BrownMartin 'MC' Brown là một tác giả chuyên nghiệp suốt hơn 15 năm, ông viết bài và cộng tác viên cho hơn 26 cuốn sách nói về một loạt các chủ đề, bao gồm cả cuốn sách mới xuất bản gần đây là Getting Started with CouchDB. Chuyên môn của ông trải rộng qua nhiều ngôn ngữ và các nền tảng phát triển như Perl, Python, Java, JavaScript, Basic, Pascal, Modula-2, C, C++, Rebol, Gawk, Shellscript, Windows, Solaris, Linux, BeOS, Microsoft® WP, Mac OS,.... Ông nguyên là một biên tập viên về Các công nghệ LAMP cho tạp chí LinuxWorld và là một cộng tác viên thường xuyên cho ServerWatch.com, LinuxPlanet, ComputerWorld và IBM developerWorks. Ông đã phát huy nền tảng phong phú và đa dạng của mình để trở thành thành viên sáng lập của một ISP hàng đầu Vương quốc Anh, giám đốc hệ thống và chuyên gia tư vấn CNTT cho một nhóm đại lý quảng cáo và các giải pháp Internet, chuyên gia kỹ thuật cho một mạng ISP xuyên lục địa và nhà thiết kế và nhà lập trình cơ sở dữ liệu và tự nhận mình là người tiêu dùng bắt buộc phần cứng và phần mềm máy tính. MC hiện là Phó chủ tịch về các ấn phẩm và kiến thức kỹ thuật cho Couchbase và chịu trách nhiệm về tất cả tài liệu hướng dẫn, chương trình đào tạo và nội dung đã xuất bản và Vùng kỹ thuật (TechZone) của Couchbase.



31 07 2013

Kiến trúc cơ sở dữ liệu văn bản (Document Database)

Một trong những thành phần quan trọng của tất cả các Document Database (cơ sở dữ liệu văn bản) là chúng có thể xử lý và làm việc với các cấu trúc lớn hơn bình thường. Đặc biệt, do tính chất phân phối của nó và cách thức khác nhau trong việc lưu trữ dữ liệu về mặt vật lý, thì đó là nơi lý tưởng để xử lý một lượng dữ liệu khổng lồ, thường là trong khai phá dữ liệu.

Những lợi ích rõ ràng như đã phân tích ở trên và trong các tài liệu khác; bài viết này tập trung vào cấu trúc và định dạng của thông tin và công nghệ được dùng để xử lý và báo cáo về các thông tin được lưu trữ.


Cấu trúc dữ liệu linh hoạt

Cơ sở dữ liệu văn bản có cấu trúc vô cùng linh hoạt (hầu như) cung cấp một số thuộc tính quan trọng khác nhau theo chức năng:

  • Schema-less (không có lược đồ): Cơ sở dữ liệu văn bản không cần phải xác định trước cấu trúc của dữ liệu được lưu trữ trong cơ sở dữ liệu. Theo cơ sở dữ liệu quan hệ (RDBMS) truyền thống, bạn xác định cấu trúc của các bảng mà các dữ liệu được lưu trữ trong đó và thử dự đoán nội dung, các giá trị có thể, và cấu trúc của thông tin. Đối với cơ sở dữ liệu văn bản, bạn có thể lưu trữ thông tin vào các tài liệu mà không cần phải lo lắng về cấu trúc, cho dù bạn có nhiều trường, hoặc thậm chí trong mối quan hệ một-nhiều và nhiều-nhiều. Thay vào đó bạn có thể tập trung vào nội dung thông tin chính mà bạn đang quan tâm. Điều này có thể giúp dễ dàng hơn trong việc lưu trữ các thông tin thô, mặc dù nó có thể đến từ các nguồn khác nhau. Linh hoạt hơn, điều này có nghĩa là bạn có thể kết hợp và xử lý các kiểu và cấu trúc thông tin khác nhau. Ví dụ, xử lý dữ liệu văn bản thì khó để đạt được với một RDBMS truyền thống bởi vì bạn cần phải đảm bảo rằng cấu trúc (số câu, đoạn văn, vv) là đủ linh hoạt để hỗ trợ các thông tin mới. Một cách cụ thể hơn, hãy tưởng tượng đối chiếu dữ liệu từ Twitter, Facebook, các nguồn xã hội khác và tìm kiếm các mẫu. Thông tin trên Twitter có một chiều dài cố định với các thông tin được nhúng vào một cách đơn lẻ, theo chuỗi nhỏ. Facebook là một tập các thành phần riêng biệt của các thông tin (văn bản, vị trí và riêng lẻ). Việc thu thập thông tin và thống nhất các thông tin đó sẽ phải mất một lượng xử lý đáng kể để đặt nó vào một kết cấu cứng nhắc.
  • Logical objects (Các đối tượng logic): Hầu hết các giải pháp RDBMS được sử dụng để mô hình hóa thông tin mà có thể định dạng theo cấu trúc thông thường (dạng quan hệ). Sau đó SQL và các phép nối được dùng để hợp nhất thông tin vào một đối tượng được sử dụng bên trong. Cá nhân bạn có thể nhìn vào các thành phần khác nhau của các cấu trúc dữ liệu tổng thể, nhưng thường là thông tin được kết hợp và báo cáo theo các đối tượng chuyên thu thập dữ liệu.

    Từ góc độ phức tạp hơn, chúng ta thường chia nhỏ các thành phần khác nhau của dữ liệu theo nhiều cách khác nhau, mặc dù trên thực tế chúng ta vẫn chỉ chọn ra các thành phần của cấu trúc tổng thể đó. Cấu trúc tài liệu thay đổi theo quan điểm đó. Thay vì nhìn một cách riêng lẻ, các điểm dữ liệu rời rạc, tài liệu có thể trông giống như các đối tượng tổng thể. Dò tìm thông tin về thu thập dữ liệu, ví dụ, có thể yêu cầu tất cả các thông tin về đối tượng tại chỗ, mặc dù thu thập dữ liệu khác nhau có thể có những phần tử nhạy cảm khác nhau, khác nhau cả về số lượng, và mức độ phức tạp.
  • Migratory Structure (Cấu trúc động): Thay đổi dữ liệu theo thời gian, đôi khi chậm và đôi khi nhanh. Sửa đổi một cấu trúc dữ liệu là một quá trình phức tạp, không chỉ ảnh hưởng đến cơ sở dữ liệu mà bạn sử dụng, nó cũng đòi hỏi thay đổi đối với các ứng dụng truy cập và sử dụng thông tin đó. Với một cấu trúc dựa trên văn bản (document-based structure), bởi vì cấu trúc của dữ liệu là cố định, việc thích nghi cấu trúc cho các phiên bản mới và các định dạng khác nhau của dữ liệu ban đầu là khó khăn và phức tạp. Hoặc là bạn cần phải tạo một bảng mới hoặc sửa đổi các bảng hiện có để đối phó với cấu trúc mới, điều đó có nghĩa là chuyển đổi tất cả các bản ghi đã được tạo trước đó để phù hợp với cấu trúc mới. Với một cơ sở dữ liệu văn bản, cấu trúc của tài liệu có thể được sửa đổi. Trên thực tế, cấu trúc của tài liệu cá nhân có thể khác nhau. Bởi vì bạn luôn phải xem xét với toàn bộ tài liệu, ứng dụng của bạn không cần thay đổi cho đến khi nó cần được xử lý để phù hợp với các dữ liệu mới.

Với tất cả những điều này, nó có ý nghĩa gì trong thực tế để thu thập, trích xuất, và xử lý thông tin?

Điều đầu tiên cần xem xét là định dạng của dữ liệu. Cơ sở dữ liệu văn bản có thể lưu trữ bất kỳ thông tin nào, nhưng định dạng cấu trúc được sử dụng rộng rãi nhất là JSON, một dạng đối tượng ký hiệu từ ngôn ngữ JavaScript. Nó cho phép bạn lưu trữ các dữ liệu dạng chuỗi, số, mảng, và mẫu tin (dạng băm), và sự kết hợp của các kiểu dữ liệu cơ bản đó.

Với mục đích hiểu biết cơ bản về xử lý tài liệu, bài viết này sử dụng dữ liệu khá đơn giản. Liệt kê 1 là một tài liệu theo dõi mực nước và nhiệt độ từ một bể nước bên ngoài:

Liệt kê 1. Tài liệu theo dõi mực nước và nhiệt độ từ một bể nước bên ngoài
{
"datestring": "Tue Nov 30 01:40:30 2010",
"hour": 1,
"min": 40,
"waterlevel": 96,
"day": 30,
"mon": 11,
"year": 2010,
"temperature": "28.64"
}

Thành phần ngày riêng lẻ đã được lưu trữ linh hoạt, mặc dù chúng hoàn toàn là tùy chọn. Mực nước và nhiệt độ được lưu trữ như các giá trị thô.

Một nhật kí khác theo dõi nhiệt độ của một bể nước tại ba thời điểm khác nhau và đại diện cho dữ liệu của nó như là một giá trị khác nhau (xem Liệt kê 2):

Liệt kê 2. Tài liệu theo dõi nhiệt độ của bể tại ba thời điểm khác nhau
{
  "datestring": "Tue Nov 30 02:06:21 2010",
  "temperature": {
    "mid": 23.2148953489378,
    "top": 23.6984348277329,
    "bot": 23.0212211444848
  }
}

Trên thực tế việc thu thập dữ liệu vào một cơ sở dữ liệu văn bản như máy chủ Hadoop hoặc máy chủ Couchbase có lẽ là phần dễ nhất của quá trình này. Bằng cách so sánh, không cần xử lý hay xây dựng dữ liệu hoặc cấu trúc để lưu trữ nó. Chúng tôi không cần phải phân tích các dữ liệu hướng tới một cấu trúc xác định, mà chúng tôi chỉ lưu trữ dữ liệu ở dạng thô.

Việc xử lý trong quá trình trích xuất dữ liệu làm cho khai phá dữ liệu dựa trên văn bản hiệu quả hơn.


Exchanging data (Trao đổi dữ liệu)

Nếu bạn có sẵn dữ liệu trong một RDBMS (hệ quản lí cơ sở dữ liệu quan hệ), chẳng hạn như IBM DB2, thì bạn có thể sử dụng một cơ sở dữ liệu văn bản để đơn giản hóa và thống nhất một cách thông thường hơn các dữ liệu khác nhau vào các tài liệu mà có thể được xử lý bởi một cơ sở dữ liệu văn bản để tận dụng ưu điểm của định dạng thống nhất.

Bạn có thể nghĩ đó là sai lầm khi thực hiện thao tác này: Nếu nó đã có trong một cơ sở dữ liệu thì tại sao di chuyển nó? Tuy nhiên những giải pháp của hệ quản trị cơ sở dữ liệu quan hệ đã được sử dụng trong nhiều năm để lưu trữ thông tin văn bản, các phiên bản khác nhau và chỉnh sửa dữ liệu bảng. Một cơ sở dữ liệu văn bản có thể là một cách hiệu quả của việc thống nhất này thành một cấu trúc có thể sử dụng được map/reduce (ánh xạ/ rút gọn) và các kỹ thuật khác.

Quá trình đơn giản nhất là tải các đối tượng khi chúng được định dạng và cấu trúc trong cơ sở dữ liệu. Điều này sẽ dễ dàng nếu bạn đang sử dụng một hệ thống ORM, chuyển mô hình dữ liệu của bạn sang mô hình đối tượng. Ngoài ra, bạn có thể thực hiện quá trình này bằng tay. Đoạn mã trong Liệt kê 3 thực hiện các hoạt động bằng cách lấy một bản ghi thành phần phức tạp thông qua chức năng biên dịch các câu lệnh SQL để tạo ra một đối tượng bên trong, định dạng cho JSON và sau đó ghi vào cơ sở dữ liệu văn bản (trong trường hợp này là CouchDB):

Liệt kê 3. Hoạt động tải (load) đối tượng của bạn
foreach my $productid (keys %{$products})
{
    my $product = new Product($fw,$productid);

    my $id = $product->{title};
    $id =~ s/[ ',\(\)]//g;
    my $record = {
        _id => $id,
        title => $product->{title},
        componentcount => $product->{componentcount},
        buildtime => $product->{metadata_bytag}->{totalbuildtime},
        testtime => $product->{metadata_bytag}->{totaltesttime},
        totaltime => $product->{metadata_bytag}->{totaltime},
        keywords => [keys %{$product->{keywordbytext}} ],
    };

    foreach my $component (@{$product->{components}})
    {
        push(@{$record->{component}},

                 componentqty => $component->{'qty'},
                 component => $component->{'componentdesc'},
                 componentcode => $component->{'componentcode'},
             }
            );
    }

    my $req = HTTP::Request->new('POST' => $base);
    $req->header('Content-Type' => 'application/json');
    $req->content(to_json($record));

    my $res = $ua->request($req);

}

Bạn có thể sử dụng quá trình tương tự với các thông tin khác và cơ sở dữ liệu văn bản. Ví dụ như trong Hadoop bạn có thể tạo một tập tin mới cho mỗi bộ dữ liệu kết quả.

Khi kết hợp thông tin từ nhiều bảng vào một định dạng duy nhất để xử lý, mặc dù bạn không cần phải sử dụng trường cùng tên (có thể được giải quyết trong lúc xử lý), không có lý do để không ít nhất là tiêu chuẩn hóa trên một số lĩnh vực (ngày, các điểm dữ liệu) nếu thông tin này phổ biến một cách rộng rãi như vậy.

Xuyên suốt quá trình xử lý đoạn mã ví dụ, bạn có thể thực thi được một số tiền xử lý và định dạng thông tin. Ví dụ, bạn có thể hòa hợp dữ liệu để sử dụng các điểm đo giống nhau, hoặc kết hợp các trường đã được dùng theo từng cách khác nhau trong nguồn dữ liệu.


Xử lý dữ liệu khi trích xuất

Với chủ định cấu trúc tài liệu linh hoạt, việc xử lý và xác định mô hình thông tin là một quá trình sẽ xảy ra khi bạn trích xuất dữ liệu, hơn là thực thi trích xuất và xử lý phản hồi tại các điểm mà dữ liệu được đưa vào.

Trong một RDBMS (hệ quản trị cơ sở dữ liệu quan hệ) điển hình, cấu trúc bao gồm các bảng và các lĩnh vực dựa trên cách bạn muốn mà thông tin được trích xuất sau đó. Ví dụ, với các thông tin ghi nhật ký (log), bạn có thể kết hợp một bảng điểm nhật ký (bao gồm ngày tháng) với một bảng điểm dữ liệu có chứa các dữ liệu nhật ký cụ thể. Bạn có biết rằng từ quá trình đó bạn có thể thực hiện một liên kết để kết nối các điểm nhật ký với các dữ liệu thời gian của bạn đến với thông tin của nhiệt độ và mức nước như vậy bạn có thể theo dõi và giám sát các giá trị theo thời gian (xem Hình 1).

Hình 1. Thực hiện một phép nối
Thực hiện một liên kết

Việc xử lý các thông tin được thực hiện tại các đầu vào, tách các thông tin để nó có thể chèn vào các bảng và và sau đó hợp nhất lại tại thời điểm đầu ra bởi sự kết hợp thông tin. Quá trình này đòi hỏi bạn biết bạn muốn các thông tin phản hồi , được kết nối, và xử lý khi nó được hiển thị như thế nào. Bạn chỉ có thể viết một câu lệnh SQL khi bạn biết cấu trúc bảng.

Với một cơ sở dữ liệu văn bản, nó là quá trình xử lý các dữ liệu thô tạo ra thông tin theo cách nhìn hài hòa để cho phép dữ liệu được xử lý, cho dù đó là dữ liệu dựa trên giá trị hoặc dữ liệu chuyên đề và văn bản. Thông tin này được đưa vào nhiều tài liệu, và hệ thống map/reduce xử lý thông tin đó và tạo ra một bảng cấu trúc từ dữ liệu (xem Hình 2 ).

Hình 2. Tạo ra một bảng có cấu trúc từ các dữ liệu
Tạo ra một bảng có cấu trúc từ các dữ liệu

Với cơ sở dữ liệu văn bản, bạn xử lý thông tin sau khi nó đã được chèn vào. Điều đó có nghĩa rằng bạn có thể xử lý và thậm chí thay đổi cách dữ liệu được trích xuất trong khi vẫn còn sử dụng và xử lý các dữ liệu thô ở định dạng ban đầu của nó. Trong suốt quá trình, bạn có được sự linh hoạt hoàn thiện về cách thông tin cần được báo cáo, mà không bị thất thoát bất kỳ thông tin ngữ cảnh nào.

Tất nhiên, phương pháp này đòi hỏi một số khác biệt trong cách bạn xử lý các dữ liệu thô.


Sử dụng Map/Reduce (Ánh xạ/rút gọn)

Có rất nhiều hệ thống khác nhau dành cho việc xử lý dữ liệu lớn, xuất và lấy thông tin rồi xử lý nó cho việc phân tích dữ liệu, đặc biệt đối với cơ sở dữ liệu văn bản. Các giải pháp thay đổi dựa trên cách tiếp cận của chúng, từ cơ cấu truy vấn đơn giản tương tự như những gì có sẵn trong cơ sở dữ liệu SQL, đến các chương trình phức tạp hơn dựa trên nền tảng phân tích và hiểu ngữ nghĩa. Giải pháp mới đây thường được sử dụng trong những tình huống mà bạn cần hình dung và hiểu được dữ liệu cơ sở để hệ thống xử lý có thể xây dựng và hiểu được thông tin gốc tồn tại dưới một định dạng thích hợp cho việc xử lý và tổng hợp của bạn.

Kỹ thuật được sử dụng nhiều hơn hẳn là Map/Reduce (Ánh xạ/Rút gọn). Kỹ thuật này có hai giai đoạn: Map để rút trích ra thông tin, và Reduce để đơn giản hóa và tóm tắt thông tin.

Vai trò của chức năng Map là lấy thông tin đầu vào, chẳng hạn như tài liệu mà bạn vừa lưu trữ, sau đó đơn giản hóa chúng thành một định dạng để cung cấp đầu ra phù hợp cho việc phân tích. Ví dụ: sử dụng dữ liệu nhật ký (log) sớm hơn, bạn có thể lấy được dữ liệu về nhiệt độ riêng, nhiệt độ của nhiều điểm và xuất ra thông tin dưới dạng một điểm dữ liệu đơn dựa trên thông tin ngày tháng và nhiệt độ, xem Liệt kê 4:

Liệt kê 4. Xuất dữ liệu về nhiệt độ riêng và nhiệt độ đa điểm dưới dạng điểm dữ liệu đơn
function (doc, meta) {
  if (doc.temperature && doc.temperature["mid"]) {
    emit(doc.datestring, parseFloat(doc.temperature["mid"]));
    emit(doc.datestring, parseFloat(doc.temperature["top"]));
    emit(doc.datestring, parseFloat(doc.temperature["bot"]));
    
  } else
  {
    emit(doc.datestring, parseFloat(doc.temperature));
  }
}

Mặc dù map sẽ hoạt động trên CouchDB và những nguyên lí cơ bản cũng sẽ làm việc bên trong Hadoop nhưng map trong Liệt kê 4 được viết bằng JavaScript và được thiết kế cho việc sử dụng bên trong Couchbase Server. Lệnh gọi đến emit để tạo ra một ‘dòng’ thông tin, trong trường hợp này là một từ khóa và một giá trị, bạn có thể xem một mẫu dữ liệu thô được xuất ra ở Liệt kê 5:

Liệt kê 5. Dữ liệu thô xuất ra
{"total_rows":404,"rows":[
{"id":"1334307543","key":"Fri Apr 13 09:59:03 2012","value":22.6132600653245},
{"id":"1334307543","key":"Fri Apr 13 09:59:03 2012","value":25.903221768301},
{"id":"1334307543","key":"Fri Apr 13 09:59:03 2012","value":29.0646016268462},
{"id":"1322793686","key":"Fri Dec  2 02:41:26 2011","value":22.7931975564504},
{"id":"1322793686","key":"Fri Dec  2 02:41:26 2011","value":23.8901498654126},
{"id":"1322793686","key":"Fri Dec  2 02:41:26 2011","value":23.9022843956552},
{"id":"1292554769","key":"Fri Dec 17 02:59:29 2010","value":26.55},
{"id":"1324617141","key":"Fri Dec 23 05:12:21 2011","value":24.43},
{"id":"1296843676","key":"Fri Feb  4 18:21:16 2011","value":23.75},
{"id":"1297446912","key":"Fri Feb 11 17:55:12 2011","value":24.56}
]
}

ID của dữ liệu xuất ra ở Liệt kê 5 là tài liệu sinh ra dòng thông tin (từ lệnh gọi emit()). Trong trường hợp này, bạn có thể thấy bản ghi đầu tiên và bản ghi thứ hai đến từ dữ liệu của nhiều cảm biến nhiệt độ có IDs đồng nhất.

Điểm then chốt trong khai phá dữ liệu với Map/Reduce là đảm bảo cho bạn thu thập đúng thông tin và các trường dữ liệu để xây dựng nên thông tin bạn muốn. Đối với Map/Reduce thì định dạng của map mang tính quyết định. Khi bạn xuất ra một từ khóa và một giá trị liên kết với nó. Giá trị đó sẽ xuyên suốt trong giai đoạn rút gọn và tôi sẽ ghi thông tin đó một cách hiệu quả trong chốc lát. Song, việc chọn ra giá trị đúng mới mang tính quyết định. Khi tiến hành xử lý văn bản, giá trị có thể liên quan đến việc phân tích câu, chữ mà đang được giám định. Khi phân tích dữ liệu phức tạp, bạn có thể phối hợp nhiều điểm dữ liệu lại với nhau. Ví dụ: khi khai phá thông tin bán hàng, bạn có thể chọn ra khách hàng đặc biệt, sản phẩm, địa điểm giao hàng.

Từ khóa rất quan trọng trong suốt quá trình khai thác dữ liệu bởi vì nó cung cấp nền tảng cho việc sắp đặt thông tin như thế nào. Trong ví dụ được cho thấy ở Liệt kê 5, tôi đã gom ngày tháng lại chung với nhau, nhưng bạn cũng có thể xây dựng các cấu trúc tinh vi hơn để chấp nhận các lựa chọn phức tạp hơn. Chẳng hạn, với thuộc tính ngày tháng, nếu bạn chia nó ra thành từng phần nhỏ (năm, tháng, ngày, giờ, phút) thì bạn có thể chia thông tin thành từng nhóm để phù hợp với từng quy tắc khác nhau.

Liệt kê 6 cho thấy một map đã được sửa đổi lại, phân chia ngày tháng thành từng phần riêng biệt:

Liệt kê 6. Ánh xạ được sửa đổi phân ngày tháng thành các phần riêng biệt
function (doc, meta) {
  if (doc.temperature && doc.temperature["mid"]) {
    emit(dateToArray(doc.datestring), parseFloat(doc.temperature["mid"]));
    emit(dateToArray(doc.datestring), parseFloat(doc.temperature["top"]));
    emit(dateToArray(doc.datestring), parseFloat(doc.temperature["bot"]));
    
  } else
  {
    emit(dateToArray(doc.datestring), parseFloat(doc.temperature));
  }
}

Điều này tạo ra một map đã được sửa đổi đôi chút với ngày tháng đã được sắp xếp thành một mảng (xem Liệt kê 7):

Liệt kê 7. Map đầu ra đã được sửa đổi với dữ liệu được sắp thàng mảng
{"total_rows":404,"rows":[
{"id":"1291323688","key":[2010,12,2,21,1,28],"value":23.17},
{"id":"1292554769","key":[2010,12,17,2,59,29],"value":26.55},
{"id":"1292896140","key":[2010,12,21,1,49,0],"value":25.79},
{"id":"1293062859","key":[2010,12,23,0,7,39],"value":23.5796487295866},
{"id":"1293062859","key":[2010,12,23,0,7,39],"value":26.7156670181177},
{"id":"1293062859","key":[2010,12,23,0,7,39],"value":29.982973219635},
{"id":"1293403599","key":[2010,12,26,22,46,39],"value":22.2949007587861},
{"id":"1293403599","key":[2010,12,26,22,46,39],"value":24.1374973576972},
{"id":"1293403599","key":[2010,12,26,22,46,39],"value":27.4711695088274},
{"id":"1293417481","key":[2010,12,27,2,38,1],"value":25.8482292176647}
]
}

Bây giờ bạn có thể kết hợp map ở trên với một hàm reduce để cung cấp một dữ liệu vắn tắt ở bên các dãy khác. Hàm reduce lấy dữ liệu đầu ra từ hàm map() và tóm tắt thông tin đó cho phù hợp với cấu trúc từ khóa được chọn thành một định dạng đơn giản. Các hàm thông dụng là sums, averages, counts. Liệt kê 8 đưa ra ví dụ về hàm reduce tính giá trị trung bình:

Liệt kê 8. Hàm reduce tính giá trị trung bình
function(keys, values, rereduce) {
    if (!rereduce){
        var length = values.length
        return [sum(values) / length, length]
    } else {
        var length = sum(values.map(function(v){return v[1]}))
        var avg = sum(values.map(function(v){
            return v[0] * (v[1] / length)
            }))
        return [avg, length]
    }
}

Bởi theo nguyên lí của hệ thống reduce, bạn buộc phải xử lý cả giá trị trung bình gốc (kết quả từ đầu ra của hàm map()) lẫn giá trị rút gọn lại (nơi mà giá trị đầu ra được rút gọn mức một kết hợp với những giá trị còn lại tạo thành một kết quả rút gọn cuối cùng đưa tới dãy đầu vào được cho).

Hàm chủ yếu tính toán giá trị trung bình dựa trên dữ liệu vào (một mảng giá trị từ hàm map()) sau đó tính giá trị trung bình bằng cách chia tổng cho số lượng đếm.

Khi được truy cập lần đầu tiên, toàn bộ dữ liệu sẽ được phân nhóm và xử lý, sau cùng tính ra giá trị trung bình cho tất cả dữ liệu lưu trữ (xem Liệt kê 9):

Liệt kê 9. Bộ dữ liệu được phân nhóm và xử lý thành giá trị trung bình cho tất cả dữ liệu lưu trữ
{"rows":[
{"key":null,"value":[26.251700506838258,400100]}
]
}

Bằng việc xuất ra thông tin ngày tháng dưới dạng mảng, bạn có thể dùng bộ phận mảng như một tiêu chuẩn chọn lựa cho dữ liệu được sinh ra. Ví dụ, nếu bạn định ra nhóm nào là nhóm mức một, thông tin sẽ được phân nhóm với phần tử đầu tiên của mảng, đó là phần tử năm (year) (xem Liệt kê 10):

Liệt kê 10. Phân nhóm thông tin dựa trên phần tử đầu tiên của mảng
{"rows":[
{"key":[2010],"value":[26.225817751696518,17484]},
{"key":[2011],"value":[26.252118781247404,199912]},
{"key":[2012],"value":[26.253719707387862,182704]}
]
}

Nếu bạn định ra một nhóm ở mức ba, bạn sẽ có được thông tin được tóm tắt cho các tổ hợp riêng biệt năm/tháng/ngày (xem Liệt kê 11):

Liệt kê 11. Tóm tắt thông tin cho các tổ hợp của năm/tháng/ngày riêng biệt nhau
{"rows":[
{"key":[2010,11,30],"value":[26.23524809151833,505]},
{"key":[2010,12,1],"value":[26.37107941210551,548]},
{"key":[2010,12,2],"value":[26.329862140504616,547]},
{"key":[2010,12,3],"value":[26.31599258504074,548]},
{"key":[2010,12,4],"value":[26.389849136337002,548]},
{"key":[2010,12,5],"value":[26.175710823088224,548]},
{"key":[2010,12,6],"value":[26.21352234443162,548]},
{"key":[2010,12,7],"value":[26.10277260171637,548]},
{"key":[2010,12,8],"value":[26.31207700104686,548]},
{"key":[2010,12,9],"value":[26.207143469079593,548]}
]
}

Bạn có thể sử dụng hàm reduce để tóm tắt và nhận dạng nhiều dạng thông tin khác nhau. Bạn có thể kết hợp một hàm rút gọn reduce() phức tạp hơn với một thông báo bằng chữ khi nhiệt độ dao động ở các mức giá trị khác nhau (warning - cảnh báo, error - lỗi, fatal - nguy hiểm) sau đó hợp chúng lại thành một cấu trúc đơn giản (xem Liệt kê 12):

Liệt kê 12. Kết hợp một hàm reduce() phức tạp với một thông báo chữ trong một cấu trúc đơn giản
function(key, values, rereduce)
{   var response = {"warning" : 0, "error": 0, "fatal" : 0 };
  for(i=0; i<data.length; i++)
  {
    if (rereduce)
    {
      response.warning = response.warning + values[i].warning;
      response.error = response.error + values[i].error;
      response.fatal = response.fatal + values[i].fatal;
    }
    else
    {
      if (values[i] == "warning")
      {
        response.warning++;
      }
      if (values[i] == "error" )
      {
        response.error++;
      }
      if (values[i] == "fatal" )
      {
        response.fatal++;
      }
    }
  }
  return response;
}

Bây giờ bạn có thể báo cáo số lượng của các lỗi riêng biệt này nằm ở bên dãy ngày/thời gian, ví dụ, dựa theo tháng (xem Liệt kê 13):

Liệt kê 13. Thể hiện của các lỗi riêng biệt được đếm dựa theo tháng
{"rows":[
{"key":[2010,7], "value":{"warning":4,"error":2,"fatal":0}},
{"key":[2010,8], "value":{"warning":4,"error":3,"fatal":0}},
{"key":[2010,9], "value":{"warning":4,"error":6,"fatal":0}},
{"key":[2010,10],"value":{"warning":7,"error":6,"fatal":0}},
{"key":[2010,11],"value":{"warning":5,"error":8,"fatal":0}},
{"key":[2010,12],"value":{"warning":2,"error":2,"fatal":0}},
{"key":[2011,1], "value":{"warning":5,"error":1,"fatal":0}},
{"key":[2011,2], "value":{"warning":3,"error":5,"fatal":0}},
{"key":[2011,3], "value":{"warning":4,"error":4,"fatal":0}},
{"key":[2011,4], "value":{"warning":3,"error":6,"fatal":0}} 
]
}

Trên đây là những ví dụ, tuy được thiết kế rất đơn giản để trình diễn khả năng và sự linh động của Map/Reduce nhưng lại rất dễ hiểu cách để nhận biết được thông tin mình cần khi có quá nhiều định dạng và cấu trúc tài liệu khác nhau trong kho thông tin lưu trữ của bạn, và cũng thấy được cách tóm tắt và trích xuất thông tin xuyên suốt quá trình xử lý.


Chaining map/reduce (Dây chuyền map/reduce)

Như bạn đã thấy, Map/Reduce là một phương thức thực tế để phân tích và xử lý khối lượng lớn dữ liệu, dù có hay không nguồn thông tin và dữ liệu được lưu trữ trong một cơ sở dữ liệu thích hợp để bắt đầu.

Trong phạm vi Map/Reduce, mặc dù có những hạn chế về số lượng thông tin liên kết (ngầm hay rõ ràng) trên các tài liệu khác nhau nhưng có thể được kết hợp và báo cáo lại với nhau. Tương tự, đối với thông tin rất phức tạp, một quá trình Map/Reduce đơn lẻ không thể xử lý quá trình phân tích đơn của Map/Reduce kết hợp.

Đặc biệt là khi so sánh với RDBMS truyền thống trong tất cả các loại, không có khả năng sử dụng JOIN để kết hợp các thông tin trên bội (kể cả cùng một bảng) làm cho các hoạt động nhất định trong khuôn khổ Map/Reduce không thể hoàn tất trong một bước đơn chiết.

Ví dụ, khi xử lý thông tin văn bản và thực hiện một phân tích chuyên đề về dữ liệu, bạn có thể tiến hành qua một quá trình, đầu tiên là xử lý thông tin và câu cú từ tài liệu thô rồi chia dữ liệu nguồn thành các khối tài liệu cá nhân. Điều đó có thể đạt được thông qua một map() đơn xử lý các thông tin vào các tài liệu mới.

Sau đó, bước thứ 2 có thể xử lý thông tin được trích chọn để cung cấp cho những phân tích chi tiết hơn trên của các mảnh riêng biệt và đối chiếu, sắp xếp, tổng hợp thông tin (xem Hình 3):

Hình 3. Xử lý thông tin trích chọn để cung cấp cho việc phân tích chi tiết hơn:
Xử lý thông tin trích chọn để cung cấp cho việc phân tích chi tiết hơn:

Từ một góc nhìn thực tế, chuỗi Map/Reduce là một trường hợp vận hành một chức năng Map/Reduce cho phân tích mức ban đầu của bạn và sử dụng khóa "key" của đầu ra (từ hàm map() của bạn) như ID của tài liệu để sau đó chứa các cấu trúc dữ liệu đầu ra cho dòng thông tin tóm gọn.

Trong ví dụ đăng nhập trước đó, bạn có thể lấy cấu trúc kết hợp của warning/error/fatal và ghi lại thành dữ liệu mới vào trong một cơ sở dữ liệu mới (hay như là một bucket được dùng trong Couchbase) và sau đó vận hành xử lý bổ sung từ bucket đó để xác định xu hướng hoặc các dữ liệu khác (xem Hình 4):

Hình 4. Vận hành xử lý bổ sung để xác định xu hướng hoặc các dữ liệu khác
Chạy xử lý bổ sung để xác định xu hướng hoặc các dữ liệu khác:

Hãy nhớ rằng Map/Reduce trực tiếp chỉ là một yếu tố của dữ liệu. Nếu bạn trích xuất và kết hợp thông tin từ các nguồn khác trong suốt quá trình xử lý, bạn cũng có thể sử dụng và kết hợp thông tin đó ở giai đoạn này vào luồng dữ liệu.

Ví dụ, khi nhìn vào thông tin bán hàng, bạn có thể có thông tin khách hàng trong một cơ sở dữ liệu, doanh số bán hàng cho khách ở một cơ sở dữ liệu khác và thông tin sản phẩm trong một cơ sở dữ liệu khác nữa. Bằng cách chạy Map/Reduce trên các dữ liệu bán hàng, trích xuất vào một cơ sở dữ liệu khác, rồi kết hợp dữ liệu đó với dữ liệu sản phẩm, và sau đó giảm bớt lại trước khi kết hợp với các thông tin của khách hàng, nó có thể sinh ra dữ liệu phức hợp trong những nguồn dữ liệu dường như khác nhau hoàn toàn.


Kết luận

Cơ sở dữ liệu văn bản đã hoàn toàn đi ngược lại với các quy tắc xử lý và cấu trúc dữ liệu thông thường. Bạn sẽ không còn phải phân tích, khởi tạo và định dạng thông tin thành dạng bảng để dễ xử lý nữa. Thay vào đó, bạn sẽ chỉ lưu trữ các định dạng dữ liệu đến bất kỳ, sau đó tiến hành xử lý phân tích dữ liệu, quản lý các định dạng và cấu trúc khác nhau như bạn vẫn thường làm. Quá trình đó có thể đơn giản hóa số lượng khổng lồ dữ liệu từ trên xuống thành các việc nhỏ dễ giải quyết hơn. Quá trình hỗ trợ này sẽ cho phép các dữ liệu cấp phát lớn được xử lý nâng cao hơn là bị gây trở ngại. Bạn có thể xử lý các dữ liệu ngày càng phức tạp và lớn hơn bằng cách tận dụng kiến trúc đa điểm. Cũng như bài viết này, mối quan tâm chủ yếu của bạn là tạo ra một tài liệu phù hợp và viết ra được một chương trình Map/Reduce để xử lý tài liệu đó một cách hiệu quả.

Tài nguyên

Học tập

  • "What is PMML?" (Alex Guazzelli, developerWorks, September 2010): Đọc bài viết này về chuẩn PMML được sử dụng bởi các công ty phân tích để hình dung được và thực hiện các giải pháp dự đoán trên các hệ thống.
  • Predictive Analytics: Đọc bài viết này trên trang Wikipedia ở mục Predictive Analytics để có cái nhìn chung về các ứng dụng và kỹ thuật phổ biến được sử dụng để tiên đoán về tương lai.
  • Đọc quyển sách PMML in Action: Unleashing the Power of Open Standards for Data Mining and Predictive Analytics (Tháng 5/2010).
  • The Data Mining Group (DMG) là một hiệp hội doanh nghiệp độc lập phát triển các tiêu chuẩn khai phá dữ liệu, chẳng hạn như chuẩn PMML (Predictive Model Markup Language – Ngôn ngữ đánh dấu mô hình dự đoán).
  • Ghé thăm trang Zementis PMML Resources để khám phá các ví dụ PMML hoàn chỉnh.
  • Ghé thăm trang Data Mining trên Wikipedia.
  • Tham gia PMML discussion group (nhóm thảo luận PMML) tại LinkedIn.
  • developerWorks Open source zone: Tìm hiểu các nâng cấp dự án, công cụ, các thông tin hướng dẫn mở rộng để tiện việc phát triển các công nghệ mã nguồn mở sử dụng chung với các sản phẩm của IBM.
  • Để lắng nghe các thảo luận và phỏng vấn đáng lưu tâm dành cho người phát triển phần mềm, hãy ghé thăm developerWorks podcasts.
  • developerWorks technical events and webcasts: Dự các sự kiện chuyên ngành cùng các bản tin trên mạng của developerWorks.

Lấy sản phẩm và công nghệ

  • Hadoop hỗ trợ một số kiến trúc NoSQL như khả năng định dạng kiểu schemaless để sử dụng Map/Reduce xử lý dữ liệu lưu trữ.
  • InfoSphere Warehouse là một bộ công cụ hoàn thiện hỗ trợ với nhiều kỹ thuật khai phá dữ liệu cho việc xây dựng và phân tích dữ liệu.
  • WEKA là bộ công cụ dựa trên nền Java, hỗ trợ nhiều thuật toán thống kê và khai thác dữ liệu.
  • SPSS là một gói chức năng thống kê bao gồm các khả năng phân tích dự đoán mạnh mẽ.
  • Couchbase Server là một cơ sở dữ liệu văn bản NoSQL với Map/Reduce dạng truy vấn và lập chỉ mục.
  • Đổi mới các dự án phát triển mã nguồn mở của bạn bằng phần mềm dùng thử của IBM, có thể tải về hoặc mua DVD.

Thảo luận

  • Tham gia vào cộng đồng developerWorks và xem các blogs.

Bình luận

developerWorks: Đăng nhập

Các trường được đánh dấu hoa thị là bắt buộc (*).


Bạn cần một ID của IBM?
Bạn quên định danh?


Bạn quên mật khẩu?
Đổi mật khẩu

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Ở lần bạn đăng nhập đầu tiên vào trang developerWorks, một hồ sơ cá nhân của bạn được tạo ra. Thông tin trong bản hồ sơ này (tên bạn, nước/vùng lãnh thổ, và tên cơ quan) sẽ được trưng ra cho mọi người và sẽ đi cùng các nội dung mà bạn đăng, trừ khi bạn chọn việc ẩn tên cơ quan của bạn. Bạn có thể cập nhật tài khoản trên trang IBM bất cứ khi nào.

Thông tin gửi đi được đảm bảo an toàn.

Chọn tên hiển thị của bạn



Lần đầu tiên bạn đăng nhập vào trang developerWorks, một bản trích ngang được tạo ra cho bạn, bạn cần phải chọn một tên để hiển thị. Tên hiển thị của bạn sẽ đi kèm theo các nội dung mà bạn đăng tải trên developerWorks.

Tên hiển thị cần có từ 3 đến 30 ký tự. Tên xuất hiện của bạn phải là duy nhất trên trang Cộng đồng developerWorks và vì lí do an ninh nó không phải là địa chỉ email của bạn.

Các trường được đánh dấu hoa thị là bắt buộc (*).

(Tên hiển thị cần có từ 3 đến 30 ký tự)

Bằng việc nhấn Gửi, bạn đã đồng ý với các điều khoản sử dụng developerWorks Điều khoản sử dụng.

 


Thông tin gửi đi được đảm bảo an toàn.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=70
Zone=Rational
ArticleID=939476
ArticleTitle=Khai phá dữ liệu dưới dạng văn bản tài liệu
publish-date=07312013