Skip to content

Commit

Permalink
Refinements in Russian stemmer.
Browse files Browse the repository at this point in the history
  • Loading branch information
parpalak committed Aug 24, 2024
1 parent f874a7a commit 3fd37b5
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 62 deletions.
108 changes: 52 additions & 56 deletions src/S2/Rose/Stemmer/PorterStemmerRussian.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class PorterStemmerRussian extends AbstractStemmer implements StemmerInterface
'когда' => '',
'где' => '',
'куда' => '',
'откуда' => '',
'если' => '',
'тире' => '',
'после' => '',
Expand Down Expand Up @@ -90,7 +91,6 @@ class PorterStemmerRussian extends AbstractStemmer implements StemmerInterface
'просто' => '',
'почему' => '',
'потому' => '',
'всего' => '',
'чтоб' => '',
'чтобы' => 'чтоб',
'лишь' => '',
Expand All @@ -107,6 +107,10 @@ class PorterStemmerRussian extends AbstractStemmer implements StemmerInterface
'из' => '',
'из-за' => '',

'всего' => 'все',
'всему' => 'все',
'всем' => 'все',

'что' => '',
'чего' => 'что',
'чему' => 'что',
Expand All @@ -131,56 +135,30 @@ class PorterStemmerRussian extends AbstractStemmer implements StemmerInterface
'никем' => 'никто',
'ником' => 'никто',

'все-таки' => '',
'во-первых' => '',
'во-вторых' => '',
'в-третьих' => '',

// Some popular prefixes and postfixes. TODO come up with a more systematic approach
'как-то' => '',
'как-нибудь' => '',
'где-то' => '',
'когда-то' => '',
'когда-нибудь' => '',
'куда-то' => '',
'почему-то' => '',
'вообще-то' => '',

'что-то' => 'что-то',
'чего-то' => 'что-то',
'чему-то' => 'что-то',
'чем-то' => 'что-то',
'чём-то' => 'что-то',

'что-нибудь' => 'что-нибудь',
'чего-нибудь' => 'что-нибудь',
'чему-нибудь' => 'что-нибудь',
'чем-нибудь' => 'что-нибудь',
'чём-нибудь' => 'что-нибудь',

'кое-что' => 'кое-что',
'кое-чего' => 'кое-что',
'кое-чему' => 'кое-что',
'кое-чем' => 'кое-что',
'кое-чём' => 'кое-что',

'кто-то' => 'кто-то',
'кого-то' => 'кто-то',
'кому-то' => 'кто-то',
'кем-то' => 'кто-то',
'ком-то' => 'кто-то',

'кто-нибудь' => 'кто-нибудь',
'кого-нибудь' => 'кто-нибудь',
'кому-нибудь' => 'кто-нибудь',
'кем-нибудь' => 'кто-нибудь',
'ком-нибудь' => 'кто-нибудь',

'кое-кто' => 'кое-кто',
'кое-кого' => 'кое-кто',
'кое-кому' => 'кое-кто',
'кое-кем' => 'кое-кто',
'кое-ком' => 'кое-кто',
// Не могу добавить тем и том из-за существительных
'того' => 'тот',
'тому' => 'тот',

'чей' => '',
'чьего' => 'чей',
'чьё' => 'чей',
'чье' => 'чей',
'чья' => 'чей',
'чьи' => 'чей',
'чьей' => 'чей',
'чьих' => 'чей',
'чьему' => 'чей',
'чьим' => 'чей',
'чью' => 'чей',
'чьею' => 'чей',
'чьими' => 'чей',
'чьём' => 'чей',
'чьем' => 'чей',

'все-таки' => '',
'во-первых' => '',
'во-вторых' => '',
'в-третьих' => '',

'печать' => 'печат', // стеммер считает, что это глагол

Expand Down Expand Up @@ -320,6 +298,18 @@ class PorterStemmerRussian extends AbstractStemmer implements StemmerInterface
'могло' => 'мочь',
'могли' => 'мочь',

'быть' => '',
'был' => 'быть',
'была' => 'быть',
'было' => 'быть',
'были' => 'быть',
'буду' => 'быть',
'будешь' => 'быть',
'будет' => 'быть',
'будем' => 'быть',
'будете' => 'быть',
'будут' => 'быть',

'другой' => 'друго',
'другого' => 'друго',
'другому' => 'друго',
Expand All @@ -343,11 +333,17 @@ public function stemWord(string $word, bool $normalize = true): string
return $this->cache[$word];
}

/**
* TODO How to deal with postfixes like "кто-либо" -> "кого-либо"?
* Ignoring postfix is not an option - there are a lot of trash results found.
*/
// $word = preg_replace('/^(.*)-(то|либо|нибудь)$/Su', '-\\2-\\1', $word);
if (\preg_match('/^([^\-]+)-(то|либо|нибудь|ка)$/Su', $word, $matches)) {
return $this->cache[$word] = $this->stemWord($matches[1]) . '-' . $matches[2];
}

if (substr($word, 0, strlen('кое-')) === 'кое-') {
return $this->cache[$word] = 'кое-' . $this->stemWord(substr($word, strlen('кое-')));
}

if (substr($word, 0, strlen('по-')) === 'по-') {
return $this->cache[$word] = $word;
}

if (isset(self::$irregularWords[$word])) {
return $this->cache[$word] = (self::$irregularWords[$word] !== '' ? self::$irregularWords[$word] : $word);
Expand Down
19 changes: 13 additions & 6 deletions tests/unit/Rose/Stemmer/StemmerTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/**
* @copyright 2016-2023 Roman Parpalak
* @copyright 2016-2024 Roman Parpalak
* @license MIT
*/

Expand Down Expand Up @@ -54,6 +54,18 @@ public function testRegexes(): void
$this->assertEquals('доб', $this->russianStemmer->stemWord('добившись'));
}

public function testParticles(): void
{
$this->assertEquals('кто-нибудь', $this->russianStemmer->stemWord('кого-нибудь'));
$this->assertEquals('когда-нибудь', $this->russianStemmer->stemWord('когда-нибудь'));
$this->assertEquals('что-то', $this->russianStemmer->stemWord('чему-то'));
$this->assertEquals('нехитр-то', $this->russianStemmer->stemWord('нехитрое-то'));
$this->assertEquals('когда-либо', $this->russianStemmer->stemWord('когда-либо'));
$this->assertEquals('что-либо', $this->russianStemmer->stemWord('чем-либо'));
$this->assertEquals('кое-что', $this->russianStemmer->stemWord('кое-чем'));
$this->assertEquals('кое-кто', $this->russianStemmer->stemWord('кое-кого'));
}

public function testStem(): void
{
$this->assertEquals('ухмыляться', $this->englishStemmer->stemWord('ухмыляться'));
Expand All @@ -65,11 +77,6 @@ public function testStem(): void

$this->assertEquals('метро', $this->russianStemmer->stemWord('метро'));

$this->assertEquals('кое-кто', $this->russianStemmer->stemWord('кое-кого'));
$this->assertEquals('чем-либ', $this->russianStemmer->stemWord('чем-либо'));
$this->assertEquals('когда-нибудь', $this->russianStemmer->stemWord('когда-нибудь'));
$this->assertEquals('нехитрое-т', $this->russianStemmer->stemWord('нехитрое-то'));

$this->assertEquals('экзамен', $this->russianStemmer->stemWord('экзамен'));
$this->assertEquals('экзамен', $this->russianStemmer->stemWord('экзамена'));
$this->assertEquals('экзамен', $this->russianStemmer->stemWord('экзамену'));
Expand Down

0 comments on commit 3fd37b5

Please sign in to comment.