Automatizace clusterizace

18.6. jsem měl možnost přednášet na SEO Restartu s tématem automatizace analýzy klíčových slov. Jelikož jsem na pódiu nešel do hloubky a nepopisoval ono řešení, tak jsem pro vás připravil tento komplexní návod, který vás provede mnou popisovaným řešením.

Obsah článku:

Clusterizace

V rámci clusterizace jsem se rozhodl zopakovat teorii, prerekvizity a následně vám ukázat všechna řešení, díky kterým můžete clusterizaci vyřešit. Schválně vám ukáži i staré řešení, abyste mohli srovnat staré versus nové řešení.

Kapitoly clusterizace:

  • Princip
  • Prerekvizity
  • Aktuální řešení
  • Řadící řešení
  • Skriptovací řešení

Princip

Clasterizace je jednoduchá činnost v rámci které se snažíte sjednotit slova, které říkají to samé a ve výsledném datasetu by vás mohly mást. A nepřidají vám žádnou přidanou hodnotu.

Ve výsledku chcete spojit následující slova:

  • krátké letní šaty
  • letní šaty krátké
  • šaty letní krátké
  • šaty krátké letní
  • letní krátké šaty
  • krátké šaty letní
  • kratke letni saty
  • letni saty kratke
  • saty letni kratke
  • saty kratke letni
  • letni kratke saty
  • kratke saty letni

Do jednoho, které bude tuto skupinu reprezentovat. Jako reprezentanta ve většině případů hledáme gramaticky správné nebo nejhledanější slovo.

Prerekvizity

Clasterizace stojí a padá na mocném nástroji OpenRefine a jeho funkce Cluster and Edit. Aby vám mohl fungovat OpenRefine, budete potřebovat Javu a zároveň budete potřebovat dataset klíčových slov s hledaností z nástroje Marketing Miner, který nám dává data o hledanosti na základě click stream dat.

OpenRefine – http://openrefine.org/download.html
Java – https://java.com/en/download/
Marketing Miner – https://www.marketingminer.com/cs

Click stream hledanost je podstatná, protože pouze na jejichž základě lze kvalitně rozhodnout, jaké slovo je z clastru nejhledanější a to využít.

Aktuální řešení

Klasickou klasterizaci aktuálně děláme pomocí funkce Cluster and Edit v Open Refine, kdy si rozkliknete sloupec klíčových slov a na něm spustíte zmiňovanou funkci. Následně vybíráte správné zástupce clusteru.

Konkrétní kroky ruční clusterizace:

  1. Připravte si projekt
  2. Otevřete si funkci Cluster and Edit
  3. Určete jednotlivé clustry

1) Připravte si projekt

Projekt v OpenRefine

Nahrajte projekt, který bude obsahovat sloupec: “klíčové slovo” a “hledanost” do nástroje OpenRefine. Pojmenování sloupců je v případě tohoto řešení nedůležité.

2) Otevřete si funkci Cluster and Edit

Abyste otevřeli funkci Cluster and Edit, tak si otevřete nastavení sloupce, nechte si rozjet “Edit cels” a klikněte na “Cluster and edit…”.

Funkce Cluster and edit

Jakmile kliknete na funkci “Cluster and edit”, tak se vám otevře pop-up, ve kterém můžete zvolit funkci pro určení clustrů, navržené clustry a “šoupátka” pro ořezání velikosti datasetu.

Pop-up funkce Cluster and Edit

3) Určete jednotlivé clustry

Ve sloupečku “Values in Cluster” jsou hodnoty, které OpenRefine označil za podobné, dle klíče, který jsem popsal v teorii clusterizace.

Jednotlivé clustry navržené nástrojem OpenRefine

Jak můžete vidět, tak za zástupce prvního clustru označil OpenRefine “hodiny nastenne”, avšak clustr by pravděpodobně lépe zastupoval gramaticky správný nebo hledanější skupina.

Abyste se rozhodli a vybrali správného zástupce, tak potřebujete vidět další informace. Stačí “najet” kurzorem na jeden sloupec, díky čemuž se vám objeví tlačítko “Browse this cluster”.

Tlačítko “Browse this cluster”

Po rozkliknutí se vám otevřou v nové záložce vyfiltrované hodnoty clastru a vy můžete rozhodnout, jaké slovo vyberete jako zástupce clastru.

Virtuální filtrace pro náhled všech slov

Ve vzorovém případě bych se rozhodnul pro “nástěnné hodiny”, jelikož mají největší hledanost a to 3 800 hledání měsíčně. Podobným způsobem to musíte udělat u každého z vybraných clastrů. Díky čemuž si budete na 100 % jisti, že sedí.

Proč je toto řešení špatné?

Toto řešení vnímám jako špatné z toho důvodu, že musíte ručně procházet všechny clustry. V případě menší analýzy klíčových slov může jít o 2 hodiny, ale když máte třeba 5 000 clastrů, tak vám to již nějakou dobu potrvá.

Řadící řešení

Pojďme se podívat na první rychlé řešení, které provede clusterizaci během několika málo sekund a které stojí na metodě řazení, které OpenRefine nabízí. V rámci tohoto řešení nemusíte o ničem rozhodovat, jen si musíte dát pozor, že vše bude správně nastavené.

1) Připravte si projekt

Stejně jako v předchozím řešení, musíte založit nový projekt v OpenRefine, který by měl opět obsahovat sloupec “Keyword” a “Search Volume”.

Projekt v OpenRefine

2) Vytvořte sloupec zálohy

Abychom se v budoucnosti dostali k nejhledanějšímu klíčovému slovu ze skupiny, tak si musíme vytvořit sloupec zálohy, do kterého umístíme původní klíčová slova.

Vytvořte si nový sloupec

Nový sloupec můžete libovolně pojmenovat a chcete do něj uložit stejná klíčová slova, jako jsou ve sloupci “Keyword”. Tudíž nic neměňte a rovnou můžete nový sloupec založit.

Nový sloupec založíte kliknutím na OK.

3) Seřaďte od nejhledanějšího po nejméně hledaný

Jakmile vytvoříte sloupec zálohy s názvem Keyword-bu, takže seřaďte dataset dle hledanosti, který vám zajistí, že se bude do clastru pravděpodobně nastavovat nejhledanější slovo z clastru.

Výběr řazení dle hledanosti

Jakmile kliknete na tlačítko “Sort…”, tak na vás vyskočí vyskakovací okno, kde musíte nastavit, že chcete srovnávat čísla od největšího po nejmenší.

Sortovací pop-up

A následně nastavte seřazení tak, aby se dataset “přeindexoval”, což vám umožní rozbalovací nabídka “Sort” a výběr “Reorder rows permanently”.

4) Proveďte clasterizaci

Nyní na sloupečku “Keyword” spusťe funkci “Cluster and Edit” a zobrazí se vám již známý pop-up, kde jednoduše můžete nastavit “Select all” a následně stačí provést clusterizaci pomocí “Merge Selected & Close”

Jednoduché nastavení clusterizace

Na pozadí se provede to, že se automaticky vybere náhodná hodnota bez toho anižbyste museli cokoliv kontrolovat a nastavovat. Onu selekci nejhledanějšího provedeme až v kroku 5.

5) Seřaďte od A – Z  + Seřaďte dle hledanosti

Nyní proveďte seřazení od A – Z na sloupci “Keyword” díky čemuž se vám jednotlivé clustry dají pěkně “pod sebe”. A stejně tak nastavte sekundární řazení dle hledanosti. Následně projekt permanentně seřaďte.

Jakmile provedete seřazení, tak využijte funkce blank down, která smaže ony hodnoty a zmeňme tak jednotlivé řádky na záznamy.

Funkce Blank down

Po funkci Blank down by měl testovací dataset vypadat následovně. Ano, dataset není pročištěný, jelikož jsem jej náhodně vybral z Marketing Mineru pro demonstraci řešení.

6) Ruční kontrola

Nyní bych vám doporučil ruční kontrolu a projít si jednotlivé prázdné řádky a zkontrolovat, jestli je na prvním místě vždy nejhledanější klíčové slovo. V následujícím kroku budeme muset zachovat původní hodnoty, abychom se k nim mohli kdykoliv v budoucnosti vrátit.

7) Sečtěte hodnoty

Nyní sjednoťte sloupce „Keyword-bu“ i „Search Volume“ do jednoho, díky čemuž budeme moc jednoduše uchovat všechny slova v clustru i sečíst hledanosti. Klikněte na Keyword-bu a vyberte „Join multi-valued cells…“

Jakmile se vám zobrazí patřičný pop-up, tak bude nutné vyplnit znak pro rozdělení slov. Za mě vám mohu doporučit znak ¤ (Alt + 15), který se ve vašem datasetu nebude pravděpodobně nikdy zobrazovat.

V případě hledanosti můžete v klidu spojit dle čárky, tam nám to ničemu vadit nebude. 🙂 Sečtení hledanosti provedete pomocí tohoto příkazu v GRELu:

forEach(value.split(','),v,v.toNumber()).sum()

8) Smažte prázdné hodnoty

Nyní vám již stačí vybrat si „Customized facets“ a „Facet by blank“ a všechny hodnoty, které obsahuji True smazat.

Umístění Facet by blank

Následně vyberte hodnoty True a ty smažte pomocí „Remove all matching rows“

Z praxe

Pokaždé, když jsem zkoušel toto řešení, tak jsem se více či méně zasekal na onom řadícím systému, avšak věřím, že když budete postupovat dle návodu, tak to zvládnete.

Skriptovací řešení

Jak již názvem napovídá, tak druhou variantou řadící metody je skriptovací řešení, které rozhoduje o Clusterizaci na základě „skriptu“. Původně jsme si chtěli funkce v OpenRefine „ohnout“ a „doprogramovat“, avšak nakonec to nebylo třeba.

Jediné, co musíte dodržet je správné založení projektu s korektním pojmenováním sloupců a o zbytek se postará OpenRefine.

1) Připravte si projekt

Základem je připravit si projekt, který bude mít dva sloupce. V tom prvním bude „Keyword“ a ve druhém „Search“. Jako hodnotu sloupce „Search“ vám výrazně doporučuji využít hledanosti z Marketing Mineru, protože jsou přesnější.

Připravte si projekt

Když nedojde ke korektnímu pojmenování, tak vám následující skript nebude fungovat, což by byla škoda.

2) Vytvořte nový sloupec Keyword-bu

Opět jako v předchozím principu vytvořte nový sloupec Keyword-bu, ze kterého budeme následně vybírat ono správné klíčové slovo.

Vytvoření nového sloupce

3) Proveďte clasterizaci

Nyní nad sloupečkem Keyword spusťte funkci Cluster and edit a rovnou zaklikněte, že to chcete nastavit tak, jak vám hodnoty do skupin navrhl OpenRefine. Je úplně v pohodě, že ty skupiny nebudou přesné, onu přesnost vykouzlíme skriptem.

4) Spusťte skript

Nyní stačí využít magické funkce Apply a umístit do ni následující kód, který vám na základě námi připravených sloupců na clusterizaci provede výběr toho nejhledanějšího slova a to uloží v novém sloupci.

[
  {
    "op": "core/row-reorder",
    "description": "Reorder rows",
    "mode": "row-based",
    "sorting": {
      "criteria": [
        {
          "errorPosition": 1,
          "caseSensitive": false,
          "valueType": "string",
          "column": "Keyword",
          "blankPosition": 2,
          "reverse": false
        }
      ]
    }
  },
  {
    "op": "core/blank-down",
    "description": "Blank down cells in column Keyword",
    "engineConfig": {
      "facets": [],
      "mode": "row-based"
    },
    "columnName": "Keyword"
  },
  {
    "op": "core/multivalued-cell-join",
    "description": "Join multi-valued cells in column Keyword-bu",
    "columnName": "Keyword-bu",
    "keyColumnName": "Keyword",
    "separator": "☼"
  },
  {
    "op": "core/multivalued-cell-join",
    "description": "Join multi-valued cells in column Search",
    "columnName": "Search",
    "keyColumnName": "Keyword",
    "separator": ", "
  },
  {
    "op": "core/text-transform",
    "description": "Text transform on cells in column Search using expression value.toString()",
    "engineConfig": {
      "facets": [],
      "mode": "row-based"
    },
    "columnName": "Search",
    "expression": "value.toString().replace('.0', '')",
    "onError": "keep-original",
    "repeat": false,
    "repeatCount": 10
  },
  {
    "op": "core/column-addition",
    "description": "Create column Index at index 3 based on column Search using expression jython:array = value\narray = array.split(',')\n\nx = 0\nmax = 0\nindex = 0\n\nwhile x < len(array):\n array[x] = int(array[x])\n if max < array[x]:\n  max = array[x]\n  index = array.index(max)\n x = x + 1\n\nreturn index",
    "engineConfig": {
      "facets": [],
      "mode": "row-based"
    },
    "newColumnName": "Index",
    "columnInsertIndex": 3,
    "baseColumnName": "Search",
    "expression": "jython:array = value\narray = array.split(',')\n\nx = 0\nmax = 0\nindex = 0\n\nwhile x < len(array):\n array[x] = int(array[x])\n if max < array[x]:\n  max = array[x]\n  index = array.index(max)\n x = x + 1\n\nreturn index",
    "onError": "set-to-blank"
  },
  {
    "op": "core/column-removal",
    "description": "Remove column Keyword",
    "columnName": "Keyword"
  },
  {
    "op": "core/column-addition",
    "description": "Create column Keyword at index 1 based on column Keyword-bu using expression grel:forEach(value.split('☼'),v,v).get(cells['Index'].value)",
    "engineConfig": {
      "facets": [],
      "mode": "row-based"
    },
    "newColumnName": "Keyword",
    "columnInsertIndex": 1,
    "baseColumnName": "Keyword-bu",
    "expression": "grel:forEach(value.split('☼'),v,v).get(cells['Index'].value)",
    "onError": "set-to-blank"
  }
]

Výsledný projekt bude aktuálně vypadat takto, tudíž si můžete zkontrolovat, že je vše naklasifikované správně.

5) Zkontrolujte řešení

Kontrolu můžete provést pouhým okem, kdy se musíte podívat na hodnoty ve sloupci Search a následně se podívat na hodnotu ve sloupci Index. V OpenRefine se index počítá stejně jako téměř v každém programocím jazyku od nuly, tudíž nula znamená první výskyt v řetězci.

Manuální kontrola

Na obrázku výše je vidět, že OpenRefine určil všude, že je nejhledanější vždy to první slovo a tedy jej i vybral. V tomto případě jde o naprosto očekávané chování, které je správné.

Jakmile budete mít zkontrolováno, tak spusťte následující skript, kterým dataset dočistíte a dostanete jeje do vámi oblíbené podoby.

[
  {
    "op": "core/text-transform",
    "description": "Text transform on cells in column Search using expression grel:forEach(value.split(','),v,v.toNumber()).sum()",
    "engineConfig": {
      "facets": [],
      "mode": "row-based"
    },
    "columnName": "Search",
    "expression": "grel:forEach(value.split(','),v,v.toNumber()).sum()",
    "onError": "keep-original",
    "repeat": false,
    "repeatCount": 10
  },
  {
    "op": "core/column-removal",
    "description": "Remove column Index",
    "columnName": "Index"
  },
  {
    "op": "core/row-removal",
    "description": "Remove rows",
    "engineConfig": {
      "facets": [
        {
          "type": "list",
          "name": "Keyword-bu",
          "expression": "isBlank(value).toString()",
          "columnName": "Keyword-bu",
          "invert": false,
          "selection": [
            {
              "v": {
                "v": "true",
                "l": "true"
              }
            }
          ],
          "selectNumber": false,
          "selectDateTime": false,
          "selectBoolean": false,
          "omitBlank": false,
          "selectBlank": false,
          "omitError": false,
          "selectError": false
        }
      ],
      "mode": "row-based"
    }
  },
  {
    "op": "core/column-reorder",
    "description": "Reorder columns",
    "columnNames": [
      "Keyword",
      "Keyword-bu",
      "Search"
    ]
  }
]

Zrychlená varianta

Jak bylo možné vidět, tak tuto cestu lze provést skutečně na pár kliků díky Extract and Apply, které zajistí, že se vše provede správně.

Jestliže tuto funkcionalitu neznáte a chtěli byste si umět dlouhodobě šetřit práci, tak vám doporučuji navštívit školení Filipa Podstavce, kde tuto funkcionalitu popisuje.

Z praxe

Tato varianta je z mého pohledu naprosto nejspolehlivější, protože funguje jak „Švýcarské hodinky“. A proběhne skutečně během pár vteřin maximálně minut.

Srovnání jednotlivých řešení

Z právě popsaných řešení, bych zvolil jako vítěznou variantu tu, která běží pomocí skriptů. Jelikož obsahuje kontrolní mechanismus, díky kterému je možné vrátit se zpět v procesu a zanalyzovat, jestli se vše provedlo správně případně ji můžete používat pomocí tlačítka „Apply“.

Avšak vám doporučuji otestovat všechny možné řešení a vybrat si z nich to nejlepší. Avšak za mě je favorit skriptová metoda. U nás v Taste Medio ji využíváme již od října a ušetřila nám přes 400 hodin, které jsme mohli vynovat do lepších datasetů a hlavně interpretace. 🙂


Závěr článku

Že jste se pustili do čtení, když ještě mluvím co? K tomuto návodu se pak vrátíte. 🙂

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *