477 lines
18 KiB
Plaintext
477 lines
18 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {
|
||
"collapsed": true
|
||
},
|
||
"source": [
|
||
"# Bir Hayvan Uzman Sistemi Uygulamak\n",
|
||
"\n",
|
||
"[AI for Beginners Curriculum](http://github.com/microsoft/ai-for-beginners) örneğinden.\n",
|
||
"\n",
|
||
"Bu örnekte, bazı fiziksel özelliklere dayanarak bir hayvanı belirlemek için basit bir bilgi tabanlı sistem uygulayacağız. Sistem, aşağıdaki VE-VEYA ağacı ile temsil edilebilir (bu, tüm ağacın bir parçasıdır, kolayca bazı ek kurallar ekleyebiliriz):\n",
|
||
"\n",
|
||
"\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Geriye dönük çıkarımlı kendi uzman sistem kabuğumuz\n",
|
||
"\n",
|
||
"Üretim kurallarına dayalı bilgi temsil için basit bir dil tanımlamaya çalışalım. Kuralları tanımlamak için anahtar kelimeler olarak Python sınıflarını kullanacağız. Temelde 3 tür sınıf olacaktır:\n",
|
||
"* `Ask`, kullanıcıya sorulması gereken bir soruyu temsil eder. Olası cevaplar kümesini içerir.\n",
|
||
"* `If`, bir kuralı temsil eder ve kuralın içeriğini saklamak için sadece sentaktik şeker gibidir.\n",
|
||
"* `AND`/`OR`, ağacın AND/OR dallarını temsil eden sınıflardır. İçerideki argüman listesini saklarlar. Kodu basitleştirmek için, tüm işlevsellik üst sınıf `Content` içinde tanımlanmıştır.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 1,
|
||
"metadata": {
|
||
"trusted": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"class Ask():\n",
|
||
" def __init__(self,choices=['y','n']):\n",
|
||
" self.choices = choices\n",
|
||
" def ask(self):\n",
|
||
" if max([len(x) for x in self.choices])>1:\n",
|
||
" for i,x in enumerate(self.choices):\n",
|
||
" print(\"{0}. {1}\".format(i,x),flush=True)\n",
|
||
" x = int(input())\n",
|
||
" return self.choices[x]\n",
|
||
" else:\n",
|
||
" print(\"/\".join(self.choices),flush=True)\n",
|
||
" return input()\n",
|
||
"\n",
|
||
"class Content():\n",
|
||
" def __init__(self,x):\n",
|
||
" self.x=x\n",
|
||
" \n",
|
||
"class If(Content):\n",
|
||
" pass\n",
|
||
"\n",
|
||
"class AND(Content):\n",
|
||
" pass\n",
|
||
"\n",
|
||
"class OR(Content):\n",
|
||
" pass"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Sistemimizde, çalışma belleği **özellik-değer çiftleri** olarak **gerçekler** listesini içerir. Bilgi tabanı, eylemleri (çalışma belleğine eklenmesi gereken yeni gerçekler) AND-OR ifadeleriyle ifade edilen koşullara eşleyen büyük bir sözlük olarak tanımlanabilir. Ayrıca, bazı gerçekler `Ask` ile sorulabilir.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"metadata": {
|
||
"trusted": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"rules = {\n",
|
||
" 'default': Ask(['y','n']),\n",
|
||
" 'color' : Ask(['red-brown','black and white','other']),\n",
|
||
" 'pattern' : Ask(['dark stripes','dark spots']),\n",
|
||
" 'mammal': If(OR(['hair','gives milk'])),\n",
|
||
" 'carnivor': If(OR([AND(['sharp teeth','claws','forward-looking eyes']),'eats meat'])),\n",
|
||
" 'ungulate': If(['mammal',OR(['has hooves','chews cud'])]),\n",
|
||
" 'bird': If(OR(['feathers',AND(['flies','lies eggs'])])),\n",
|
||
" 'animal:monkey' : If(['mammal','carnivor','color:red-brown','pattern:dark spots']),\n",
|
||
" 'animal:tiger' : If(['mammal','carnivor','color:red-brown','pattern:dark stripes']),\n",
|
||
" 'animal:giraffe' : If(['ungulate','long neck','long legs','pattern:dark spots']),\n",
|
||
" 'animal:zebra' : If(['ungulate','pattern:dark stripes']),\n",
|
||
" 'animal:ostrich' : If(['bird','long nech','color:black and white','cannot fly']),\n",
|
||
" 'animal:pinguin' : If(['bird','swims','color:black and white','cannot fly']),\n",
|
||
" 'animal:albatross' : If(['bird','flies well'])\n",
|
||
"}"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Geriye doğru çıkarım yapmak için, `Knowledgebase` sınıfını tanımlayacağız. İçerecek:\n",
|
||
"* Çalışan `memory` - nitelikleri değerlere eşleyen bir sözlük\n",
|
||
"* Yukarıda tanımlandığı biçimdeki Bilgi tabanı `rules`\n",
|
||
"\n",
|
||
"İki ana yöntem şunlardır:\n",
|
||
"* Gerekirse çıkarım yaparak bir niteliğin değerini elde etmek için `get`. Örneğin, `get('color')` bir renk yuvasının değerini alır (gerekirse sorar ve bu değeri daha sonra kullanım için çalışan belleğe kaydeder). `get('color:blue')` derseniz, renk sorar ve ardından renge bağlı olarak `y`/`n` değerini döndürür.\n",
|
||
"* `eval` gerçek çıkarımı gerçekleştirir, yani VE/VEYA ağacında gezinir, alt hedefleri değerlendirir vb.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"metadata": {
|
||
"trusted": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"class KnowledgeBase():\n",
|
||
" def __init__(self,rules):\n",
|
||
" self.rules = rules\n",
|
||
" self.memory = {}\n",
|
||
" \n",
|
||
" def get(self,name):\n",
|
||
" if ':' in name:\n",
|
||
" k,v = name.split(':')\n",
|
||
" vv = self.get(k)\n",
|
||
" return 'y' if v==vv else 'n'\n",
|
||
" if name in self.memory.keys():\n",
|
||
" return self.memory[name]\n",
|
||
" for fld in self.rules.keys():\n",
|
||
" if fld==name or fld.startswith(name+\":\"):\n",
|
||
" # print(\" + proving {}\".format(fld))\n",
|
||
" value = 'y' if fld==name else fld.split(':')[1]\n",
|
||
" res = self.eval(self.rules[fld],field=name)\n",
|
||
" if res!='y' and res!='n' and value=='y':\n",
|
||
" self.memory[name] = res\n",
|
||
" return res\n",
|
||
" if res=='y':\n",
|
||
" self.memory[name] = value\n",
|
||
" return value\n",
|
||
" # field is not found, using default\n",
|
||
" res = self.eval(self.rules['default'],field=name)\n",
|
||
" self.memory[name]=res\n",
|
||
" return res\n",
|
||
" \n",
|
||
" def eval(self,expr,field=None):\n",
|
||
" # print(\" + eval {}\".format(expr))\n",
|
||
" if isinstance(expr,Ask):\n",
|
||
" print(field)\n",
|
||
" return expr.ask()\n",
|
||
" elif isinstance(expr,If):\n",
|
||
" return self.eval(expr.x)\n",
|
||
" elif isinstance(expr,AND) or isinstance(expr,list):\n",
|
||
" expr = expr.x if isinstance(expr,AND) else expr\n",
|
||
" for x in expr:\n",
|
||
" if self.eval(x)=='n':\n",
|
||
" return 'n'\n",
|
||
" return 'y'\n",
|
||
" elif isinstance(expr,OR):\n",
|
||
" for x in expr.x:\n",
|
||
" if self.eval(x)=='y':\n",
|
||
" return 'y'\n",
|
||
" return 'n'\n",
|
||
" elif isinstance(expr,str):\n",
|
||
" return self.get(expr)\n",
|
||
" else:\n",
|
||
" print(\"Unknown expr: {}\".format(expr))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Şimdi hayvan bilgi tabanımızı tanımlayalım ve danışmanlığı gerçekleştirelim. Unutmayın, bu çağrı size sorular soracak. Evet-hayır sorularına `y`/`n` yazarak, daha uzun çoktan seçmeli sorulara ise 0..N arasında bir sayı belirterek cevap verebilirsiniz.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"metadata": {
|
||
"trusted": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"hair\n",
|
||
"y/n\n",
|
||
"sharp teeth\n",
|
||
"y/n\n",
|
||
"claws\n",
|
||
"y/n\n",
|
||
"forward-looking eyes\n",
|
||
"y/n\n",
|
||
"color\n",
|
||
"0. red-brown\n",
|
||
"1. black and white\n",
|
||
"2. other\n",
|
||
"has hooves\n",
|
||
"y/n\n",
|
||
"long neck\n",
|
||
"y/n\n",
|
||
"long legs\n",
|
||
"y/n\n",
|
||
"pattern\n",
|
||
"0. dark stripes\n",
|
||
"1. dark spots\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"'giraffe'"
|
||
]
|
||
},
|
||
"execution_count": 4,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"kb = KnowledgeBase(rules)\n",
|
||
"kb.get('animal')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"## İleri Çıkarım için Experta Kullanımı\n",
|
||
"\n",
|
||
"Bir sonraki örnekte, bilgi temsili için kullanılan kütüphanelerden biri olan [Experta](https://github.com/nilp0inter/experta) kullanarak ileri çıkarımı uygulamaya çalışacağız. **Experta**, Python'da ileri çıkarım sistemleri oluşturmak için geliştirilmiş bir kütüphanedir ve klasik eski sistem [CLIPS](http://www.clipsrules.net/index.html) ile benzer olacak şekilde tasarlanmıştır.\n",
|
||
"\n",
|
||
"İleri zincirlemeyi kendimiz de çok sorun yaşamadan uygulayabilirdik, ancak sezgisel (naif) uygulamalar genellikle çok verimli olmaz. Daha etkili kural eşleştirme için özel bir algoritma [Rete](https://en.wikipedia.org/wiki/Rete_algorithm) kullanılır.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 5,
|
||
"metadata": {
|
||
"trusted": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Collecting git+https://github.com/nilp0inter/experta\n",
|
||
" Cloning https://github.com/nilp0inter/experta to /tmp/pip-req-build-7qurtwk3\n",
|
||
" Running command git clone --filter=blob:none --quiet https://github.com/nilp0inter/experta /tmp/pip-req-build-7qurtwk3\n",
|
||
" Resolved https://github.com/nilp0inter/experta to commit c6d5834b123861f5ae09e7d07027dc98bec58741\n",
|
||
" Installing build dependencies ... \u001b[?25ldone\n",
|
||
"\u001b[?25h Getting requirements to build wheel ... \u001b[?25ldone\n",
|
||
"\u001b[?25h Preparing metadata (pyproject.toml) ... \u001b[?25ldone\n",
|
||
"\u001b[?25hRequirement already satisfied: frozendict~=2.4.6 in /opt/conda/envs/ai4beg/lib/python3.12/site-packages (from experta==1.9.5.dev1) (2.4.7)\n",
|
||
"Collecting schema~=0.6.7 (from experta==1.9.5.dev1)\n",
|
||
" Downloading schema-0.6.8-py2.py3-none-any.whl.metadata (14 kB)\n",
|
||
"Downloading schema-0.6.8-py2.py3-none-any.whl (14 kB)\n",
|
||
"Building wheels for collected packages: experta\n",
|
||
" Building wheel for experta (pyproject.toml) ... \u001b[?25ldone\n",
|
||
"\u001b[?25h Created wheel for experta: filename=experta-1.9.5.dev1-py3-none-any.whl size=34804 sha256=888c459512a5e713f4b674caa9a0f96cfdf07ec0d6eb56cc318ce0653d218014\n",
|
||
" Stored in directory: /tmp/pip-ephem-wheel-cache-1eeii9zy/wheels/3d/e8/bb/22d7956359603fa8dd679aa09f5b8efb3f29991c3986fdc787\n",
|
||
"Successfully built experta\n",
|
||
"Installing collected packages: schema, experta\n",
|
||
"\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2/2\u001b[0m [experta]\n",
|
||
"\u001b[1A\u001b[2KSuccessfully installed experta-1.9.5.dev1 schema-0.6.8\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"import sys\n",
|
||
"!{sys.executable} -m pip install git+https://github.com/nilp0inter/experta"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 13,
|
||
"metadata": {
|
||
"trusted": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"from experta import *\n",
|
||
"#import experta"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Sistemimizi `KnowledgeEngine` sınıfından türeyen bir sınıf olarak tanımlayacağız. Her kural, ne zaman tetikleneceğini belirten `@Rule` anotasyonuyla ayrı bir fonksiyon olarak tanımlanır. Kuralın içinde, `declare` fonksiyonunu kullanarak yeni gerçekler ekleyebiliriz ve bu gerçeklerin eklenmesi, ileri çıkarım motoru tarafından bazı ek kuralların çağrılmasına yol açar.\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 14,
|
||
"metadata": {
|
||
"trusted": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"class Animals(KnowledgeEngine):\n",
|
||
" @Rule(OR(\n",
|
||
" AND(Fact('sharp teeth'),Fact('claws'),Fact('forward looking eyes')),\n",
|
||
" Fact('eats meat')))\n",
|
||
" def cornivor(self):\n",
|
||
" self.declare(Fact('carnivor'))\n",
|
||
" \n",
|
||
" @Rule(OR(Fact('hair'),Fact('gives milk')))\n",
|
||
" def mammal(self):\n",
|
||
" self.declare(Fact('mammal'))\n",
|
||
"\n",
|
||
" @Rule(Fact('mammal'),\n",
|
||
" OR(Fact('has hooves'),Fact('chews cud')))\n",
|
||
" def hooves(self):\n",
|
||
" self.declare('ungulate')\n",
|
||
" \n",
|
||
" @Rule(OR(Fact('feathers'),AND(Fact('flies'),Fact('lays eggs'))))\n",
|
||
" def bird(self):\n",
|
||
" self.declare('bird')\n",
|
||
" \n",
|
||
" @Rule(Fact('mammal'),Fact('carnivor'),\n",
|
||
" Fact(color='red-brown'),\n",
|
||
" Fact(pattern='dark spots'))\n",
|
||
" def monkey(self):\n",
|
||
" self.declare(Fact(animal='monkey'))\n",
|
||
"\n",
|
||
" @Rule(Fact('mammal'),Fact('carnivor'),\n",
|
||
" Fact(color='red-brown'),\n",
|
||
" Fact(pattern='dark stripes'))\n",
|
||
" def tiger(self):\n",
|
||
" self.declare(Fact(animal='tiger'))\n",
|
||
"\n",
|
||
" @Rule(Fact('ungulate'),\n",
|
||
" Fact('long neck'),\n",
|
||
" Fact('long legs'),\n",
|
||
" Fact(pattern='dark spots'))\n",
|
||
" def giraffe(self):\n",
|
||
" self.declare(Fact(animal='giraffe'))\n",
|
||
"\n",
|
||
" @Rule(Fact('ungulate'),\n",
|
||
" Fact(pattern='dark stripes'))\n",
|
||
" def zebra(self):\n",
|
||
" self.declare(Fact(animal='zebra'))\n",
|
||
"\n",
|
||
" @Rule(Fact('bird'),\n",
|
||
" Fact('long neck'),\n",
|
||
" Fact('cannot fly'),\n",
|
||
" Fact(color='black and white'))\n",
|
||
" def straus(self):\n",
|
||
" self.declare(Fact(animal='ostrich'))\n",
|
||
"\n",
|
||
" @Rule(Fact('bird'),\n",
|
||
" Fact('swims'),\n",
|
||
" Fact('cannot fly'),\n",
|
||
" Fact(color='black and white'))\n",
|
||
" def pinguin(self):\n",
|
||
" self.declare(Fact(animal='pinguin'))\n",
|
||
"\n",
|
||
" @Rule(Fact('bird'),\n",
|
||
" Fact('flies well'))\n",
|
||
" def albatros(self):\n",
|
||
" self.declare(Fact(animal='albatross'))\n",
|
||
" \n",
|
||
" @Rule(Fact(animal=MATCH.a))\n",
|
||
" def print_result(self,a):\n",
|
||
" print('Animal is {}'.format(a))\n",
|
||
" \n",
|
||
" def factz(self,l):\n",
|
||
" for x in l:\n",
|
||
" self.declare(x)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Bir bilgi tabanı tanımladıktan sonra, çalışma belleğimizi bazı başlangıç gerçekleriyle doldururuz ve sonra çıkarım yapmak için `run()` metodunu çağırırız. Sonuç olarak, çalışma belleğine yeni çıkarılan gerçeklerin eklendiğini görebilirsiniz; bunlar hayvanla ilgili nihai gerçeği de içerir (eğer tüm başlangıç gerçeklerini doğru şekilde ayarladıysak).\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 15,
|
||
"metadata": {
|
||
"trusted": true
|
||
},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"Animal is tiger\n"
|
||
]
|
||
},
|
||
{
|
||
"data": {
|
||
"text/plain": [
|
||
"FactList([(0, InitialFact()),\n",
|
||
" (1, Fact(color='red-brown')),\n",
|
||
" (2, Fact(pattern='dark stripes')),\n",
|
||
" (3, Fact('sharp teeth')),\n",
|
||
" (4, Fact('claws')),\n",
|
||
" (5, Fact('forward looking eyes')),\n",
|
||
" (6, Fact('gives milk')),\n",
|
||
" (7, Fact('mammal')),\n",
|
||
" (8, Fact('carnivor')),\n",
|
||
" (9, Fact(animal='tiger'))])"
|
||
]
|
||
},
|
||
"execution_count": 15,
|
||
"metadata": {},
|
||
"output_type": "execute_result"
|
||
}
|
||
],
|
||
"source": [
|
||
"ex1 = Animals()\n",
|
||
"ex1.reset()\n",
|
||
"ex1.factz([\n",
|
||
" Fact(color='red-brown'),\n",
|
||
" Fact(pattern='dark stripes'),\n",
|
||
" Fact('sharp teeth'),\n",
|
||
" Fact('claws'),\n",
|
||
" Fact('forward looking eyes'),\n",
|
||
" Fact('gives milk')])\n",
|
||
"ex1.run()\n",
|
||
"ex1.facts"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": []
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"---\n\n<!-- CO-OP TRANSLATOR DISCLAIMER START -->\n**Feragatname**: \nBu belge, yapay zeka çeviri servisi [Co-op Translator](https://github.com/Azure/co-op-translator) kullanılarak çevrilmiştir. Doğruluk için özen gösterilse de, otomatik çevirilerin hatalar veya yanlışlıklar içerebileceğini lütfen unutmayın. Orijinal belge, kendi dilinde yetkili kaynak olarak kabul edilmelidir. Kritik bilgiler için profesyonel insan çevirisi önerilir. Bu çevirinin kullanımı sonucu oluşabilecek yanlış anlamalar veya yorum hatalarından sorumlu değiliz.\n<!-- CO-OP TRANSLATOR DISCLAIMER END -->\n"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3.7.4 64-bit (conda)",
|
||
"metadata": {
|
||
"interpreter": {
|
||
"hash": "86193a1ab0ba47eac1c69c1756090baa3b420b3eea7d4aafab8b85f8b312f0c5"
|
||
}
|
||
},
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.11.2"
|
||
},
|
||
"coopTranslator": {
|
||
"original_hash": "8ef43db4b9182239fd150a76bd494fdb",
|
||
"translation_date": "2026-01-15T14:05:13+00:00",
|
||
"source_file": "lessons/2-Symbolic/Animals.ipynb",
|
||
"language_code": "tr"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 2
|
||
} |