首先导入需要的包
import numpy as np # 科学计算库
from matplotlib import pyplot as plt # python 的2D绘图库
import sympy as sp #数学符号计算库
绘制指定直线
k,b = 2,5 # 斜率与截距
x = np.arange(0,10,1) # 随机生成点x的坐标
y = k*x+b # 直线方程
plt.figure() # 空白窗体
#plt.axis([0,9,5.0,22.5]) # 设置横纵坐标轴的范围
plt.xlabel('x')
plt.ylabel('y')
plt.title('y=kx+b')
plt.plot(x,y,color='b',linestyle='None',marker='o')
plt.show()
根据第一步产生的点产生服从正态分布的噪声点
u = 0 # 均值
f = 1 # 方差
x = np.arange(0,10,1)
k,b = 2,5 # 斜率与截距
y = k*x+b
len_x = len(x)
noisy_d = np.random.normal(u,f,len_x) # 噪声值
#noisy_d = np.random.randn(u,f,len_x) # 也可这样产生服从标准正态分布的点
noisy_y = y + noisy_d # 有噪点纵坐标
plt.figure()
plt.plot(x,y,color='b',linestyle='None',marker='o')
plt.plot(x,noisy_y,color='c',linestyle='None',marker='d')
plt.legend(['Inital Point','Noisy Point'],loc='upper left',ncol=1)
plt.show()
随机抽取噪声点的其中的两个点
m = [np.random.choice(x) for i in range(2)] # 随机生成两个数作为下表抽取点
x1,x2 = x[m[0]],x[m[1]]
noisy_y[m[0]],noisy_y[m[1]]
u = 0 # 均值
f = 1 # 方差
x = np.arange(0,10,1)
k,b = 2,5 # 斜率与截距
y = k*x+b
len_x = len(x)
noisy_d = np.random.normal(u,f,len_x) # 噪声值
#noisy_d = np.random.randn(u,f,len_x)
noisy_y = y + noisy_d
#x1,x2 = x[3],x[6] # 随机选取两个点的横坐标
m = [np.random.choice(x) for i in range(2)] # 随机生成两个数作为下表抽取点
x1,x2 = x[m[0]],x[m[1]]
plt.figure()
# 真实点,点的绘图可以使用散点图scatter
plt.plot(x,y,color='b',linestyle='None',marker='o')
# 含噪声的点
plt.plot(x,noisy_y,color='c',linestyle='None',marker='d')
# 随机选择的两个点
plt.plot(x1,noisy_y[m[0]],color='r',linestyle='None',marker='s')
plt.plot(x2,noisy_y[m[1]],color='r',linestyle='None',marker='s')
# 图标
plt.legend(['Inital Point','Noisy Point','Random Points'],loc='upper left',ncol=1)
plt.show()
根据上面随机选择的两个点绘制直线
u,f = 0,1 # 均值 方差
x = np.arange(0,10,1) # x坐标
k,b = 2,5 # 斜率与截距
y = k*x+b # 直线方程
len_x = len(x)
noisy_d = np.random.normal(u,f,len_x) # 噪声值
noisy_y = y + noisy_d # 噪声点的纵坐标
m = [np.random.choice(x) for i in range(2)] # 随机生成两个数作为下表抽取点
# 过两点确定一条直线
k = sp.symbols('k')
b = sp.symbols('b')
# 选择solve还会linsolve,返回结果的类型是不一样的
s = sp.solve([k*x[m[0]]+b-noisy_y[m[0]],k*x[m[1]]+b-noisy_y[m[1]]],(k,b))
# s为所求的k,b s的类型是字典
plt.figure()
plt.plot(x,y,color='b',linestyle='None',marker='o') # 真值点
plt.plot(x,noisy_y,color='c',linestyle='None',marker='d') # 噪声点
plt.plot(x[m[0]],noisy_y[m[0]],color='r',linestyle='None',marker='s') # 随机选择的噪声点
plt.plot(x[m[1]],noisy_y[m[1]],color='r',linestyle='None',marker='s')
plt.plot(x,s[k]*x+s[b],color='g',linewidth=2.5,linestyle='--') # 有两个噪声点确定的直线
plt.plot()
plt.legend(['Inital Point','Noisy Point','Random Points1','Random Points2','Line'],loc='upper left',ncol=1)
plt.show()
计算噪声点到直线的平均距离和方差
u = 0.5 # 均值
f = 1 # 方差
x = np.arange(0,10,1)
k,b = 2,5 # 斜率与截距
y = k*x+b
len_x = len(x)
noisy_d = np.random.normal(u,f,len_x) # 噪声值
k = sp.symbols('k')
b = sp.symbols('b')
noisy_y = y + noisy_d
m = [np.random.choice(x) for i in range(2)] # 随机生成两个数作为下表抽取点
s = sp.solve([k*x[m[0]]+b-noisy_y[m[0]],k*x[m[1]]+b-noisy_y[m[1]]],(k,b))
# 以上步骤求解了直线方程的k,b即确定了直线
# 求解平均距离和每个点到直线的距离,参数列表(点的x坐标,y坐标,直线方程的斜率,截距)
def avg_noisdir1(x,y,a,b):
L=[]
n,sum = len(x),0
for i in range(0,n):
up = np.abs(a*x[i]-y[i]+b)
down = np.power((a*a+1),1/2) # 因为sqrt不能对float进行开方,所以选择了power
one = up/down # 每个点到直线的距离
sum+=one # 总的距离
L.append(one) # 每一个的距离
return (sum/n,L)
avg_nd,L = avg_noisdir1(x,noisy_y,s[k],s[b])
# 求取方差
sum1 = 0
for i in range(len(L)):
sum1 += np.power((L[i]-avg_nd),2)
var = sum1/len(L)
print("方差:",var)
print("平均距离:",avg_nd)
plt.plot(x,L,color='b',linewidth=2.5,linestyle=':',marker='o')
s = []
for i in range(len(x)):
s.append(avg_nd)
plt.plot(x,s,linewidth=2.5,linestyle='-')
plt.grid(True)
plt.text(1,0,"var=%.8f"%var,fontsize=16)
plt.show()