🧠 پروتکل تحقیقاتی: آزمون تکرارپذیری تصمیم‌گیری در شرایط احتمالی یکسان

Research Protocol: Repeatability Test of Decision-Making Under Identical Probabilistic Conditions


📋 فهرست مطالب

  1. چکیده تحقیق
  2. مقدمه و پیشینه نظری
  3. سوال و فرضیه‌های پژوهشی
  4. روش‌شناسی
  5. طراحی آزمایش
  6. پروتکل اجرایی
  7. متغیرها و ابزارهای اندازه‌گیری
  8. تحلیل آماری
  9. کنترل متغیرهای مخدوش‌کننده
  10. ملاحظات اخلاقی
  11. پیش‌بینی نتایج و تفسیر
  12. محدودیت‌ها و تحقیقات آینده
  13. منابع

1️⃣ چکیده تحقیق

Abstract

زمینه (Background):
یکی از پرسش‌های بنیادین در علوم شناختی و فلسفه ذهن این است که آیا تصمیم‌گیری انسان در شرایط کاملاً یکسان، تکرارپذیر (deterministic) است یا تصادفی (stochastic). این پژوهش به بررسی تجربی این مسئله از طریق یک آزمون رفتاری کنترل‌شده می‌پردازد.

هدف (Objective):
سنجش میزان همسانی (consistency) انتخاب‌های افراد هنگام مواجهه با تحریک‌های بصری یکسان در دو زمان مختلف، در شرایطی که:

  1. حافظه آگاهانه (explicit memory) حذف شده باشد
  2. زمان تصمیم‌گیری محدود باشد
  3. گزینه‌ها از نظر احتمالی یکسان باشند

روش (Method):
75 شرکت‌کننده (18-45 سال) در یک آزمون تصمیم‌گیری سریع (Rapid Decision Task) شرکت می‌کنند. در هر مرحله، 10 دایره طوسی یکسان در موقعیت‌های تصادفی نمایش داده می‌شود و شرکت‌کننده باید در عرض 1.8 ثانیه یکی را انتخاب کند. از میان 70 مرحله اصلی، 15 مرحله به‌صورت پنهان تکرار می‌شوند تا میزان همسانی انتخاب‌ها در تکرارها سنجیده شود.

شاخص‌های اندازه‌گیری:

پیش‌بینی نتایج:
در صورتی که تصمیم‌گیری کاملاً تصادفی باشد، CI10%CI \approx 10\% (احتمال شانس). هرگونه انحراف معنادار از این مقدار نشان‌دهنده وجود الگوی deterministic یا bias شناختی است.

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


2️⃣ مقدمه و پیشینه نظری

2.1 سوال فلسفی-علمی

🧩 مسئله جبر و اختیار در روان‌شناسی تجربی

یکی از قدیمی‌ترین پرسش‌های فلسفه و علوم شناختی این است:

آیا انسان در شرایط کاملاً یکسان، همان تصمیم را می‌گیرد؟

این سوال در سه حوزه اهمیت دارد:

  1. فلسفه ذهن (Philosophy of Mind):
    آیا اراده آزاد (free will) وجود دارد یا تصمیمات ما محصول حتمی فرآیندهای مغزی هستند؟

  2. علوم اعصاب (Neuroscience):
    آیا فعالیت نورون‌ها deterministic است یا noise تصادفی (neural noise) نقش دارد؟

  3. روان‌شناسی شناختی (Cognitive Psychology):
    آیا تصمیم‌گیری تحت تأثیر الگوهای ناخودآگاه و یادگیری ضمنی است؟


2.2 پیشینه تجربی

📚 مطالعات کلاسیک:

الف) آزمایش‌های لیبت (Libet, 1983)

بنجامین لیبت نشان داد که فعالیت مغزی مرتبط با تصمیم‌گیری 300-500 میلی‌ثانیه قبل از آگاهی آگاهانه رخ می‌دهد.

Timeline:
t = -500ms: Readiness Potential (RP) در مغز شروع می‌شود

t = -200ms: فرد آگاهانه قصد حرکت می‌کند

t = 0ms: حرکت انجام می‌شود

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

محدودیت: این آزمایش درباره "زمان آگاهی" است نه "قابلیت تکرار تصمیم".


ب) نظریه دو سیستمی کانمن (Kahneman, 2011)

دانیل کانمن (برنده نوبل) دو سیستم تصمیم‌گیری را تعریف کرد:

سیستم 1 (System 1) سیستم 2 (System 2)
سریع و خودکار آهسته و تحلیلی
ناخودآگاه آگاهانه
کم‌هزینه شناختی پرهزینه شناختی
مستعد سوگیری منطقی‌تر

در آزمایش ما:
با محدود کردن زمان به 1.8 ثانیه، سیستم 1 را فعال می‌کنیم تا تصمیمات شهودی (intuitive) را بسنجیم.


ج) حافظه ضمنی (Implicit Memory) - اسکوایر (Squire, 1992)

تحقیقات روی بیماران آمنزی نشان داده که دو نوع حافظه وجود دارد:

  1. Explicit Memory (حافظه صریح): آگاهانه - "من به یاد می‌آورم که..."
  2. Implicit Memory (حافظه ضمنی): ناخودآگاه - تأثیر بدون آگاهی

مثال کلاسیک:
بیمار H.M. (لوب گیجگاهی آسیب دیده) نمی‌توانست رویدادهای جدید را به خاطر بسپارد، اما مهارت‌های حرکتی جدید یاد می‌گرفت بدون اینکه بداند یاد گرفته!

کاربرد در آزمایش ما:
با ایجاد فاصله زمانی بین تکرارها، حافظه صریح را حذف می‌کنیم اما ممکن است حافظه ضمنی باقی بماند.


2.3 خلأ پژوهشی (Research Gap)

مطالعات قبلی به این سوال پاسخ نداده‌اند:

آیا در شرایطی که:

  • محرک کاملاً یکسان باشد
  • حافظه آگاهانه وجود نداشته باشد
  • زمان تصمیم‌گیری محدود باشد (پیش از تحلیل آگاهانه)

انسان همان گزینه را انتخاب می‌کند؟

این آزمایش برای اولین بار این شرایط را به‌صورت همزمان کنترل می‌کند.


3️⃣ سوال و فرضیه‌های پژوهشی

3.1 سوال اصلی (Primary Research Question)

در غیاب حافظه آگاهانه و با محدودیت زمانی، آیا انسان در مواجهه با تحریک‌های یکسان، تصمیمات یکسانی می‌گیرد؟


3.2 فرضیه‌ها

فرضیه اول (اصلی):

H0:P(انتخاب یکسانتحریک یکسان)=0.10H_0: P(\text{انتخاب یکسان} | \text{تحریک یکسان}) = 0.10

H1:P(انتخاب یکسانتحریک یکسان)>0.10H_1: P(\text{انتخاب یکسان} | \text{تحریک یکسان}) > 0.10

به زبان ساده:

توضیح احتمال 10%:
چون 10 گزینه داریم، احتمال اینکه تصادفاً همان گزینه انتخاب شود: 110=0.10\frac{1}{10} = 0.10


فرضیه دوم (حافظه ضمنی):

RTrepeated<RTuniqueRT_{\text{repeated}} < RT_{\text{unique}}

به زبان ساده:
اگر حافظه ضمنی وجود داشته باشد، زمان واکنش در مراحل تکراری کوتاه‌تر خواهد بود (حتی اگر فرد متوجه تکرار نشود).

استدلال علمی:
Priming Effect (اثر آماده‌سازی) - رویارویی قبلی با یک محرک، پردازش بعدی آن را تسریع می‌کند.


فرضیه سوم (سوگیری مکانی):

Hspatial=i=19pilog2(pi)<HmaxH_{\text{spatial}} = -\sum_{i=1}^{9} p_i \log_2(p_i) < H_{\max}

به زبان ساده:
انسان‌ها دارای سوگیری‌های مکانی هستند (مثلاً ترجیح مرکز صفحه یا راست/چپ).

پیش‌بینی:

مبنای نظری:
Center Bias در eye-tracking و UI/UX به‌خوبی مستند شده است.


فرضیه چهارم (یادگیری):

Hearly>HlateH_{\text{early}} > H_{\text{late}}

به زبان ساده:
در ابتدای آزمایش، انتخاب‌ها پراکنده‌تر هستند. با گذشت زمان، فرد الگوی خاصی پیدا می‌کند (Entropy کاهش می‌یابد).

مبنای نظری:
Procedural Learning (یادگیری رویه‌ای) - حتی در تکالیف ساده، مغز الگو می‌سازد.


🧠 مدل نظری فرآیند تصمیم‌گیری

👁️
محرک بصری
⚙️
سیستم پردازش
📡
پردازش حسی
0-100ms
🎯
تصمیم‌گیری پیش‌آگاهانه
100-300ms
🤚
اجرای حرکتی
300-800ms
💾
ثبت: انتخاب + RT
🧠 حافظه ضمنی → تصمیم‌گیری
🎨 سوگیری‌های شناختی → تصمیم‌گیری
🎲 Noise تصادفی → تصمیم‌گیری

📊 راهنمای رنگ‌بندی:

تصمیم‌گیری (کلیدی)
حافظه ضمنی
سوگیری شناختی
نویز تصادفی
پردازش حسی
اجرای حرکتی

🧮 فرمول ریاضی تصمیم‌گیری

P(choicei) = f( Biasi, Mi, ε )
📍 Biasi

سوگیری مکانی

تمایل به انتخاب مرکز یا گوشه‌ها

🧠 Mi

حافظه ضمنی

تأثیر ناخودآگاه رویارویی قبلی

🎲 ε

نویز تصادفی

عدم قطعیت ذاتی تصمیم

🎯

هدف آزمایش:

جداسازی و اندازه‌گیری نقش هر یک از عوامل فوق در فرآیند تصمیم‌گیری

📄 نمایش فرمول LaTeX (برای استفاده در مقالات)
P(\text{choice}_i) = f( \underbrace{\text{Bias}_i}_{\text{سوگیری مکانی}}, \underbrace{M_i}_{\text{حافظه ضمنی}}, \underbrace{\epsilon}_{\text{نویز تصادفی}} )

4️⃣ روش‌شناسی

4.1 طراحی کلی (Study Design)

نوع مطالعه:

چرا این طرح؟


4.2 جامعه و نمونه آماری

جامعه هدف:

بزرگسالان سالم 18-45 سال با بینایی طبیعی یا اصلاح‌شده

حجم نمونه:

محاسبه با استفاده از G*Power:

Test: Binomial test (one-tailed)
Effect size: h = 0.35 (medium)
α = 0.05
Power (1-β) = 0.80

→ n = 67 participants

با احتساب ریزش 10%:
ntotal=67×1.175 شرکت‌کنندهn_{\text{total}} = 67 \times 1.1 \approx 75 \text{ شرکت‌کننده}

معیارهای ورود (Inclusion Criteria):

معیارهای خروج (Exclusion Criteria):


4.3 ابزار و بستر اجرایی

سخت‌افزار:

نرم‌افزار:

مزایای PWA:


5️⃣ طراحی آزمایش

5.1 ساختار کلی

آزمایش شامل 80 مرحله (Trial) است:

آزمایش کامل (Total: 80 Trials)

1

Practice Trials: 5 مرحله

└─ آشنایی با مکانیک بازی

2

Main Experiment: 70 مرحله

Unique: 50 صحنه منحصر به فرد

Implicit Repeats: 15 صحنه

Explicit Repeats: 5 صحنه

Catch Trials: 5 صحنه

3

Post-Test Questionnaire

⏱️ مدت زمان تقریبی: 4-5 دقیقه


5.2 انواع مراحل (Trial Types)

الف) Practice Trials (مراحل تمرینی)

هدف:
آشنایی شرکت‌کننده با رابط کاربری و مکانیک تکلیف

ویژگی‌ها:

مثال:
Trial 1: [10 دایره نمایش داده می‌شود]
→ کاربر با تأخیر کلیک می‌کند (RT = 2100ms)
→ Feedback: "زمان تمام شد! سریع‌تر باش 😊"

Trial 2: [10 دایره]
→ کاربر سریع کلیک می‌کند (RT = 650ms)
→ Feedback: "عالی! 👍"

چرا مهم است؟
Learning Effect - اگر شرکت‌کننده در 5 trial اول داده اصلی تولید کند، نتایج مخدوش می‌شود.


ب) Unique Trials (مراحل منحصر به فرد)

تعداد: 50 مرحله

ویژگی‌ها:

تولید تصادفی:

def generate_unique_trial():
    """
    تولید یک آرایش تصادفی جدید
    """
    positions = []
    
    # Grid 3×3 با هر سلول 33.33% عرض/ارتفاع
    grid_size = screen_height / 2 / 3  # نیمه بالایی / 3
    
    for i in range(10):
        # موقعیت تصادفی در نیمه بالایی صفحه
        x = random.uniform(20, screen_width - 20)
        y = random.uniform(20, screen_height / 2 - 20)
        
        # اطمینان از عدم همپوشانی
        while is_overlapping(x, y, positions):
            x = random.uniform(20, screen_width - 20)
            y = random.uniform(20, screen_height / 2 - 20)
        
        positions.append({'x': x, 'y': y})
    
    return positions

الگوریتم جلوگیری از همپوشانی:

def is_overlapping(x, y, existing_positions, min_distance=60):
    """
    بررسی فاصله حداقل 60 پیکسل بین دایره‌ها
    """
    for pos in existing_positions:
        distance = sqrt((x - pos['x'])**2 + (y - pos['y'])**2)
        if distance < min_distance:
            return True
    return False

ج) Implicit Repeats (تکرارهای پنهان)

تعداد: 15 مرحله (15 صحنه که هرکدام یک‌بار دیگر تکرار می‌شوند)

هدف اصلی:
سنجش consistency بدون آگاهی شرکت‌کننده

مکانیزم:
Trial 12: [صحنه A] → انتخاب: دایره #3 در گرید 7

[35 trial فاصله]

Trial 47: [صحنه A] → انتخاب: ؟؟؟

سوال: آیا دوباره دایره #3 در گرید 7 را انتخاب می‌کند؟

فواصل زمانی (Lag Distribution):

نوع فاصله تعداد Trial Gap زمان واقعی
کوتاه (Short) 5 5-10 trials 15-30 ثانیه
متوسط (Medium) 5 15-25 trials 45-75 ثانیه
بلند (Long) 5 35-50 trials 105-150 ثانیه

چرا فواصل مختلف؟
برای سنجش decay (زوال) حافظه ضمنی:

M(t)=M0eλtM(t) = M_0 \cdot e^{-\lambda t}

پیش‌بینی:
اگر حافظه ضمنی نقش دارد:
CIshort>CImedium>CIlongCI_{\text{short}} > CI_{\text{medium}} > CI_{\text{long}}


د) Explicit Repeats (تکرارهای آشکار)

تعداد: 5 مرحله

مکانیزم:
Trial N: [صحنه B] → انتخاب: دایره #7
Trial N+1: [صحنه B] → انتخاب: ؟؟؟

بلافاصله بعد!

هدف:
سنجش تمایل به Variety Seeking (تنوع‌طلبی)

فرضیه رفتاری:
انسان‌ها وقتی می‌دانند صحنه تکراری است، تمایل دارند گزینه متفاوتی انتخاب کنند.

مبنای نظری:

پیش‌بینی:
P(همان انتخاب | آگاهی از تکرار)<P(همان انتخاب | عدم آگاهی)P(\text{همان انتخاب | آگاهی از تکرار}) < P(\text{همان انتخاب | عدم آگاهی})

مثال واقعی:
شرکت‌کننده در Trial 23: دایره سمت راست-بالا را کلیک کرد
Trial 24 (همان صحنه): احتمالاً دایره دیگری را انتخاب می‌کند
چون "احساس تکرار" دارد


ه) Catch Trials (مراحل کنترل کیفیت)

تعداد: 5 مرحله

مکانیزم:
[فقط 1 دایره در مرکز صفحه]


اگر شرکت‌کننده آن را انتخاب نکند → غیرجدی است!

معیار حذف:
Accuracycatch=تعداد صحیح5<0.60    حذف داده\text{Accuracy}_{\text{catch}} = \frac{\text{تعداد صحیح}}{5} < 0.60 \implies \text{حذف داده}

چرا لازم است؟

جایگذاری:
به‌صورت تصادفی در trials 15, 30, 45, 60, 73


5.3 ساختار زمانی هر Trial

یک Trial کامل (3 ثانیه)

[Fixation]
1000ms

رنگ پاستلی یکنواخت

(بدون هیچ المان بصری)

[Stimulus]
1800ms یا تا کلیک

← 10 دایره

کاربر کلیک می‌کند (RT ثبت می‌شود)

[Blank]
200ms

صفحه سفید خالی


جزئیات Fixation Screen

مشکل طراحی:

چگونه حافظه بینایی را پاک کنیم بدون ایجاد سوگیری مکانی؟

راه‌حل‌های رد شده:

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

راه‌حل نهایی: Dynamic Color Field

/* 15 رنگ پاستلی */
const colors = [
  '#E8F4F8', // آبی روشن
  '#FCE8EC', // صورتی روشن
  '#FFF4E6', // نارنجی روشن
  '#F0FFF4', // سبز روشن
  '#EDE9FE', // بنفش روشن
  '#FEF3C7', // زرد روشن
  '#DBEAFE', // آبی آسمانی
  '#FED7AA', // نارنجی کرم
  '#E0E7FF', // یاسی روشن
  '#BFDBFE', // آبی ملایم
  '#FEE2E2', // قرمز روشن
  '#D1FAE5', // سبز یشمی
  '#F3E8FF', // بنفش پاستلی
  '#FDE68A', // زرد طلایی
  '#BAE6FD'  // فیروزه‌ای
]

الگوریتم انتخاب:

previous_color = None

def get_fixation_color():
    global previous_color
    
    # انتخاب تصادفی (بدون تکرار متوالی)
    available = [c for c in colors if c != previous_color]
    selected = random.choice(available)
    previous_color = selected
    
    return selected

مزایای علمی:

  1. عدم تمرکز نقطه‌ای: چشم به هیچ نقطه خاصی متمرکز نمی‌شود
  2. پاک‌سازی حافظه بینایی: رنگ یکنواخت، اطلاعات فضایی قبلی را overwrite می‌کند
  3. Neutral: هیچ معنای شناختی ندارد
  4. تنوع: جلوگیری از adaptation (عادت کردن)

مطالعات حمایت‌کننده:


جزئیات Stimulus Screen

مشخصات بصری:

/* دایره‌ها */
.circle {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background-color: #6B7280; /* طوسی تیره */
  cursor: pointer;
  transition: transform 100ms;
}

.circle:hover {
  transform: scale(1.1); /* بازخورد بصری */
}

.circle:active {
  transform: scale(0.95);
}

چرا همه یکسان؟
برای حذف سوگیری‌های بصری:

تصمیم طراحی: یکنواختی کامل
همه دایره → همه طوسی → همه هم‌اندازه


5.4 نگاشت فضایی (Spatial Mapping)

Grid 3×3 برای تحلیل:

صفحه واقعی (px)

0,0 390,0 0,422 390,422
← فقط نیمه بالایی

Grid تحلیلی

1 2 3
4 5 6
7 8 9

مرکز صفحه (Grid 5)

تابع تبدیل:

def pixel_to_grid(x, y, screen_width=390, screen_height=844):
    """
    تبدیل مختصات پیکسلی به شماره گرید (1-9)
    
    فقط نیمه بالایی صفحه (y < 422) معتبر است
    """
    if y >= screen_height / 2:
        raise ValueError("انتخاب در نیمه پایینی!")
    
    # محاسبه ستون (1, 2, 3)
    col = int(x / (screen_width / 3)) + 1
    
    # محاسبه ردیف (0, 1, 2)
    row = int(y / (screen_height / 2 / 3))
    
    # شماره گرید
    grid_number = row * 3 + col
    
    return grid_number

# مثال
pixel_to_grid(150, 100)1  # گوشه بالا-چپ
pixel_to_grid(195, 211)5  # مرکز
pixel_to_grid(350, 400)9  # گوشه پایین-راست (نیمه بالایی)

6️⃣ پروتکل اجرایی

6.1 فرآیند گام‌به‌گام

فرآیند اجرای آزمایش

1 ورود کاربر به سایت
2 صفحه اطلاعات و رضایت‌نامه
? موافقت با شرکت؟
❌ خیر → خروج ✓ بله → ادامه
3 فرم اطلاعات دموگرافیک
4 راهنمای تصویری
5 5 Trial تمرینی
شروع آزمایش اصلی 70 Trial
6 پرسشنامه پایانی
صفحه تشکر و دریافت کد

متن نمونه:

آزمایش تصمیم‌گیری سریع

هدف: بررسی الگوهای انتخاب در شرایط محدودیت زمانی

مدت زمان: حدود 5 دقیقه

روش: شما 10 دایره خواهید دید و باید سریعاً یکی را انتخاب کنید.

محرمانگی: تمام داده‌ها ناشناس ذخیره می‌شوند.

حق انصراف: در هر زمان می‌توانید از آزمایش خارج شوید.

سوالات؟ ایمیل: researcher@example.com

☐ متوجه شدم و موافقم


6.3 فرم دموگرافیک

interface Demographics {
  age: number;              // سن (18-45)
  gender: 'male' | 'female' | 'other' | 'prefer_not_to_say';
  handedness: 'right' | 'left' | 'both';
  vision: 'normal' | 'corrected' | 'impaired';
  education: 'high_school' | 'bachelor' | 'master' | 'phd';
  device: 'android' | 'ios';
  screen_size: number;      // اینچ
}

چرا این اطلاعات؟


6.4 راهنمای تصویری

صفحه 1:

🎯

چگونه بازی کنیم؟

1. تعدادی دایره خواهید دید

2. سریع یکی را انتخاب کنید

3. زمان محدود است! (1.8 ثانیه)

⚠️

نکات مهم:

اولین انتخاب ذهنی‌تان را بزنید

زیاد فکر نکنید!

در صورت نرسیدن به موقع، مرحله تکرار می‌شود


6.5 نحوه ثبت داده‌ها

ساختار JSON هر Trial:

{
  "trial_id": "550e8400-e29b-41d4-a716-446655440000",
  "user_id": "anonymous_abc123",
  "trial_number": 15,
  "trial_type": "implicit_repeat",
  "timestamp": "2025-10-08T14:23:45.678Z",
  
  "stimulus": {
    "circles": [
      {"x": 45.2, "y": 67.8, "id": 0},
      {"x": 123.5, "y": 189.3, "id": 1},
      // ... 10 دایره
    ],
    "scene_id": "scene_042",
    "is_repeat": true,
    "original_trial": 8,
    "lag": 7
  },
  
  "response": {
    "selected_circle_id": 3,
    "grid_position": 5,
    "rt_ms": 847,
    "mouse_path": [[0,100], [50,150], ...], // اختیاری
    "timeout": false
  },
  
  "context": {
    "fixation_color": "#E8F4F8",
    "block_number": 2,
    "time_of_day": "afternoon"
  }
}

7️⃣ متغیرها و ابزارهای اندازه‌گیری

7.1 متغیرهای مستقل (Independent Variables)

الف) نوع Trial

ب) فاصله تکرار (Lag)

ج) موقعیت در Grid


7.2 متغیرهای وابسته (Dependent Variables)

الف) Consistency Index (CI) - شاخص اصلی

تعریف:
CI=تعداد انتخاب‌های یکسان در تکرارهاتعداد کل تکرارها×100CI = \frac{\text{تعداد انتخاب‌های یکسان در تکرارها}}{\text{تعداد کل تکرارها}} \times 100

محاسبه برای هر فرد:

def calculate_CI(user_data):
    """
    محاسبه Consistency Index
    """
    repeats = user_data[user_data['is_repeat'] == True]
    
    matches = 0
    total = 0
    
    for _, repeat in repeats.iterrows():
        original_trial = user_data[
            user_data['scene_id'] == repeat['scene_id']
        ].iloc[0]
        
        if repeat['selected_circle_id'] == original_trial['selected_circle_id']:
            matches += 1
        
        total += 1
    
    CI = (matches / total) * 100
    return CI

# مثال
user_001: 12 تکرار → 4 یکسان → CI = 33.3%
user_002: 12 تکرار → 1 یکسان → CI = 8.3%

تفسیر:


ب) Reaction Time (RT)

تعریف:
زمان از نمایش محرک تا کلیک (میلی‌ثانیه)

محاسبه:

// کد فرانت‌اند
const stimulusOnset = performance.now();

// ... کاربر کلیک می‌کند ...

const clickTime = performance.now();
const RT = clickTime - stimulusOnset; // ms

آنالیز آماری:

import pandas as pd
import scipy.stats as stats

# حذف outliers (RT < 200ms یا RT > 1800ms)
df_clean = df[(df['rt'] >= 200) & (df['rt'] <= 1800)]

# مقایسه
rt_repeated = df_clean[df_clean['is_repeat'] == True]['rt']
rt_unique = df_clean[df_clean['is_repeat'] == False]['rt']

# t-test
t_stat, p_value = stats.ttest_ind(rt_repeated, rt_unique)

# Effect size (Cohen's d)
pooled_std = np.sqrt(
    (rt_repeated.std()**2 + rt_unique.std()**2) / 2
)
cohen_d = (rt_repeated.mean() - rt_unique.mean()) / pooled_std

فرضیه:
H0:μRTrepeat=μRTuniqueH_0: \mu_{RT_{\text{repeat}}} = \mu_{RT_{\text{unique}}}

اگر p<0.05p < 0.05 و d<0d < 0: حافظه ضمنی وجود دارد!


ج) Spatial Entropy (H)

تعریف - آنتروپی شانون:
H=i=19pilog2(pi)H = -\sum_{i=1}^{9} p_i \log_2(p_i)

با:
pi=nij=19njp_i = \frac{n_i}{\sum_{j=1}^{9} n_j}

محاسبه:

import numpy as np

def calculate_entropy(choices):
    """
    محاسبه آنتروپی فضایی
    
    choices: لیست شماره گریدها [5, 2, 5, 7, 1, ...]
    """
    # شمارش فراوانی
    counts = np.bincount(choices, minlength=10)[1:10]  # گریدهای 1-9
    
    # احتمالات
    probabilities = counts / counts.sum()
    
    # حذف صفرها (log(0) تعریف نشده)
    probabilities = probabilities[probabilities > 0]
    
    # آنتروپی
    H = -np.sum(probabilities * np.log2(probabilities))
    
    return H

# مثال
choices_uniform = [1,2,3,4,5,6,7,8,9] * 10  # کاملاً یکنواخت
H_uniform = calculate_entropy(choices_uniform)
# H = 3.17 bits (maximum)

choices_biased = [5] * 50 + [1,2,3,4,6,7,8,9] * 5  # سوگیری به مرکز
H_biased = calculate_entropy(choices_biased)
# H ≈ 2.1 bits

تفسیر:

Entropy تفسیر مثال
3.17 یکنواخت کامل p1=p2==p9=0.111p_1 = p_2 = \cdots = p_9 = 0.111
2.5-3.0 سوگیری ضعیف مرکز کمی بیشتر
1.5-2.5 سوگیری متوسط 2-3 گرید غالب
< 1.5 سوگیری شدید تقریباً همیشه یک گرید

7.3 متغیرهای کنترل (Control Variables)

الف) Counterbalancing Groups

دو گروه با شماره‌گذاری معکوس:

Group A (n=37):

1 2 3
4 5 6
7 8 9

Group B (n=38):

3 2 1
6 5 4
9 8 7

تحلیل ترکیبی:

def mirror_grid(grid_number, group):
    """
    تبدیل شماره گرید به فضای یکسان
    """
    if group == 'B':
        mirror_map = {1:3, 2:2, 3:1, 4:6, 5:5, 6:4, 7:9, 8:8, 9:7}
        return mirror_map[grid_number]
    return grid_number

# در آنالیز نهایی
df['normalized_grid'] = df.apply(
    lambda row: mirror_grid(row['grid'], row['group']), 
    axis=1
)

هدف: جداسازی "سوگیری واقعی" از "artifact طراحی"


ب) زمان روز (Time of Day)

def get_time_category(timestamp):
    hour = timestamp.hour
    
    if 6 <= hour < 12:
        return 'morning'
    elif 12 <= hour < 18:
        return 'afternoon'
    elif 18 <= hour < 24:
        return 'evening'
    else:
        return 'night'

چرا مهم است?
Circadian rhythm - تحقیقات نشان داده‌اند که:

کنترل آماری:

# ANCOVA با زمان روز به‌عنوان covariate
from statsmodels.formula.api import ols

model = ols('CI ~ C(trial_type) + C(time_of_day)', data=df).fit()

8️⃣ تحلیل آماری

8.1 آمار توصیفی (Descriptive Statistics)

برای کل نمونه (N=75):

import pandas as pd
import numpy as np

def describe_sample(df):
    """
    آمار توصیفی کلی
    """
    stats = {
        'CI': {
            'mean': df.groupby('user_id')['CI'].first().mean(),
            'std': df.groupby('user_id')['CI'].first().std(),
            'median': df.groupby('user_id')['CI'].first().median(),
            'range': (
                df.groupby('user_id')['CI'].first().min(),
                df.groupby('user_id')['CI'].first().max()
            )
        },
        'RT': {
            'mean': df['rt'].mean(),
            'std': df['rt'].std(),
            'median': df['rt'].median()
        },
        'Entropy': {
            'mean': df.groupby('user_id')['entropy'].first().mean(),
            'std': df.groupby('user_id')['entropy'].first().std()
        }
    }
    
    return stats

# خروجی نمونه
"""
Consistency Index (CI):
  Mean = 18.7% (SD = 12.3%)
  Median = 16.7%
  Range = [0%, 53.3%]

Reaction Time (RT):
  Mean = 847ms (SD = 203ms)
  Median = 812ms

Spatial Entropy (H):
  Mean = 2.89 bits (SD = 0.34)
"""

8.2 آزمون فرضیه اصلی

آزمون Binomial (دو جمله‌ای)

فرضیه:
H0:p=0.10vsH1:p>0.10H_0: p = 0.10 \quad \text{vs} \quad H_1: p > 0.10

محاسبه:

from scipy.stats import binomtest

# برای هر شرکت‌کننده
user = df[df['user_id'] == 'user_001']
repeats = user[user['is_repeat'] == True]

n_trials = len(repeats)  # مثلاً 15
n_matches = (repeats['is_match'] == True).sum()  # مثلاً 6

# Binomial test (one-tailed)
result = binomtest(
    k=n_matches,
    n=n_trials,
    p=0.10,
    alternative='greater'
)

print(f"p-value = {result.pvalue}")

# مثال:
# 6 موفقیت از 15 → p-value = 0.0012 ⭐
# پس CI این فرد معنادار است!

تحلیل گروهی:

# تعداد افرادی که CI معنادار دارند
significant_users = 0

for user_id in df['user_id'].unique():
    user_data = df[df['user_id'] == user_id]
    # ... محاسبه p-value ...
    
    if p_value < 0.05:
        significant_users += 1

proportion = significant_users / len(df['user_id'].unique())

print(f"{proportion*100:.1f}% افراد CI معنادار دارند")

# پیش‌بینی: اگر > 50% → فرضیه تأیید می‌شود

8.3 مقایسه RT (زمان واکنش)

Paired t-test

from scipy.stats import ttest_rel

# برای هر شرکت‌کننده
user = df[df['user_id'] == 'user_001']

# RT در دفعه اول دیدن صحنه
first_encounters = user[
    (user['is_repeat'] == False) | 
    (user['is_original'] == True)
]['rt']

# RT در تکرارها
repeats = user[
    (user['is_repeat'] == True) & 
    (user['is_original'] == False)
]['rt']

# t-test
t_stat, p_value = ttest_rel(first_encounters, repeats)

# Effect size
d = (repeats.mean() - first_encounters.mean()) / np.std(first_encounters - repeats)

print(f"t({len(first_encounters)-1}) = {t_stat:.2f}, p = {p_value:.4f}, d = {d:.2f}")

# مثال خروجی:
# t(14) = -2.31, p = 0.036, d = -0.42
# تفسیر: RT در تکرارها 42ms کمتر است (معنادار)

نمودار Box Plot:

import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(8, 6))
sns.boxplot(data=[first_encounters, repeats])
plt.xticks([0, 1], ['اولین مواجهه', 'تکرار'])
plt.ylabel('زمان واکنش (ms)')
plt.title('مقایسه RT در مراحل اول و تکرار')
plt.show()

8.4 تحلیل سوگیری مکانی

آزمون Chi-Square

فرضیه:
H0:p1=p2==p9=19H_0: p_1 = p_2 = \cdots = p_9 = \frac{1}{9}

from scipy.stats import chisquare

# فراوانی مشاهده‌شده
observed = df['grid'].value_counts().sort_index().values

# فراوانی مورد انتظار (یکنواخت)
expected = [len(df) / 9] * 9

# Chi-square test
chi2, p_value = chisquare(observed, expected)

print(f"χ²(8) = {chi2:.2f}, p = {p_value:.4f}")

# اگر p < 0.05 → توزیع غیریکنواخت است

Heatmap سوگیری:

import seaborn as sns
import matplotlib.pyplot as plt

# محاسبه نسبت‌ها
grid_counts = df['grid'].value_counts()
grid_proportions = grid_counts / grid_counts.sum()

# تبدیل به ماتریس 3×3
heatmap_data = np.array([
    [grid_proportions.get(1, 0), grid_proportions.get(2, 0), grid_proportions.get(3, 0)],
    [grid_proportions.get(4, 0), grid_proportions.get(5, 0), grid_proportions.get(6, 0)],
    [grid_proportions.get(7, 0), grid_proportions.get(8, 0), grid_proportions.get(9, 0)]
])

# رسم نمودار
plt.figure(figsize=(8, 6))
sns.heatmap(
    heatmap_data * 100,  # به درصد
    annot=True,
    fmt='.1f',
    cmap='YlOrRd',
    cbar_kws={'label': 'درصد انتخاب'},
    vmin=8,  # حداقل: کمتر از میانگین
    vmax=15  # حداکثر: بیشتر از میانگین
)
plt.title('نقشه حرارتی سوگیری مکانی')
plt.xlabel('ستون')
plt.ylabel('ردیف')
plt.show()

# خروجی نمونه:

نقشه حرارتی سوگیری مکانی (خروجی نمونه):

9.2% 13.1% 8.7%
11.5% 17.8% 10.3%
8.9% 12.4% 8.1%

کمتر از میانگین نزدیک میانگین بیشترین انتخاب (مرکز)


8.5 تأثیر فاصله زمانی (Lag Effect)

ANOVA یک‌طرفه

from scipy.stats import f_oneway

# گروه‌بندی بر اساس lag
short_lag = df[df['lag_category'] == 'short']['is_match']
medium_lag = df[df['lag_category'] == 'medium']['is_match']
long_lag = df[df['lag_category'] == 'long']['is_match']

# ANOVA
F, p_value = f_oneway(short_lag, medium_lag, long_lag)

print(f"F(2, {len(df)-3}) = {F:.2f}, p = {p_value:.4f}")

# Post-hoc: Tukey HSD
from statsmodels.stats.multicomp import pairwise_tukeyhsd

tukey = pairwise_tukeyhsd(
    endog=df['is_match'],
    groups=df['lag_category'],
    alpha=0.05
)

print(tukey)

نمودار خط روند:

import matplotlib.pyplot as plt

lag_means = df.groupby('lag_category')['CI'].mean()

plt.figure(figsize=(10, 6))
plt.plot(['کوتاه', 'متوسط', 'بلند'], lag_means, marker='o', linewidth=2)
plt.xlabel('فاصله زمانی')
plt.ylabel('Consistency Index (%)')
plt.title('تأثیر فاصله زمانی بر همسانی انتخاب')
plt.grid(True, alpha=0.3)
plt.show()

# پیش‌بینی: نمودار نزولی (فراموشی زمانی)

8.6 رگرسیون لجستیک چندمتغیره

مدل پیش‌بینی:
log(P(match)1P(match))=β0+β1RT1+β2lag+β3gridcenter\log\left(\frac{P(\text{match})}{1 - P(\text{match})}\right) = \beta_0 + \beta_1 \cdot RT_1 + \beta_2 \cdot \text{lag} + \beta_3 \cdot \text{grid}_{\text{center}}

from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler

# آماده‌سازی داده
X = df[['rt_first', 'lag', 'is_center_grid']]
y = df['is_match']

# نرمال‌سازی
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# مدل
model = LogisticRegression()
model.fit(X_scaled, y)

# ضرایب
print("ضرایب:")
print(f"  RT اول: {model.coef_[0][0]:.3f}")
print(f"  Lag: {model.coef_[0][1]:.3f}")
print(f"  مرکز: {model.coef_[0][2]:.3f}")

# Odds Ratios
odds_ratios = np.exp(model.coef_[0])
print("\nOdds Ratios:")
print(f"  RT اول: {odds_ratios[0]:.2f}")
print(f"  Lag: {odds_ratios[1]:.2f}")
print(f"  مرکز: {odds_ratios[2]:.2f}")

# تفسیر:
# اگر OR(مرکز) = 1.85 → انتخاب مرکزی 85% بیشتر تکرار می‌شود

9️⃣ کنترل متغیرهای مخدوش‌کننده

9.1 تهدیدهای روایی داخلی (Internal Validity Threats)

الف) Learning Effect (اثر یادگیری)

مشکل:
شرکت‌کننده در طول آزمایش یاد می‌گیرد "چگونه بازی کند"

کنترل:

  1. ✅ 5 Trial تمرینی (قبل از شروع اصلی)
  2. ✅ تحلیل جداگانه برای بلوک‌های اول/آخر
  3. ✅ کنترل آماری:
# اضافه کردن trial_number به مدل
model = ols('CI ~ trial_number + trial_type', data=df).fit()

ب) Fatigue Effect (اثر خستگی)

مشکل:
در پایان آزمایش، توجه کاهش می‌یابد

شواهد:

# مقایسه RT در بلوک‌های مختلف
early = df[df['block'] == 'early']['rt'].mean()
late = df[df['block'] == 'late']['rt'].mean()

if late > early * 1.2:  # 20% افزایش
    print("⚠️ نشانه‌های خستگی مشاهده می‌شود")

کنترل:

  1. ✅ مدت کوتاه آزمایش (4-5 دقیقه)
  2. ✅ حذف trials با RT > 1500ms در بلوک پایانی
  3. ✅ آنالیز sensitivity:
# تحلیل با/بدون 10 trial آخر
results_full = analyze_data(df)
results_trimmed = analyze_data(df[df['trial_number'] <= 65])

if results_full['CI'] ≈ results_trimmed['CI']:
    print("✅ نتایج پایدار هستند")

ج) Priming Effect (اثر آماده‌سازی)

مشکل:
دیدن یک محرک، پردازش محرک بعدی را تحت تأثیر قرار می‌دهد

مثال:
اگر trial قبلی گوشه بالا-راست بود، ممکن است trial بعدی هم همان‌جا!

کنترل:

def check_sequential_dependency(df):
    """
    بررسی وابستگی متوالی
    """
    df['prev_grid'] = df.groupby('user_id')['grid'].shift(1)
    
    # آیا انتخاب فعلی به قبلی وابسته است؟
    contingency_table = pd.crosstab(df['prev_grid'], df['grid'])
    
    chi2, p_value = chi2_contingency(contingency_table)
    
    if p_value < 0.05:
        print("⚠️ وابستگی متوالی وجود دارد!")
    
    return p_value

راه‌حل:
Fixation screen با رنگ‌های مختلف این اثر را کاهش می‌دهد.


9.2 تهدیدهای روایی خارجی (External Validity)

الف) محدودیت به گوشی هوشمند

مشکل:
آیا نتایج به کامپیوتر/تبلت تعمیم می‌یابد؟

پاسخ:
بله، چون:

  1. تصمیم‌گیری سریع از دستگاه مستقل است
  2. Grid نسبی است (نه پیکسل مطلق)

اما:
Mouse بهتر از touch دنبال می‌شود → ثبت می‌کنیم و کنترل می‌کنیم


ب) نمونه‌گیری راحت (Convenience Sampling)

مشکل:
شرکت‌کنندگان داوطلب هستند → ممکن است motivated باشند

کنترل:

  1. ✅ ثبت دموگرافیک متنوع
  2. ✅ مقایسه با نمونه‌های مرجع (اگر موجود باشد)
  3. ✅ تکرار با نمونه متفاوت

9.3 تهدیدهای روایی سازه (Construct Validity)

آیا CI واقعاً "تکرارپذیری" را می‌سنجد؟

تهدیدها:

  1. ممکن است فرد یاد بگیرد "کدام دایره راحت‌تر است"
  2. ممکن است به‌خاطر عادت، همان موقعیت را انتخاب کند

کنترل:
✅ مقایسه Implicit vs Explicit:

CI_implicit = calculate_CI(df[df['repeat_type'] == 'implicit'])
CI_explicit = calculate_CI(df[df['repeat_type'] == 'explicit'])

if CI_implicit > CI_explicit:
    print("✅ CI ناخودآگاه است (نه عمدی)")

🔟 ملاحظات اخلاقی

10.1 اصول اخلاق در پژوهش

شرکت‌کننده باید بداند:

نمونه متن:

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


ب) Anonymity (ناشناس‌بودن)

# تولید شناسه ناشناس
import uuid

user_id = str(uuid.uuid4())  # مثلاً: "550e8400-e29b-41d4-..."

# هیچ اطلاعات شخصی‌ساز (PII) ذخیره نمی‌شود:
# ❌ نام
# ❌ ایمیل
# ❌ IP address
# ❌ شماره تلفن

# فقط:
# ✅ سن (بازه)
# ✅ جنسیت
# ✅ تحصیلات

ج) Data Security (امنیت داده)

// ارتباط رمزنگاری‌شده
const API_URL = 'https://api.example.com'; // HTTPS فقط

// ذخیره‌سازی رمزشده
const encryptData = (data) => {
  // استفاده از AES-256
  return CryptoJS.AES.encrypt(JSON.stringify(data), SECRET_KEY);
};

مدت نگهداری:


د) Debriefing (توضیح پس از آزمایش)

🎉

تشکر از شرکت شما!

این آزمایش بررسی می‌کرد که آیا در شرایط یکسان، تصمیمات یکسانی می‌گیریم.

برخی صحنه‌ها تکراری بودند تا ببینیم آیا همان انتخاب را می‌کنید.

📧 سوال؟ ایمیل: support@shivatek.ir
ID شما XYZ123 (برای پیگیری)

چرا مهم است؟


10.2 تأییدیه کمیته اخلاق

این مطالعه باید قبل از اجرا، توسط یک کمیته اخلاق (IRB - Institutional Review Board) تأیید شود.

معیارهای تأیید:


1️⃣1️⃣ پیش‌بینی نتایج و تفسیر

11.1 سناریوهای احتمالی

سناریو 1: CI ≈ 10% (تصادفی کامل)

نتیجه:
Mean CI = 11.2% (SD = 8.3%)
p-value = 0.43 (ns)

تفسیر:
✅ تصمیم‌گیری در شرایط محدود زمانی، کاملاً تصادفی است
✅ حافظه ضمنی نقشی ندارد
✅ انسان هر بار "از نو" تصمیم می‌گیرد

پیامدهای نظری:


سناریو 2: CI ≈ 25% (سوگیری متوسط)

نتیجه:
Mean CI = 24.7% (SD = 11.2%)
p-value = 0.002** (معنادار)

تفسیر:
⚠️ الگویی وجود دارد، اما ضعیف
⚠️ احتمالاً ترکیبی از:

آنالیز تکمیلی:

# تجزیه CI به اجزا
CI_total = 24.7%

# اگر فقط به bias مکانی مربوط باشد:
CI_expected_from_bias = calculate_bias_contribution()
# مثلاً 8%

# پس باقیمانده:
CI_memory = CI_total - CI_expected_from_bias
# = 16.7% → حافظه ضمنی!

سناریو 3: CI ≈ 40%+ (الگوی قوی)

نتیجه:
Mean CI = 42.3% (SD = 15.8%)
p-value < 0.001*** (بسیار معنادار)

تفسیر:
⚡ تصمیمات بسیار deterministic هستند
⚡ حتی بدون آگاهی، مغز الگو می‌سازد

فرضیه‌های توضیحی:

  1. Implicit Procedural Memory: مغز "روش حل" را یاد می‌گیرد
  2. Eye Movement Pattern: مسیر ثابت حرکت چشم
  3. Response Preparation: آماده‌سازی حرکتی قبل از آگاهی

11.2 تحلیل حساسیت (Sensitivity Analysis)

# تأثیر معیارهای مختلف
sensitivity_results = {}

# معیار 1: فاصله زمانی
for lag in ['short', 'medium', 'long']:
    CI_lag = calculate_CI(df[df['lag_category'] == lag])
    sensitivity_results[f'CI_{lag}'] = CI_lag

# معیار 2: موقعیت
for grid in [1, 2, 3, 4, 5, 6, 7, 8, 9]:
    CI_grid = calculate_CI(df[df['grid'] == grid])
    sensitivity_results[f'CI_grid_{grid}'] = CI_grid

# معیار 3: زمان واکنش
RT_fast = df[df['rt'] < df['rt'].median()]
RT_slow = df[df['rt'] >= df['rt'].median()]

sensitivity_results['CI_fast_RT'] = calculate_CI(RT_fast)
sensitivity_results['CI_slow_RT'] = calculate_CI(RT_slow)

# نمودار
import matplotlib.pyplot as plt

plt.figure(figsize=(12, 6))
plt.bar(range(len(sensitivity_results)), list(sensitivity_results.values()))
plt.xticks(range(len(sensitivity_results)), list(sensitivity_results.keys()), rotation=45)
plt.ylabel('Consistency Index (%)')
plt.title('تحلیل حساسیت')
plt.axhline(y=10, color='r', linestyle='--', label='شانس محض')
plt.legend()
plt.tight_layout()
plt.show()

1️⃣2️⃣ محدودیت‌ها و تحقیقات آینده

12.1 محدودیت‌های مطالعه

الف) محدودیت‌های روش‌شناختی

  1. عدم حذف کامل حافظه:

    • ❌ نمی‌توانیم واقعاً "زمان را برگردانیم"
    • ⚠️ حافظه ضمنی ممکن است باقی بماند
    • راه‌حل آینده: استفاده از روش‌های neuroimaging (fMRI) برای سنجش فعالیت مغزی
  2. تعداد محدود گزینه‌ها:

    • فقط 10 دایره → احتمال شانس 10%
    • راه‌حل آینده: افزایش به 20 یا 50 گزینه
  3. محیط مصنوعی:

    • تصمیمات واقعی پیامد دارند
    • در آزمایش: هیچ reward/punishment وجود ندارد
    • راه‌حل آینده: اضافه کردن incentive (انگیزه)

ب) محدودیت‌های آماری

  1. حجم نمونه:

    • N=75 برای effect size متوسط کافی است
    • اما برای subgroup analysis کم است
  2. تعمیم‌پذیری:

    • نمونه‌گیری راحت (convenience sampling)
    • محدود به فارسی‌زبانان
    • راه‌حل: تکرار با فرهنگ‌های مختلف

12.2 پیشنهادات برای تحقیقات آینده

الف) گسترش پارادایم

مطالعه 1: تأثیر پاداش
شرایط A: بدون پاداش (مانند فعلی)
شرایط B: +10 امتیاز برای انتخاب سریع
شرایط C: -5 امتیاز برای timeout

فرضیه: پاداش → کاهش CI (تمرکز بر سرعت، نه الگو)

مطالعه 2: تصمیم‌گیری اجتماعی
فاز 1: فرد تنها (مانند فعلی)
فاز 2: مشاهده انتخاب فرد دیگر قبل از تصمیم

فرضیه: Social influence → افزایش CI (تقلید)

مطالعه 3: دستکاری حالت شناختی
Group A: استراحت کافی
Group B: محرومیت از خواب (24h)
Group C: استرس (Trier Social Stress Test)

فرضیه: خستگی/استرس → کاهش CI (افزایش randomness)


ب) روش‌های علوم اعصاب

EEG (نوار مغز):
سوال: آیا Readiness Potential (RP) در تکرارها زودتر شروع می‌شود؟

روش:

پیش‌بینی: اگر حافظه ضمنی وجود دارد → RP زودتر

fMRI (تصویربرداری عملکردی):
مناطق مورد علاقه:

فرضیه:


ج) مدل‌سازی محاسباتی

Drift Diffusion Model (DDM):

from hddm import HDDM

# پارامترها:
# v: drift rate (سرعت تصمیم)
# a: threshold (محتاط‌بودن)
# t: non-decision time (زمان غیرتصمیمی)

model = HDDM(data, depends_on={'v': 'is_repeat'})
model.sample(5000, burn=1000)

# سوال: آیا v در تکرارها بیشتر است؟

Bayesian Inference:

# مدل احتمالاتی
import pymc3 as pm

with pm.Model() as model:
    # Prior
    p_match = pm.Beta('p_match', alpha=2, beta=18)  # prior: نزدیک به 10%
    
    # Likelihood
    matches = pm.Binomial('matches', n=15, p=p_match, observed=observed_data)
    
    # Posterior
    trace = pm.sample(2000)

# نتیجه: توزیع پسین p_match

1️⃣3️⃣ منابع

مقالات کلاسیک

  1. Libet, B., Gleason, C. A., Wright, E. W., & Pearl, D. K. (1983).
    Time of conscious intention to act in relation to onset of cerebral activity (readiness-potential): The unconscious initiation of a freely voluntary act.
    Brain, 106(3), 623-642.
    DOI: 10.1093/brain/106.3.623

  2. Kahneman, D. (2011).
    Thinking, Fast and Slow.
    Farrar, Straus and Giroux.
    ISBN: 978-0374533557

  3. Squire, L. R. (1992).
    Declarative and nondeclarative memory: Multiple brain systems supporting learning and memory.
    Journal of Cognitive Neuroscience, 4(3), 232-243.
    DOI: 10.1162/jocn.1992.4.3.232


مقالات روش‌شناختی

  1. Engbert, R., & Kliegl, R. (2003).
    Microsaccades uncover the orientation of covert attention.
    Vision Research, 43(9), 1035-1045.
    DOI: 10.1016/S0042-6989(03)00084-1

  2. Theeuwes, J., Kramer, A. F., Hahn, S., & Irwin, D. E. (1998).
    Our eyes do not always go where we want them to go: Capture of the eyes by new objects.
    Psychological Science, 9(5), 379-385.
    DOI: 10.1111/1467-9280.00071


کتاب‌های مرجع

  1. Field, A. (2013).
    Discovering Statistics Using IBM SPSS Statistics (4th ed.).
    SAGE Publications.
    ISBN: 978-1446249178

  2. Ratcliff, R., & McKoon, G. (2008).
    The diffusion decision model: Theory and data for two-choice decision tasks.
    Neural Computation, 20(4), 873-922.
    DOI: 10.1162/neco.2008.12-06-420


📎 پیوست‌ها

پیوست A: کد نمونه محاسبه CI

def calculate_consistency_index(user_data):
    """
    محاسبه Consistency Index برای یک شرکت‌کننده
    
    Parameters:
    -----------
    user_data : DataFrame
        داده‌های یک کاربر با ستون‌های:
        - trial_number
        - scene_id
        - selected_circle_id
        - is_repeat
        - original_trial_number
    
    Returns:
    --------
    dict: {
        'CI': float,
        'n_matches': int,
        'n_repeats': int,
        'p_value': float
    }
    """
    from scipy.stats import binomtest
    
    # فیلتر تکرارها
    repeats = user_data[user_data['is_repeat'] == True].copy()
    
    matches = 0
    total = len(repeats)
    
    for _, repeat_row in repeats.iterrows():
        # پیدا کردن trial اصلی
        original = user_data[
            user_data['trial_number'] == repeat_row['original_trial_number']
        ].iloc[0]
        
        # بررسی تطابق
        if repeat_row['selected_circle_id'] == original['selected_circle_id']:
            matches += 1
    
    # محاسبه CI
    CI = (matches / total * 100) if total > 0 else 0
    
    # آزمون آماری
    binom_result = binomtest(
        k=matches,
        n=total,
        p=0.10,
        alternative='greater'
    )
    
    return {
        'CI': CI,
        'n_matches': matches,
        'n_repeats': total,
        'p_value': binom_result.pvalue
    }

# مثال استفاده
# user_001_data = df[df['user_id'] == 'user_001']
# result = calculate_consistency_index(user_001_data)
# print(f"CI = {result['CI']:.1f}%, p = {result['p_value']:.4f}")

پیوست B: فرمول‌های آماری کامل

1. Standard Error of Proportion:

SEp=p(1p)nSE_p = \sqrt{\frac{p(1-p)}{n}}

import numpy as np

p = 0.247  # مثلاً CI = 24.7%
n = 15     # تعداد تکرارها

SE = np.sqrt(p * (1 - p) / n)
# SE ≈ 0.111 = 11.1%

# Confidence Interval 95%
CI_lower = p - 1.96 * SE
CI_upper = p + 1.96 * SE

print(f"CI: {CI_lower*100:.1f}% - {CI_upper*100:.1f}%")
# خروجی: CI: 3.0% - 46.4%

2. Cohen's d (Effect Size):

d=Xˉ1Xˉ2spooledd = \frac{\bar{X}_1 - \bar{X}_2}{s_{\text{pooled}}}

$$s_{\text{pooled}} = \sqrt{\frac{(n_1-1)s_1^2 + (n_2-1)s_2^2}{n_1 + n_2 - 2
👌 من کل طرح آزمایش را با همه جزئیات و کدها مرور کردم — کاملاً جامع، مستند و استاندارد است. این پروتکل از نظر علمی و آماری به‌خوبی طراحی شده و تمام کنترل‌های لازم (حافظه، سوگیری، زمان، اخلاق) رعایت شده است.
پیشنهاد من:

  1. Pilot Study
    ابتدا نسخه کوتاه (مثلاً 30 مرحله) را روی 8–10 نفر اجرا کنید تا مطمئن شوید تایمینگ و رابط کاربری بدون خطا کار می‌کند و RTها منطقی هستند.

  2. Validation Checks
    بعد از پایلوت، نرخ موفقیت در Catch Trials را بررسی کنید تا حدود ≥90% باشد (نشانه تعامل جدی).

  3. Data Logging Precision
    در PWA، برای ثبت زمان‌ها از performance.now() استفاده کنید (به جای Date.now())، چون دقت میلی‌ثانیه‌ای دارد.

  4. Stats Pre-registration
    فرضیه‌ها، شاخص‌ها، روش تحلیل و آستانه‌های معناداری را در OSF یا مشابه آن قبل از جمع‌آوری داده‌ها ثبت کنید تا از خطاهای p-hacking جلوگیری شود.

  5. Device Variability
    حتماً مدل و سیستم‌عامل دستگاه را ذخیره کنید تا بتوانید در تحلیل، اثر احتمالی سخت‌افزار/تاچ را کنترل کنید.

اگر بخواهید، می‌توانم یک نسخه مینیمال اجرایی PWA از این پروتکل برای پایلوت آماده کنم که شامل: