一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第22天,点击查看活动详情。
一、请随机生成1000个二维数据点,从中分别随机抽取约75%,50%,25%的数据点,并绘图展示抽取数据点的情况。
Code:
import matplotlib.pyplot as plt
import random as rd
x=[rd.gauss(0,1) for i in range(1000)]
y=[rd.gauss(0,1) for i in range(1000)]
x1=[]
y1=[]
for i in range(1000):
if rd.random() >= 0.25:
x1.append(x[i])
y1.append(y[i])
x2=[]
y2=[]
for i in range(1000):
if rd.random() >= 0.5:
x2.append(x[i])
y2.append(y[i])
x3=[]
y3=[]
for i in range(1000):
if rd.random() >= 0.75:
x3.append(x[i])
y3.append(y[i])
plt.subplot(221)
plt.title("all--"+str(1000))
plt.scatter(x, y, s=[0.5])
plt.subplot(222)
plt.title("75%--"+str(len(x1)))
plt.scatter(x1, y1, s=[0.5])
plt.subplot(223)
plt.title("50%--"+str(len(x2)))
plt.scatter(x2, y2, s=[0.5])
plt.subplot(224)
plt.title("25%--"+str(len(x3)))
plt.scatter(x3, y3, s=[0.5])
plt.show()
输出结果:
二、请计算生成正弦函数序列和余弦函数序列,并绘图展示。将正弦序列和余弦序列添加随机偏差(噪音)后再次绘图,观察噪音对数据的影响。
Code:
from math import *
import matplotlib.pyplot as plt
import numpy as np
x=np.arange(-6*pi,6*pi,0.1)
y1=np.sin(x)
y2=np.cos(x)
y3 = y1+np.random.randn(len(y1)) #加入噪声
y4 = y2+np.random.randn(len(y2))
plt.subplot(211)
plt.plot(x, y1)
plt.plot(x, y2)
plt.show()
plt.subplot(221)
plt.plot(x, y3)
plt.plot(x, y4)
plt.show()
输出结果:
三、验证几类变量变换的效果,包括:指数变换、>1幂变换、对数变换、(0,1)幂变换、<0幂变换、正弦变换,绘图演示各类变换的效果。
Code:
import matplotlib.pyplot as plt
import numpy as np
x= np.linspace(1,50,100)
y1=np.exp(x)
y2=x**3
y3=np.log10(x)
y4=np.sqrt(x)
y5=1/x
y6=np.sin(x)
plt.subplot(121)
plt.title(r"$y=x^3$")
plt.plot(x, y2)
plt.subplot(122)
plt.title(r"$y=log_{10}x$")
plt.plot(x, y3)
plt.show()
plt.subplot(121)
plt.title(r"$y=\sqrt{x}$")
plt.plot(x, y4)
plt.subplot(122)
plt.title(r"$y=\frac{1}{x}$")
plt.plot(x, y5)
plt.show()
plt.subplot(121)
plt.title(r"$y=sin(x)$")
plt.plot(x, y6)
plt.subplot(122)
plt.title(r"$y=e^x$")
plt.plot(x, y1)
plt.show()
输出结果:
四、标准变换
为了提出变量量纲对数据分析的影响,经常需要对变量进行一定的变换,其中常用的一种是标准化(normalization)变换
(即将数据序列转换为期望值为0和方差为1的序列),转换公式为:
其中/x为序列的均值,Sx为序列的样本标准差,即
请随机生成一个序列,并生成它的标准化序列,将两个序列通过绘图展示出来。 Code:
from math import *
import matplotlib.pyplot as plt
import numpy as np
y1=np.random.normal(1000,200,1000)
std = sqrt(sum((y1-np.average(y1))**2)/(len(y1)-1))
y2 = (y1 - np.average(y1))/std
print(np.mean(y2),np.std(y2))
plt.subplot(211)
plt.plot(y1)
plt.subplot(212)
plt.plot(y2)
plt.show()
输出结果(其中随机生成的序列为期望值1000,标准差200,长度1000的正态分布序列):
五、距离计算
向量间的闵可夫斯基距离的定义如下:
其中当r=1时成为街区距离,为不同分量差绝对值的和
当r=2时即为欧几里得距离
当r=+infinity时,等于所有分量差绝对值中最大的一个
编写函数实现三种距离的计算,并对下面4个二维向量分别计算其三种距离定义的距离矩阵。
Code:
from math import *
import matplotlib.pyplot as plt
import numpy as np
#计算街区距离
def city_dist(x,y):
return sum([abs(x[i]-y[i]) for i in range(len(x))])
#计算欧几里德距离
def euclid_dist(x,y):
return sqrt(sum([(x[i]-y[i])**2 for i in range(len(x))]))
#计算max距离
def max_dist(x , y):
return max([abs(x[i]-y[i]) for i in range(len(x))])
#计算矩阵行向量之间的距离
def matrix_row_dist(x,dist):
rc = np.size(x,axis=0)
rel = np.linspace(0.0,0.0,rc*rc).reshape(rc,rc)
for i in range(rc):
for j in range(i,rc):
rel[j,i]=rel[i,j]=dist(x[i],x[j])
return rel
X = np.array([[0,2],[2,0],[3,1],[5,1]])
print("Data Matrix:")
print(X)
print("City Blocik Distance")
print(matrix_row_dist(X,city_dist))
print("Euclid Distance:")
print(matrix_row_dist(X,euclid_dist))
print("Distance with Element Max Difference:")
print(matrix_row_dist(X,max_dist))
输出结果如下:
Data Matrix:
[[0 2]
[2 0]
[3 1]
[5 1]]
City Blocik Distance
[[0. 4. 4. 6.]
[4. 0. 2. 4.]
[4. 2. 0. 2.]
[6. 4. 2. 0.]]
Euclid Distance:
[[0. 2.82842712 3.16227766 5.09901951]
[2.82842712 0. 1.41421356 3.16227766]
[3.16227766 1.41421356 0. 2. ]
[5.09901951 3.16227766 2. 0. ]]
Distance with Element Max Difference:
[[0. 2. 3. 5.]
[2. 0. 1. 3.]
[3. 1. 0. 2.]
[5. 3. 2. 0.]]
六、二元变量的相似度衡量可以使用简单匹配系数(SMC)或Jaccard系数
设x和y是两个对象,都由n个二元属性组成,这样两个对象可生成如下四个量(频率):
简单匹配系数(Simple Matching Coefficient, SMC)定义为:
Jaccard系数(Jaccard Coefficient)的定义为:
编写两个函数分别实现连个系数的计算,并生成两个随机序列调用函数计算。 Code:
import numpy as np
import random as rd
def smc(x,y):
f = np.linspace(0,0,4,dtype="int32").reshape(2,2)
for i in range(len(x)):
f[x[i],y[i]]+=1
return float(f[1,1]+f[0,0])/(f[0,0]+f[0,1]+f[1,0]+f[1,1])
def jc(x,y):
f = np.linspace(0, 0, 4, dtype="int32").reshape(2, 2)
for i in range(len(x)):
f[x[i], y[i]] += 1
return float(f[1,1]/(f[0,1]+f[1,0]+f[1,1]))
a=np.linspace(0,0,100,dtype='int32')
b=a.copy()
for i in range(100):
if rd.random() >0.5:
a[i]=1
for i in range(100):
if rd.random() >0.5:
b[i]=1
print("Vector a is:")
print(a)
print("Vector b is:")
print(b)
print("SCM coefficient:")
print(smc(a,b))
print("Jaccard coefficient:")
print(jc(a,b))
输出结果:
Vector a is:
[1 1 1 0 1 1 0 0 0 0 0 0 0 1 0 1 0 1 0 1 1 0 1 1 1 0 1 0 0 1 0 0 1 1 0 1 0
0 0 1 1 0 0 0 0 0 0 1 1 1 0 1 1 1 0 1 0 1 0 1 1 1 1 0 1 1 0 1 0 0 1 0 0 1
0 0 1 0 0 1 1 0 0 1 1 1 1 0 0 1 1 1 1 1 1 0 0 1 1 1]
Vector b is:
[0 0 0 0 1 0 0 1 1 1 1 0 1 1 1 1 1 0 1 0 1 1 0 1 0 0 1 1 1 1 1 1 1 1 0 1 0
1 1 1 0 0 0 0 1 0 1 0 0 0 0 1 1 0 1 0 0 1 0 1 1 0 0 1 0 1 1 0 1 1 0 1 0 0
1 1 1 0 1 0 1 0 1 1 1 1 1 0 0 0 0 0 1 1 0 1 1 0 1 0]
SCM coefficient:
0.44
Jaccard coefficient:
0.3170731707317073
七、余弦相似度
余弦相似度是衡量数值向量相似度的一种方法,设x和y是两个n元向量,则余弦相似度定义为
编写函数实现余弦相似度的计算,并调用函数计算下面两个向量的余弦相似度。
Code:
from math import *
#计算两个向量的内积
def inner_prod(x,y):
return sum([x[i]*y[i] for i in range(len(x))])
#计算向量的模
def vec_mode(x):
return sqrt(inner_prod(x,x))
#计算夹角余弦值
def vec_cos(x,y):
return float(inner_prod(x,y))/(vec_mode(x)*vec_mode(y))
a=[3,2,0,5,0,0,0,2,0,0]
b=[1,0,0,0,0,0,0,1,0,2]
print(r"Vector Angel Cosine:{}".format(vec_cos(a,b)))
输出结果:
Vector Angel Cosine:0.314970394174356
八、mahalanobis距离
从统计学的观点看,计算多维向量的距离时,应该使用mahalanobis距离,其定义为:
属性间协方差的定义如下所示:
实现欧几里得距离、使用方差逆矩阵调整的距离、使用协方差逆矩阵调整的距离三类距离的计算函数,并构造两个随机向量验证三种距离的不同。
Code:
参考输出结果: