cover

پیاده‌سازی الگوریتم COBWEB در پایتون با مطالعات موردی

۱. مقدمه

ر بخش نخست، مبانی نظری الگوریتم COBWEB، خوشه‌بندی مفهومی، یادگیری افزایشی و معیار Category Utility بررسی شد. در این بخش، همان مباحث به یک فرایند عملی تبدیل می‌شوند. تمام کدهای ارائه‌شده اجرا شده‌اند و خروجی‌های عددی، جدول‌ها و نمودارهای درج‌شده در فایل از اجرای واقعی همین کدها به دست آمده‌اند.

ساختار این بخش با الگوی فایل پیاده‌سازی Spectral Clustering تنظیم شده است: ابتدا محیط اجرا و قالب داده‌ها معرفی می‌شود، سپس کد پیاده‌سازی ارائه می‌گردد و بعد از یک مثال آموزشی، سه مطالعه موردی مستقل بررسی می‌شوند.

نکته روش‌شناختی: پیاده‌سازی حاضر یک نسخه آموزشی از منطق COBWEB برای تشکیل مفاهیم سطح اول است. تصمیم میان افزودن نمونه به مفهوم موجود و ایجاد مفهوم جدید با Category Utility انجام می‌شود. هدف، اجرای شفاف و قابل بازتولید مطالعات موردی است؛ نه بازسازی کامل تمام جزئیات نسخه کلاسیک شامل همه حالت‌های Merge و Split.

2. محیط اجرا و آماده‌سازی داده‌ها

۲.۱. کتابخانه های موردنیاز

کتابخانهکاربرد
NumPyمحاسبات عددی و مدیریت برچسب‌ها
Pandasساخت جدول داده‌ها و نتایج
Matplotlibرسم نمودار اندازه مفاهیم
Scikit-learnمحاسبه ARI و NMI
collections و copyشمارش مقادیر و شبیه‌سازی تصمیم‌ها
from collections import Counter, defaultdict
from copy import deepcopy
import random
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import adjusted_rand_score, normalized_mutual_info_score

۲.۲. قالب داده ورودی

COBWEB کلاسیک برای ویژگی‌های طبقه‌ای مناسب است. هر نمونه در این فایل به صورت یک دیکشنری شامل زوج‌های ویژگی ـ مقدار تعریف می‌شود:

sample = {
    "color": "red",
    "shape": "circle",
    "size": "small"
}

ویژگی‌های عددی، پیش از اجرا، باید به بازه‌های طبقه‌ای تبدیل شوند. برای نمونه، سن می‌تواند به گروه‌های کمتر از ۱۸، ۱۸ تا ۲۹، ۳۰ تا ۴۹ و ۵۰ سال یا بیشتر تبدیل شود.

۳. پیاده‌سازی الگوریتم COBWEB در پایتون

کد زیر نسخه اجرایی استفاده‌شده در تمام مطالعات موردی این فایل است. این کد آمار مقادیر ویژگی‌ها را نگهداری می‌کند، Category Utility را محاسبه می‌کند، داده‌ها را به‌صورت افزایشی می‌پذیرد و برای هر نمونه یک مفهوم سطح اول تعیین می‌کند.

from collections import Counter, defaultdict
from copy import deepcopy
from pathlib import Path
import random
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.metrics import adjusted_rand_score, normalized_mutual_info_score

OUT=Path('/mnt/data/cobweb_assets'); OUT.mkdir(exist_ok=True)

class Concept:
    def __init__(self):
        self.n=0
        self.counts=defaultdict(Counter)
    def add(self,x):
        self.n+=1
        for a,v in x.items(): self.counts[a][v]+=1
    def p(self,a,v):
        return self.counts[a][v]/self.n if self.n else 0.0
    def sqsum(self, all_values):
        s=0.0
        for a,vals in all_values.items():
            for v in vals:
                p=self.p(a,v); s+=p*p
        return s

class EducationalCOBWEB:
    """آموزشی: مفاهیم سطح اول را با معیار Category Utility می‌سازد."""
    def __init__(self):
        self.root=Concept(); self.concepts=[]; self.all_values=defaultdict(set)
    def _refresh_values(self,x):
        for a,v in x.items(): self.all_values[a].add(v)
    def category_utility(self, concepts=None, root=None):
        concepts=self.concepts if concepts is None else concepts
        root=self.root if root is None else root
        k=len(concepts)
        if root.n==0 or k==0: return 0.0
        base=root.sqsum(self.all_values)
        total=0.0
        for c in concepts:
            total += (c.n/root.n)*(c.sqsum(self.all_values)-base)
        return total/k
    def _simulate_add(self, idx, x):
        root=deepcopy(self.root); root.add(x)
        concepts=deepcopy(self.concepts); concepts[idx].add(x)
        return self.category_utility(concepts,root)
    def _simulate_new(self,x):
        root=deepcopy(self.root); root.add(x)
        concepts=deepcopy(self.concepts); c=Concept(); c.add(x); concepts.append(c)
        return self.category_utility(concepts,root)
    def insert(self,x):
        self._refresh_values(x)
        if not self.concepts:
            self.root.add(x); c=Concept(); c.add(x); self.concepts.append(c); return 0
        scores=[self._simulate_add(i,x) for i in range(len(self.concepts))]
        new_score=self._simulate_new(x)
        # deterministic: new concept only if strictly better
        if new_score > max(scores)+1e-12:
            self.root.add(x); c=Concept(); c.add(x); self.concepts.append(c); return len(self.concepts)-1
        idx=int(np.argmax(scores)); self.root.add(x); self.concepts[idx].add(x); return idx
    def fit(self,data):
        for x in data: self.insert(x)
        return self
    def score_sample(self,c,x):
        return sum(c.p(a,v) for a,v in x.items())/max(len(x),1)
    def predict(self,data):
        return np.array([int(np.argmax([self.score_sample(c,x) for c in self.concepts])) for x in data])
    def summaries(self):
        rows=[]
        for i,c in enumerate(self.concepts):
            row={'concept':i,'samples':c.n}
            for a,ctr in c.counts.items():
                v,n=ctr.most_common(1)[0]; row[a]=v; row[a+'_p']=round(n/c.n,3)
            rows.append(row)
        return pd.DataFrame(rows)

۴. مثال آموزشی کوچک

۴.۱. تعریف داده

شش شیء با سه ویژگی رنگ، شکل و اندازه به الگوریتم داده شدند. دو الگوی واضح «قرمز، دایره، کوچک» و «آبی، مربع، بزرگ» وجود دارند و دو نمونه دیگر حالت مرزی دارند.

toy_data = [
    {"color":"red", "shape":"circle", "size":"small"},
    {"color":"red", "shape":"circle", "size":"small"},
    {"color":"blue", "shape":"square", "size":"large"},
    {"color":"blue", "shape":"square", "size":"large"},
    {"color":"red", "shape":"square", "size":"medium"},
    {"color":"blue", "shape":"circle", "size":"medium"}
]
model = EducationalCOBWEB().fit(toy_data)
labels = model.predict(toy_data)
print(labels)
print(model.category_utility())

۴.۲. خروجی واقعی اجرا

Number of concepts: 2
Category Utility: 0.4167
colorshapesizeconcept
redcirclesmall0
redcirclesmall0
bluesquarelarge1
bluesquarelarge1
redsquaremedium0
bluecirclemedium0

خروجی نشان داد که داده‌ها در دو مفهوم اصلی سازمان‌دهی شدند. مقدار Category Utility برابر با ۰٫۴۱۶۷ است. دو نمونه تکراری هر الگوی اصلی در یک گروه قرار گرفتند و نمونه‌های مرزی بر اساس ترکیب ویژگی‌ها به نزدیک‌ترین مفهوم تخصیص یافتند.

.

۵. مطالعه موردی اول: خوشه‌بندی قارچ‌ها با COBWEB

۵.۱. معرفی مسئله

در این مطالعه، قارچ‌ها بر اساس ویژگی‌های ظاهری شامل شکل و رنگ کلاهک، سطح کلاهک، بو، شکل ساقه، زیستگاه و قابلیت کبودی خوشه‌بندی شدند. متغیر «خوراکی یا سمی بودن» در تشکیل مفاهیم وارد نشد و فقط برای ارزیابی خروجی نگهداری شد.

۵.۲. کد اجرا

df = pd.DataFrame(mushroom_records)
X = df.drop(columns=["id", "class"]).to_dict("records")
model = EducationalCOBWEB().fit(X)
labels = model.predict(X)
ari = adjusted_rand_score(pd.Categorical(df["class"]).codes, labels)
nmi = normalized_mutual_info_score(pd.Categorical(df["class"]).codes, labels)

۵.۳. خروجی واقعی اجرا

Number of concepts: 4
Category Utility: 0.7222
Adjusted Rand Index: 0.653
Normalized Mutual Information: 0.733
Purity: 1.000
idcap_shapecap_colorcap_surfaceodorstem_shapehabitatbruisesclassconcept
M01convexbrownsmoothalmondthickforestyesedible0
M02convexwhitesmoothalmondthickgrasslandyesedible1
M03flatbrownsmoothnonethickforestyesedible2
M04bellredscalypungentthinmoistnopoisonous3
M05convexredscalyfoulthinforestnopoisonous3
M06bellwhitescalypungentthinmoistnopoisonous3
M07flatwhitesmoothnonethickgrasslandyesedible1
M08convexbrownscalyfoulthinmoistnopoisonous3
M09flatbrownsmoothalmondthickforestyesedible0
M10bellredscalyfoulthinmoistnopoisonous3
M11convexwhitesmoothnonethickgrasslandyesedible1
M12flatredscalypungentthinforestnopoisonous3

۵.۴. خلاصه مفاهیم

conceptsamplescap_shapecap_shape_pcap_colorcap_color_pcap_surfacecap_surface_podorodor_pstem_shapestem_shape_phabitathabitat_pbruisesbruises_p
02convex0.5brown1.0smooth1.0almond1.0thick1.0forest1.0yes1.0
13convex0.667white1.0smooth1.0none0.667thick1.0grassland1.0yes1.0
21flat1.0brown1.0smooth1.0none1.0thick1.0forest1.0yes1.0
36bell0.5red0.667scaly1.0pungent0.5thin1.0moist0.667no1.0

۵.۵. تحلیل نتایج

الگوریتم چهار مفهوم تشکیل داد. مقدار خلوص برابر ۱٫۰۰ بود؛ یعنی در هر مفهوم، برچسب غالب کاملاً یکدست بود. ARI برابر ۰٫۶۵۳ و NMI برابر ۰٫۷۳۳ نشان می‌دهند که ساختار مفهومی با تقسیم خوراکی/سمی ارتباط قابل توجهی دارد، هرچند چهار مفهوم به جای دو برچسب واقعی تشکیل شده است. این نتیجه طبیعی است، زیرا COBWEB می‌تواند زیرگروه‌های توصیفی بیشتری از برچسب نهایی کشف کند.

ویژگی‌هایی مانند ساقه باریک، سطح فلس‌دار، نبود کبودی و بوهای تند یا نامطبوع در مفاهیم مربوط به نمونه‌های سمی غالب شدند. در مقابل، ساقه ضخیم، سطح صاف و وجود کبودی در مفاهیم مربوط به نمونه‌های خوراکی فراوان‌تر بود. این مطالعه صرفاً آموزشی است و برای تشخیص واقعی خوراکی بودن قارچ قابل استفاده نیست.

.

۶. مطالعه موردی دوم: شناسایی الگوهای یادگیری دانش‌آموزان

۶.۱. معرفی مسئله

در این مطالعه، دانش‌آموزان بر اساس مشارکت، نظم تکالیف، زمان مطالعه، منبع آموزشی، درخواست کمک و حضور خوشه‌بندی شدند. متغیر «سطح عملکرد تحصیلی» در تشکیل مفاهیم وارد نشد و فقط برای ارزیابی خروجی نگهداری شد.

۶.۲. کد اجرا

df = pd.DataFrame(student_records)
X = df.drop(columns=["id", "performance"]).to_dict("records")
model = EducationalCOBWEB().fit(X)
labels = model.predict(X)
ari = adjusted_rand_score(pd.Categorical(df["performance"]).codes, labels)
nmi = normalized_mutual_info_score(pd.Categorical(df["performance"]).codes, labels)

۶.۳. خروجی واقعی اجرا

Number of concepts: 4
Category Utility: 0.6222
Adjusted Rand Index: 0.674
Normalized Mutual Information: 0.778
Purity: 0.933
idparticipationhomeworkstudy_timeresourcehelp_seekingattendanceperformanceconcept
S01highregularhighinteractivemediumregularstrong0
S02highregularhighvideolowregularstrong1
S03mediummostly_regularmediumbookmediumregularaverage2
S04lowirregularlowvideolowpoorneeds_support3
S05lowirregularlowbookhighmediumneeds_support3
S06mediummostly_regularmediuminteractivehighregularaverage2
S07highregularhighbooklowregularstrong1
S08mediummostly_regularmediumvideomediummediumaverage2
S09lowirregularlowinteractivehighpoorneeds_support3
S10highmostly_regularmediuminteractivemediumregularstrong0
S11mediumregularmediumbooklowregularaverage1
S12lowirregularlowvideomediumpoorneeds_support3
S13highregularhighinteractivelowregularstrong1
S14mediummostly_regularmediumvideohighmediumaverage2
S15lowirregularlowbookhighpoorneeds_support3

۶.۴. خلاصه مفاهیم

conceptsamplesparticipationparticipation_phomeworkhomework_pstudy_timestudy_time_presourceresource_phelp_seekinghelp_seeking_pattendanceattendance_p
02high1.0regular0.5high0.5interactive1.0medium1.0regular1.0
14high0.75regular1.0high0.75book0.5low1.0regular1.0
24medium1.0mostly_regular1.0medium1.0video0.5medium0.5regular0.5
35low1.0irregular1.0low1.0video0.4high0.6poor0.8

۶.۵. تحلیل نتایج

چهار مفهوم تشکیل شد. خلوص ۰٫۹۳۳، ARI برابر ۰٫۶۷۴ و NMI برابر ۰٫۷۷۸ نشان می‌دهند که الگوهای رفتاری شناسایی‌شده با سطح عملکرد ارتباط زیادی دارند. یکی از مفاهیم عمدتاً شامل دانش‌آموزان با مشارکت زیاد، تکالیف منظم، مطالعه زیاد و حضور منظم بود. مفهوم دیگری بیشتر دانش‌آموزان با مشارکت کم، تکالیف نامنظم، مطالعه کم و حضور ضعیف را در بر گرفت.

این خروجی برای توصیف الگوهای یادگیری مناسب است، اما نباید به‌تنهایی برای تصمیم‌گیری قطعی درباره دانش‌آموزان استفاده شود. کیفیت نتیجه به کیفیت و بی‌طرفی داده‌های ثبت‌شده وابسته است.

.

۷. مطالعه موردی سوم: گروه‌بندی درخواست‌های پشتیبانی نرم‌افزار

۷.۱. معرفی مسئله

در این مطالعه، درخواست‌های پشتیبانی بر اساس بخش نرم‌افزار، شدت، تکرارپذیری، دستگاه، مرحله وقوع، پیام خطا و نوع کاربر خوشه‌بندی شدند. متغیر «موضوع واقعی درخواست» در تشکیل مفاهیم وارد نشد و فقط برای ارزیابی خروجی نگهداری شد.

۷.۲. کد اجرا

df = pd.DataFrame(support_records)
X = df.drop(columns=["id", "topic"]).to_dict("records")
model = EducationalCOBWEB().fit(X)
labels = model.predict(X)
ari = adjusted_rand_score(pd.Categorical(df["topic"]).codes, labels)
nmi = normalized_mutual_info_score(pd.Categorical(df["topic"]).codes, labels)

۷.۳. خروجی واقعی اجرا

Number of concepts: 5
Category Utility: 0.5164
Adjusted Rand Index: 0.326
Normalized Mutual Information: 0.745
Purity: 0.667
idmoduleseverityreproducibilitydevicestageerror_messageuser_typetopicconcept
T01loginhighalwaysmobileauthenticationyesregularlogin_failure1
T02loginhighalwaysdesktopauthenticationyesregularlogin_failure1
T03loginmediumsometimesmobilerecoverynonewpassword_reset2
T04paymentcriticalalwaysmobileconfirmationyesregularpayment_failure0
T05paymentcriticalalwaysdesktopconfirmationyesbusinesspayment_failure3
T06paymentmediumsometimesmobileprocessingnoregularpayment_delay2
T07reportmediumalwaysdesktopexportyesbusinessreport_export3
T08reportmediumalwaysdesktopexportyesregularreport_export3
T09reportlowsometimesdesktopgenerationnobusinessslow_report4
T10profilelowsometimesmobilesavenonewprofile_update2
T11profilelowone_timetabletsavenoregularprofile_update4
T12loginhighalwaysmobileauthenticationyesbusinessaccount_lock1
T13paymentcriticalalwaystabletconfirmationyesbusinesspayment_failure0
T14reportlowsometimesdesktopgenerationnoregularslow_report4
T15profilelowsometimesmobilesavenoregularprofile_update2

۷.۴. خلاصه مفاهیم

conceptsamplesmodulemodule_pseverityseverity_preproducibilityreproducibility_pdevicedevice_pstagestage_perror_messageerror_message_puser_typeuser_type_p
03payment0.667critical0.667always1.0mobile0.667confirmation0.667yes1.0regular0.667
12login1.0high1.0always1.0desktop0.5authentication1.0yes1.0regular0.5
24profile0.5medium0.5sometimes1.0mobile1.0save0.5no1.0new0.5
33report0.667medium0.667always1.0desktop1.0export0.667yes1.0business0.667
43report0.667low1.0sometimes0.667desktop0.667generation0.667no1.0regular0.667

۷.۵. تحلیل نتایج

پنج مفهوم تشکیل شد. NMI برابر ۰٫۷۴۵ نشان می‌دهد که مفاهیم مقدار زیادی اطلاعات درباره موضوع واقعی درخواست‌ها دارند؛ اما ARI برابر ۰٫۳۲۶ و خلوص ۰٫۶۶۷ بیان می‌کنند که تطابق یک‌به‌یک با موضوع‌ها متوسط است. دلیل اصلی آن است که برخی موضوع‌ها از نظر ویژگی‌های عملیاتی مشابه‌اند؛ برای مثال خطای ورود و قفل حساب هر دو در بخش ورود، مرحله احراز هویت و با شدت زیاد رخ می‌دهند.

مزیت این خروجی، توصیف‌پذیری مفاهیم است. یک مفهوم می‌تواند با ویژگی‌هایی مانند «پرداخت، شدت بحرانی، وقوع در مرحله تأیید و وجود پیام خطا» مشخص شود و برای مسیردهی خودکار درخواست‌ها به تیم مناسب به کار رود.

.

۸. بررسی حساسیت به ترتیب ورود داده‌ها

برای بررسی یکی از محدودیت‌های شناخته‌شده COBWEB، داده‌های مطالعه قارچ‌ها با سه ترتیب تصادفی متفاوت وارد الگوریتم شدند. خروجی واقعی به صورت زیر بود:

Run 1 - Number of concepts: 3
Run 2 - Number of concepts: 4
Run 3 - Number of concepts: 2
ARI between run 1 and run 2: 0.824
ARI between run 1 and run 3: 0.750

تعداد مفاهیم در سه اجرا به‌ترتیب ۳، ۴ و ۲ بود. با وجود شباهت نسبتاً زیاد عضویت نمونه‌ها میان اجراها، ساختار نهایی کاملاً یکسان نشد. این نتیجه به صورت عملی حساسیت الگوریتم به ترتیب ورود نمونه‌ها را نشان می‌دهد.

.

۹. معیارهای ارزیابی

Category Utility معیار داخلی COBWEB است و افزایش پیش‌بینی‌پذیری ویژگی‌ها در اثر دانستن عضویت مفهومی را اندازه‌گیری می‌کند. برای مقایسه با برچسب‌های مرجع از Adjusted Rand Index، Normalized Mutual Information و خلوص استفاده شد.

مطالعهتعداد مفاهیمCUARINMIخلوص
قارچ‌ها40.72220.6530.7331.000
دانش‌آموزان40.62220.6740.7780.933
پشتیبانی50.51640.3260.7450.667

Silhouette Score در این فایل معیار اصلی نیست، زیرا معمولاً بر فاصله میان نمونه‌های عددی تکیه دارد؛ در حالی که COBWEB کلاسیک بر توزیع مقادیر طبقه‌ای و معیار Category Utility استوار است.

.

۱۰. محدودیت‌های پیاده‌سازی

پیاده‌سازی حاضر برای آموزش و بازتولید مطالعات موردی طراحی شده است و مفاهیم سطح اول را با تصمیم Create/Incorporate تشکیل می‌دهد. نسخه کامل کلاسیک COBWEB عملیات Merge و Split و جزئیات بیشتری برای بازآرایی درخت دارد. بنابراین، نتایج این فایل باید به عنوان خروجی یک پیاده‌سازی آموزشی و نه مرجع نرم‌افزاری کامل الگوریتم تفسیر شوند.

ویژگی‌های پیوسته باید گسسته‌سازی شوند. ترتیب ورود داده‌ها می‌تواند ساختار نهایی را تغییر دهد. نمونه‌های نویزی ممکن است مفاهیم کوچک ایجاد کنند و هزینه محاسبات با افزایش تعداد نمونه‌ها و ویژگی‌ها بیشتر می‌شود.

.

۱۱. نتیجه‌گیری

در این بخش، الگوریتم COBWEB به صورت عملی در پایتون اجرا شد. مثال آموزشی نشان داد که داده‌های طبقه‌ای بر اساس افزایش پیش‌بینی‌پذیری ویژگی‌ها به مفاهیم تقسیم می‌شوند. در مطالعه قارچ‌ها، زیرگروه‌های توصیفی با خلوص کامل نسبت به برچسب خوراکی/سمی شکل گرفتند. سپس در مطالعه دانش‌آموزان، الگوهای رفتاری با سطح عملکرد ارتباط زیادی داشتند. در مطالعه درخواست‌های پشتیبانی، مفاهیم عملیاتی قابل تفسیر شکل گرفتند، هرچند تطابق کامل با موضوع‌های دستی مشاهده نشد.

مهم‌ترین مزیت COBWEB در این مطالعات، افزایشی بودن و تفسیرپذیری خروجی است. مهم‌ترین محدودیت مشاهده‌شده نیز حساسیت به ترتیب ورود داده‌ها بود. تمام مقادیر عددی، جدول‌ها و نمودارهای این فایل مستقیماً از اجرای کدهای درج‌شده به دست آمده‌اند.

دکتر محمدرضا عاطفی

عضو هیئت علمی دانشگاه
رئیس هیئت مدیره گروه ناب
هم بنیان گذار شرکت دانش بنیان
مشاور شرکت ها و سازمان های بزرگ کشور

آنچه می خوانید

هوش مصنوعی

پیاده‌سازی الگوریتم COBWEB در پایتون با مطالعات موردی

۱. مقدمه ر بخش نخست، مبانی نظری الگوریتم COBWEB، خوشه‌بندی مفهومی، یادگیری افزایشی و معیار Category Utility بررسی شد. در این بخش، همان مباحث به یک فرایند عملی تبدیل می‌شوند. تمام کدهای ارائه‌شده اجرا شده‌اند و خروجی‌های عددی، جدول‌ها و نمودارهای درج‌شده در فایل از اجرای واقعی همین کدها به

توضیحات بیشتر »
هوش مصنوعی

الگوریتم COBWEB چیست؟ آموزش خوشه‌بندی مفهومی افزایشی

1.اهداف یادگیری انتظار می‌رود خواننده پس از مطالعه این فصل بتواند: 2.پیش‌نیازها . 3. چکیده 3.1. معرفی فشرده الگوریتم COBWEB یکی از روش‌های کلاسیک در حوزه خوشه‌بندی مفهومی (Conceptual Clustering) و یادگیری افزایشی (Incremental Learning) است که نخستین‌بار توسط داگلاس فیشر (Douglas H. Fisher) در سال 1987 معرفی شد. برخلاف

توضیحات بیشتر »
هوش مصنوعی

پیاده‌سازی الگوریتم EM در Python

۱. مقدمه الگوریتم امید ریاضی–بیشینه‌سازی (Expectation–Maximization یا EM) چارچوبی تکرارشونده برای برآورد پارامترهای مدل‌های احتمالی دارای متغیر پنهان است. در مدل آمیخته گوسی، شناسه مؤلفه‌ای که هر نمونه از آن تولید شده مشاهده نمی‌شود؛ بنابراین EM در گام E احتمال تعلق هر نمونه به مؤلفه‌ها را محاسبه می‌کند و در

توضیحات بیشتر »
error: محتوا غیر قابل انتخاب و کپی است.