アキネーターはすべてを見つけることができます。akinator のアルゴリズムは推測できますが、理解できません。akinator はすべてを検索するため、データベースまたは検索エンジンを使用します。データベースを使用する場合、データベースのロジックは何ですか? 創始者はどのようにしてすべての知識を見つけることができますか?
今のところそれで十分です:)
アキネーターはすべてを見つけることができます。akinator のアルゴリズムは推測できますが、理解できません。akinator はすべてを検索するため、データベースまたは検索エンジンを使用します。データベースを使用する場合、データベースのロジックは何ですか? 創始者はどのようにしてすべての知識を見つけることができますか?
今のところそれで十分です:)
私はこの素晴らしいロボットを書いた人の中にいないので、ここで推測をするつもりですが、確かなことは何もありません。
最初は今ほど賢くはなかったと思いますが、覚えておいてください。答えが間違っているたびに、Akinatorの提案を、あなたが考えている実際の人と区別する別の質問をするように求められます。したがって、それは独自の知識ベースに基づいて構築されます。
Akinatorは決定木、あるいはC4.5アルゴリズムを使用して、毎回何をクエリするかを選択していると思います。これは、従来の決定木ではなく、C4.5アルゴリズムに近づく前の回答に基づいて質問をします。Akinatorの本当に素晴らしい点は、1つまたは2つの答えを間違えたケースのいくつかを推測できることです。これは、ロボットの作者によって開発されたアルゴリズムへのアドオンだと思います。
数十万の質問が含まれていて、それらのすべてに5つの可能な回答があるかどうかを計算するだけで、推測できるさまざまな性格がいくつあります。
Akinator の元のアルゴリズムがどのように正確に実装されているかはわかりませんが、データベースを使用して同様のタスクを解決しました。https://github.com/nesterovsky-bros/KBでその実装について読むことができます。
編集:
推奨される解決策は、回答付きの質問のリストを入力として受け取り、次の質問を提供するアルゴリズムです。その質問とそれに対する回答が一連の質問と回答に追加されます。質問がなくなると、これらの質問に対する回答を含む一連の質問によって、エンティティのリストが決定されます。
本質的に、SQL ソリューションは次のように機能します。
テーブル「エンティティ」はオブジェクトを定義します:
create table Data.Entity
(
EntityID int not null primary key, -- Object key.
Name nvarchar(256) -- Object name
);
表 "PredicateType" は、質問の種類を定義します。
create table Data.PredicateType
(
PredicateID int not null primary key, -- question id
Name nvarchar(128) not null unique -- question name.
);
テーブル「述語」には、述語が真であるエンティティが格納されます。
create table Data.Predicate
(
PredicateID int not null,
EntityID int not null,
constraint PK_Predicate primary key clustered(PredicateID, EntityID),
constraint IX_Predicate_Entity unique(EntityID, PredicateID)
);
たとえば、P(i) - 質問、A(i) - 回答、i = 1..5、
A(1) = A(3) = 1、A(2) = A(4) = A(5) = 0 の場合、select は次のようになります。
with P1 as -- P(1), A(1) = 1
(
select EntityID from Data.Predicate where PredicateID = @p1
),
P2 as -- P(2), A(2) = 0
(
select EntityID from Data.Predicate where PredicateID = @p2
),
P3 as -- P(3), A(3) = 1
(
select EntityID from Data.Predicate where PredicateID = @p3
),
P4 as -- P(4), A(4) = 0
(
select EntityID from Data.Predicate where PredicateID = @p4
),
P5 as -- P(5), A(5) = 0
(
select EntityID from Data.Predicate where PredicateID = @p5
),
M as
(
select EntityID from Data.Entity
intersect
select EntityID from P1
intersect
select EntityID from P3
except
select EntityID from P2
except
select EntityID from P4
except
select EntityID from P5
),
P as
(
select
P.PredicateID,
count(*) EntityCount,
(select count(*) from M) TotalCount
from
Data.Predicate P
inner join
M
on
P.EntityID = M.EntityID
where
P.PredicateID not in (@p1, @p2, @p3, @p4, @p5)
group by
P.PredicateID
)
select top(5) PredicateID from P order by abs(TotalCount - EntityCount * 2);
返された結果セットが最適な場所は、次善の述語です。