web-dev-qa-db-ja.com

PHPの文字列から言語を検出します

PHPで、文字列の言語を検出する方法はありますか?文字列がUTF-8形式であると仮定します。

30
Beier

文字種から言語を検出することはできません。そして、これを行うための絶対的な方法はありません。

どの方法でも、知識に基づいた推測を行うだけです。利用可能な数学関連の 記事 があります

17
Ólafur Waage

Text_LanguageDetect pear package を使用して、妥当な結果を得ました。使い方は非常に簡単で、適度な52言語データベースがあります。欠点は、東アジア言語が検出されないことです。

require_once 'Text/LanguageDetect.php';
$l = new Text_LanguageDetect();
$result = $l->detect($text, 4);
if (PEAR::isError($result)) {
    echo $result->getMessage();
} else {
    print_r($result);
}

結果は:

Array
(
    [german] => 0.407037037037
    [dutch] => 0.288065843621
    [english] => 0.283333333333
    [danish] => 0.234526748971
)
34
scott

私はこれが古い投稿であることを知っていますが、実行可能な解決策が見つからなかった後に開発したものをここに示します。

  • 他の提案はすべて、私の状況では重すぎて扱いにくい
  • 私は有限数の言語を私のウェブサイトでサポートしています(現時点ではtwo: 'en'と 'de'-しかしソリューションは一般化されています)。
  • ユーザーが生成した文字列の言語について妥当な推測が必要で、フォールバック(ユーザーの言語設定)があります。
  • したがって、私は最小限の誤検知-の解決策が必要ですが、誤検知についてはあまり気にしません。

ソリューションは、言語で最も一般的な20の単語を使用し、干し草の山でのそれらの出現をカウントします。次に、最初にカウントされた言語と2番目にカウントされた言語のカウントを比較します。次点数が勝者の10%未満の場合、勝者がすべてを獲得します。

コード-速度向上のための提案は大歓迎です!

    function getTextLanguage($text, $default) {
      $supported_languages = array(
          'en',
          'de',
      );
      // German Word list
      // from http://wortschatz.uni-leipzig.de/Papers/top100de.txt
      $wordList['de'] = array ('der', 'die', 'und', 'in', 'den', 'von', 
          'zu', 'das', 'mit', 'sich', 'des', 'auf', 'für', 'ist', 'im', 
          'dem', 'nicht', 'ein', 'Die', 'eine');
      // English Word list
      // from http://en.wikipedia.org/wiki/Most_common_words_in_English
      $wordList['en'] = array ('the', 'be', 'to', 'of', 'and', 'a', 'in', 
          'that', 'have', 'I', 'it', 'for', 'not', 'on', 'with', 'he', 
          'as', 'you', 'do', 'at');
      // clean out the input string - note we don't have any non-ASCII 
      // characters in the Word lists... change this if it is not the 
      // case in your language wordlists!
      $text = preg_replace("/[^A-Za-z]/", ' ', $text);
      // count the occurrences of the most frequent words
      foreach ($supported_languages as $language) {
        $counter[$language]=0;
      }
      for ($i = 0; $i < 20; $i++) {
        foreach ($supported_languages as $language) {
          $counter[$language] = $counter[$language] + 
            // I believe this is way faster than fancy RegEx solutions
            substr_count($text, ' ' .$wordList[$language][$i] . ' ');;
        }
      }
      // get max counter value
      // from http://stackoverflow.com/a/1461363
      $max = max($counter);
      $maxs = array_keys($counter, $max);
      // if there are two winners - fall back to default!
      if (count($maxs) == 1) {
        $winner = $maxs[0];
        $second = 0;
        // get runner-up (second place)
        foreach ($supported_languages as $language) {
          if ($language <> $winner) {
            if ($counter[$language]>$second) {
              $second = $counter[$language];
            }
          }
        }
        // apply arbitrary threshold of 10%
        if (($second / $max) < 0.1) {
          return $winner;
        } 
      }
      return $default;
    }
17
Swiss Mister

あなたはこれを完全にクライアント側で行うことができます GoogleのAJAX Language API (現在は消滅しています)。

AJAX Language APIを使用すると、JavaScriptのみを使用してWebページ内のテキストブロックの言語を翻訳および検出できます。さらに、Webページの任意のテキストフィールドまたはテキスト領域で文字変換を有効にできます。たとえば、ヒンディー語に文字変換する場合、このAPIを使用すると、ユーザーは英語を使用してヒンディー語を音声で綴り、ヒンディー語のスクリプトに表示させることができます。

文字列の言語を自動的に検出できます

var text = "¿Dónde está el baño?";
google.language.detect(text, function(result) {
  if (!result.error) {
    var language = 'unknown';
    for (l in google.language.Languages) {
      if (google.language.Languages[l] == result.language) {
        language = l;
        break;
      }
    }
    var container = document.getElementById("detection");
    container.innerHTML = text + " is: " + language + "";
  }
});

そして、のいずれかで書かれた文字列を翻訳します サポートされている言語 (また消滅)

google.language.translate("Hello world", "en", "es", function(result) {
  if (!result.error) {
    var container = document.getElementById("translation");
    container.innerHTML = result.translation;
  }
});
15
Esteban Küber

Google Translate APIは無料サービスとして終了するので、Google Translate APIの代わりとなる次の無料の代替を試すことができます。

http://detectlanguage.com

7
Laurynas

Text_LanguageDetectライブラリを試しましたが、得られた結果はあまり良くありませんでした(たとえば、「test」というテキストは英語ではなくエストニア語として識別されました)。

100万の Yandex Translate API[〜#〜] free [〜#〜]を試してみることをお勧めします文字数は24時間、1か月あたり最大1,000万文字です。 (ドキュメントによると)60以上の言語をサポートしています。

<?php
function identifyLanguage($text)
{
    $baseUrl = "https://translate.yandex.net/api/v1.5/tr.json/detect?key=YOUR_API_KEY";
    $url = $baseUrl . "&text=" . urlencode($text);

    $ch = curl_init($url);

    curl_setopt($ch, CURLOPT_CAINFO, YOUR_CERT_PEM_FILE_LOCATION);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

    $output = curl_exec($ch);
    if ($output)
    {
        $outputJson = json_decode($output);
        if ($outputJson->code == 200)
        {
            if (strlen($outputJson->lang) > 0)
            {
                return $outputJson->lang;
            }
        }
    }

    return "unknown";
}

function translateText($text, $targetLang)
{
    $baseUrl = "https://translate.yandex.net/api/v1.5/tr.json/translate?key=YOUR_API_KEY";
    $url = $baseUrl . "&text=" . urlencode($text) . "&lang=" . urlencode($targetLang);

    $ch = curl_init($url);

    curl_setopt($ch, CURLOPT_CAINFO, YOUR_CERT_PEM_FILE_LOCATION);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

    $output = curl_exec($ch);
    if ($output)
    {
        $outputJson = json_decode($output);
        if ($outputJson->code == 200)
        {
            if (count($outputJson->text) > 0 && strlen($outputJson->text[0]) > 0)
            {
                return $outputJson->text[0];
            }
        }
    }

    return $text;
}

header("content-type: text/html; charset=UTF-8");

echo identifyLanguage("エクスペリエンス");
echo "<br>";
echo translateText("エクスペリエンス", "en");
echo "<br>";
echo translateText("エクスペリエンス", "es");
echo "<br>";
echo translateText("エクスペリエンス", "zh");
echo "<br>";
echo translateText("エクスペリエンス", "he");
echo "<br>";
echo translateText("エクスペリエンス", "ja");
echo "<br>";
?>
4
Muzikant

サービスLnag IDのAPIを使用できます http://langid.net/identify-language-from-api.html

3
Akim Kelar

Text_LanguageDetectナシパッケージはひどい結果を生成しました:「ダウンタウンの高級アパートメント」はポルトガル語として検出されます...

Google APIは依然として最良のソリューションであり、300 $の無料クレジットを提供し、何かを請求する前に警告します

以下は、file_get_contentsを使用してAPIによって検出された言語をダウンロードする非常に単純な関数です。ライブラリなどをダウンロードまたはインストールする必要はありません。

function guess_lang($str) {

    $str = str_replace(" ", "%20", $str);

    $content = file_get_contents("https://translation.googleapis.com/language/translate/v2/detect?key=YOUR_API_KEY&q=".$str);

    $lang = (json_decode($content, true));

    if(isset($lang))
        return $lang["data"]["detections"][0][0]["language"];
 }

実行:

echo guess_lang("luxury apartments downtown montreal"); // returns "en"

ここでGoogle Translate APIキーを取得できます: https://console.cloud.google.com/apis/library/translate.googleapis.com/

これは、簡単な短いフレーズの例です。より複雑なアプリケーションの場合は、APIキーを制限し、ライブラリを明らかに使用する必要があります。

2
Robert Sinclair

おそらく Google Translate API を使用して言語を検出し、必要に応じて翻訳します

2
strager

php内の文字列の言語を検出する方法Text_LanguageDetect Pearパッケージを使用するか、通常のphpライブラリのように個別に使用するためにダウンロードすることができます。

2
adiian

1つの方法としては、入力文字列を単語に分割し、それらの単語を英語の辞書で調べて、存在する単語の数を確認します。このアプローチにはいくつかの制限があります。

  • 固有名詞はうまく処理されない可能性があります
  • スペルミスは検索を中断する可能性があります
  • 「lol」や「b4」のような略語は、必ずしも辞書にあるとは限りません
1
Greg Hewgill

さまざまな言語のドキュメントを取得して、Unicodeで参照します。次に、ベイジアン推論を使用して、使用されているUnicode文字だけで言語を判別できます。これにより、フランス語と英語またはロシア語が分離されます。

(同様の確率論的アプローチを使用して)言語を決定するために言語辞書で単語を検索することを除いて、他に何ができるか正確にはわかりません。

1
MathGladiator

おそらく、この言語推測に文字列を送信します。

http://www.xrce.xerox.com/competencies/content-analysis/tools/guesser

1
Andy

aSCIIエンコードを使用してみてください。そのコードを使用して、ソーシャルボットプロジェクトの言語を決定します

function language($string) {
        $ru = array("208","209","208176","208177","208178","208179","208180","208181","209145","208182","208183","208184","208185","208186","208187","208188","208189","208190","208191","209128","209129","209130","209131","209132","209133","209134","209135","209136","209137","209138","209139","209140","209141","209142","209143");
        $en = array("97","98","99","100","101","102","103","104","105","106","107","108","109","110","111","112","113","114","115","116","117","118","119","120","121","122");
        $htmlcharacters = array("<", ">", "&amp;", "&lt;", "&gt;", "&");
        $string = str_replace($htmlcharacters, "", $string);
        //Strip out the slashes
        $string = stripslashes($string);
        $badthings = array("=", "#", "~", "!", "?", ".", ",", "<", ">", "/", ";", ":", '"', "'", "[", "]", "{", "}", "@", "$", "%", "^", "&", "*", "(", ")", "-", "_", "+", "|", "`");
        $string = str_replace($badthings, "", $string);
        $string = mb_strtolower($string);
        $msgarray = explode(" ", $string);
        $words = count($msgarray);
        $letters = str_split($msgarray[0]);
        $letters = ToAscii($letters[0]);
        $brackets = array("[",",","]");
        $letters = str_replace($brackets,  "", $letters);
        if (in_array($letters, $ru)) {
            $result = 'Русский' ; //russian
        } elseif (in_array($letters, $en)) {
            $result = 'Английский'; //english
        } else {
            $result = 'ошибка' . $letters; //error
        }} return $result;  
1
Master-Bunny

https://github.com/patrickschur/language-detection で良い結果が得られ、本番環境で使用しています:

  • 言語でngramを使用して、最も可能性の高い言語を検出します(文字列が長いほど、単語が多いほど、精度が高くなります)。これは確かな実証済みの方法のようです。
  • 110の言語がサポートされていますが、必要な言語のみに言語の数を制限することもできます。
  • トレーナーと言語検出器は簡単に改善/カスタマイズできます。言語を検出するための基礎として、各言語の世界人権宣言を使用しますが、どのような種類の文章を経験しているのかがわかっていれば、各言語で使用されているテキストを簡単に拡張または置換して、より良い結果をすばやく得ることができます。このライブラリをより良くするための「トレーニング」は簡単です。
  • トレーナーでsetMaxNgramsを増やし(9000に設定)、一度実行してから、言語検出クラスでその設定を使用することをお勧めします。 ngrams数の変更は少し直感的ではなく(コードを調べてどのように機能するかを調べる必要がありました)、これは欠点であり、デフォルト(310)は常に低すぎると私は考えています。より多くのngramを使用すると、推測が大幅に改善されます。
  • ライブラリは非常に小さいため、何が起こっているのか、どのように微調整するのかを理解するのは比較的簡単でした。

私の使用方法:CRMシステムの電子メールを分析して、電子メールがどの言語で書かれているかを確認しているため、テキストをサードパーティのサービスに送信することはできませんでした。世界人権宣言はおそらく電子メールの言語を分類するための最良の基礎ではありません(電子メールには挨拶のような定型的な部分があり、人権宣言の一部ではないため)の正しい言語を99%程度で識別します場合、少なくとも5つの単語が含まれている場合。

更新:次の方法で言語検出ライブラリを使用すると、メールの言語認識を基本的に100%まで向上させることができました。

  • 「あいさつ」、「よろしく」、「誠意をこめて」などの一般的なフレーズを(関連)言語サンプルに追加します。この種の表現は、世界人権宣言では使用されていません。人間のコミュニケーションを分析している場合、一般的に使用されるフレーズは、言語認識、特に私の人間が頻繁に使用する定型的なフレーズ(「Hello」、「Have a Nice day」)に役立ちます。
  • Ngramの最大長を(デフォルトの3ではなく)4に設定します。
  • 以前と同様に、maxNgramsを9000に維持します。

これらはライブラリを少し遅くするので、可能であれば非同期に使用してパフォーマンスを測定することをお勧めします。私の場合、それは十分に速く、はるかに正確です。

1
iquito

JavaでApache Tikaのモジュールを実装し、結果をtxtファイル、DBなどに挿入し、phpを使用して、ファイルdbから読み取ることができます。コンテンツがそれほどない場合は、GoogleのAPIを使用できますが、呼び出しは制限され、APIに送信できる文字数には制限があります。執筆時点では、APIのバージョン1(それほど正確ではないことが判明)とラボバージョン2(1日あたり100,000文字の上限があることを読んだ後、私は取りやめました)のテストを終えました。

0
Osvaldo Mercado