CONTENTS

ഇന്ററാക്ടീവ് ഗൗസിയൻ മിശ്രിത മോഡലുകൾ

ലക്ഷ്യം

നമുക്ക് സവിശേഷതകളുടെ ഒരു ഡാറ്റാസെറ്റ് ഉണ്ടെന്ന് കരുതുക, പക്ഷേ ലേബലുകളില്ല. ഡാറ്റാസെറ്റിൽ ക്ലാസുകൾ ഉണ്ടെന്ന് നമുക്ക് അറിയാമെങ്കിൽ (അല്ലെങ്കിൽ ഊഹിക്കാമെങ്കിൽ), ഡാറ്റാസെറ്റിനെ ക്ലാസ്–കണ്ടീഷണൽ ഗൗസിയനുകളുടെ ഭാരം കണക്കാക്കിയ ശരാശരിയായി മാതൃകയാക്കാം. ഇതാണ് ഗൗസിയൻ മിശ്രിത മാതൃകകൾ (Gaussian Mixture Models) ചെയ്യുന്നത്.

മാതൃക എന്ന പാരാമീറ്ററുകളാൽ സവിശേഷതപ്പെടുത്തപ്പെട്ടതാണെന്ന് നമ്മൾ അനുമാനിക്കുന്നു. ഇവിടെ മാതൃകയിലെ –ആമത്തെ ഗൗസിയന്റെ ഭാരം നിർണ്ണയിക്കുന്നു.

നമ്മുടെ ഡാറ്റാസെറ്റ് i.i.d. ആയതിനാൽ, അതിന്റെ ലോഗ്–സാധ്യത (log–likelihood) ഇതാണ്:

പ്രതീക്ഷ പരമാവധികരണം (Expectation Maximization)

നമ്മുടെ ഡാറ്റയുടെ സാധ്യത (likelihood) പരമാവധി ആക്കുന്ന കണ്ടെത്താൻ, ഇനിപ്പറയുന്ന പ്രക്രിയ ഉപയോഗിക്കും:

  1. എന്നതിന് പ്രാഥമിക ഊഹങ്ങൾ കണക്കാക്കുക.

  2. എന്നത് എന്ന ക്ലാസ്സിൽ ഉൾപ്പെടാനുള്ള സാധ്യത കണക്കാക്കുക. ഇതിനെ അല്ലെങ്കിൽ യുടെ ലേക്കുള്ള ഉത്തരവാദിത്വം എന്ന് സൂചിപ്പിക്കുന്നു.

  1. ഇനി നമ്മൾ അപ്ഡേറ്റ് ചെയ്യുന്നു
    • ഭാരങ്ങൾ എന്നത് ഗാസിയൻ ന്റെ ശരാശരി ഉത്തരവാദിത്വമായിരിക്കും.
    • മാധ്യങ്ങൾ എന്നത് എല്ലാ നും കൊണ്ട് ഭാരം നൽകിയ ഡാറ്റാപോയിന്റുകളുടെ ശരാശരിയായിരിക്കും.
    • വേരിയൻസുകൾ എന്നത് പുതിയ ൽ നിന്നുള്ള ഡാറ്റാപോയിന്റുകളുടെ വേരിയൻസ് ആയിരിക്കും, സമാനമായി കൊണ്ട് ഭാരം നൽകിയത്.

ഈ പ്രക്രിയയും കെർണൽ റിഗ്രഷൻ തമ്മിലുള്ള സാദൃശ്യം ശ്രദ്ധിക്കുക! ഇവിടെ, കെർണൽ ഫംഗ്ഷൻ ആണ്, അത് ക്ലാസ്സിൽ ഉൾപ്പെടാനിടയുള്ള ഫീച്ചറുകളുടെ ഒരു പരിസരം (neighborhood) നിർവ്വചിക്കുന്നു.

ഭാരങ്ങൾ സംയോജിക്കുന്നത് വരെ (converge) 2, 3 എന്നീ ഘട്ടങ്ങൾ ആവർത്തിക്കുന്നു.

ഇടപെടൽ ഡെമോ

താഴെ കാണുന്നത് EM അൽഗോരിതത്തിന്റെ ഒരു ഇടപെടൽ ഡെമോ ആണ്. ഡാറ്റ ഗൗസിയനുകളിൽ നിന്ന് ജനറേറ്റ് ചെയ്യപ്പെടുന്നു, അവയുടെ മീൻസ്, വേരിയൻസുകൾ, ഭാരങ്ങൾ എന്നിവ റാൻഡമായി തിരഞ്ഞെടുക്കപ്പെടുന്നു. പിന്നീട്, ഗൗസിയനുകളുള്ള ഒരു GM മോഡൽ ഡാറ്റയിൽ ഫിറ്റ് ചെയ്യുന്നു.

നിങ്ങൾക്ക് Start ബട്ടൺ ആവർത്തിച്ച് അമർത്താം. ഡെസ്ക്ടോപ്പ് ശുപാർശ ചെയ്യുന്നു.

Iteration: 0
$k$ True $(\mu_k, \sigma_k^2)$ Est $(\hat \mu_k, \hat \sigma_k^2)$ True $\pi_k$ Est $\hat{\pi}_k$
കോഡ്

ഇതാ ജാവാസ്ക്രിപ്റ്റിലെ കോർ അൽഗോരിതം കോഡ്. പ്ലോട്ടിംഗ് കോഡും HTML/CSS ഉം ഞാൻ ഒഴിവാക്കിയതിനാൽ, ഇത് നേരിട്ട് മുകളിലെ പ്ലോട്ട് പുനർനിർമ്മിക്കില്ല. മുഴുവൻ കാര്യങ്ങളും കാണാൻ നിങ്ങൾക്ക് Inspect Element ഉപയോഗിക്കാം.

function randn() {
  let u = 0, v = 0;
  while(u === 0) u = Math.random();
  while(v === 0) v = Math.random();
  return Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
}

function gaussianPDF(x, mean, variance) {
  const std = Math.sqrt(variance);
  const coeff = 1.0 / (std * Math.sqrt(2 * Math.PI));
  const exponent = -0.5 * Math.pow((x - mean)/std, 2);
  return coeff * Math.exp(exponent);
}

function generateSeparatedMeans(C) {
  let candidate = [];
  for (let i = 0; i < C; i++) {
    candidate.push(Math.random());
  }
  candidate.sort((a,b) => a - b);
  let means = candidate.map(x => -5 + x*10);
  for (let i = 1; i < C; i++) {
    if (means[i] - means[i-1] < 0.5) {
      means[i] = means[i-1] + 0.5;
    }
  }
  return means;
}

function generateData(C, N=1000) {
  let means = generateSeparatedMeans(C);
  let variances = [];
  let weights = [];
  for (let i = 0; i < C; i++) {
    variances.push(0.5 + 1.5*Math.random());
    weights.push(1.0/C);
  }

  let data = [];
  for (let i = 0; i < N; i++) {
    const comp = Math.floor(Math.random() * C);
    const x = means[comp] + Math.sqrt(variances[comp])*randn();
    data.push(x);
  }
  return {data, means, variances, weights};
}

function decentInitialGuess(C, data) {
  const N = data.length;
  let means = [];
  let variances = [];
  let weights = [];
  for (let c = 0; c < C; c++) {
    means.push(data[Math.floor(Math.random()*N)]);
    variances.push(1.0);
    weights.push(1.0/C);
  }
  return {means, variances, weights};
}

function emGMM(data, C, maxIter=100, tol=1e-4) {
  const N = data.length;
  let init = decentInitialGuess(C, data);
  let means = init.means.slice();
  let variances = init.variances.slice();
  let weights = init.weights.slice();

  let logLikOld = -Infinity;
  let paramsHistory = [];

  for (let iter = 0; iter < maxIter; iter++) {
    let resp = new Array(N).fill(0).map(() => new Array(C).fill(0));
    for (let i = 0; i < N; i++) {
      let total = 0;
      for (let c = 0; c < C; c++) {
        const val = weights[c]*gaussianPDF(data[i], means[c], variances[c]);
        resp[i][c] = val;
        total += val;
      }
      for (let c = 0; c < C; c++) {
        resp[i][c] /= (total + 1e-15);
      }
    }

    for (let c = 0; c < C; c++) {
      let sumResp = 0;
      let sumMean = 0;
      let sumVar = 0;
      for (let i = 0; i < N; i++) {
        sumResp += resp[i][c];
        sumMean += resp[i][c]*data[i];
      }
      const newMean = sumMean / (sumResp + 1e-15);

      for (let i = 0; i < N; i++) {
        let diff = data[i] - newMean;
        sumVar += resp[i][c]*diff*diff;
      }
      const newVar = sumVar/(sumResp + 1e-15);

      means[c] = newMean;
      variances[c] = Math.max(newVar, 1e-6);
      weights[c] = sumResp/N;
    }

    let logLik = 0;
    for (let i = 0; i < N; i++) {
      let p = 0;
      for (let c = 0; c < C; c++) {
        p += weights[c]*gaussianPDF(data[i], means[c], variances[c]);
      }
      logLik += Math.log(p + 1e-15);
    }

    paramsHistory.push({
      means: means.slice(),
      variances: variances.slice(),
      weights: weights.slice()
    });

    if (Math.abs(logLik - logLikOld) < tol) {
      break;
    }
    logLikOld = logLik;
  }
  return paramsHistory;
}
LLM സുതാര്യത

ഇന്ററാക്ടീവ് ഡെമോകൾ കോഡ് ചെയ്യാൻ ChatGPT ഉപയോഗിച്ചു. എല്ലാ എഴുത്തും എന്റെ സ്വന്തമാണ്.