Home > Archives > 2008年01月 > JavaScriptで簡易形態素解析 その2

JavaScriptで簡易形態素解析 その2

JavaScriptで簡易形態素解析 その2

JavaScriptで簡易形態素解析 - mayokara lab

JavaScriptで簡易形態素解析 - mayokara memo

さらに改造。

コード

/*
ipadic Licence
---
Copyright 2000, 2001, 2002, 2003 Nara Institute of Science
and Technology.  All Rights Reserved.

Use, reproduction, and distribution of this software is permitted.
Any copy of this software, whether in its original form or modified,
must include both the above copyright notice and the following
paragraphs.

Nara Institute of Science and Technology (NAIST),
the copyright holders, disclaims all warranties with regard to this
software, including all implied warranties of merchantability and
fitness, in no event shall NAIST be liable for
any special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether in an
action of contract, negligence or other tortuous action, arising out
of or in connection with the use or performance of this software.

A large portion of the dictionary entries
originate from ICOT Free Software.  The following conditions for ICOT
Free Software applies to the current dictionary as well.

Each User may also freely distribute the Program, whether in its
original form or modified, to any third party or parties, PROVIDED
that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear
on, or be attached to, the Program, which is distributed substantially
in the same form as set out herein and that such intended
distribution, if actually made, will neither violate or otherwise
contravene any of the laws and regulations of the countries having
jurisdiction over the User or the intended distribution itself.

NO WARRANTY

The program was produced on an experimental basis in the course of the
research and development conducted during the project and is provided
to users as so produced on an experimental basis.  Accordingly, the
program is provided without any warranty whatsoever, whether express,
implied, statutory or otherwise.  The term "warranty" used herein
includes, but is not limited to, any warranty of the quality,
performance, merchantability and fitness for a particular purpose of
the program and the nonexistence of any infringement or violation of
any right of any third party.

Each user of the program will agree and understand, and be deemed to
have agreed and understood, that there is no warranty whatsoever for
the program and, accordingly, the entire risk arising from or
otherwise connected with the program is assumed by the user.

Therefore, neither ICOT, the copyright holder, or any other
organization that participated in or was otherwise related to the
development of the program and their respective officials, directors,
officers and other employees shall be held liable for any and all
damages, including, without limitation, general, special, incidental
and consequential damages, arising out of or otherwise in connection
with the use or inability to use the program or any product, material
or result produced or otherwise obtained by using the program,
regardless of whether they have been advised of, or otherwise had
knowledge of, the possibility of such damages at any time during the
project or thereafter.  Each user will be deemed to have agreed to the
foregoing by his or her commencement of use of the program.  The term
"use" as used herein includes, but is not limited to, the use,
modification, copying and distribution of the program and the
production of secondary products from the program.

In the case where the program, whether in its original form or
modified, was distributed or delivered to or received by a user from
any person, organization or entity other than ICOT, unless it makes or
grants independently of ICOT any specific warranty to the user in
writing, such person, organization or entity, will also be exempted
from and not be held liable to the user for any such damages as noted
above as far as the program is concerned.
・
*/
var parse = function(str){
    var re = {
        kanji: "[一-龠々〆ヵヶ]",
        hiragana: "[ぁ-ん]",
        katakana: "[ァ-ヴ]",
        hankakukana: "([ヲ-ン][゙゚]?)",
        prolong: "[ー~]",
        alphanumeric: "[0-9A-Za-z\\-_,.]",
        alphanumeric2: "[0-9A-Za-z,.]",
        punctuation: "[,.、。]",
        ellipsis: "[・…―]",
        interrobang: "[!?!?]",
        bracket: "[()\\[\\]{}<>()[]{}‘’“”〈〉《》「」『』【】〔〕<>]",
        space: "[ ]",
        end_of_sentence: "[,.、。・…―!?!?)」』]",
        conjunction: "(にもかかわらず|だからといって|おしむらくは|おそれながら|惜しむらくは|しかしながら|それにしても|それどころか|さもなければ|つまるところ|でなければ|そのうえで|恐れながら|だけれども|そうすると|だからこそ|そうしたら|それなのに|それだけに|だとすると|したがって|というのも|そうですが|なかんづく|そのうえに|然しながら|それでいて|そうなると|そやさかい|なかんずく|そういえば|ですけれど|ともすれば|だとすれば|ですから|そういや|はんめん|それでも|そもそも|おなじく|いっぽう|それとも|さりとて|若しくは|こうして|ましてや|ならびに|なぜなら|ちなみに|あわせて|と同時に|そしたら|ところが|でないと|たとへば|ほんじゃ|ふんじゃ|おまけに|もっとも|ないしは|それでは|ついては|それなら|あるいは|どころか|もしくは|てゆーか|ほんなら|そのうえ|たとえば|けれども|然し乍ら|それから|とすれば|ところで|わけても|そうして|ぎゃくに|すなわち|かくして|ともあれ|そーいや|因みに|よって|じゃあ|されど|それに|並びに|譬えば|すると|併せて|しかし|そこで|従って|ともに|同じく|それも|そして|だけど|だって|まずは|しかも|ないし|ほなら|じゃが|さらに|それと|ついで|例へば|けれど|ほんで|追って|なので|譬へば|ならば|本当は|および|つまり|或いは|だから|または|そりゃ|ゆえに|それで|ですが|んじゃ|次いで|ただし|したら|なのに|例えば|かたや|及び|然し|ほな|さて|但し|ただ|実は|では|だが|でも|反面|かつ|また|一方|いえ|又は|じゃ|いや|逆に|乃至|けど|即ち|次に|或は|故に|尤も|なお|なら|尚|又|但|が|で|亦|否|即)",
        particle: "(にわたりまして|にたいしまして|にあたりまして|に当たりまして|をめぐりまして|にまつわります|に関しまして|としましたら|を通じまして|にかけまして|とかいいます|にとりまして|によりまして|をめぐります|にたいします|に対しまして|を通しまして|に従いまして|にあたります|におきまして|に際しまして|をもちまして|につきまして|にわたります|に当たります|といいます|に対します|にまつわる|をめぐって|にあたって|にわたって|にたいして|に関します|にたいする|としまして|によります|に従います|に当たって|につれて|において|とかいう|にわたり|に対して|に当たる|どころか|について|とかいふ|やいなや|をもって|にかけて|に関する|における|といった|にあたる|からには|っていう|にあたり|っちゅう|に当たり|に従って|をめぐる|を通して|に関して|にわたる|を通じて|によって|ばっかり|に対する|にとって|に際して|とともに|けれども|として|に従い|に対し|に関し|を以て|につけ|を通じ|ていう|にかけ|なんぞ|ぐらい|ばかし|につれ|により|けども|にとり|ながら|に際し|と共に|による|といふ|および|という|ばかり|じゃあ|ちゃあ|なんか|につき|じゃァ|くらい|だって|けれど|に従う|ものの|っきゃ|さかい|なんて|ばっか|から|しか|すら|さえ|こそ|じゃ|なり|しも|のみ|ほど|だけ|にて|ちゃ|とも|のに|けど|でも|かも|つつ|ども|なぞ|やら|だに|んで|より|ので|ずつ|だり|だの|とか|たり|まで|など|っと|[こそあど]?の|程|と|に|や|が|で|て|も|ぞ|は|へ|ヲ|ヘ|迄|ノ|か|之|を|デ)",
        post_particle: "(かしら|なぁー|だって|かぁ|もん|わい|ねエ|やら|なァ|なあ|なー|ねぇ|よー|ねェ|よう|ねえ|っけ|ヨー|てん|なぁ|ねッ|ねん|のう|かい|ねー|ヨ|ぜ|ナ|け|な|で|わ|の|さ|ん|ね|ワ|ぞ|べ|ネ|や|よ)"
    };
    re.verb = re.kanji + re.hiragana + "[るれろよ]?";
    re.adjective = re.kanji + "し?(かろ|かっ|く|う|い|けれ)";
    
    var re_particle = new RegExp("((" + re.adjective + "|"
                                      + re.conjunction + "|"
                                      + re.particle + "(?!" + re.particle + ")|"
                                      + re.post_particle + "(?=" + re.end_of_sentence + "))|\\s+)", "g");
    var re_particle2 = new RegExp("^(" + re.adjective + "|"
                                       + re.conjunction + "|"
                                       + re.particle + "|"
                                       + re.post_particle + ")$", "g");
    var re_word = new RegExp("(" + re.verb + "|"
                                 + re.kanji + "+|"
                                 + "(" + re.hiragana + "|" + re.prolong + ")+|"
                                 + "(" + re.katakana + "|" + re.prolong + ")+|"
                                 + re.hankakukana + "+|"
                                 + re.prolong + "+|"
                                 + re.alphanumeric + "+|"
                                 + re.alphanumeric2 + "+|"
                                 + re.punctuation + "+|"
                                 + re.ellipsis + "+|"
                                 + re.interrobang + "+|"
                                 + re.bracket + "|"
                                 + re.space + "+)", "g");
    
    var result = [];
    var array = str.replace(re_particle, "<<>>$2<<>>").split("<<>>");
    var i = 0, ilength = array.length, token = null;
    var j = 0, jlength = 0;
    for (i=0; i<ilength; i++) {
        if (array[i] == "") {
            continue;
        }
        if (re_particle2.test(array[i])) {
            result.push(array[i]);
            continue;
        }
        token = array[i].replace(re_word, "<<>>$1<<>>").split("<<>>");
        jlength = token.length;
        for (j=0; j<jlength; j++) {
            if (token[j] == "") {
                continue;
            }
            result.push(token[j]);
        }
    }
    return result;
};

変更点

  • 正規表現をばらした
  • 半角カナ群を追加
  • 文字の分類の見直し
  • 半角スペースはMeCabに合わせて省くようにした
  • 未知の文字列をそのまま返すようにした(前のはマッチしたもののみを返していた)
  • 形容詞らしき部分の切り出しを行うようにした
  • 接続詞と助詞で区切るようにした(辞書使用)
  • 連続する助詞(終助詞除く)は最後のみ、終助詞は文の終わりのみにマッチするようにした

辞書について

MeCab: Yet Another Part-of-Speech and Morphological Analyzer

接続詞、助詞、括弧の語彙はMeCab用のIPA辞書から拝借しました。

ただし、いくつかの短い助詞は影響が大きいので省き、さらに前回と同じく「[こそあど]の」を追加してあります。

ライセンスについては

ipadicのライセンスの件 - mir the tritonn

IPADIC ライセンス関連書メモ

ということらしいので、念のためCOPYINGの内容をコメントで付加。

これでいいのかな。

比較ページ

JS形態素解析もどきのテスト

MECAPIとの比較ページを作りました。

MECAPIのcallback関数の指定が効かないようなので、別ページです。

文章が長すぎるとMECAPIの結果が返ってきません。

おことわり

仕組み上、ひらがな列・カタカナ列・漢字列が連なるとしょーもない結果になります。

テスト

順にJSもどき版、MeCab(IPA辞書)。


  1. 「吾輩は猫である。名前はまだ無い。」
    1. 「吾輩|は|猫|で|ある|。|名前|は|まだ|無い|。」
    2. 「吾輩|は|猫|で|ある|。|名前|は|まだ|無い|。」
  2. 「私は、その男の写真を三葉、見たことがある。」
    1. 「私|は|、|その|男|の|写真|を|三葉|、|見た|こと|が|ある|。」
    2. 「私|は|、|その|男|の|写真|を|三|葉|、|見|た|こと|が|ある|。」
  3. 「私の執事をやらないか?」
    1. 「私|の|執事|を|やら|ない|か|?」
    2. 「私|の|執事|を|やら|ない|か|?」
  4. 「サンタクロースをいつまで信じていたかなんてことはたわいもない世間話にもならないくらいのどうでもいいような話だが、それでも俺がいつまでサンタなどという想像上の赤服じーさんを信じていたかと言うとこれは確信を持って言えるが最初から信じてなどいなかった。」
    1. 「サンタクロース|を|いつ|まで|信じ|て|いたか|なんて|こと|は|たわい|も|ない|世間話|に|も|なら|ないくらい|の|どう|でも|いいような|話|だが|、|それでも|俺|が|いつ|まで|サンタ|など|という|想像上|の|赤服|じーさん|を|信じ|て|いたか|と|言う|と|これ|は|確信|を|持っ|て|言える|が|最初|から|信じ|て|など|いな|か|った|。」
    2. 「サンタクロース|を|いつ|まで|信じ|て|い|た|か|なんて|こと|は|たわい|も|ない|世間|話|に|も|なら|ない|くらい|の|どう|でも|いい|よう|な|話|だ|が|、|それでも|俺|が|いつ|まで|サンタ|など|という|想像|上|の|赤|服|じ|ーさんを|信じ|て|い|た|か|と|言う|と|これ|は|確信|を|持っ|て|言える|が|最初|から|信じ|て|など|い|なかっ|た|。」

Comment: 0

Attention
コメントの受け付けは終了しました。

Trackback: 0

Attention
トラックバックの受け付けは終了しました。

Home > Archives > 2008年01月 > JavaScriptで簡易形態素解析 その2

Feeds
Counter
  • Counter

    since 2008.01.11

Page Top