Ключови думи

dakata__92

Super Moderator
Здравейте. Създадох си един метод за генериране на ключови думи от текст. Търся начин да го подобря, без да ми се налага да се допитвам до база с данни. Та ако има някой вдъхновение и желание да сподели опит, ще съм много благодарен. Ако можем и да го оптимизираме да работи по-бързо също ще е плюс.


PHP:
/**
 * @param string $string
 * @return string
 */
public function generateKeywords(string $string): string
{
    if (empty($string)) {
        return '';
    }
    $stripArray = [",", ".", ";", ":", "\"", "'", "“", "”", "(", ")", "!", "?", "„", "`", "[", "]",];
    $space = ' ';
    $string = str_replace($stripArray, $space, strip_tags($string));
    $string = mb_strtolower(trim(preg_replace('/\s+/u', $space, $string)));
    $minWordLength = 2;
    $words = explode($space, $string);
    $keywords = [];
    foreach ($words as $key => $word) {
        if (mb_strlen($word) > $minWordLength && !is_numeric($word)) {
            $keywords[$word] = $word;
        }
    }
    return implode(',', $keywords ?? []) ?? '';
}
 
Забелязваш ли голямо забавяне при по-големи стрингове? И за колко големи текстове говорим тук? Според забавянето може да се мислят конкретни оптимизации вече.

Иначе stripArray можеш да го замениш с preg_replace отново, защото е лесно да изпуснеш определени знаци.

Също понеже използваш асоциативен масив да запазваш думите, на if-а можеш да му добавиш !isset($keywords[$word]), за да предотвратиш влизането в блока. Това е много малка оптимизация, ако гониш хилядните.

Може и друго да се измисли, ако наистина се налага. Тествах с 10000 думи (lorem ipsum) и си минава сравнително бързо.
 
Реално искаш, от кода като гледам, две думи като минимум, ако правилно го разчитам. Това е нещо, което може да е Ок, но има и с по една кл. дума. Но не е проблем, разбира се. Трябва да има и алгоритъм, който да прекалкулира % наситеност и да извади конкретните, като в този случай, за да не се получи спам ще е нужно също да удариш максимум за кл. думи, да речем 8 или 10.

П.П: Искам да не съм скептичен, но оптимизация и SEO не са много съвместими понятия. Просто човек най-добре обработва и преценява. Което не значи с малко по-сложни алгоритми да се доближи до желания хюмън резултат.
 
Текста е генериран от човек. Въпроса е просто да се попълни мета датата с ключови думи от съдържанието. Под оптимизация имах предвид ускорение на кода, не SEO оптимизация. Иначе искам да отсея съдържанието и реално започвам от трибуквени думички. Има ли значение в каква поредност са думите в мета тага? Смисъл ако трябва да ги подредя от по-дълги към по-къси?
 
Забелязваш ли голямо забавяне при по-големи стрингове? И за колко големи текстове говорим тук? Според забавянето може да се мислят конкретни оптимизации вече.

Иначе stripArray можеш да го замениш с preg_replace отново, защото е лесно да изпуснеш определени знаци.

Също понеже използваш асоциативен масив да запазваш думите, на if-а можеш да му добавиш !isset($keywords[$word]), за да предотвратиш влизането в блока. Това е много малка оптимизация, ако гониш хилядните.

Може и друго да се измисли, ако наистина се налага. Тествах с 10000 думи (lorem ipsum) и си минава сравнително бързо.
То повече от 150 думи няма да има. Понеже се зарежда на всяка страница, ако съм направил някоя колосална глупост да я махна, че съм го писал доста отдавна това нещо.
 
Текста е генериран от човек. Въпроса е просто да се попълни мета датата с ключови думи от съдържанието. Под оптимизация имах предвид ускорение на кода, не SEO оптимизация. Иначе искам да отсея съдържанието и реално започвам от трибуквени думички. Има ли значение в каква поредност са думите в мета тага? Смисъл ако трябва да ги подредя от по-дълги към по-къси?
Аз за метата говорех, текста още трудно би могъл да бъде изцяло машинно генериран с поставяне на кл. думи. Няма значение по какъв начин ще са разположени, но се предполага, че първите са с по-голяма тежест и искаш те са по-значими. Имай предвид, че кл. думи от много време вече не са фактор за оптимизацията, гледа се дали ги има, но не влияят пряко на on-page SEO-то. Мета описанието е хубаво да го има, даже препоръчително, като трябва да е кратко резюме от едно изречение на контента от страницата и за какво се отнася самата страница.


В статията се появява и един наш любим герой от едно време Мат Кътц, който всички SEO-та мразехме. :) Стана популярен със спам войната си срещу т.нар. контент спаминг и контент ъпдейтите - по-конкретно Панда ъпдейта. :)


Агонията продължи доста време и много сайтове улетята от SERP-а.
 
Направих промяна в кода и се надявам се да съм подобрил нещата. Споделете мнение за новата версия.

PHP:
/**
* @param string $string
* @param int $minWordLength
* @return string
*/
public function generateKeywords(
    string $string,
    int    $minWordLength = 3
): string
{
    $keywords = '';
    if (empty($string)) {
        return $keywords;
    }
    $stripArray = [",", ".", ";", ":", "\"", "'", "“", "”", "(", ")", "!", "?", "„", "`", "[", "]",];
    $space = ' ';
    $string = str_replace($stripArray, $space, strip_tags(mb_strtolower($string)));
    $string = trim(preg_replace('/\s+/u', $space, $string));
    $words = explode($space, $string);
    $arrayKeywords = [];
    foreach ($words as $word) {
        if (isset($arrayKeywords[$word]) || is_numeric($word)) {
            continue;
        }
        $wordLength = mb_strlen($word);
        if ($wordLength >= $minWordLength) {
            $arrayKeywords[$word] = $wordLength;
        }
    }
    if (count($arrayKeywords) > 0) {
        arsort($arrayKeywords);
        $keywords = implode(',', array_keys($arrayKeywords));
    }
    return $keywords;
}
 
Защо си вдигнал на 3? 2 беше ОК си мисля също.
То и преди бяха пак от три. Всичко по-голямо от две, а сега просто го направих по-разбираемо. Всичко по-голямо или равно на 3 символа. Ако го сложа на две то реално вкарвам повече местоимения отколкото по-важно съдържание в ключовите думи.
 
Защо не връщаш арей с цел да се ползва и другаде тоя код
Намира се в специализиран клас за Метадата и няма къде другаде да го ползвам. Ако се налага ще се промени логиката по контролерите и ще връщам масив.
 
Ето нови промени. Благодаря за забележките.

PHP:
/**
* @param string $string
* @param int $minWordLength
* @return array
*/
public function generateKeywords(
    string $string,
    int    $minWordLength = 3
): array
{
    $keywords = [];
    if (empty($string)) {
        return $keywords;
    }
    $space = ' ';
    $string = preg_replace('/[^\p{L}\p{N}]/u', $space, strip_tags(mb_strtolower($string)));
    $string = trim(preg_replace('/\s+/u', $space, $string));
    $words = explode($space, $string);
    foreach ($words as $word) {
        if (isset($keywords[$word]) || is_numeric($word)) {
            continue;
        }
        $wordLength = mb_strlen($word);
        if ($wordLength >= $minWordLength) {
            $keywords[$word] = $wordLength;
        }
    }
    if (count($keywords) > 0) {
        arsort($keywords);
    }
    return $keywords;
}

/**
* @param string $string
* @param int $minWordLength
* @return string
*/
public function generateStringOfKeywords(
    string $string,
    int    $minWordLength = 3
): string
{
    return implode(',', array_keys(
        $this->generateKeywords($string, $minWordLength)
    ));
}
 
Нещо, което ми се върти в главата е да добавя и брояч на различните думи. Колкото по-често е срещана толкова по-напред в редицата да бъде. Какво мислите за това хрумване?
 
Още една оптимизация или подобрение би било да разкарваш всички предлози, защото има сравнително много трибуквени като над под зад и т.н. Иначе в едно изречение може да се напълниш с тях.

Колкото за твоята идея - ако има значение позицията, то тогава звучи добре.

Между другото тази част би трябвало да можеш да сместиш в един preg_repalce

PHP:
$string = preg_replace('/[^\p{L}\p{N}]/u', $space, strip_tags(mb_strtolower($string)));
$string = trim(preg_replace('/\s+/u', $space, $string));
 
За предлозите и местоименията, ще трябва за всеки език да се игнорират по отделно.

Чудих му се как да стане, но не се сетих и го оставих така. Вече съм забил и пиша машинално, а тази задача ми е в графа оптимизации и се прехвърлих от основна към нея.

PHP:
$string = preg_replace('/[^\p{L}\p{N}]/u', $space, strip_tags(mb_strtolower($string)));
$string = trim(preg_replace('/\s+/u', $space, $string));

Добавих логика обвързана с броя повторения на думата и дължината и.

PHP:
/**
* @param string $string
* @param int $minWordLength
* @return array
*/
public function generateKeywords(
    string $string,
    int    $minWordLength = 3
): array
{
    $keywords = [];
    if (empty($string)) {
        return $keywords;
    }
    $space = ' ';
    $string = preg_replace('/[^\p{L}\p{N}]/u', $space, strip_tags(mb_strtolower($string)));
    $string = trim(preg_replace('/\s+/u', $space, $string));
    $words = explode($space, $string);
    $countWords = array_count_values($words);
    foreach ($words as $word) {
        if (isset($keywords[$word]) || is_numeric($word)) {
            continue;
        }
        $wordLength = mb_strlen($word);
        if ($wordLength >= $minWordLength) {
            $wordWeightNumber = ($countWords[$word] ?? 0) + $wordLength;
            $keywords[$word] = $wordWeightNumber;
        }
    }
    if (count($keywords) > 0) {
        arsort($keywords);
    }
    return $keywords;
}
 
PHP:
$space = ' ';
$string = preg_replace('/[^\p{L}\p{N}]|\s+/u', $space, strip_tags(mb_strtolower($string)));
$words = explode($space, trim($string));

Просто ти трябва | да разделиш шаблоните.
 
PHP:
$space = ' ';
$string = preg_replace('/[^\p{L}\p{N}]|\s+/u', $space, strip_tags(mb_strtolower($string)));
$words = explode($space, trim($string));

Просто ти трябва | да разделиш шаблоните.
Това няма да сработи, защото ако имам символи до разстояние и ги заменя реално след това ще остане двоен „space“. Иначе се сетих за този вариант, но затова го отхвърлих.
 
Нещо, което ми се върти в главата е да добавя и брояч на различните думи. Колкото по-често е срещана толкова по-напред в редицата да бъде. Какво мислите за това хрумване?
Това е добро. И може, ако има възможност да се сложи някакви параметри за наситеност на кл. дума на база цялостно съдържание на страницата. Добрият % е

Код:
How To Calculate Keyword Density?

It is natural to think it’s important to identify that sweet spot to achieve higher rankings in Google. The question is what is the optimal keyword density? Is it 1%, 2% 3% or 0.3% or 33% ? If you look online you’ll find a lot of conflicting opinions on the ideal keyword density %. It all sounds very scientific, too.

There is, of course, a FORMULA to work out the local keyword density of any page:

    Density = ( Nkr / ( Tkn -( Nkr x ( Nwp-1 ) ) ) ) x 100
    Density = your keyword density
    Nkr = how many times you repeated a specific key-phrase
    Nwp = number of words in your key-phrase
    Tkn = total words in the analyzed text


Код:
Some experts will tell you between 0.5% and 0.8%. Other sites will say anywhere between 0.5% and 2.5% is acceptable.
 
Това няма да сработи, защото ако имам символи до разстояние и ги заменя реално след това ще остане двоен „space“. Иначе се сетих за този вариант, но затова го отхвърлих.
Това, което ще стане е просто да имаш елементи, които са празен низ в масива, който explode() ти връща. Това като цяло не е проблем, защото останалата ти логика ги отсява така или иначе. Втори preg_replace() може да се окаже една идея по-бавен, отколкото един в твоя случай.

Като цяло няма голямо значение тук. Просто се изчиства кода малко.
 

Back
Горе