python——绘图、插值、优化

本文首先使用matplotlib模块来绘制一些图形,包括:折线、柱状图、直方图等,其中内容涉及一些概率分布函数,包括均匀分布、高斯分布、泊松分布等。然后利用scipy中的interpolate模块进行一些插值操作。最后利用scipy中的optimize模块,用最小二乘法求解线性回归问题。

涉及的主要包括matplotlib(https://matplotlib.org/index.html)和scipy(https://scipy.org/)两个包。

1、基本绘图

(1)绘制正态分布概率密度函数

#!/usr/bin/python
# -*- coding:utf-8 -*-

import numpy as np
import math
import matplotlib as mpl
import matplotlib.pyplot as plt
from scipy import stats

#设置显示的字体,否则会乱码
mpl.rcParams['font.sans-serif'] = [u'SimHei']  #黑体,也可以是FangSong/KaiTi等电脑上的字体
mpl.rcParams['axes.unicode_minus'] = False  #对座标轴上的减号不进行设置,否则会乱码

mu = 0
sigma = 1
#取51个点,把中间的0包含进去
x = np.linspace(mu - 3 * sigma, mu + 3 * sigma, 51)
#手动计算概率密度值
y = np.exp(-(x - mu) ** 2 / (2 * sigma ** 2)) / (math.sqrt(2 * math.pi) * sigma)
print 'x = \n', x
print 'y = \n', y
#背景白色
plt.figure(facecolor = 'w')
#'g-'表示绿色实线绘制线条,'ro'表示红色圈绘制点;linewidth和markersize分别设置线的宽度和点的大小
plt.plot(x, y, 'g-', x, y, 'ro', linewidth = 2 , markersize = 8)
plt.xlabel('X', fontsize = 15)
plt.ylabel('Y', fontsize = 15)
plt.title(u'高斯分布', fontsize = 18)
plt.grid(True)
plt.show()

(2)绘制一些损失函数:logistic损失,Adaboost损失, Hinge损失,0/1损失

#!/usr/bin/python
# -*- coding:utf-8 -*-

import numpy as np
import math
import matplotlib as mpl
import matplotlib.pyplot as plt
from scipy import stats

#设置显示的字体,否则会乱码
mpl.rcParams['font.sans-serif'] = [u'SimHei']  #黑体,也可以是FangSong/KaiTi等电脑上的字体
mpl.rcParams['axes.unicode_minus'] = False  #对座标轴上的减号不进行设置,否则会乱码

plt.figure(figsize = (5, 4)) #设置图像大小,单位英寸
x  = np.linspace(-2, 3, 1001, dtype = np.float)
y_logit = np.log(1 + np.exp(-x)) / math.log(2)
y_boost = np.exp(-x)
y_01 = x < 0
y_hinge = 1 - x
y_hinge[y_hinge < 0] = 0
#label用于设置图例的名称
plt.plot(x, y_logit, 'r-', label = 'Logitic Loss', linewidth = 2)
plt.plot(x, y_boost, 'm--', label = 'Adaboost Loss', linewidth = 2)  #品红虚线
plt.plot(x, y_01, 'g-', label = '0/1 Loss', linewidth = 2)
plt.plot(x, y_hinge, 'b-', label = 'Hinge Loss', linewidth = 2)
plt.legend(loc = 'upper right')   #设置、显示图例
plt.xlabel('X', fontsize = 10)
plt.ylabel('Y', fontsize = 10)
plt.grid()
plt.savefig('1.png')
plt.show()

(3)绘制柱状图

#!/usr/bin/python
# -*- coding:utf-8 -*-

import numpy as np
import math
import matplotlib as mpl
import matplotlib.pyplot as plt
from scipy import stats

x = np.arange(1, 11)
y = x * 10
mpl.rcParams['font.sans-serif'] = [u'SimHei']  #黑体, 也可以是FangSong/KaiTi等电脑上的字体
mpl.rcParams['axes.unicode_minus'] = False  #对座标轴上的减号不进行设置,否则会乱码
plt.bar(x, y, width = 0.7)   #柱子的宽度设置为0.8(也是默认值)
plt.title(u'柱状图')
plt.xlabel('X')
plt.ylabel('Y')
plt.xlim(x.min() - 1, x.max() + 1) #限制座标范围
plt.grid()
plt.show()

(4)绘制均匀分布直方图,并验证中心极限定理

#!/usr/bin/python
# -*- coding:utf-8 -*-

import numpy as np
import math
import matplotlib as mpl
import matplotlib.pyplot as plt
from scipy import stats

mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False
#产生10000均匀分布的随机值
x = np.random.rand(10000)
plt.subplot(121) #'121'表示共一行两列,现在绘制第一幅
#bins参数表示横座标划分为30个区域,alpha表示透明度
plt.hist(x, bins = 30, color = 'g', alpha = 0.5, label = u'均匀分布')
plt.legend(loc = 'upper right')
plt.grid()
#验证中心极限定理
t = 1000  #叠加1000次
a = np.zeros(10000)
for i in range(t):
    a += np.random.uniform(-5, 5, 10000)
a /= t
plt.subplot(122) #绘制第二幅图
# normed参数使得概率密度和为1,即面积
his = plt.hist(a, bins = 30, color = 'g', normed = True, alpha = 0.5, label = u'均匀分布叠加')
#his是一个tuple,当normed为True时,his[0]表示对应的30个概率密度函数值数组。his[1]表是横座标边界数组
print 'area: \n', sum(his[0] * np.diff(his[1]))
plt.legend(loc = 'upper right')
plt.grid()
plt.show()

(5)绘制泊松分布直方图,并验证中心极限定理

#!/usr/bin/python
# -*- coding:utf-8 -*-

import numpy as np
import math
import matplotlib as mpl
import matplotlib.pyplot as plt
from scipy import stats

lamda = 10 #泊松分布参数
p = stats.poisson(lamda)
y = p.rvs(size = 1000) #random value从分布中随机取值
mi = 0
mx = 30
r = (mi, mx)
bins = 30
plt.figure(figsize = (6, 4), facecolor = 'w')
plt.subplot(121) #'121'表示共一行两列,现在绘制第一幅
plt.hist(y, bins = bins, range = r, color = 'g', alpha = 0.8, normed = True)
t = np.arange(mi, mx + 1)  #由于不包含,所以加1
plt.plot(t, p.pmf(t), 'ro-', lw = 2)  #Probability mass function,计算概率密度值
plt.grid()
# #验证中心极限定理
N = 1000 #叠加1000次
M = 10000
plt.subplot(122) #绘制第二幅图
a = np.zeros(M, dtype = np.float)
p = stats.poisson(lamda)
for i in range(N):
    a += p.rvs(size = M)
a /= N
plt.hist(a, bins = 20, normed = True, color = 'g', alpha = 0.8)
plt.grid()
plt.show()



2、利用scipy.interpolate进行中心插值、三次样条插值

#!/usr/bin/python
# -*- coding:utf-8 -*-

import numpy as np
import math
import matplotlib as mpl
import matplotlib.pyplot as plt
from scipy import stats
from scipy import interpolate

p = stats.poisson(5)
# 这里必须为float类型,否则在计算插值时不精准,会出现很大的误差,包括画出来的图
x = np.arange(0, 16, dtype = np.float)
y = p.pmf(x)
itp = interpolate.BarycentricInterpolator(x, y) #中心插值
x2 = np.linspace(x.min(), x.max(), 50)
y2 = itp(x2)
cs = interpolate.CubicSpline(x, y)  #三次样条插值
y3 = cs(x2)
plt.plot(x2, y3, 'm--', linewidth=5, label='CubicSpine')
plt.plot(x2, y2, 'g-', linewidth=3, label='Barycentric')
plt.plot(x, y, 'r-', linewidth = 1, label = 'Actural Value')
plt.legend(loc = 'upper right')
plt.grid()
plt.show()

3、利用scipy.optimize模块,用最小二乘法求解线性回归问题

#!/usr/bin/python
# -*- coding:utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import leastsq

def residual(t, x, y):
    return y - (t[0] * x ** 2 + t[1] * x + t[2])

x = np.linspace(-2, 2,50)
A, B, C = 2, 3, -1
y = (A * x ** 2 + B * x + C) + np.random.rand(len(x)) * 1
t = leastsq(residual, [0, 0, 0], args = (x, y))  #从[0, 0, 0]作为初始解
theta = t[0]
print '所谓的真实值:', A, B, C
print '最小二乘求解的二次拟合参数:', theta
y_hat = theta[0] * x ** 2 + theta[1] * x + theta[2]
plt.plot(x, y, 'r-', linewidth = 2, label = 'Actual')
plt.plot(x, y_hat, 'g--', linewidth = 2, label = 'Predict')
plt.legend(loc = 'upper right')
plt.grid()
plt.show()

参考文献:

1、matplotlib(https://matplotlib.org/index.html
2、scipy(https://scipy.org/
发布了37 篇原创文章 · 获赞 88 · 访问量 10万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章