സി-യിൽ മെഷീൻ ലേണിംഗ് ഫണ്ടമെന്റൽസ്, ഭാഗം 1Draft

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

ഞാൻ ആദ്യം ന്യൂറൽ നെറ്റ്വർക്കുകൾ പഠിക്കാൻ തുടങ്ങിയപ്പോൾ, എനിക്ക് കണ്ടെത്തിയത് ഇവയായിരുന്നു:

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

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

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

മുൻഗണനാ അറിവ്

നിങ്ങളെക്കുറിച്ച് ഞാൻ ഇനിപ്പറയുന്നവ അനുമാനിക്കുന്നു

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

ആമുഖം

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

ക്ലിഷേ ആകാൻ, ChatGPT-യോട് ചോദിക്കാം, മെഷീൻ ലേണിംഗ് എന്താണെന്ന് അത് എന്താണ് കരുതുന്നത്:

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

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

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

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

ഒറ്റ വേരിയബിൾ ലീനിയർ മോഡൽ

പാർട്ട് 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};
// അനുബന്ധ വീടിന്റെ വില, 1000s ഡോളറിൽ. ഞങ്ങളുടെ 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;
		// [min, max] x [min, max] എന്ന ശ്രേണിയിൽ (w, b) ഇറേറ്റേറ്റ് ചെയ്യുക
		// ഏറ്റവും കുറഞ്ഞ error ഉള്ള ജോഡി കണ്ടെത്തുക
		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;
}

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

Brute force optimization model: {w: 0.400000, b: 331.800000}
Error: 88068.508000

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

brute force prediction

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

എന്നാൽ സത്യം പറഞ്ഞാൽ: ഇതൊരു അത്യന്തം സബ്-ഒപ്റ്റിമൽ പരിഹാരമാണ്. സാമ്പിളുകളുടെ എണ്ണത്തിനനുസരിച്ച് റൺടൈം ആണ്, ഇത് രണ്ട് പാരാമീറ്ററുകൾ മാത്രമായ , എന്നിവയുള്ളപ്പോൾ വളരെ മോശമല്ല. എന്നാൽ നമുക്ക് 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 ന്റെ ഫാക്ടർ alpha-യിലേക്ക് തള്ളി ഒരു ഗുണനം ലാഭിക്കും
		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 എന്നത് ലേണിംഗ് റേറ്റ് ആണ്. ഇത് വളരെ കുറവാണെങ്കിൽ, അൽഗോരിതത്തിന് പിശക് താഴ്വരയിലെത്താൻ കൂടുതൽ ഘട്ടങ്ങളും (കൂടുതൽ സമയവും) ആവശ്യമാണ്. ഇത് വളരെ ഉയർന്നതാണെങ്കിൽ, അൽഗോരിതം കൺവേർജ് ചെയ്യില്ല. ഇത് പിശക് മലയുടെ താഴ്വര അര മൈൽ വീതിയുള്ളതും ഒരു ദിശയിൽ മാത്രം ഒരു മൈൽ ചലിക്കാൻ കഴിയുന്നതുമായിരുന്നെങ്കിൽ പോലെയാണ്. നിങ്ങൾക്ക് ഒരുപക്ഷേ താഴെയെത്താൻ കഴിയില്ല.

നമുക്ക് num_iterations = 1e8 ഉം alpha = 1e-7 ഉം ശ്രമിക്കാം.

Gradient descent optimization model: {w: 0.451677, b: 124.026882}
Error: 85341.496159

gradient descent prediction

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

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

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

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

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

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

✦ No LLMs were used in the ideation, research, writing, or editing of this article.