CONTENTS

സി-യിലെ മെഷീൻ ലേണിംഗ് അടിസ്ഥാനങ്ങൾ, ഭാഗം 1Draft

എൻ-ഭാഗ പരമ്പരയിലേക്ക് (എൻ നിർണ്ണയിക്കേണ്ടതുണ്ട്) സ്വാഗതം. ഈ പരമ്പരയിൽ ഞങ്ങൾ അടിസ്ഥാനങ്ങളെ കുറിച്ച് മാത്രമായിരിക്കും, ഇന്റർനെറ്റിൽ ലഭ്യമായ മെഷീൻ ലേണിംഗ്, ന്യൂറൽ നെറ്റ്വർക്കുകളുമായി ബന്ധപ്പെട്ട ഉറവിടങ്ങളിൽ പലപ്പോഴും ഇത് കാണപ്പെടാത്തതായി എനിക്ക് തോന്നുന്നു.

ഞാൻ ആദ്യം ന്യൂറൽ നെറ്റ്വർക്കുകളെക്കുറിച്ച് അറിയാൻ തേടിയപ്പോൾ, എനിക്ക് കണ്ടെത്തിയത് ഇനിപ്പറയുന്ന ലേഖനങ്ങൾ മാത്രമായിരുന്നു:

  1. ട്രെയിനിംഗ് ഡാറ്റ എടുക്കുക, മോഡൽ പരിശീലിപ്പിക്കുക, പ്രവചനങ്ങൾ നടത്തുക എന്നിവ ചെയ്യുന്ന കുറച്ച് വരികളുടെ ടെൻസർഫ്ലോ കോഡ് കാണിക്കുന്നവ, അല്ലെങ്കിൽ
  2. നടപ്പിലാക്കൽ വിശദാംശങ്ങൾ നൽകിയെങ്കിലും, ഉത്തരങ്ങളേക്കാൾ കൂടുതൽ ചോദ്യങ്ങൾ ഉണ്ടാക്കിയ താഴ്ന്ന-ലെവൽ ട്യൂട്ടോറിയലുകൾ

അവയൊന്നും നിങ്ങളെ ന്യൂറോണിന്റെ അടിസ്ഥാനത്തിലേക്ക് നയിക്കുന്ന (വളരെ മടുപ്പിക്കുന്ന) പ്രാഥമിക ആശയങ്ങളിലൂടെ കൊണ്ടുപോകുന്നില്ല. ഈ പരമ്പരയിലൂടെ ഞാൻ ചെയ്യാൻ ഉദ്ദേശിക്കുന്നത് അതാണ്. ഇത് ചെയ്യും:

  1. ഒരു യുക്തിസഹമായ അളവ് ഗണിതശാസ്ത്രത്തോടെ അന്തർദൃഷ്ടി വളർത്തുക
  2. അത് കോഡിലേക്ക് വിവർത്തനം ചെയ്യുക, എല്ലാം സി-യിൽ, സീറോ ലൈബ്രറികളോടെ, അങ്ങനെ നടപ്പിലാക്കൽ വിശദാംഖങ്ങളൊന്നും മറഞ്ഞിരിക്കില്ല

മുൻഗണന അറിവ്

നിങ്ങളെക്കുറിച്ച് ഞാൻ താഴെപ്പറയുന്ന അനുമാനങ്ങൾ ചെയ്യുന്നു

  1. നിങ്ങൾക്ക് C, അല്ലെങ്കിൽ C-സദൃശമായ ഒരു ഭാഷ (C++, Java, C#, മുതലായവ) പരിചിതമാണ്.
  2. നിങ്ങൾക്ക് ഡെറിവേറ്റീവുകൾ (ഉദാ. ) ഭാഗിക ഡെറിവേറ്റീവുകൾ (ഉദാ. ) മനസ്സിലാക്കാം.

ആമുഖം

അപ്പോൾ നമ്മൾ ലീനിയർ റിഗ്രഷൻ പോലെ സാധാരണയായ ഒന്നിൽ നിന്നാണ് തുടങ്ങുന്നത്; ഇതിന് മെഷീൻ ലേണിങ്ങുമായി എന്ത് സംബന്ധമുണ്ട്? ഇത് അടുത്ത ചാറ്റ്ജിപിടി സൃഷ്ടിക്കാൻ എങ്ങനെ എന്നെ സഹായിക്കും??

ഒരു പഴഞ്ചൊല്ല് പറയാനായി, മെഷീൻ ലേണിങ് എന്താണെന്ന് ചാറ്റ്ജിപിടിയോട് ചോദിക്കാം:

“മെഷീൻ ലേണിങ്” എന്ന പദത്തിന് ഏറ്റവും അടിസ്ഥാനപരവും ഏറ്റവും ചുരുങ്ങിയതുമായ നിർവ്വചനം എന്താണ്?

മെഷീൻ ലേണിങ് എന്നത് ഡാറ്റയിൽ നിന്ന് പഠിച്ച്, ടാസ്ക്കുകളിൽ കമ്പ്യൂട്ടറുകളുടെ പ്രകടനം മെച്ചപ്പെടുത്തുന്ന ഒരു പ്രക്രിയയാണ് വ്യക്തമായി പ്രോഗ്രാം ചെയ്യാതെ തന്നെ (എന്റെ ഊന്നൽ).

ഈ പരമ്പരയുടെ ശ്രദ്ധ കേന്ദ്രീകരിക്കുന്ന ടാസ്ക് പ്രവചനം ആണ്. അതായത്, ചില ഇൻപുട്ട് ഡാറ്റ നൽകുമ്പോൾ ഫലങ്ങൾ എങ്ങനെ പ്രവചിക്കാമെന്ന് നമ്മുടെ മോഡലിനെ പഠിപ്പിക്കാൻ നമുക്ക് ആഗ്രഹമുണ്ട്. കൂടുതൽ ഡാറ്റ ഫീഡ് ചെയ്യുമ്പോൾ, അത് വ്യക്തമായ പ്രോഗ്രാമിംഗ് ഇല്ലാതെ തന്നെ, കാണാത്ത ഡാറ്റയിൽ പ്രവചനങ്ങൾ നടത്തുന്നതിൽ മെച്ചപ്പെടണം.

നമുക്ക് ആദ്യം ഒരു ലളിതമായ മോഡൽ നിർവ്വചിക്കാം.

ഏക ചര രേഖീയ മാതൃക

ഭാഗം 1-നുള്ള കോഡ്

ഈ മാതൃക ഒരു പ്രവചന ജോലിക്കായി നിർമ്മിച്ചതാണ്, അത് a) ഒരു ഇൻപുട്ട് ചരം മാത്രമുള്ളതും, b) ഒരു ഔട്ട്പുട്ട് ചരം മാത്രമുള്ളതും, c) ഇൻപുട്ട്, ഔട്ട്പുട്ട് ചരങ്ങൾ തമ്മിലുള്ള ബന്ധം ഏകദേശം രേഖീയവുമാണ്. ഇത് ഇനിപ്പറയുന്ന രീതിയിൽ നിർവ്വചിക്കപ്പെടുന്നു.

കോഡിൽ ഇങ്ങനെ:

struct linear_model {
	double w;
	double b;
};

double predict(struct linear_model m, double x) {
	return m.w * x + m.b; // y hat
}

നിങ്ങൾക്ക് കാണാനാകുന്നതുപോലെ, മാതൃകയെ നിർവ്വചിക്കുന്നത് , എന്നീ രണ്ട് പാരാമീറ്ററുകളാണ്, അവ ഇൻപുട്ട് ഉം പ്രവചിത ഔട്ട്പുട്ട് ഉം തമ്മിലുള്ള ബന്ധം നിർണ്ണയിക്കുന്നു. മാതൃക പരീക്ഷിക്കാൻ, നമുക്ക് കുറച്ച് ഡാറ്റ നിർമ്മിക്കാം.

// വീടിന്റെ വലിപ്പം, ചതുരശ്ര അടിയിൽ. നമ്മുടെ x ചരം
static double xs[] = {2360, 5272, 4592, 1966, 5926, 4944, 4671, 4419, 1630, 3185};
// അനുബന്ധ വീടിന്റെ വില, 1000 കണക്കിന് ഡോളറിൽ. നമ്മുടെ y ചരം
static double ys[] = {1359, 2576, 2418, 655, 2531, 2454, 2657, 1541, 1057, 1657};

data

ഇപ്പോൾ, വീടിന്റെ വലിപ്പം അടിസ്ഥാനമാക്കി വില പ്രവചിക്കുകയാണ് നമ്മുടെ ജോലി, അതിനാൽ ഒരു “ഉത്തമ” മാതൃക നിർവ്വചിക്കുന്ന , കണ്ടെത്തേണ്ടതുണ്ട്. എന്നാൽ “ഉത്തമം” എങ്ങനെ നിർവ്വചിക്കും? അത് ഏറ്റവും കുറച്ച് മോശം മാതൃക അല്ലെങ്കിൽ ഏറ്റവും ചെറിയ പിശക് ഉള്ള മാതൃകയാണ്. എന്നാൽ “പിശക്” എങ്ങനെ നിർവ്വചിക്കും? ഒരു വഴി

ഇതിലെ പ്രശ്നം, പിശക് കുറയ്ക്കുന്നത് നമ്മുടെ മാതൃകയ്ക്കുള്ള ഉത്തമ പ്രവചനം ആക്കി മാറ്റുമെന്നതാണ്, അതാണ് ഏറ്റവും കുറഞ്ഞ പിശക്, പക്ഷേ നാം തിരയുന്നത് അതല്ല. നമുക്ക് വേണ്ടത് ഒരു കോൺകേവ് പിശക് ഫംഗ്ഷൻ ആണ്, അതിനർത്ഥം അതിന് ഒരു പരിമിതമായ ഏറ്റവും കുറഞ്ഞ മൂല്യം ഉണ്ടായിരിക്കും, അത് യഥാർത്ഥത്തിൽ നല്ല പ്രകടനത്തെ പ്രതിഫലിപ്പിക്കും.

ഈ ഫംഗ്ഷന്റെ ഏറ്റവും കുറഞ്ഞ മൂല്യം ആണ്, ആണെങ്കിൽ . അതിനാൽ ഈ ഫംഗ്ഷൻ കുറയ്ക്കുന്നത് നമുക്ക് ഉത്തമ മാതൃക നൽകും. ഇനി മുതൽ, ഇതിനെ നഷ്ട ഫംഗ്ഷൻ എന്ന് വിളിക്കാം.

double loss(double y_hat, double y) {
	double diff = y_hat - y;
	return diff * diff;
}

എന്നാൽ നമുക്ക് എല്ലാ ഡാറ്റ സാമ്പിളുകളിലും നഷ്ടം കുറയ്ക്കണം. അതിനാൽ, എല്ലാ സാമ്പിളുകളിലും ശരാശരി നഷ്ടം എടുത്ത്, മൊത്തം പിശക് ഫംഗ്ഷൻ, എന്ന് വിളിക്കാം.

double error(struct linear_model model, double *xs, double *ys, int m) {
	double sum = 0.0;
	for (int i = 0; i < m; i++) {
		double y_hat = predict(model, xs[i]);
		double _loss = loss(y_hat, ys[i]);
		sum += _loss;
	}
	return sum / ((double) m);
}

ഇത് നമുക്ക് ഒരു സംഖ്യ നൽകുന്നു, അത് മാതൃക എത്ര മോശം ആണെന്ന് പറയുന്നു. ഇപ്പോൾ ഇത് പൂജ്യത്തിലേക്ക് കൊണ്ടുവരണം.

പിശക് കുറയ്ക്കൽ

നായിവ് രീതി

ഇത് ചെയ്യാനുള്ള ഒരു നായിവ് സമീപനം, ഒരു ശ്രേണി wകളും bകളും ഉപയോഗിച്ച് ധാരാളം linear_modelകൾ ജനറേറ്റ് ചെയ്ത്, നമ്മുടെ ഡാറ്റാസെറ്റിന് ഏറ്റവും ചെറിയ error ഏതിനാണെന്ന് കാണുക എന്നതായിരിക്കും.

struct linear_model
optimize_brute_force(double *xs, double *ys, int m)
{
		const double min = -1000.0, max = 1000.0;
		const int num_samples = 1e4;
		const double increment = (max - min) / ((double)num_samples);

		double min_error = 1e10;
		struct linear_model curr;
		struct linear_model optimal;
		// (w, b) in [min, max] x [min, max] വരെ ഇറേറ്റ് ചെയ്യുക
		// ഏറ്റവും കുറഞ്ഞ എററർ ഉള്ള ജോഡി കണ്ടെത്തുക
		for (int i = 0; i < num_samples; i++) {
				curr.w = min + increment * i;
				for (int j = 0; j < num_samples; j++) {
						curr.b = min + increment * j;

						double err = error(curr, xs, ys, m);
						if (err < min_error) {
								min_error = err;
								optimal = curr;
						}
				}
		}
		return optimal;
}

നമുക്ക് ഇത് നമ്മുടെ ഡാറ്റാസെറ്റിൽ റൺ ചെയ്യാം:

ബ്രൂട്ട് ഫോഴ്സ് ഒപ്റ്റിമൈസേഷൻ മോഡൽ: {w: 0.400000, b: 331.800000}
എററർ: 88068.508000

ഇത് എത്രമാത്രം നന്നായി പ്രെഡിക്റ്റ് ചെയ്യുന്നു?

ബ്രൂട്ട് ഫോഴ്സ് പ്രെഡിക്ഷൻ

വളരെ നല്ലത്! തന്നിരിക്കുന്ന മൂല്യങ്ങളിൽ നിന്ന് അല്ലെങ്കിൽ ഉള്ളിൽ തന്നെയാണ് സിദ്ധാന്തപരമായ ഒപ്റ്റിമം ഉള്ളതെന്ന് നമുക്കറിയാം.

എന്നാൽ സത്യം പറയാം: ഇതൊരു അങ്ങേയറ്റം സബ്-ഒപ്റ്റിമൽ പരിഹാരമാണ്. സാമ്പിളുകളുടെ എണ്ണത്തിനനുസരിച്ച് റൺടൈം ആണ്, നമുക്ക് രണ്ട് പാരാമീറ്ററുകൾ മാത്രമാണെങ്കിൽ ഉം ഉം ഉള്ളത് അത്ര മോശമല്ല. എന്നാൽ നമുക്ക്, 10 എണ്ണം ഉണ്ടെന്ന് കരുതുക, അപ്പോൾ അത് ആയിരിക്കും. ഒന്നിലധികം ഇൻപുട്ട് വേരിയബിളുകൾ ഉള്ളപ്പോൾ ഇത് വളരെ അപ്രായോഗികമാക്കുന്നു, ഏതാണ്ട് എല്ലാ യഥാർത്ഥ-ലോക പ്രശ്നങ്ങൾക്കും അതുണ്ട്.

ഗ്രേഡിയന്റ് ഡിസെന്റ്

അതിനാൽ എല്ലാ സംഖ്യകളും അക്ഷരാർത്ഥത്തിൽ ഊഹിക്കുന്നതിനേക്കാൾ ബുദ്ധിപൂർവ്വമായ ഒരു മാർഗ്ഗം കണ്ടെത്തേണ്ടതുണ്ട്.

മുന്നറിയിപ്പ്: കാൽക്കുലസ് (😱) മുന്നിലുണ്ട്

JK.

ഇത് ചിന്തിക്കുക: നിങ്ങളെ ഒരു കുന്നുകൾ നിറഞ്ഞ പ്രദേശത്തിന്റെ നടുവിൽ ഒരു ക്രമരഹിതമായ സ്ഥലത്ത് ഇട്ടിരിക്കുന്നു. എവിടെയോ ഒരു താഴ്വര ഉണ്ടെന്ന് നിങ്ങളോട് മുമ്പ് പറഞ്ഞിരുന്നു. ആ താഴ്വരയിൽ ഭക്ഷണവും വെള്ളവുമുണ്ട്. നിങ്ങൾ താഴ്വര കണ്ടെത്തിയില്ലെങ്കിൽ, നിങ്ങൾ മരിക്കും. കൂടാതെ, അങ്ങേയറ്റം കട്ടിയുള്ള മൂടൽമഞ്ഞുണ്ട്, അതിനാൽ നിങ്ങളുടെ ചുറ്റുമുള്ള 1 അടി ആരത്തിൽ മാത്രമേ നിങ്ങൾക്ക് കാണാൻ കഴിയൂ. ഏറ്റവും താഴ്ന്ന സ്ഥലത്താണ് താഴ്വര എന്ന് മാത്രമേ നിങ്ങൾക്കറിയാവൂ എങ്കിൽ, നിങ്ങൾക്ക് അത് എങ്ങനെ കണ്ടെത്താനാകും?

തന്ത്രം:

  1. നിങ്ങളുടെ ചുറ്റുമുള്ള നിലം നോക്കുക
  2. ഏത് ദിശയിലാണ് ഏറ്റവും കുത്തനെയുള്ള ഇറക്കം?
  3. ആ ദിശയിൽ ഒരടി നീങ്ങുക
  4. ഘട്ടം 1 ലേക്ക് പോകുക

താഴ്വര നിലനിൽക്കുന്നിടത്തോളം, ഇത് നിങ്ങളെ താഴെയെത്തിക്കും. പ്ലോട്ട് ട്വിസ്റ്റ്: ആ കുന്നുകൾ നിറഞ്ഞ പ്രദേശത്തിന് യഥാർത്ഥത്തിൽ പിശക് കുന്നുകൾ എന്നാണ് പേര്, നിങ്ങളുടെ തന്ത്രത്തിന് ഗ്രേഡിയന്റ് ഡിസെന്റ് എന്നാണ് പേര്! ഇനി ഗണിത സമയം.

ഗണിതം

ആദ്യം നമുക്ക് അൽപ്പം മാറ്റുന്നത് പിശകിൽ ഉണ്ടാക്കുന്ന ഫലം കാണേണ്ടതുണ്ട്. ഇത് യുമായി ബന്ധപ്പെട്ട പിശക് ഫങ്ഷന്റെ ഡെറിവേറ്റീവ് ആണ്. താഴെ കാണുന്നത് പരിഹരിക്കുക:

യും മാറ്റേണ്ടതുണ്ട്, അതിനാൽ യുമായി ബന്ധപ്പെട്ട പിശകിന്റെ ഡെറിവേറ്റീവ് കണക്കാക്കാം.

ഇവിടെ നാം ഗുണനനിയമം ഉം ചെയിൻ റൂൾ ഉം മാത്രമാണ് ഉപയോഗിക്കുന്നത്. അതിനാൽ ഈ രണ്ട് ഡെറിവേറ്റീവുകളും ഈ ചോദ്യത്തിന് ഉത്തരം നൽകുന്നു: “ഞാൻ വേരിയബിൾ അൽപ്പം വർദ്ധിപ്പിച്ചാൽ, പിശക് എത്രമാത്രം വർദ്ധിക്കും?”. ഇപ്പോൾ, പിശക് കുറയാൻ ആണ് നാം ആഗ്രഹിക്കുന്നത്, അതിനാൽ നാം വിപരീത ദിശ എടുക്കണം.

അൽഗോരിതം:

  1. ആരംഭ ബിന്ദു സജ്ജമാക്കുക:
  2. ഡെറിവേറ്റീവുകളുടെ വിപരീത ദിശയിൽ വേരിയബിളുകൾ നീക്കുക, സ്റ്റെപ്പ് സൈസ് ഉപയോഗിച്ച്:
  3. ഘട്ടം 2 ലേക്ക് പോകുക.

അവസാനം സംഭവിക്കുന്നത്, അവയുടെ ഏറ്റവും കുറഞ്ഞ മൂല്യത്തിൽ ആയിരിക്കുമ്പോൾ ഡെറിവേറ്റീവുകൾ 0 ലേക്ക് അടുക്കും എന്നതാണ്. കാരണം, ഏറ്റവും താഴ്ന്ന ബിന്ദുവിൽ (അല്ലെങ്കിൽ താഴ്വരയുടെ അടിയിൽ), നിങ്ങൾ ഏത് ദിശയിലേക്ക് പോയാലും പിശക് ഗണ്യമായി മാറില്ല.

കോഡ്

ആദ്യം ഡെറിവേറ്റീവുകൾ കണക്കാക്കുന്ന ഒരു ഫംഗ്ഷൻ എഴുതാം, ഇത് ഞങ്ങൾ gradient എന്ന സ്ട്രക്റ്റിലേക്ക് പാക്കേജ് ചെയ്യും.

struct gradient {
		double dJ_dw;
		double dJ_db;
};

struct gradient
calculate_gradient(struct linear_model model, double *xs, double *ys, int m)
{
		double dJ_dw = 0.0, dJ_db = 0.0;
		for (int i = 0; i < m; i++) {
				double y_hat = predict(model, xs[i]);
				double diff = y_hat - ys[i];
				dJ_db += diff;
				dJ_dw += diff * xs[i];
		}
		// ഗുണനം ലാഭിക്കാൻ ഞങ്ങൾ 2 എന്ന ഫാക്ടർ ആൽഫയിലേക്ക് തള്ളാൻ പോകുന്നു
		dJ_dw /= ((double)m);
		dJ_db /= ((double)m);
		return (struct gradient){.dJ_dw = dJ_dw, .dJ_db = dJ_db};
}

അടുത്തതായി, നമുക്ക് ഇത് ഉപയോഗിച്ച് ഗ്രേഡിയന്റ് ഡിസെന്റ് അൽഗോരിതം പ്രവർത്തിപ്പിക്കാം.

struct linear_model
optimize_gradient_descent(double *xs, double *ys, int m, int num_iterations, double alpha)
{
		struct linear_model model = {0.0, 0.0};
		for (int i = 0; i < num_iterations; i++) {
				struct gradient g = calculate_gradient(model, xs, ys, m);
				model.w -= alpha * g.dJ_dw;
				model.b -= alpha * g.dJ_db;
		}
		return model;
}

num_iterations എന്നതിന്റെയും alpha എന്നതിന്റെയും മൂല്യം പരീക്ഷണാത്മകമായി ക്രമീകരിക്കേണ്ടതുണ്ട്. alpha എന്നത് ലേണിംഗ് റേറ്റ് ആണ്. ഇത് വളരെ കുറവാണെങ്കിൽ, പിശക് താഴ്വരയിലെത്താൻ അൽഗോരിതത്തിന് കൂടുതൽ ഘട്ടങ്ങളും (കൂടുതൽ സമയവും) ആവശ്യമായി വരും. ഇത് വളരെ കൂടുതലാണെങ്കിൽ, അൽഗോരിതം കൺവേർജ് ചെയ്യില്ല. പിശക് കുന്നിന്മേൽ താഴ്വര അര മൈൽ വീതിയുള്ളതും ഒരു ദിശയിൽ മാത്രം ഒരു സമയം 1 മൈൽ നീങ്ങാൻ കഴിയുന്നതുമായിരുന്നുവെന്ന് കരുതുക. നിങ്ങൾക്ക് ഒരുപക്ഷേ അടിയിലെത്താൻ കഴിയില്ല.

നമുക്ക് num_iterations = 1e8, alpha = 1e-7 എന്നിവ പരീക്ഷിക്കാം

ഗ്രേഡിയന്റ് ഡിസെന്റ് ഒപ്റ്റിമൈസേഷൻ മോഡൽ: {w: 0.451677, b: 124.026882}
പിശക്: 85341.496159

ഗ്രേഡിയന്റ് ഡിസെന്റ് പ്രവചനം

കൊള്ളാം! ഈ രീതി ഉപയോഗിച്ച് നമുക്ക് വളരെ കുറഞ്ഞ പിശക് ലഭിച്ചു. പക്ഷേ, അതിലും പ്രധാനമായി, ഇതിന് ഒരു വലിയ ബിഗ്-ഒ റൺടൈം ഇല്ല. ഇത് ആണ്, ഇവിടെ എന്നത് ഇറ്ററേഷനുകളും എന്നത് പാരാമീറ്ററുകളുമാണ്.

ഇതാണ്—ഗ്രേഡിയന്റ് ഡിസെന്റ്—യന്ത്രങ്ങൾക്ക് സ്വയം പഠിക്കാൻ അനുവദിക്കുന്ന അടിസ്ഥാന അൽഗോരിതം. പ്രതീക്ഷിച്ച ഫലത്തിന് യോജിക്കുന്നതിന് അതിന്റെ ആന്തരിക മോഡൽ എങ്ങനെ ക്രമീകരിക്കണമെന്ന് പ്രോഗ്രാമിനോട് ഇത് പറയുന്നു.

ഉപസംഹാരവും അടുത്തത് എന്തെന്നും

അതിനാൽ നിങ്ങൾക്ക് കാണാനാകുന്നതുപോലെ, ഗ്രേഡിയന്റ് ഡിസെന്റ് വളരെ നല്ല യുക്തിയുള്ളതാണ്, കുറഞ്ഞത് നമുക്ക് ഇത്രയും ലളിതമായ ഒരു മോഡൽ ഉള്ളപ്പോഴെങ്കിലും. അടുത്ത ഭാഗത്ത്, കാര്യങ്ങൾ കുറച്ചുകൂടി സങ്കീർണ്ണമാകും, പക്ഷേ ഇപ്പോഴും നിയന്ത്രിക്കാനാകുന്നതായിരിക്കുമെന്ന് പ്രതീക്ഷിക്കാം. നമ്മൾ നോക്കുന്നത് മൾട്ടിവേറിയറ്റ് ലീനിയർ റിഗ്രഷൻ ആയിരിക്കും, അതിൽ ഔട്ട്പുട്ട് മൂല്യത്തെ ബാധിക്കുന്ന ഒന്നിലധികം വേരിയബിളുകൾ ഉണ്ടായിരിക്കും, അതായത് കിടപ്പുമുറികളുടെ എണ്ണം, പ്ലോട്ട് വലുപ്പം, നഗരത്തിൽ നിന്നുള്ള ദൂരം മുതലായവ.

ലേഖനത്തിൽ എന്തെങ്കിലും വ്യക്തമല്ലെങ്കിൽ, ദയവായി താഴെ കമന്റ് ചെയ്യുക, ഞാൻ വ്യക്തമാക്കാൻ പരമാവധി ശ്രമിക്കും. നിങ്ങൾക്ക് എന്തെങ്കിലും നിർദ്ദേശങ്ങളുണ്ടെങ്കിൽ, എന്നെ അറിയിക്കുക! വായിച്ചതിന് നന്ദി.

ഭാഗം 2-ലേക്ക് പോകുക

✦ ഈ ലേഖനത്തിന്റെ ആശയരൂപീകരണം, ഗവേഷണം, എഴുത്ത്, അല്ലെങ്കിൽ എഡിറ്റിംഗ് എന്നിവയിൽ LLM-കൾ ഉപയോഗിച്ചിട്ടില്ല.