Yandex Linguistics API for .NET

さらに別のConference 2013に参加した後、.NETですべてのYandex言語サービス用のAPIを書くというアイデアがありました。 短いグーグルの後、 幸いなことにそのようなライブラリはありませんでした。 誰も実際にそれを必要としないかもしれないという事実にもかかわらず、私は少なくともRestSharp 、テスト、およびさまざまなgithub機能(発行者、リリース、 マークダウンなど)で練習するために、それを実装することにしました。 さらに、実装の過程で、興味深い文字列比較アルゴリズムに出くわす必要がありました。これについては、トピックで説明します。



すぐにソースコードとバイナリへのリンクをGitHubにスローします: Codeバイナリ



実装されたAPI







RestSharpを使用すると、同期および非同期のHTTP GETおよびPOSTリクエストのコードを非常に簡単に記述できるだけでなく、XMLまたはJSON形式で受信した応答を.NETオブジェクトに変換できます(このプロジェクトではXMLが使用されました)。



拡張ダメラウ—レーベンシュタイン距離計算関数



スペルを実装するプロセスで、テキストの修正バージョンだけでなく、エラーも表示されるようにしたかったのです。 レビンシュタイン距離の考えがすぐに頭に浮かんだ。 ただし:



最初の欠点はDamerau –レーベンシュタイン距離によって相殺され、2番目はアルゴリズム中に得られたマトリックスの分析によるものでした(距離はマトリックスの最後の列の最後の行要素の値です。したがって、私の場合、距離は)



したがって、誤った(単語)および正しい(修正された単語)単語で次のエラーを検索するアルゴリズムが実装されました。



さらに、さまざまなエラーの重みを調整できます(デフォルトでは、すべて同じ重みが1になります)。



Damerau —レーベンシュタイン拡張距離カウントコード
public static List<Mistake> DamerauLevenshteinDistance( string word, string correctedWord, bool transposition = true, int substitutionCost = 1, int insertionCost = 1, int deletionCost = 1, int transpositionCost = 1) { int w_length = word.Length; int cw_length = correctedWord.Length; var d = new KeyValuePair<int, CharMistakeType>[w_length + 1, cw_length + 1]; var result = new List<Mistake>(Math.Max(w_length, cw_length)); if (w_length == 0) { for (int i = 0; i < cw_length; i++) result.Add(new Mistake(i, CharMistakeType.Insertion)); return result; } for (int i = 0; i <= w_length; i++) d[i, 0] = new KeyValuePair<int, CharMistakeType>(i, CharMistakeType.None); for (int j = 0; j <= cw_length; j++) d[0, j] = new KeyValuePair<int, CharMistakeType>(j, CharMistakeType.None); for (int i = 1; i <= w_length; i++) { for (int j = 1; j <= cw_length; j++) { bool equal = correctedWord[j - 1] == word[i - 1]; int delCost = d[i - 1, j].Key + deletionCost; int insCost = d[i, j - 1].Key + insertionCost; int subCost = d[i - 1, j - 1].Key; if (!equal) subCost += substitutionCost; int transCost = int.MaxValue; if (transposition && i > 1 && j > 1 && word[i - 1] == correctedWord[j - 2] && word[i - 2] == correctedWord[j - 1]) { transCost = d[i - 2, j - 2].Key; if (!equal) transCost += transpositionCost; } int min = delCost; CharMistakeType mistakeType = CharMistakeType.Deletion; if (insCost < min) { min = insCost; mistakeType = CharMistakeType.Insertion; } if (subCost < min) { min = subCost; mistakeType = equal ? CharMistakeType.None : CharMistakeType.Substitution; } if (transCost < min) { min = transCost; mistakeType = CharMistakeType.Transposition; } d[i, j] = new KeyValuePair<int, CharMistakeType>(min, mistakeType); } } int w_ind = w_length; int cw_ind = cw_length; while (w_ind >= 0 && cw_ind >= 0) { switch (d[w_ind, cw_ind].Value) { case CharMistakeType.None: w_ind--; cw_ind--; break; case CharMistakeType.Substitution: result.Add(new Mistake(cw_ind - 1, CharMistakeType.Substitution)); w_ind--; cw_ind--; break; case CharMistakeType.Deletion: result.Add(new Mistake(cw_ind, CharMistakeType.Deletion)); w_ind--; break; case CharMistakeType.Insertion: result.Add(new Mistake(cw_ind - 1, CharMistakeType.Insertion)); cw_ind--; break; case CharMistakeType.Transposition: result.Add(new Mistake(cw_ind - 2, CharMistakeType.Transposition)); w_ind -= 2; cw_ind -= 2; break; } } if (d[w_length, cw_length].Key > result.Count) { int delMistakesCount = d[w_length, cw_length].Key - result.Count; for (int i = 0; i < delMistakesCount; i++) result.Add(new Mistake(0, CharMistakeType.Deletion)); } result.Reverse(); return result; }
      
      









インターフェース



インターフェイスがWinFormsに実装され、アプリケーションがMonoでも実行されることを期待していました。 ただし、テストは行われていません。



画像



このライブラリは任意のプロジェクトで使用できますが、属性があります(Apache 2.0)。



All Articles