PHPで任意のテキスト蚀語を自動的に怜出する-PHPLangautodetectラむブラリ

垂堎で新しくおナニヌクなものを䜜成しようずしおいるスタヌトアップず仕事をするこずはずおも゚キサむティングです。 そしお、オヌプニングの機䌚だけでなく、クリ゚ヌタヌに向けられ、か぀お誰も解決したこずのない些现なタスクや質問もしばしばありたす。 昚日、私の前に出おきたこれらの質問の1぀がありたす任意のテキスト行が私たちに䞎えられたした。それは2぀であり、堎合によっおは3か囜語であるこずが知られおいたす。 ナヌザヌは、テキストを蚘述する蚀語を決定する必芁がありたす。



実際、タスクはそれほど珍しくありたせん。同様の機胜がテキスト゚ディタヌ、PuntoSwitcherキヌボヌドスむッチ、および機械翻蚳システムにあり、情報怜玢システムはもちろんのこず、そのような機胜が求められおいたす。 ちなみに、このような問題が発生したのは、特殊な怜玢゚ンゞンずテキスト分類子を䜜成するずいうコンテキストでした。 PHPプラットフォヌムの独自のプログラムでこの機䌚を取埗し、同時にサヌドパヌティのサヌビスを䜿甚しないこずが必芁でした-Google蚀語APIにはWebサヌビスの圢匏で同様の機䌚がありたす ブログでこのサヌビスを既に怜蚎したした が、リモヌトで実行され、特に、蚀語認識のプロセスは倧幅に遅れお実行され、本質的に非同期です。 さらに、プロセスを完党に制埡し、柔軟に構成できるようにしたかったのですが、これはサヌドパヌティのサヌビスには含たれおいたせん。 したがっお、私は自分でそれを考えお実装する必芁がありたしたが、結果をあなたの泚意に瀺したす。





たず、少しの理論。 蚀語の自動決定のプロセスは䞍正確であり、原則ずしお確率的であるずすぐに蚀わなければなりたせん。 ぀たり、結果は垞に確率で䞎えられたす。特に、スペルが非垞に䌌おいる、たたは同じアルファベットでさえあるが、異なる蚀語の堎合はそうです。 さらに、調査察象のテキストの行の長さにも䟝存したす。調査のための資料が少ないほど、そのような定矩はより困難たたは䞍可胜にさえなりたす。 実際、統蚈情報の堎合は、パラメヌタヌを蚈算するためのフィヌルドを倧きくする必芁がありたす。短い行では、特に同じアルファベットに基づく蚀語を分析する堎合、識別に十分な資料を取埗できたせん。 そのようなテキストでは、䞀意の文字は単に発生しない堎合があり、別の蚀語の単語ずしお定矩されたす。 したがっお、䜿甚されるアルファベットの分析方法の最初の制限は、テキストの長さです。それが倧きいほど、分析の粟床が高くなりたす。 䟋を挙げたしょう。「 rappel 」ずいう蚀葉です。 それは䜕語ですか 英語で それは「ロヌプで降りる」こずを意味したす。 しかし、同じ蚀葉はドむツ語です そしお、それは「突然の狂気、怒りの発䜜」を意味したす。



この方法には2぀の皮類がありたす。 「アルファベットの䜿甚率」の䜿甚䟋では、テキストで䜿甚されおいるアルファベットの䞀意の文字数の蚈算ず、総量のの蚈算を䜿甚したす。 2番目は、アルファベットず䞀臎するテキストの文字数を倉曎したすが、䞀郚の文字は異なるアルファベットに分類され、䞡方の蚀語にカりントされる可胜性がありたす。



2番目の方法は、蚀語の文法に固有たたは兞型的な䞀連の文字たずえば、英語の蚘事、ロシア語の文字「b」および「e」、たたはりクラむナ語の「є」を䜿甚しおテキストのアむデンティティを確立する事前に圢成されたルヌルの䜿甚に基づいおいたす。 このようなN-gramのルヌルは蚀語孊者が開発でき、テキストの蚀語を迅速か぀正確に決定できたすが、保蚌された結果は埗られたせん。 最初に䜜成する必芁がありたす。぀たり、蚀語の優れた胜力があり、さたざたな蚀語に固有の特性シヌケンスはそれほど倚くありたせん。 ただし、どの蚀語を定矩する必芁があるかを事前に知っおいる堎合は、すべおの蚀語を䜿甚する堎合よりも固有の組み合わせがより倚く存圚する可胜性がありたす。 ロシア語ず英語しかない堎合、ドむツ語ず英語のペアよりも明らかにこのような文字の組み合わせが倚くありたす。



たた、テキストに異なるアルファベットの単語が混圚しおいる堎合に぀いおも怜蚎する必芁がありたす。 たずえば、䌚瀟や補品の名前は、元の蚀語、ほずんどの堎合は英語で蚘述できたすが、文党䜓はロシア語で䜜成されたす。 ここでは、アルファベットに属する文字の総数を蚈算するオプションのみが圹立ち、誰がより倚くの文字に基づいお決定を䞋すこずができたす。 将来のバヌゞョンでは、ラむブラリはそのようなオプションを認識し、文字列で芋぀かった蚀語の配列を発行できるようになり、文字列で最も文字数が倚いメむン蚀語のみを衚瀺するようになりたす。



私のラむブラリでは、䞡方のアプロヌチずすべおの可胜なオプションを䜿甚するこずにしたした。これにより、任意のアプロヌチたたは䞡方の組み合わせを䜿甚するようにアルゎリズムを柔軟に構成できたす。 技術的には、ラむブラリは非垞に単玔です-1぀のクラス、䜜業のパラメヌタヌを指定するいく぀かのメ゜ッドずプロパティ。 圌は゜ヌスコヌドの行ごずにコメントしたので、ここでは実装の完党な説明はせず、機胜のみに焊点を圓おたす。



ラむブラリはUTF-8で゚ンコヌドされたテキストで動䜜するため、mb_stringsモゞュヌルが必芁です。たず、結果の文字列を暙準圢匏に倉換し、トランスコヌドを詊みお、䜙分な文字を削陀しお長さをチェックしたす。 最小テキストサむズは50文字、最倧テキストサむズは1680です。これは、1぀の暙準A4ペヌゞずほが同じです。



さたざたな怜出オプションを蚭定できたす。 ラむブラリは、テキストの合蚈量たたは各アルファベットで䜿甚されおいる文字の割合を確認しながら、アルファベットの分析を䜿甚できたす。 決定のしきい倀も蚭定されたす。デフォルトでは75です蚈算に応じお、アルファベットの文字の75か、テキストでこの蚀語の文字の総数が75を超えたす。 ヒュヌリスティックルヌルを䜿甚しお結果を明確にするこずもできたすが、優先順䜍を調敎できたす-ルヌルが統蚈に埓っお分析の結果を確認しない堎合、ルヌルの結果を考慮するか、統蚈を信頌する必芁がありたす。 特に倧量のテキストたたは倚数の蚀語で䜜業を高速化するには、ルヌルのみを䜿甚できたす。通垞は、アルファベットの文字よりもはるかに小さくなりたす。 ちなみに、ルヌルの䜿甚も蚭定可胜です-結果を取埗するには、ルヌルの1぀ずの䞀臎ずしお䜿甚するか、同じ蚀語のすべおのルヌルずの䞀臎を芁求できたすが、これは長いテキストにのみ適甚され、垞に゚ラヌの可胜性がありたす。



ラむブラリは、怜出埌たたはfalseを返したす。これは、ラむブラリを刀別できないか、䜿甚されおいる蚀語がデヌタベヌスにないこずを意味したす。 成功するず、2文字の蚀語コヌド䟋「en」、「ru」、たたは「ua」、および远加情報-蚀語のフルネヌム、およびボヌナスずしおりィキペディアの蚀語に関する蚘事ぞのリンクを含む配列を取埗したす。 orgもちろん、同じ蚀語で。



これたでのずころ、ラむブラリの最初のバヌゞョンは、英語、ロシア語、りクラむナ語の3぀の蚀語のみで動䜜したすが、蚀語を操䜜するためのアルファベットずルヌルを远加するこずを劚げるものはありたせん。



最埌に、速床に぀いおの1぀の発蚀。 最速のオプションはルヌルのみを䜿甚するこずです。これは垞に文字よりもルヌルの数が少なく、ラむブラリ内で短いルヌプを䜿甚するためです。 特に、デヌタベヌス内で怜玢するテキストが長くなり、蚀語が倚くなるほど、ルヌルのみのオプションが速くなりたす。 したがっお、最適化のためには、事前に蚀語セットを制限し、䞍芁な蚀語を削陀するこずをお勧めしたす。これにより、サむクル数が倧幅に削枛され、アルゎリズムが高速に実行されたす。 システムでUTF-8゚ンコヌディングに倉換されたアルゎリズム倉換された文字列のみがアルゎリズムの入力に送られるこずが確実な堎合は、文字列のチェックずデコヌドを削陀するこずもできたす。



プロゞェクトの公匏サむト  http : //code.google.com/p/phplangautodetect/

ラむセンス  GNU General Public License v3

䜜成者 Alexander Lozovyukaleks_raiden、aleks.raiden @ gmail.com

蚀語/プラットフォヌム PHP 5mb_stringsモゞュヌルが必芁

ディストリビュヌションには、実隓甚の最もシンプルなスクリプトが含たれおいたす 。 最新のオンラむンバヌゞョンはこちらです。



以䞋は、䞊蚘のアルゎリズムの実装に関するコメントず芋解を含む゜ヌスコヌドです。



  1. Lang_Auto_Detect クラス
  2. {
  3. //䞻な倉数
  4. //サポヌトされおいる蚀語のリスト
  5. public $ lang = Array 'en' => array 'English' 、 'http://en.wikipedia.org/wiki/English_language' 、
  6. 'ru' =>配列 'ロシア語' 、 'http://en.wikipedia.org/wiki/%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0 B9_D18FD0B7D18BD0BA ' 、
  7. 'ua' =>配列 'りクラむナ' 、 'http://uk.wikipedia.org/wiki/%D0%A3%D0%BA%D1%80%D0%B0%D1%97%D0%BD%D1 81D18CD0BAD0B0_D0BCD0BED0B2D0B0 ' 
  8. ;
  9. //感床のしきい倀、定矩する蚀語に䜕の文字が必芁か
  10. public $ detect_range = 75;
  11. //倚蚀語ドキュメントを凊理し、䜿甚される蚀語の配列を返すかどうか
  12. public $ detect_multi_lang = false ; //ただ実装されおいたせん
  13. //すべおの結果ず確率を返したす
  14. public $ return_all_results = false ; //実際の䜿甚では、無効にする方が良い
  15. //ルヌルず䟋倖の远加システムを䜿甚したす
  16. public $ use_rules = false ;
  17. //ルヌルのみを適甚したすはるかに高速ですが、結果は少なく、テキストが倚いほど信頌性が高くなりたす
  18. public $ use_rules_only = false ;
  19. //統蚈よりもルヌルの優先床-
  20. public $ use_rules_priory = true ; // true-統蚈に関する芏則、false-芏則に関する統蚈
  21. //最初のルヌルたたは最倧䞀臎のみを怜玢したすか
  22. public $ match_all_rules = false ; // 1぀だけ= else
  23. //アルファベットのたたは各アルファベットの文字の総数を䜿甚したす
  24. public $ use_str_len_per_lang = true ; // true-優先床よりもテキストの党長をアルファベットの文字のよりも䜿甚し、false-その逆
  25. //怜出のための最小文字列長
  26. public $ min_str_len_detect = 50;
  27. //通垞のパフォヌマンスを確保するために、比范する文字の最倧長を指定したす
  28. public $ max_str_len_detect = 1680; //
  29. //内郚の非倉数-定矩で䜿甚されるアルファベットの衚
  30. private $ _langs = array
  31. 'en' =>配列 'a' 、 'b' 、 'c' 、 'd' 、 'e' 、 'f' 、 'g' 、 'h' 、 'i' 、 'j' 、 'k' 、 「l」 、 「m」 、 「n」 、 「o」 、 「p」 、 「q」 、 「r」 、 「s」 、 「t」 、 「u」 、 「v」 、 「w」 、 「 x ' 、 ' y ' 、 ' z ' 、
  32. 'ru' =>配列 'a' 、 'b' 、 'c' 、 'd' 、 'd' 、 'e' 、 'e' 、 'w' 、 's' 、 'and' 、 'i' 、 「k」 、 「l」 、 「m」 、 「n」 、 「o」 、 「p」 、 「p」 、 「s」 、 「t」 、 「y」 、 「f」 、 「x」 、 「 c ' 、 ' h ' 、 ' w ' 、 ' u ' 、 ' b ' 、 ' s ' 、 ' b ' 、 ' e ' 、 ' u ' 、 ' i ' 、
  33. 'ua' =>配列 'a' 、 'b' 、 'c' 、 'd' 、 'ґ' 、 'd' 、 'e' 、 'є' 、 'w' 、 's' 、 'and' 、 「і」 、 「ї」 、 「y」 、 「k」 、 「l」 、 「m」 、 「n」 、 「o」 、 「p」 、 「r」 、 「s」 、 「t」 、 「 y ' 、 ' f ' 、 ' x ' 、 ' c ' 、 ' h ' 、 ' w ' 、 ' u ' 、 ' b ' 、 ' u ' 、 ' i ' 
  34. ;
  35. //ルヌルを保存したす
  36. //ルヌルは文字たたは行であり、その存圚いずれかたたはすべおは自動的にテキストの識別を䌎いたす
  37. private $ _lang_rules = array
  38. 'en' =>配列 'th' 、 'ir' 、
  39. 'ru' =>配列 '' 、 '' 、
  40. 'ua' =>配列 'ї' 、 'є' 
  41. ;
  42. //クラスコンストラクタヌ
  43. パブリック 関数 __construct
  44. {
  45. trueを 返し たす 。
  46. }
  47. //保存する入力文字列を準備したす
  48. プラむベヌト 関数 _prepare_str$ tmp_str = null 
  49. {
  50. if $ tmp_str == null  falseを 返し たす ; //䜕も枡されない堎合、終了したす
  51. $ tmp_str = trim$ tmp_str;
  52. $ tmp_encoding = mb_detect_encoding$ tmp_str;
  53. if mb_strlen$ tmp_str、$ tmp_encoding> $ this-> max_str_len_detect
  54. {
  55. //パフォヌマンスのために、テキストの長さをトリミングしたす
  56. $ tmp_str = mb_substr$ tmp_str、0、$ this-> max_str_len_detect、$ tmp_encoding;
  57. }
  58. 他に
  59. if mb_strlen$ tmp_str、$ tmp_encoding<= $ this-> min_str_len_detect false ;
  60. //゚ンコヌドを倉換したす
  61. $ tmp_str = mb_convert_encoding$ tmp_str、 'UTF-8' 、$ tmp_encoding;
  62. //すべおを小文字にキャストしたす
  63. $ tmp_str = mb_strtolower$ tmp_str、 'UTF-8' ;
  64. return $ tmp_str;
  65. }
  66. //ルヌルに埓っお蚀語を決定する機胜
  67. //ルヌルは蚀語を明確に決定したすが、省略できたす:)
  68. プラむベヌト 関数 _detect_from_rules$ tmp_str = null 
  69. {
  70. if $ tmp_str == null  falseを 返し たす ; //䜕も枡されない堎合、終了したす
  71. if is_array$ this-> _ lang_rules return false ;
  72. //すべおのルヌルを反埩凊理したす
  73. foreach $ this-> _ lang_rules as $ lang_code => $ lang_rules
  74. {
  75. $ tmp_freq = 0;
  76. foreach $芏則ずしおの $ lang_rules
  77. {
  78. $ tmp_term = mb_substr_count$ tmp_str、$ルヌル;
  79. if $ tmp_term> 1 //぀たり、文字列内の文字が1回以䞊
  80. {
  81. $ tmp_freq ++; //この行にある蚀語文字のカりンタヌを増やしたす
  82. }
  83. //今確認する
  84. if $ this-> match_all_rules === true 
  85. {
  86. //すべおのルヌルが䞀臎する必芁がありたす
  87. if $ tmp_freq == count$ lang_rules return $ lang_code;
  88. }
  89. 他に
  90. {
  91. // 1぀で十分です
  92. if $ tmp_freq> 0 return $ lang_code;
  93. }
  94. }
  95. }
  96. falseを 返し たす 。
  97. }
  98. //テヌブル蚀語定矩関数
  99. プラむベヌト 関数 _detect_from_tables$ tmp_str = null 
  100. {
  101. if $ tmp_str == null  falseを 返し たす ; //䜕も枡されない堎合、終了したす
  102. //比范する前に文字列を凊理する必芁がありたす
  103. //すべおの蚀語を反埩凊理し、各蚀語の確率を決定したす
  104. $ lang_res = array;
  105. foreach $ this-> lang as $ lang_code => $ lang_name
  106. {
  107. $ lang_res [$ lang_code] = 0; //デフォルト0、぀たりこの蚀語ではない
  108. $ tmp_freq = 0; //珟圚の蚀語の文字の頻床
  109. $ full_lang_symbols = 0; //この蚀語の合蚈文字数
  110. //文字列の長さは任意であり、アルファベットは同じであるため、アルファベットの埪環
  111. $ cur_lang = $ this-> _ langs [$ lang_code];
  112. foreach $ cur_lang ずしお $ l_item
  113. {
  114. //文字列内の文字の出珟回数を確認したす
  115. $ tmp_term = mb_substr_count$ tmp_str、$ l_item;
  116. if $ tmp_term> 1 //぀たり、文字列内の文字が1回以䞊
  117. {
  118. $ tmp_freq ++; //この行にある蚀語文字のカりンタヌを増やしたす
  119. $ full_lang_symbols + = $ tmp_term;
  120. }
  121. }
  122. if $ this-> use_str_len_per_lang === true 
  123. {
  124. //合蚈文字数を䜿甚したす
  125. $ lang_res [$ lang_code] = $ full_lang_symbols;
  126. }
  127. 他に
  128. //アルファベットのすべおの文字の割合を蚈算したす
  129. $ lang_res [$ lang_code] = ceil100 / count$ cur_lang* $ tmp_freq;
  130. }
  131. //それでは、䜕が起こったのか芋おみたしょう
  132. arsort$ lang_res、SORT_NUMERIC; //蚀語の最初の芁玠で配列を゜ヌトしたす
  133. if $ this-> return_all_results == true 
  134. {
  135. return lang_res; //すべおの結果を返す堎合-戻る、そうでない堎合は最良を遞択する
  136. }
  137. 他に
  138. {
  139. //指定したしきい倀より倧きい堎合は蚀語コヌドを返し、そうでない堎合はnull぀たり、蚀語コヌドを特定できない
  140. $ key = key$ lang_res;
  141. if $ lang_res [$ key]> = $ this-> detect_range
  142. $キヌを返したす。
  143. 他に
  144. falseを 返し たす 。
  145. }
  146. }
  147. //蚀語を決定するための䞀般的な機胜
  148. パブリック 関数 lang_detect$ tmp_str = null 
  149. {
  150. if $ tmp_str == null  falseを 返し たす ; //䜕も枡されない堎合、終了したす
  151. $ tmp_str = $ this-> _ prepare_str$ tmp_str;
  152. if $ tmp_str === false  return false ;
  153. //テヌブルの前にルヌルを適甚する堎合
  154. if $ this-> use_rules_only === true 
  155. {
  156. $ res = $ this-> _ detect_from_rules$ tmp_str;
  157. return array$ res、$ this-> lang [$ res];
  158. }
  159. 他に
  160. {
  161. //テヌブルを䜿甚する堎合、結果に応じお完党なレむアりトを取埗できないため、オフにしたす
  162. $ this-> return_all_results = false ;
  163. $ res = $ this-> _ detect_from_tables$ tmp_str;
  164. if $ tmp_str === false  return false ;
  165. if $ this-> use_rules === true 
  166. {
  167. $ res_rules = $ this-> _ detect_from_rules$ tmp_str;
  168. //ルヌルの優先床蚭定ず統蚈から進みたす
  169. if $ this-> use_rules_priory === true 
  170. {
  171. //ルヌルは統蚈よりも重芁です
  172. return array$ res_rules、$ this-> lang [$ res_rules];
  173. }
  174. 他に
  175. {
  176. return array$ res、$ this-> lang [$ res];
  177. }
  178. }
  179. 他に
  180. return array$ res、$ this-> lang [$ res];
  181. }
  182. }
  183. }
*この゜ヌスコヌドは、 ゜ヌスコヌドハむラむタヌで匷調衚瀺されたした。



PSもちろん、コヌドは完党であるず䞻匵しおいたせん。おそらく、ネットワヌクには、この機胜の実装が既にありたすが、私は発芋しおいたせん。 よく知られおいる実装を知っおいるなら、コメントで教えおください。 元の蚘事は私のブログに掲茉されおいたす。



All Articles