python,核回归

# -*- coding: utf-8 -*-
"""
Created on Fri Apr  3 17:40:00 2020

@author: guangjie2333

"""

""""
库
"""  
import matplotlib.pyplot as plt
import numpy as np
from scipy.spatial.distance import cdist



""""
内部类
"""  
#核回归
class KernelRegression:
    
    def __init__(self,bandwidth):
        self.bandwidth = bandwidth;
    
    def fit(self,X,Y):
        self.X = X;
        self.Y = Y;
        return self;
    
    def predict(self,data):
        size = self.X.shape[0]; #X.shape 获取行列数矩阵-> (行数,列数).shape[0]即行数,.shape[1]为列数 
        #计算测试数据和原始数据的距离
        distance = cdist(self.X, data)**2; #两个向量对应之差的平方
        #将距离变换成kernel相似度
        kernel_dist = self.rbf_kernel(distance);
        sum = np.sum(kernel_dist,axis = 1).reshape((size,1));#axis = 0 按列 1 按行 ,.reshape(2,8) 以2行8列的形式显示
        weight = kernel_dist/sum;
        #得到预测值,其实就是加权和,距离近的权重大,距离远的权重小
        pred=weight.T.dot(self.Y)
        return pred
    
    def rbf_kernel(self,distance):
        return np.exp(-distance/(self.bandwidth**2))
    
    
    
    
""""
主函数
"""   

if __name__ == '__main__':    
    #训练数据
    X=np.linspace(0,10,100).reshape((100,1)) #生成横坐标数据
    #测试数据
    text_data=np.linspace(0,10,100).reshape((100,1))
    
    #真实值
    Y=np.sin(X)   
    #噪声
    noise=np.random.normal(0,1,Y.shape) #产生高斯噪声   
    #带噪声的数据
    Y_real=Y+0.4*noise
    
    KR=KernelRegression(0.5)
    KR.fit(X,Y_real)
    pred=KR.predict(text_data)
    plt.scatter(X,Y_real)
    plt.plot(X,Y,label ="True")
    plt.plot(text_data,pred,label="Prediction")
    plt.legend()
    plt.show()

当带宽bandwidth = 0.5时,已经接近真实曲线,但是在某些节点处不平滑。
python,核回归_第1张图片

当带宽bandwidth = 0.2时,
相比于bandwith = 0.5在某些地方波动更大
python,核回归_第2张图片

当带宽bandwidth = 0.8时
相比于0.5,在拐点处的平滑度更好,但是总体离真实值的极点更远
python,核回归_第3张图片

你可能感兴趣的:(python课堂实验)