<jupyter_start><jupyter_text>Формула Надарая–Ватсона $$\largea_h(x; X^l) = \frac{\sum\limits_{i=1}^l y_i K\left(\frac{\rho(x, x_i)}{h}\right)}{\sum\limits_{i=1}^l K\left(\frac{\rho(x, x_i)}{h}\right)}$$<jupyter_code>def kernelConst(x):
    return (np.abs(x) < 1.0) * 0.5

def kernelTriangle(x):
    xabs = np.abs(x)
    return (xabs < 1.0) * (1.0 - xabs)

def kernelEpanechnikov(x):
    return 0.75 * (1.0 - x ** 2.0) * (np.abs(x) < 1.0)

def kernelExp(x):
    return np.exp(-(x ** 2.0) / 2.0)

def kernelSqr(x):
    return (1 - x ** 2) ** 2 * (np.abs(x) < 1)


class nwClassifier():
    def __init__(self, h, kernel):
        self.h = h
        self.kernel = kernel

    def fit(self, x, y):
        self.x = x
        self.y = y
        
    def calc_kernels(self, point):
        return self.kernel(np.abs(self.x - point) / self.h)

    def predict(self, point):
        kernels = self.calc_kernels(point)
        return np.sum(self.y * kernels) / np.sum(kernels)

    def __str__(self):
        return "{} with h={} and kernelFunction={}".format(type(self).__name__, str(self.h), self.kernel.__name__)
def plot_classifier(classifier, plot_x):
    classifier.fit(X, Y)
    plot_y = np.vectorize(classifier.predict)(plot_x)
    plt.plot(plot_x, plot_y, label=str(classifier))
classifier1 = nwClassifier(1.5, kernelConst)
classifier2 = nwClassifier(3,   kernelTriangle)
classifier3 = nwClassifier(4.5, kernelEpanechnikov)
classifier1.fit(X, Y)
classifier2.fit(X, Y)
classifier3.fit(X, Y)
fig = plt.figure(figsize=(15, 10))
plt.scatter(X, Y)
plot_classifier(classifier1, plot_x)
plot_classifier(classifier2, plot_x)
plot_classifier(classifier3, plot_x)
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>LOWESS<jupyter_code>class lowessClassifier(nwClassifier):
    EPS = 0.1
    
    def calc_gamma(self):
        self.gamma = np.ones_like(self.x)
        aaa = np.zeros_like(self.x)
        errors = np.zeros_like(self.x)
        while (True):
            for i, x in enumerate(self.x):
                kernels = self.calc_kernels(x)
                kernels[i] = 0
                aaa[i] = np.sum(self.y * kernels) / np.sum(kernels)
            errors = np.abs(aaa - self.y)
            med6 = 6 * np.median(errors)
            new_gamma = self.kernel(errors / med6)
            norm = np.linalg.norm(new_gamma - self.gamma)
            self.gamma = new_gamma
            if (norm < self.EPS):
                break
            
    def fit(self, x, y):
        nwClassifier.fit(self, x, y)
        self.calc_gamma()
        
    def calc_kernels(self, point):
        return self.gamma * nwClassifier.calc_kernels(self, point)
classifier1 = lowessClassifier(2.5, kernelConst)
classifier2 = lowessClassifier(3.5, kernelTriangle)
classifier3 = lowessClassifier(5,   kernelEpanechnikov)
classifier4 = lowessClassifier(2.5, kernelEpanechnikov)
classifier1.fit(X, Y)
classifier2.fit(X, Y)
classifier3.fit(X, Y)
classifier4.fit(X, Y)
fig = plt.figure(figsize=(15, 10))
plt.scatter(X, Y)
plot_classifier(classifier1, plot_x)
plot_classifier(classifier2, plot_x)
plot_classifier(classifier3, plot_x)
plot_classifier(classifier4, plot_x)
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>Сглаживание B-сплайнами<jupyter_code>class SplineClassifier:
    
    T = 10
    
    def fit(self, X, Y):
        self.a0, self.a1, self.a2, self.a3 = [], [], [], []
        self.b0, self.b1, self.b2, self.b3 = [], [], [], []
        self.X = X
        
        for i in range(len(X) - 1):
            im1 = i - 1 if i > 0 else 0
            i1  = i + 1
            i2  = i + 2 if i + 2 < len(X) else i + 1 
            
            self.a0.append((X[im1] + 4 * X[i]+ X[i1]) / 6)
            self.a1.append((-X[im1] + X[i1]) / 2)
            self.a2.append((X[im1] - 2 * X[i] + X[i1]) / 2)
            self.a3.append((-X[im1] + 3 * X[i] - 3 * X[i1] + X[i2]) / 6)
            
            self.b0.append((Y[im1] + 4 * Y[i]+ Y[i1]) / 6)
            self.b1.append((-Y[im1] + Y[i1]) / 2)
            self.b2.append((Y[im1] - 2 * Y[i] + Y[i1]) / 2)
            self.b3.append((-Y[im1] + 3 * Y[i] - 3 * Y[i1] + Y[i2]) / 6) 
        
    def predict(self, x):
        if (x < self.X[0] or x > self.X[len(self.X) - 1]): 
            raise "illegal argument"
        
        for i in range(len(self.X) - 1):
            if (x <= self.X[i + 1]):
                break

        min_t = None
        min_x_dist = None
        for t in range(self.T + 1):
            t /= self.T
            
            x_pred = ((self.a3[i] * t + self.a2[i]) * t + self.a1[i]) *t + self.a0[i]
            x_dist = abs(x - x_pred)
            if (min_x_dist is None or x_dist < min_x_dist):
                min_x_dist = x_dist
                min_t = t
            
        return ((self.b3[i] * min_t + self.b2[i]) * min_t + self.b1[i]) * min_t + self.b0[i]
    
    def __str__(self):
        return "B-spline classifier"
splineClassifier = SplineClassifier()
splineClassifier.fit(X, Y)
fig = plt.figure(figsize=(15, 10))
plt.scatter(X, Y)
plot_classifier(splineClassifier, plot_x)
plt.legend()
plt.show()<jupyter_output><empty_output><jupyter_text>Оценка алгоритмов<jupyter_code>def rmse(X, Y, classifier):
    classifier.fit(X, Y)
    predict_vect = np.vectorize(lambda x : classifier.predict(x))
    Y_pred = predict_vect(X)
    return np.sqrt(np.sum((Y - Y_pred) ** 2) / len(Y))

def rmse_loo(X, Y, classifier):
    mse = 0
    for i in range(len(X))[1:-1]:
        X_1 = np.delete(X, i)
        Y_1 = np.delete(Y, i)
        
        classifier.fit(X_1, Y_1)
        y_pred = classifier.predict(X[i])
        
        mse += (Y[i] - y_pred) ** 2
    return math.sqrt(mse / len(X))
print(rmse(X, Y, classifier1))
print(rmse(X, Y, classifier2))
print(rmse(X, Y, classifier3))
print(rmse(X, Y, classifier4))
print(rmse(X, Y, splineClassifier))
print(rmse_loo(X, Y, classifier1))
print(rmse_loo(X, Y, classifier2))
print(rmse_loo(X, Y, classifier3))
print(rmse_loo(X, Y, classifier4))
print(rmse_loo(X, Y, splineClassifier))
h_range = np.linspace(2.4, 10, 9)
kernels = [kernelConst, kernelTriangle, kernelEpanechnikov, kernelExp, kernelSqr]

parameters = [(h, kernel) for h in h_range for kernel in kernels]
nw_classifiers = [nwClassifier(h, kernel) for h, kernel in parameters]
nw_rmses = [rmse_loo(X, Y, classifier) for classifier in nw_classifiers]
nw_argmin = np.argmin(nw_rmses)
lowess_classifiers = [lowessClassifier(h, kernel) for h, kernel in parameters]
lowess_rmses = [rmse_loo(X, Y, classifier) for classifier in lowess_classifiers]
lowess_argmin = np.argmin(nw_rmses)
fig = plt.figure(figsize=(15, 10))
plt.scatter(X, Y)
plot_classifier(splineClassifier, plot_x)
plot_classifier(nw_classifiers[nw_argmin], plot_x)
plot_classifier(lowess_classifiers[lowess_argmin], plot_x)
plt.legend()
plt.show()
print(rmse_loo(X, Y, nw_classifiers[nw_argmin]), rmse_loo(X, Y, lowess_classifiers[lowess_argmin]))<jupyter_output>30.83810381799322 30.353874787845243
{'fraction_non_alphanumeric': 0.15391254315304947, 'fraction_numerical': 0.03063866513233602, 'mean_word_length': 2.778804347826087, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 18, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '51241', 'license': 'MIT', 'n_tokens_mistral': 2944, 'n_tokens_neox': 2772, 'n_words': 540, 'path': 'non-parametric/non-parametric.ipynb', 'repo_name': 'artemohanjanyan/ml-hw', 'size': '6952'}