এটি একটি আকর্ষণীয় সমস্যা! দুটি জিনিস এটিকে বিশেষ করে চ্যালেঞ্জিং করে তোলে:
- আমাদের কীভাবে দুটি পয়েন্ট সেট তুলনা করা উচিত? মেশিন লার্নিংয়ে ধ্রুপদী সমস্যাগুলির একটি নির্দিষ্ট সংখ্যক বৈশিষ্ট্য রয়েছে এবং এই বৈশিষ্ট্যগুলি বিনিময়যোগ্য নয়: উদাহরণস্বরূপ, বৈশিষ্ট্যযুক্ত
ageএবং পৃথক ব্যক্তিদের সাথে আমার ডেটা থাকতে পারে height(সেন্টিমিটারে)। প্রতিটি নমুনায় প্রত্যেকের জন্য একটি করে প্রবেশ রয়েছে এবং অবশ্যই এর (age, height) = (22, 180)মতো নয় (age, height) = (180, 22)। আপনার সমস্যার ক্ষেত্রেও সত্য নয়। একটি বিন্দুতে 3 থেকে 10 পয়েন্টের মধ্যে থাকে এবং দুটি বিন্দু সেটগুলির তুলনা করার সময় আমরা যে বিন্দুতে পয়েন্টগুলি প্রবেশ করি তাতে কোনও তাত্পর্য হওয়া উচিত নয়।
- আমরা কীভাবে ভবিষ্যদ্বাণী করব? বলুন আমরা আমাদের প্রশিক্ষণ সেট থেকে পয়েন্ট সেট বাছাই করার একটি উপায় খুঁজে পেয়েছি যা উপরের আপনার পয়েন্ট সেটগুলির অনুরূপ। আমরা সমস্যার মুখোমুখি হই যে আমাদের ভবিষ্যদ্বাণীটি অবশ্যই আপনার ছবিতে points পয়েন্টের একটি হতে হবে; তবে এই পয়েন্টগুলির মধ্যে কোনওটি একই পয়েন্ট সেটে থাকতে পারে।
আমাকে একটি অ্যালগরিদমের রূপরেখা দিন যা উভয় চ্যালেঞ্জ নিয়ে কাজ করে। পূর্বাভাসের নির্ভুলতা খুব ভাল নয়; তবে আপনি কীভাবে এটি উন্নত করতে পারেন তার কোনও উপায় দেখতে পাবেন। এবং কমপক্ষে এটি কিছু ভবিষ্যদ্বাণী করে , তাই না?
1. নমুনা অনুকরণ
অ্যালগরিদম পরীক্ষা করতে সক্ষম হতে, আমি ফাংশন লিখেছি যা নমুনা এবং লেবেল উত্পন্ন করে।
উত্পাদনের নমুনা:
প্রতিটি নমুনায় 3 থেকে 10 পয়েন্ট থাকে। পয়েন্ট সংখ্যা এলোমেলো, একটি অভিন্ন বিতরণ থেকে আঁকা। প্রতিটি পয়েন্ট ফর্ম হয় (x_coordinate, y_coordinate)। স্থানাঙ্কগুলি আবার এলোমেলো, একটি সাধারণ বিতরণ থেকে আঁকা।
import numpy as np
from random import randint
def create_samples(number_samples, min_points, max_points):
def create_single_sample(min_points, max_points):
n = randint(min_points, max_points)
return np.array([np.random.normal(size=2) for _ in range(n)])
return np.array([create_single_sample(min_points, max_points) for _ in range(number_samples)])
তৈরির লেবেল: খেলনার উদাহরণ হিসাবে, ধরে নেওয়া যাক যে পয়েন্টটি বেছে নেওয়ার নিয়মটি হল: সর্বদা নিকটতম বিন্দুটি বেছে নিন (0, 0), যেখানে 'নিকটতম' ইউক্যালিডিয়ান আদর্শের বিবেচনায় বোঝা উচিত।
def decision_function_minnorm(sample):
norms = np.apply_along_axis(np.linalg.norm, axis=1, arr=sample)
return sample[norms.argmin()]
def create_labels(samples, decision_function):
return np.array([decision_function(sample) for sample in samples])
আমরা এখন আমাদের ট্রেন এবং পরীক্ষার সেটগুলি তৈরি করতে পারি:
n_train, n_test = 1000, 100
dec_fun = decision_function_minnorm
X_train = create_samples(number_samples=n_train, min_points=3, max_points=10)
X_test = create_samples(number_samples=n_test, min_points=3, max_points=10)
y_train = create_labels(X_train, dec_fun)
y_test = create_labels(X_test, dec_fun)
২.হসডর্ফ দূরত্বের মাধ্যমে পয়েন্ট সেটগুলির তুলনা করুন
আসুন প্রথম সমস্যাটি মোকাবেলা করুন: আমাদের কীভাবে বিভিন্ন পয়েন্ট সেটগুলির তুলনা করা উচিত? পয়েন্ট সেটে পয়েন্টের সংখ্যা পৃথক। এছাড়াও মনে রাখবেন যে আমরা পয়েন্টগুলি যে ক্রমে পয়েন্টগুলি লিখেছি তা বিবেচনা করা উচিত নয়: পয়েন্ট সেটটির [(0,0), (1,1), (2,2)]সাথে তুলনা করলে পয়েন্ট সেটের তুলনায় একই ফল পাওয়া উচিত [(2,2), (0,0), (1,1)]। আমার পদ্ধতিটি হসডরফের দূরত্বের মাধ্যমে পয়েন্ট সেটগুলির তুলনা করা :
def hausdorff(A, B):
def dist_point_to_set(x, A):
return min(np.linalg.norm(x - a) for a in A)
def dist_set_to_set(A, B):
return max(dist_point_set(a, B) for a in A)
return max(dist_set_to_set(A, B), dist_set_to_set(B, A))
৩. কে-নিকটতম প্রতিবেশীদের মাধ্যমে ভবিষ্যদ্বাণী করা এবং গড়
আমাদের এখন পয়েন্ট সেটগুলির মধ্যে দূরত্বের ধারণা রয়েছে। এটি কে-নিকটতম প্রতিবেশীদের শ্রেণিবিন্যাস ব্যবহার করা সম্ভব করে তোলে: একটি পরীক্ষার পয়েন্ট সেট দেওয়া, আমরা kআমাদের প্রশিক্ষণের নমুনায় পয়েন্ট সেটগুলি পাই যা পরীক্ষার পয়েন্ট সেটটির সাথে সামান্যতম হাউসডর্ফ দূরত্বে থাকে এবং তাদের লেবেল প্রাপ্ত করে। এখন দ্বিতীয় সমস্যাটি আসে: আমরা কীভাবে এই kলেবেলগুলিকে পরীক্ষার পয়েন্ট সেটটির ভবিষ্যদ্বাণীতে পরিণত করব ? আমি সবচেয়ে সহজ পদ্ধতির গ্রহণ করেছি: লেবেলগুলি গড় করুন এবং টেস্ট পয়েন্ট সেটটিতে পয়েন্টটি পূর্বাভাস দিন যা গড়ের নিকটে থাকে।
def predict(x, num_neighbors):
# Find num_neighbors closest points in X_train.
distances_to_train = np.array([hausdorff(x, x_train) for x_train in X_train])
neighbors_idx = np.argpartition(distances_to_train, -num_neighbors)[-num_neighbors:]
# Get labels of the neighbors and calculate the average.
targets_neighbors = y_train[neighbors_idx]
targets_mean = sum(targets_neighbors) / num_neighbors
# Find point in x that is closest to targets_mean and use it as prediction.
distances_to_mean = np.array([np.linalg.norm(p - targets_mean) for p in x])
closest_point = x[distances_to_mean.argmin()]
return closest_point
4. পরীক্ষা
আমাদের অ্যালগরিদমের কর্মক্ষমতা পরীক্ষা করার জন্য সবকিছুই ঠিক আছে।
num_neighbors = 70
successes = 0
for i, x in enumerate(X_test):
print('%d/%d' % (i+1, n_test))
prediction = predict(x, num_neighbors)
successes += np.array_equal(prediction, y_test[i])
প্রদত্ত সিদ্ধান্ত ফাংশনের জন্য এবং num_neighbors = 70আমরা 84% এর পূর্বাভাসের সঠিকতা পাই get এটি মারাত্মকভাবে ভাল নয় এবং এটি অবশ্যই আমাদের সিদ্ধান্তের কার্যক্রমে নির্দিষ্ট, যা পূর্বাভাস দেওয়া মোটামুটি সহজ বলে মনে হয়।
এটি দেখতে, একটি ভিন্ন সিদ্ধান্ত ফাংশন সংজ্ঞায়িত করুন:
decision_function_maxaverage(sample):
avgs = (sample[:, 0] + sample[:, 1]) / 2
return sample[norms.argmin()]
এই ফাংশনটি ব্যবহার dec_fun = decision_function_maxaverageকরে ভবিষ্যদ্বাণীটির নির্ভুলতা 45% এ নেমে আসে। এটি দেখায় যে আপনার লেবেলগুলি উত্পন্ন করে এমন সিদ্ধান্তের বিধি সম্পর্কে চিন্তা করা কতটা গুরুত্বপূর্ণ। লোকেরা কেন নির্দিষ্ট পয়েন্টগুলি বেছে নেয় আপনার যদি ধারণা থাকে তবে এটি আপনাকে সেরা অ্যালগরিদম খুঁজে পেতে সহায়তা করবে।
এই অ্যালগরিদমকে উন্নত করার কয়েকটি উপায়: (১) হাউসডর্ফ দূরত্বের পরিবর্তে আলাদা দূরত্বের ফাংশন ব্যবহার করুন, (২) কে-নিকটবর্তী প্রতিবেশীদের চেয়ে আরও পরিশীলিত কিছু ব্যবহার করুন, (৩) কীভাবে নির্বাচিত প্রশিক্ষণ লেবেলগুলিকে পূর্বাভাসে পরিণত করা যায় তা উন্নতি করুন।