class.__dict__[‘attribute’]

class Test(object):
	def __init__(self):
		self.test = 1

t = Test()
print(t.__dict__['test'])

[vagrant@localhost python]$ python app.py
1

クラスのattributeには、class.__dict__[‘attribute’]というアクセス方法がある
呼び出しの方法で便利なのね。

pythonのclassととコンストラクタ

基本型

class Tea:
	def test(self):
		print("this is mugicha")

tea = Tea()
tea.test()

[vagrant@localhost python]$ python app.py
this is mugicha

メソッドの中で、インスタンスが生成されるときに自動的に呼び出されるメソッドのことをコンストラクタと言う。
コンストラクタを定義する際には、initというメソッドを作成する

class Tea:
	def __init__(self, num):
		self.num = num; 

	def test(self):
		print("this is mugicha v{}".format(self.num))

tea = Tea(2)
tea.test()

[vagrant@localhost python]$ python app.py
this is mugicha v2

selfはインスタンス自身を表す

最小二乗法

まず、散布図を作成します。

import matplotlib.pyplot as plt 

x = [1,2,3,4,5]
y = [1571,1630,1681,1603,1623]

plt.scatter(x, y)

合計距離の最小値を求める
D = 5Σ[t=1]*{yl – (w0 + w1xl)}^2

実装する

import numpy as np
import matplotlib.pyplot as plt 

x = np.array([1,2,3,4,5])
y = np.array([1571,1630,1681,1603,1623])

def reg1dim(x, y):
	a = np.dot(x, y)/ (x ** 2).sum()
	return a 

a = reg1dim(x, y)

plt.scatter(x, y, color="k")
plt.plot([0,x.max()], [0,a * x.max()])

ああああああああああ、全然やりたいことと違う
plotする時に、0からスタートすると駄目なのか。。

平均(mean)は、np.mean()だから、こうか?

x = np.array([1,2,3,4,5])
y = np.array([1571,1630,1681,1603,1623])

m = np.mean(y)

def reg1dim(x, y):
	a = np.dot(x, y)/ (x ** 2).sum()
	return a 

a = reg1dim(x, y)

plt.scatter(x, y, color="k")
plt.plot([0,x.max()], [m,a * x.max()])

あれ、なんかちゃうなー、 [m,a * x.max()]のところがおかしい。。

最小二乗法はこういう図になるはずなんだけど。。

確率変数

変数Xが確率Pで得られる確率は、P(X)
Xが飛び飛びの場合は、離散型確率変数
続くものは、連続型確率変数(身長、体重、経過時間など)
-> 正規分布、指数分布、スチューデントのt分布、パレート分布、ロジスティック分布などがある。

P(X) = f(x)

ヒストグラムはplt.hist(x)

import numpy as np 
import matplotlib.pyplot as plt 

x = np.random.normal(40, 10, 1000)

plt.hist(x)

離散確率分布は、ベル・カーブ=正規分布と呼ばれる釣鐘型に近づく。

確率

probabilityを指定する

import numpy as np 
n = np.random.choice(["a","b","c","d"], p=[0.8, 0.1, 0.05, 0.05])
print(n)

8割の確率で”a”が出力される
[vagrant@localhost python]$ python app.py
a

アルファベットではなく、数字で指定も可能

n = np.random.choice(4, p=[0.8, 0.1, 0.05, 0.05])
import numpy as np 
n = np.random.choice(4, size=10, p=[0.8, 0.1, 0.05, 0.05])
print(n)

numpyに限らず、ランダム関数は面白いね。
[vagrant@localhost python]$ python app.py
[0 0 0 0 0 0 3 0 0 0]

import numpy as np 
import pandas as pd 
import scipy.stats 

a = pd.Series([5,2,4,9])
print(a.describe())

[vagrant@localhost python]$ python app.py
count 4.00000
mean 5.00000
std 2.94392
min 2.00000
25% 3.50000
50% 4.50000
75% 6.00000
max 9.00000
dtype: float64

固有値と固有ベクトル

Ax = λEx
λを固有値、xを固有ベクトルと言う
(A – λE)x = 0
線形変換でベクトルの回転が起こらず、拡大・縮小のみで表現

2×2の行列の場合、固有値と固有ベクトルは必ず2ペア存在する。

import numpy as np

import numpy.linalg as LA
a = np.array([[1,0],[0,2]])
print(a)

print(LA.eig(a))

b = np.array([[2,5],[3, -8]])

print(b)
print(LA.eig(b))

[vagrant@localhost python]$ python app.py
[[1 0]
[0 2]]
(array([1., 2.]), array([[1., 0.],
[0., 1.]]))
[[ 2 5]
[ 3 -8]]
(array([ 3.32455532, -9.32455532]), array([[ 0.96665615, -0.40390206],
[ 0.25607791, 0.91480224]]))

なるほど、確かに2ペアあります。
LA.eig(x)が固有値、固有ベクトルの計算ですね。

c = np.random.randint(-10,10,size=(3,3))

w,v = LA.eig(c)
print(w)
print(v)

[vagrant@localhost python]$ python app.py
[ 4.97854958+7.44028681j 4.97854958-7.44028681j -9.95709916+0.j ]
[[ 0.08381118-0.45630028j 0.08381118+0.45630028j 0.41009134+0.j ]
[ 0.81099969+0.j 0.81099969-0.j -0.22863604+0.j ]
[ 0.30533936+0.18388344j 0.30533936-0.18388344j 0.88292166+0.j ]]

有向線分(矢印)の計算

要はベクトル計算です

from numpy import array

v1 = array([2,5])
v2 = array([3,9])

print(v1+v2)
print(v1-v2)
print(v1*v2)
print(v1.dot(v2))

掛け算(*)はarrayの要素同士の計算
内積を使うにはdotメソッドを使用する
[vagrant@localhost python]$ python app.py
[ 5 14]
[-1 -4]
[ 6 45]
51

スカラー倍だと、単純に係数を描ければOKですね。
print(v1*5)

内積: 対応する成分同士を掛け算してそれらの和を取る
a1b1 + a2b2 … + anbn = nΣi=1*aibi
内積の公式
= ||a|| ||b||*cosθ
a = (2,1), b = (1,3)の時、 = √5 * √10 * √2/2 = 5

内積が0のベクトルは直行
|a| |b| *cos90° = 0

シグモイド関数

ロジスティック回帰
-> 線形回帰式をシグモイド関数にかけて確率値と解釈

f(x) = 1 / (1 + exp^(-ax)) = a・exp(-ax) / (1 + exp^(-ax))^2

sympyを使っていく

import sympy

x = sympy.Symbol('x')
y = sympy.Symbol('y')

print(type(x))

[vagrant@localhost python]$ python app.py

変数を使っていく

import sympy

x = sympy.Symbol('x')
y = sympy.Symbol('y')
expr = x**2 + y + 1
print(expr)

ほう
[vagrant@localhost python]$ python app.py
x**2 + y

x = sympy.Symbol('x')
y = sympy.Symbol('y')
expr = x**2 + y + 1
print(expr.subs(x,3))
print(expr.subs(x,y))

代入も出来る。完全に再現できるわけね。当たり前か。
[vagrant@localhost python]$ python app.py
y + 10
y**2 + y + 1

xとyの代入も

print(expr.subs([(x,3),(y,2)]))

式の展開

expr = (x + 1)**2
print(sympy.expand(expr))

こいつは凄い
[vagrant@localhost python]$ python app.py
x**2 + 2*x + 1

因数分解

print(sympy.factor(x**3 - x**2 - 3*x + 3))
print(sympy.factor(x*y + x + y + 1))

[vagrant@localhost python]$ python app.py
(x – 1)*(x**2 – 3)
(x + 1)*(y + 1)
何これー

print(sympy.solve(x**2 - 3*x +2))
print(sympy.solve(x**2 + x + 1))

Iは虚数ですね。
[vagrant@localhost python]$ python app.py
[1, 2]
[-1/2 – sqrt(3)*I/2, -1/2 + sqrt(3)*I/2]

で、肝心の微分
来ましたねー

print(sympy.diff(x**3 + 2*x**2 + x))

expr = x**3 + y**2 - y
print(sympy.diff(expr, x))
print(sympy.diff(expr, y))

[vagrant@localhost python]$ python app.py
3*x**2 + 4*x + 1
3*x**2
2*y – 1

常微分

odeintは1階の常微分方程式を解くのに有効な積分器

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt 

def func(y, x, a):
	dydx = a*y
	return dydx

a = 1
y0 = 1
x = np.arange(0, 3, 0.01)

y = odeint(func, y0, x, args=(a,))

plt.plot(x, y, label='exp')
plt.legend()
plt.savefig('01')

import matplotlib.pyplot as plt
import numpy as np 
from scipy.integrate import odeint
from numpy import sin, cos, pi 
from matplotlib.animation import FuncAnimation 

def func(state, t):
	dydt = np.zeros_like(state)
	dydt[0] = state[1]
	dydt[1] = -(G/L)*sin(state[0])
	return dydt 

G = 9.8
L = 1

th1 = 30.0
w1 = 0.0

state = np.radians([th1, w1])

dt = 0.05
t = np.arange(0.0, 20, dt)

sol = odeint(func, state, t)

theta = sol[:, 0]
x = L * sin(theta)
y = - L * cos(theta)

fig = plt.figure()
ax = fig.add_subplot(111, autoscale_on=False, xlim=(-L, L), ylim=(-L, L))
ax.set_aspect('equal')
ax.grid()

line, = ax.plot([], [], 'o-', lw=2)

def animate(i):
	thisx = [0, x[i]]
	thisy = [0, y[i]]

	line.set_date(thisx, thisy)
	return line,

ani = FuncAnimation(fig, animate, frames=np.arange(0, len(t)), interval=25, blit=True)

plt.savefig('01')