Что такое значения, начинающиеся с t, и как их игнорировать при подсчете

Я пытаюсь запросить частоту определенных атрибутов в Викиданных, используя SPARQL.

Например, чтобы узнать, какова частота различных значений пола, у меня есть следующий запрос:

SELECT ?rid (COUNT(?rid) AS ?count)
WHERE { ?qid wdt:P21 ?rid.
  BIND(wd:Q5 AS ?human)
  ?qid wdt:P31 ?human.
} GROUP BY ?rid

Я получаю следующий результат:

wd:Q6581097 2752163
wd:Q6581072 562339
wd:Q1052281 223
wd:Q1097630 68
wd:Q2449503 67
wd:Q48270   36
wd:Q44148   8
wd:Q43445   4
t152990852  1
t152990762  1
t152990752  1
t152990635  1
t152775383  1
t152775370  1
t152775368  1
...

У меня есть следующие вопросы по этому поводу:

  • К чему относятся эти значения t152...?
  • Как я могу игнорировать кортежи, содержащие t152...?
    Я попробовал FILTER ( !strstarts(str(?rid), "wd:") ), но время ожидания истекло.
  • Как мне подсчитать различное количество ответов?
    Я попробовал SELECT (COUNT(DISTINCT ?rid) AS ?count) с приведенным выше запросом, но снова истекло время ожидания.

person benroth    schedule 05.06.2017    source источник
comment
Почему вы считаете ?rid? Разве вы не должны посчитать количество людей, то есть ?qid? В противном случае использование DISTINCT всегда будет возвращать 1 в качестве значения.   -  person UninformedUser    schedule 05.06.2017
comment
ну, я хочу подсчитать количество возможных значений для пола (женщина, мужчина, трансгендер и т. д.), поэтому я считаю идентификаторы результатов (рид), а не людей   -  person benroth    schedule 05.06.2017
comment
Но rid — это гендерный тип, верно? Что вы хотите, так это количество людей, которые имеют каждый пол, или нет? Тройка, например. :human1 :gender :male . Конечно, без DISTINCT это работает, но на самом деле вам нужно число qid Если вы используете DISTINCT для rid, по которому вы группируете, то счетчик всегда будет равен 1.   -  person UninformedUser    schedule 05.06.2017
comment
Нет, мне нужно количество возможных вариантов «пола» в приведенном выше случае. Например. |{мужчина, женщина, трансгендер}| = 3, независимо от того, сколько человек относится к этим категориям.   -  person benroth    schedule 05.06.2017
comment
т.е. в примере, приведенном в сообщении, желаемое количество будет равно 8 (игнорируя значения, начинающиеся с t152...).   -  person benroth    schedule 05.06.2017
comment
Ok. Я все еще не понимаю. Что такое qid тогда? Просто как подсказка, вы группируете по переменной qid - если вы считаете РАЗЛИЧНЫЕ значения qid, то это всегда будет 1. Кстати, у меня это работает без таймаута: SELECT ?rid (COUNT(DISTINCT ?rid) AS ?count) WHERE { VALUES ?human {wd:Q5} ?qid wdt:P31 ?human. ?qid wdt:P21 ?rid. } GROUP BY ?rid   -  person UninformedUser    schedule 05.06.2017
comment
qid (сокращение от идентификатора запроса) соответствует идентификатору конкретного человека, а human соответствует понятию/типу Q5 (человек) в Викиданных.   -  person benroth    schedule 05.06.2017
comment
Вы можете игнорировать вторую и третью строку тела WHERE. (Это просто гарантирует, что учитывается только пол людей, а не вымышленных животных, инопланетян и других второстепенных вещей в викиданных).   -  person benroth    schedule 05.06.2017
comment
Просто для уточнения: вы просто хотите иметь количество различных гендерных значений? Или частота каждого гендерного значения?   -  person UninformedUser    schedule 05.06.2017
comment
Эти странные значения t можно отфильтровать, добавив FILTER(isURI(?rid))   -  person UninformedUser    schedule 05.06.2017
comment
в идеале я хотел бы знать, как сделать оба   -  person benroth    schedule 05.06.2017
comment
У вас уже есть решения: SELECT (COUNT(DISTINCT ?rid) AS ?count) это возвращает 17 для меня   -  person UninformedUser    schedule 05.06.2017
comment
А другой запрос возвращает частоту для каждого пола   -  person UninformedUser    schedule 05.06.2017
comment
Спасибо, это очень помогло! FILTER(isURI(?rid)) работает намного быстрее, чем моя версия. Почему-то SELECT (COUNT(distinct ?rid) AS ?count) все еще не дает ожидаемого результата для меня (1 1 1 ... вместо количества разных значений)   -  person benroth    schedule 06.06.2017
comment
Тогда вам нужно удалить GROUP BY.   -  person UninformedUser    schedule 06.06.2017
comment
Кстати, это то, что я имел в виду, используя DISTINCT для rid, что приведет к 1 значению для каждого пола. В этом случае это должно быть qid.   -  person UninformedUser    schedule 06.06.2017
comment
@benroth, возможно, вас заинтересует whgi.wmflabs.org/gender-by- язык.html   -  person Stanislav Kralin    schedule 07.06.2017


Ответы (1)


Значения, начинающиеся с t, "сколемизированы" неизвестные значения (см., например, Q2423351 для лица неизвестного пола).

Чтобы повысить производительность, я предлагаю вам разделить ваш запрос на три части:

  1. Все "нормальные" полы:

    SELECT ?rid (COUNT(?qid) AS ?count) 
    WHERE {
       ?qid wdt:P31 wd:Q5.
       ?qid wdt:P21 ?rid.
       ?rid wdt:P31 wd:Q48264 
    } GROUP BY ?rid ORDER BY DESC(?count)
    

    Обратите внимание, что, согласно Викиданным, wd:Q746411 является подкласс wd:Q48270 и т. д.

  2. Все "ненормальные" полы:

    SELECT ?rid (COUNT(?qid) AS ?count) 
    WHERE {
       ?qid wdt:P31 wd:Q5.
       ?qid wdt:P21 ?rid.
       FILTER (?rid NOT IN
               (
                wd:Q6581097,
                wd:Q6581072,
                wd:Q1052281,
                wd:Q2449503,
                wd:Q48270,
                wd:Q746411,
                wd:Q189125,
                wd:Q1399232,
                wd:Q3277905
               )
              ).
       FILTER (isURI(?rid))
    } GROUP BY ?rid ORDER BY DESC(?count)
    

    Я не использую FILTER NOT EXISTS {?rid wdt:P31 wd:Q48264 } из соображений производительности.

  3. Все (т.е. 1) «неизвестные» гендеры:

    SELECT (COUNT(?qid) AS ?count) 
    WHERE {
       ?qid wdt:P31 wd:Q5.
       ?qid wdt:P21 ?rid.
       FILTER (!isURI(?rid))
    } 
    

На самом деле в вашем случае это не очень важно — считать отдельные wd:Q5 или считать они не различимы — но последнее предпочтительнее из соображений производительности.

person Stanislav Kralin    schedule 06.06.2017