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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章