I am working on the file "Lecture/12. Scikit-Learn & statsmodels 패키지 소개/4) Scikit-Learn 패키지의 샘플 데이터 - classification용.ipynb".
The first task is:
Olivetti faces
fetch_olivetti_faces()

얼굴 인식 이미지
Can you write Python code for it?

from sklearn.datasets import fetch_olivetti_faces
olivetti = fetch_olivetti_faces()
print(olivetti.DESCR)
print(olivetti.keys())

N=2; M=5;
fig = plt.figure(figsize=(8,5))
plt.subplots_adjust(top=1, bottom=0, hspace=0, wspace=0.05)
klist = np.random.choice(range(len(olivetti.data)), N * M)
for i in range(N):
    for j in range(M):
        k = klist[i*M+j]
        ax = fig.add_subplot(N, M, i*M+j+1)
        ax.imshow(olivetti.images[k], cmap=plt.cm.bone);
        ax.grid(False)
        ax.xaxis.set_ticks([])
        ax.yaxis.set_ticks([])
        plt.title(olivetti.target[k])
plt.tight_layout()
plt.show()


I am working on the file "Lecture/12. Scikit-Learn & statsmodels 패키지 소개/4) Scikit-Learn 패키지의 샘플 데이터 - classification용.ipynb".
The first task is:
Scikit-Learn 패키지의 샘플 데이터 - classification용
Iris Dataset
load_iris()

https://en.wikipedia.org/wiki/Iris_flower_data_set
R.A Fisher의 붓꽃 분류 연구
관찰 자료
꽃받침 길이(Sepal Length)
꽃받침 폭(Sepal Width)
꽃잎 길이(Petal Length)
꽃잎 폭(Petal Width)
종
setosa
versicolor
virginica
Can you write Python code for it?

from sklearn.datasets import load_iris
iris = load_iris()
print(iris.DESCR)

df = pd.DataFrame(iris.data, columns=iris.feature_names)
sy = pd.Series(iris.target, dtype="category")
sy = sy.cat.rename_categories(iris.target_names)
df['species'] = sy
df.tail()

sns.pairplot(df, hue="species")
plt.show()


I am working on the file "Lecture/12. Scikit-Learn & statsmodels 패키지 소개/4) Scikit-Learn 패키지의 샘플 데이터 - classification용.ipynb".
The first task is:
mldata.org repository
fetch_mldata()

http://mldata.org
public repository for machine learning data, supported by the PASCAL network
홈페이지에서 data name 을 검색 후 key로 이용

MNIST 숫자 필기인식 자료

https://en.wikipedia.org/wiki/MNIST_database
Mixed National Institute of Standards and Technology (MNIST) database
0-9 필기 숫자 이미지
28x28 pixel bounding box
anti-aliased, grayscale levels
60,000 training images and 10,000 testing images
Can you write Python code for it?

from sklearn.datasets.mldata import fetch_mldata
mnist = fetch_mldata('MNIST original')
mnist.keys()

N=2; M=5;
fig = plt.figure(figsize=(8,5))
plt.subplots_adjust(top=1, bottom=0, hspace=0, wspace=0.05)
klist = np.random.choice(range(len(mnist.data)), N * M)
for i in range(N):
    for j in range(M):
        k = klist[i*M+j]
        ax = fig.add_subplot(N, M, i*M+j+1)
        ax.imshow(mnist.data[k].reshape(28, 28), cmap=plt.cm.bone, interpolation="nearest");
        ax.grid(False)
        ax.xaxis.set_ticks([])
        ax.yaxis.set_ticks([])
        plt.title(mnist.target[k])
plt.tight_layout()
plt.show()


I am working on the file "Lecture/12. Scikit-Learn & statsmodels 패키지 소개/4) Scikit-Learn 패키지의 샘플 데이터 - classification용.ipynb".
The first task is:
뉴스 그룹 텍스트
fetch_20newsgroups(): 20 News Groups text
Can you write Python code for it?

from sklearn.datasets import fetch_20newsgroups
newsgroups = fetch_20newsgroups(subset='all')
print(newsgroups.description)
print(newsgroups.keys())

from pprint import pprint
pprint(list(newsgroups.target_names))

print(newsgroups.data[1])
print("=" * 80)
print(newsgroups.target_names[newsgroups.target[1]])


I am working on the file "Lecture/13. 데이터 전처리/1) Scikit-Learn의 전처리 기능.ipynb".
The first task is:
DictVectorizer
DictVectorizer는 사전 형태로 되어 있는 feature 정보를 matrix 형태로 변환하기 위한 것으로  feature_extraction 서브 패키지에서 제공한다.
사전 정보는  텍스트 정보에서 corpus 상의 각 단어의 사용 빈도를 나타내는 경우가 많다.

http://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.DictVectorizer.html
Can you write Python code for it?

from sklearn.feature_extraction import DictVectorizer
v = DictVectorizer(sparse=False)
D = [{'foo': 1, 'bar': 2}, {'foo': 3, 'baz': 1}]
X = v.fit_transform(D)
X

v.feature_names_

v.inverse_transform(X)

v.transform({'foo': 4, 'unseen_feature': 3})

instances = [ {'city': 'New York'}, {'city': 'San Francisco'}, {'city': 'Chapel Hill'} ]
v.fit_transform(instances)

v.feature_names_


I am working on the file "Lecture/13. 데이터 전처리/1) Scikit-Learn의 전처리 기능.ipynb".
The first task is:
FunctionTransformer
FunctionTransformer 입력값 $x$를 다항식이 아닌 사용자가 원하는 함수를 사용하여 변환한다.
$$ x \;\; \rightarrow \;\; [ f_1(x),  f_2(x),  f_3(x),  \cdots ] $$

http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.FunctionTransformer.html
Can you write Python code for it?

from sklearn.preprocessing import FunctionTransformer
def all_but_first_column(X):
    return X[:, 1:]

X = np.arange(12).reshape(4, 3)
X

FunctionTransformer(all_but_first_column).fit_transform(X)


I am working on the file "Lecture/13. 데이터 전처리/1) Scikit-Learn의 전처리 기능.ipynb".
The first task is:
Imputer
Imputer는 누락된 정보를 채우는 변환이다. 다음과 같은 인수를 제공한다.

missing_values : 누락 정보
strategy : 채우는 방법. 디폴트는 "mean"
"mean": 평균
"median": 중앙값

"most_frequent": 최빈값

http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.Imputer.html
Can you write Python code for it?

from sklearn.preprocessing import Imputer
imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
imp.fit_transform([[1, 2], [np.nan, 3], [7, 6]])


I am working on the file "Lecture/13. 데이터 전처리/1) Scikit-Learn의 전처리 기능.ipynb".
The first task is:
Label Binarizer
Label Binarizer는 one-hot-encoder와 유사하지만 실제로 사용된 클래스만 인코딩에 사용하며 0/1 대신 사용할 값을 지정할 수 있다.

http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelBinarizer.html
Can you write Python code for it?

from sklearn.preprocessing import LabelBinarizer
lb = LabelBinarizer()
lb.fit([1, 2, 6, 1, 2])

lb.classes_

lb.transform([1, 6])

lb.fit_transform(['yes', 'no', 'no', 'yes'])

lb = LabelBinarizer(neg_label=-1)
lb.fit_transform(['yes', 'no', 'no', 'yes'])


I am working on the file "Lecture/13. 데이터 전처리/1) Scikit-Learn의 전처리 기능.ipynb".
The first task is:
Label Encoding
Label Encoding 은 실제 값에 상관없이 $0$ ~ $K-1$ 까지의 정수로 변환한다. 변환된 규칙은 classes_ 속성에서 확인할 수 있다. 또한 역변환을 위한 inverse_transform 메서드도 지원한다.

http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html
Can you write Python code for it?

from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit([1, 2, 2, 6])
le.classes_

le.transform([1, 1, 2, 6])

le.inverse_transform([0, 0, 1, 2])

le.fit(["paris", "paris", "tokyo", "amsterdam"])
le.classes_

le.transform(["tokyo", "tokyo", "paris"])

list(le.inverse_transform([2, 2, 1]))


I am working on the file "Lecture/13. 데이터 전처리/1) Scikit-Learn의 전처리 기능.ipynb".
The first task is:
PolynomialFeatures
PolynomialFeatures 입력값 $x$를 다항식으로 변환한다.
$$ x \;\; \rightarrow \;\; [ 1, x, x^2, x^3, \cdots ] $$
또는
$$ [x_1, x_2] \;\; \rightarrow \;\; [ 1, x_1, x_2, x_1 \cdot x_2 ] $$
다음과 같은 입력 인수를 가진다.

degree : 차수
interaction_only: 상호 작용 생성 여부
include_bias : 상수항 생성 여부

http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PolynomialFeatures.html
Can you write Python code for it?

from sklearn.preprocessing import PolynomialFeatures
X = np.arange(6).reshape(3, 2)
X

poly = PolynomialFeatures(2)
poly.fit_transform(X)

poly = PolynomialFeatures(interaction_only=True)
poly.fit_transform(X)


I am working on the file "Lecture/13. 데이터 전처리/1) Scikit-Learn의 전처리 기능.ipynb".
The first task is:
Scikit-Learn의 전처리 기능
Scikit-Learn 패키지의 전처리 기능은 크게 다음과 같은 4가지이다. 이 기능들은 preprocessing 서브 패키지와 feature_extraction 서브 패키지에 구현되어 있다.

스케일링(Scaling): 자료의 크기 조정
scale, StandardScaler
normalize, Normalizer
minmax_scale, MinMaxScaler
maxabs_scale, MaxAbsScaler

robust_scale, RobustScaler

인코딩(Encoding): 카테고리 값의 정수 표현

binarize, Binarizer
label_binarize, LabelBinarizer
LabelEncoder
OneHotEncoder

DictVectorizer

Imputation: 결손 데이터(missing data) 처리

Imputer

Transform: 데이터 변환

PolynomialFeatures
FunctionTransformer

스케일링
스케일링은 자료 집합에 적용되는 전처리 과정으로 모든 자료에 다음과 같은 선형 변환을 적용하여 전체 자료의 분포를 평균 0, 분산 1이 되도록 만드는 과정이다.
$$ x' = c_0 + c_x x $$
스케일링은 자료의 overflow나 underflow를 방지하고 독립 변수의 공분산 행렬의 condition number 를 감소시켜 최적화 과정에서의 안정성 및 수렴 속도를 향상시킨다.
Scikit-Learn에서는 스케일링을 위한 함수와 클래스를 각각 제공한다. 스케일링 함수는 다음과 같다.

scale(X): 표준정상분포 Standard Normal Gaussian 기본 스케일
robust_scale(X): median, interquartile range 사용. outlier 영향 최소화
minmax_scale(X): 최대/최소값 사용
maxabs_scale(X): 최대절대값 사용
Can you write Python code for it?

from sklearn.preprocessing import scale, robust_scale, minmax_scale, maxabs_scale

x = (np.arange(10, dtype=np.float) - 3).reshape(-1, 1)
df = pd.DataFrame(np.hstack([x, scale(x), robust_scale(x), minmax_scale(x), maxabs_scale(x)]),
                  columns=["x", "scale(x)", "robust_scale(x)", "minmax_scale(x)", "maxabs_scale(x)"])
df

from sklearn.datasets import load_iris
iris = load_iris()

data1 = iris.data
data2 = scale(iris.data)

print("old mean:", np.mean(data1, axis=0))
print("old std: ", np.std(data1, axis=0))
print("new mean:", np.mean(data2, axis=0))
print("new std: ", np.std(data2, axis=0))

sns.jointplot(data1[:,0], data1[:,1])
plt.show()

sns.jointplot(data2[:,0], data2[:,1])
plt.show()


I am working on the file "Lecture/13. 데이터 전처리/1) Scikit-Learn의 전처리 기능.ipynb".
The first task is:
만약 추후에 파이프 라인을 이용하게 된다면 스케일링을 함수가 아닌 스케일러 클래스로 구현해야 한다.
Scaler 클래스의 사용 방법은 다음과 같다.

클래스 객체 생성
fit() 메서드와 트레이닝 데이터를 사용하여 변환 계수 추정
transform() 메서드를 사용하여 실제로 자료를 변환

또는 fit_transform() 메서드를 사용하여 계수 추정과 자료 변환을 동시에 실행할 수도 있다.
Can you write Python code for it?

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
scaler.fit(data1)
data2 = scaler.transform(data1)

data1.std(), data2.std()


I am working on the file "Lecture/13. 데이터 전처리/1) Scikit-Learn의 전처리 기능.ipynb".
The first task is:
인코딩(Encoding)
인코딩은 카테고리 값이나 텍스트 정보를 처리가 쉬운 정수로 변환하는 과정이다.

크기가 없는 1-of-K 라벨을 숫자로 인식되지 않도록 0/1 vector로 변환
실수 타겟을 유한한 정수개의 카테고리로 변환
복수 라벨을 가지는 경우를 포함하여 카테고리로 변환

One-Hot-Encoder
One-Hot-Encoder는 one-of-K 인코딩이라고도 불리며 K개의 값을 가지는 스칼라 값을 0 또는1 값을 가지는 K-차원 벡터로 변환한다.
만약 입력이 스칼라가 아니라 벡터이면 stack된 결과가 출력된다. 이 때는 feature_indices_ 를 사용하여 분리해야 한다.
또 입력이 벡터인 경우에 특정한 열(column)만 카테고리 값이면 categorical_features 인수를 사용하여 카테고리 열을 지정한다. 이 때 인코딩 결과는 순서가 바뀔 수 있으므로 주의한다.
fit 메서드를 호출하면 다음과 같은 속성이 지정된다.

n_values_ : 최대 클래스 수
feature_indices_ : 입력이 벡터인 경우 각 원소를 나타내는 slice 정보
active_features_ : 실제로 사용된 클래스들

One-Hot-Encoding 결과는 메모리 절약을 위한 sparse matrix 형식으로 출력된다. 일반적인 배열로 바꾸려면 toarray 메서드를 사용한다.

http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html
Can you write Python code for it?

from sklearn.preprocessing import OneHotEncoder
ohe = OneHotEncoder()

X = np.array([[0], [1], [2]])
X

ohe.fit(X)
ohe.n_values_, ohe.feature_indices_, ohe.active_features_

ohe.transform(X).toarray()

X = np.array([[0, 0, 4], [1, 1, 0], [0, 2, 1], [1, 0, 2]])
X

ohe.fit(X)
ohe.n_values_, ohe.feature_indices_, ohe.active_features_

ohe.transform(X).toarray()

ohe = OneHotEncoder(categorical_features=[False, True, False])
ohe.fit_transform(X).toarray()


I am working on the file "Lecture/13. 데이터 전처리/1) Scikit-Learn의 전처리 기능.ipynb".
The first task is:
정규화 (Normalization)
정규화(Normarlization)는 스케일링과 달리 개별 데이터의 크기를 모두 같게 만들기 위한 변환이다. 따라서 개별 데이터에 대해 서로 다른 변환 계수가 적용된다.
정규화는 다차원 독립 변수 벡터가 있을 때 각 벡터 원소들의 상대적 크기만 중요한 경우에 사용된다.
Can you write Python code for it?

from sklearn.preprocessing import normalize

x = np.vstack([np.arange(5, dtype=float) - 20, np.arange(5, dtype=float) - 2]).T
y1 = scale(x)
y2 = normalize(x)

print("original x:\n", x)
print("scale:\n", y1)
print("norms (scale)\n", np.linalg.norm(y1, axis=1))
print("normlize:\n", y2)
print("norms (normalize)\n", np.linalg.norm(y2, axis=1))

from sklearn.datasets import load_iris
iris = load_iris()

data1 = iris.data[:,:2]
data3 = normalize(data1)

sns.jointplot(data1[:,0], data1[:,1])
plt.show()

sns.jointplot(data3[:,0], data3[:,1])
plt.show()


I am working on the file "Lecture/14. 선형 회귀 분석/1) 회귀 분석용 가상 데이터 생성 방법.ipynb".
The first task is:
만약 실제로 y값에 영향을 미치는 종속 변수는 하나 뿐이라면 다음과 같이 사용한다.
Can you write Python code for it?

X, y, c = make_regression(n_samples=300, n_features=2, n_informative=1, noise=0, coef=True, random_state=0)

plt.scatter(X[:,0], X[:,1], c=y, s=100)
plt.xlabel("x1")
plt.ylabel("x2")
plt.axis("equal")
plt.show()


I am working on the file "Lecture/14. 선형 회귀 분석/1) 회귀 분석용 가상 데이터 생성 방법.ipynb".
The first task is:
이번에는 n_features 즉, 독립 변수가 2개인 표본 데이터를 생성하여 스캐터 플롯을 그리면 다음과 같다. 종속 변수 값은 점의 명암으로 표시하였다.
Can you write Python code for it?

X, y, c = make_regression(n_samples=300, n_features=2, noise=10, coef=True, random_state=0)

plt.scatter(X[:,0], X[:,1], c=y, s=100)
plt.xlabel("x1")
plt.ylabel("x2")
plt.axis("equal")
plt.show()


I am working on the file "Lecture/14. 선형 회귀 분석/2) 선형 회귀 분석의 기초.ipynb".
The first task is:
Boston Housing Price
Can you write Python code for it?

from sklearn.datasets import load_boston
boston = load_boston()
dfX_boston = pd.DataFrame(boston.data, columns=boston.feature_names)
dfy_boston = pd.DataFrame(boston.target, columns=["MEDV"])
df_boston0 = pd.concat([dfX_boston, dfy_boston], axis=1)
df_boston0.tail()

model_boston = LinearRegression().fit(boston.data, boston.target)
print(model_boston.coef_)
print(model_boston.intercept_)

predictions = model_boston.predict(boston.data)
plt.scatter(boston.target, predictions)
plt.xlabel("target")
plt.ylabel("prediction")
plt.show()

mean_abs_error = (np.abs(((boston.target - predictions)/boston.target)*100)).mean()
print("MAE: %.2f%%" % (mean_abs_error))

sk.metrics.median_absolute_error(boston.target, predictions)

sk.metrics.mean_squared_error(boston.target, predictions)


I am working on the file "Lecture/14. 선형 회귀 분석/2) 선형 회귀 분석의 기초.ipynb".
The first task is:
OLS (Ordinary Least Squares)
OLS는 가장 기본적인 결정론적 회귀 방법으로 Residual Sum of Squares(RSS)를 최소화하는 가중치 벡터 값을 미분을 통해 구한다.

Residual 잔차
$$ e_i = {y}_i - x_i^T w $$

Stacking (Vector Form)
$$ e = {y} - Xw $$

Residual Sum of Squares (RSS)
$$\begin{eqnarray}
\text{RSS}
&=& \sum (y_i - \hat{y}_i)^2 \
&=& \sum e_i^2 = e^Te \
&=& (y - Xw)^T(y - Xw) \
&=& y^Ty - 2y^T X w + w^TX^TXw
\end{eqnarray}$$

Minimize using Gradient
$$ \dfrac{\partial \text{RSS}}{\partial w} = -2 X^T y + 2 X^TX w = 0 $$

$$ X^TX w = X^T y $$
$$  w = (X^TX)^{-1} X^T y $$
여기에서 그레디언트를 나타내는 다음 식을 Normal equation 이라고 한다.
$$ X^T y - X^TX w = 0 $$
Normal equation 에서 잔차에 대한 다음 특성을 알 수 있다.
$$ X^T (y - X w ) = X^T e = 0 $$
Can you write Python code for it?

y = y.reshape(len(y), 1)
w = np.dot(np.dot(np.linalg.inv(np.dot(X.T, X)), X.T), y)
print("bias:", bias)
print("coef:", coef)
print("w:\n", w)

w = np.linalg.lstsq(X, y)[0]
w

xx = np.linspace(np.min(X0) - 1, np.max(X0) + 1, 1000)
XX = np.vstack([np.ones(xx.shape[0]), xx.T]).T
yy = np.dot(XX, w)
plt.scatter(X0, y)
plt.plot(xx, yy, 'r-')
plt.show()


I am working on the file "Lecture/14. 선형 회귀 분석/2) 선형 회귀 분석의 기초.ipynb".
The first task is:
scikit-learn 패키지를 사용한  선형 회귀 분석
sklearn 패키지를 사용하여 선형 회귀 분석을 하는 경우에는 linear_model 서브 패키지의 LinearRegression 클래스를 사용한다.

http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html

입력 인수

fit_intercept : 불리언, 옵션
상수상 추가 여부

normalize : 불리언, 옵션

회귀 분석전에 정규화 여부

속성

coef_ : 추정된 가중치 벡터
intercept_ : 추정된 상수항

Diabetes Regression
Can you write Python code for it?

from sklearn.datasets import load_diabetes
diabetes = load_diabetes()
dfX_diabetes = pd.DataFrame(diabetes.data, columns=["X%d" % (i+1) for i in range(np.shape(diabetes.data)[1])])
dfy_diabetes = pd.DataFrame(diabetes.target, columns=["target"])
df_diabetes0 = pd.concat([dfX_diabetes, dfy_diabetes], axis=1)
df_diabetes0.tail()

from sklearn.linear_model import LinearRegression
model_diabetes = LinearRegression().fit(diabetes.data, diabetes.target)
print(model_diabetes.coef_)
print(model_diabetes.intercept_)

predictions = model_diabetes.predict(diabetes.data)
plt.scatter(diabetes.target, predictions)
plt.xlabel("target")
plt.ylabel("prediction")
plt.show()

mean_abs_error = (np.abs(((diabetes.target - predictions)/diabetes.target)*100)).mean()
print("MAE: %.2f%%" % (mean_abs_error))

sk.metrics.median_absolute_error(diabetes.target, predictions)

sk.metrics.mean_squared_error(diabetes.target, predictions)


I am working on the file "Lecture/14. 선형 회귀 분석/2) 선형 회귀 분석의 기초.ipynb".
The first task is:
statsmodels 를 사용한 선형 회귀 분석
statsmodels 패키지에서는 OLS 클래스를 사용하여 선형 회귀 분석을 실시한다.

http://www.statsmodels.org/dev/generated/statsmodels.regression.linear_model.OLS.html

statsmodels.regression.linear_model.OLS(endog, exog=None)

입력 인수
endog : 종속 변수. 1차원 배열
exog : 독립 변수, 2차원 배열.

statsmodels 의 OLS 클래스는 자동으로 상수항을 만들어주지 않기 때문에 사용자가 add_constant 명령으로 상수항을 추가해야 한다.
모형 객체가 생성되면 fit, predict 메서드를 사용하여 추정 및 예측을 실시한다.
예측 결과는 RegressionResults 클래스 객체로 출력되면 summary 메서드로 결과 보고서를 볼 수 있다.
Can you write Python code for it?

df_diabetes = sm.add_constant(df_diabetes0)
df_diabetes.tail()

model_diabetes2 = sm.OLS(df_diabetes.ix[:, -1], df_diabetes.ix[:, :-1])
result_diabetes2 = model_diabetes2.fit()
result_diabetes2

print(result_diabetes2.summary())

df_boston = sm.add_constant(df_boston0)
model_boston2 = sm.OLS(df_boston.ix[:, -1], df_boston.ix[:, :-1])
result_boston2 = model_boston2.fit()
print(result_boston2.summary())


I am working on the file "Lecture/14. 선형 회귀 분석/3) 레버리지와 아웃라이어.ipynb".
The first task is:
Outlier

Good Leverage Points

leverage가(영향력이) 높지만 residual이(오차가) 작은 데이터

Bad Leverage Points = Outliner

leverage도(영향력도) 높지만 residual도(오차도) 큰 데이터
Can you write Python code for it?

plt.figure(figsize=(10, 2))
plt.stem(result.resid)
plt.xlim([-2, len(y)+2])
plt.show()

sm.graphics.plot_leverage_resid2(result)
plt.show()


I am working on the file "Lecture/14. 선형 회귀 분석/4) 확률론적 선형 회귀 모형.ipynb".
The first task is:
가중치 중 상수항의 경우 평균은 -1.6이지만 표분 편차가 $\sqrt{4.81}=2.19$이므로 0일 가능성을 배제할 수 없다.
이 결과를 statsmodels 의 회귀 분석 보고서와 비교하자.
Can you write Python code for it?


I am working on the file "Lecture/14. 선형 회귀 분석/4) 확률론적 선형 회귀 모형.ipynb".
The first task is:
다음으로 이 데이터에서 중복을 허락하여 N개의 데이터를 선택한 후 다시 회귀 분석을 한다. 이론적으로 $2^{100}$개의 경우가 있지만 1,000번만 반복해 본다.
Can you write Python code for it?

N = 1000
params_c = np.zeros(N)
params_x1 = np.zeros(N)
for i in range(N):
    idx = np.random.choice(len(dfy), len(dfy), replace=True)
    dfX2 = dfX.ix[idx, :]
    dfy2 = dfy.ix[idx]
    r = sm.OLS(dfy2, dfX2).fit()
    params_c[i] = r.params.const
    params_x1[i] = r.params.X1


I am working on the file "Lecture/14. 선형 회귀 분석/4) 확률론적 선형 회귀 모형.ipynb".
The first task is:
보고서의 std err 항목을 보면 표준 편차의 경우 2.163 이고 마지막의 신뢰 구간(confidence interval)이 -5.920 ~ 2.663 임을 보이고 있다. 부트스트래핑으로 얻은 결과와 유사하다. 이 결과는 다음에 설명할 확률론적 가정에 의해 계산된 값이다.
확률론적 선형 회귀 모형
확률론적 선형 회귀 모형에서는 $y$가 확률 변수로부터 생성된 표본이라고 가정하며 다음과 같은 조건을 만족한다.

선형 정규 분포 가정
종속 변수 $y$는 기댓값 $w^Tx$, 분산 $\sigma^2$ 를 가지는 정규 분포 확률 변수이다.
   $$ p(y \mid x, \theta) = \mathcal{N}(y \mid w^Tx, \sigma^2 ) $$

따라서 오차(disturbance)  $ \epsilon = y-w^Tx $ 도 정규 분포 확률 변수이다.
   $$ p(\epsilon \mid \theta) = \mathcal{N}(0, \sigma^2 ) $$

외생성(Exogeneity) 가정

오차 $\epsilon$와 독립 변수 $x$는 서로 독립이다.
   $$ \text{E}[\epsilon \mid x] = 0$$

조건부 독립 가정

오차 $\epsilon$는 $x$에 대해 조건부 독립이다.
   $$ \text{Cov}[\epsilon_i, \epsilon_j \mid x] =  0$$

MLE를 사용한 선형 회귀 분석
앞의 확률론적 선형 회귀 모형과 MLE(Maximum Likelihood Estimation)을 사용하여 가중치 벡터 $w$의 값을 구해보자.
Likelihood는 다음과 같다.
$$
\begin{eqnarray}
p(y_{1:N} \,\big|\, x_{1:N}, \theta)
&=& \prod_{i=1}^N N(y_i \,\big|\, w^T x_i , \sigma^2) \
&=& \prod_{i=1}^N \frac{1}{\sqrt{2\pi\sigma^2}}\exp\left{-\frac{(y_i-w^T x_i)^2}{2\sigma^2} \right}  \
\end{eqnarray}
$$
계산을 용이하기 위해 Log를 취하면 다음과 같다.
$$
\begin{eqnarray}
\text{LL}
&=& \log p(y_{1:N} \,\big|\, x_{1:N}, \theta) \
&=& \log \prod_{i=1}^N \frac{1}{\sqrt{2\pi\sigma^2}}\exp\left{-\frac{(y_i-w^T x_i)^2}{2\sigma^2} \right}  \
&=& -\dfrac{1}{2\sigma^2} \sum_{i=1}^N (y_i-w^T x_i)^2 + \dfrac{1}{2} \sum_{i=1}^N  \log{2\pi}{\sigma^2}  \
\end{eqnarray}
$$
이를 행렬로 표시하면 다음과 같다.
$$
\text{LL}  =  -C_1 (y - Xw)^T(y-Xw) + C_0 = -C_1(w^TX^TXw -2 y^TXw + y^Ty) + C_0
$$
$$
C_1 =  -\dfrac{1}{2\sigma^2}
$$
$$
C_0 =  \dfrac{1}{2} \sum_{i=1}^N  \log{2\pi}{\sigma^2}
$$
이를 최적화하면 OLS와 동일한 결과를 얻을 수 있다.
$$
\dfrac{\partial}{\partial w} \text{LL} \propto - 2X^TX \hat{w} + 2X^Ty = 0
$$
$$
\hat{w} = (X^TX)^{-1}X^T y
$$
잔차의 분포
위의 확률론적 선형 회귀 모형에 따르면 잔차 $e = y - \hat{w}^Tx$ 도 정규 분포를 따른다. 이는 다음과 같이 증명할 수 있다.
확률론적 선형 회귀 모형의 오차 $\epsilon$와 잔차 $e$는 다음과 같은 관계를 가진다.
$$  \hat{y} = X\hat{w} = X (X^TX)^{-1}X^T y = Hy $$
$$ e = y - \hat{y}= y - Hy = (I - H) y$$
$M = I - H$이라고 정의하면
$$ e = My = M (Xw + \epsilon) $$
최적화 조건에서
$$
X^TX...
Can you write Python code for it?

sp.stats.probplot(result.resid, plot=plt)
plt.show()

plt.plot(X0, result.resid, 'o')
plt.axhline(y=0, c='k')
plt.xlabel("X1")
plt.ylabel("Residual")
plt.show()

import statsmodels.stats.api as sms
test = sms.omni_normtest(result.resid)
for x in zip(['Chi^2', 'P-value'], test):
    print("%-12s: %6.3f" % x)

import statsmodels.stats.api as sms
test = sms.jarque_bera(result.resid)
for x in zip(['Jarque-Bera', 'P-value', 'Skew', 'Kurtosis'], test):
    print("%-12s: %6.3f" % x)


I am working on the file "Lecture/14. 선형 회귀 분석/4) 확률론적 선형 회귀 모형.ipynb".
The first task is:
평균과 분산은 다음과 같다.
Can you write Python code for it?


I am working on the file "Lecture/14. 선형 회귀 분석/7) 분산 분석 기반의 카테고리 분석.ipynb".
The first task is:
더미 변수와 모형 비교
더미 변수를 사용하면 사실상 회귀 모형 복수개를 동시에 사용하는 것과 실질적으로 동일하다.
더미 변수의 예 1
$$ Y = \alpha_{1} + \alpha_{2} D_2 + \alpha_{3} D_3  $$

$D_2 = 0, D_3 = 0$ 이면 $Y = \alpha_{1} $
$D_2 = 1, D_3 = 0$ 이면 $Y = \alpha_{1} + \alpha_{2} $
$D_2 = 0, D_3 = 1$ 이면 $Y = \alpha_{1} + \alpha_{3} $

더미 변수의 예 2
$$ Y = \alpha_{1} + \alpha_{2} D_2 + \alpha_{3} D_3  + \alpha_{4} X $$

$D_2 = 0, D_3 = 0$ 이면 $Y = \alpha_{1}  + \alpha_{4} X $
$D_2 = 1, D_3 = 0$ 이면 $Y = \alpha_{1} + \alpha_{2}  + \alpha_{4} X $
$D_2 = 0, D_3 = 1$ 이면 $Y = \alpha_{1} + \alpha_{3}  + \alpha_{4} X $

더미 변수의 예 3
$$ Y = \alpha_{1} + \alpha_{2} D_2 + \alpha_{3} D_3  + \alpha_{4} X + \alpha_{5} D_4 X + \alpha_{6} D_5 X  $$

$D_2 = 0, D_3 = 0$ 이면 $Y = \alpha_{1} + \alpha_{4} X $
$D_2 = 1, D_3 = 0$ 이면 $Y = \alpha_{1} + \alpha_{2}  + (\alpha_{4} + \alpha_{5}) X $
$D_2 = 0, D_3 = 1$ 이면 $Y = \alpha_{1} + \alpha_{3}  + (\alpha_{4} + \alpha_{6}) X $

더미 변수의 예 4: Boston Dataset
Can you write Python code for it?

from sklearn.datasets import load_boston
boston = load_boston()
dfX0_boston = pd.DataFrame(boston.data, columns=boston.feature_names)
dfy_boston = pd.DataFrame(boston.target, columns=["MEDV"])

import statsmodels.api as sm
dfX_boston = sm.add_constant(dfX0_boston)

df_boston = pd.concat([dfX_boston, dfy_boston], axis=1)
df_boston.tail()

dfX_boston.CHAS.plot()
dfX_boston.CHAS.unique()

model = sm.OLS(dfy_boston, dfX_boston)
result = model.fit()
print(result.summary())

params1 = result.params.drop("CHAS")
params1

params2 = params1.copy()
params2["const"] += result.params["CHAS"]
params2

df_boston.boxplot("MEDV", "CHAS")
plt.show()

sns.stripplot(x="CHAS", y="MEDV", data=df_boston, jitter=True, alpha=.3)
sns.pointplot(x="CHAS", y="MEDV", data=df_boston, dodge=True, color='r')
plt.show()


I am working on the file "Lecture/14. 선형 회귀 분석/7) 분산 분석 기반의 카테고리 분석.ipynb".
The first task is:
분산 분석을 이용한 모형 비교
$K$개의 복수의 카테고리 값을 가지는 더미 변수의 영향을 보기 위해서는 F-검정을 통해 복수 개의 모형을 비교하는 분산 분석을 사용할 수 있다.
이 경우에는 분산 분석에 사용되는 각 분산의 의미가 다음과 같다.

ESS: 각 그룹 평균의 분산 (Between-Group Variance)
  $$ BSS = \sum_{k=1}^K (\bar{x} - \bar{x}_k)^2 $$

RSS: 각 그룹 내의 오차의 분산의 합 (Within-Group Variance)
  $$ WSS = \sum_{k=1}^K \sum_{i} (x_{i} - \bar{x}_k)^2 $$

TSS : 전체 오차의 분산
  $$ TSS = \sum_{i} (x_{i} - \bar{x})^2 $$

| | source  | degree of freedom | mean square | F statstics |
|-|-|-|-|-|
| Between | $$\text{BSS}$$ | $$K-1$$ | $$\dfrac{\text{ESS}}{K-1}$$   | $$F$$ |
| Within   | $$\text{WSS}$$ | $$N-K$$ | $$\dfrac{\text{RSS}}{N-K}$$ |
| Total      | $$\text{TSS}$$ | $$N-1$$ | $$\dfrac{\text{TSS}}{N-1}$$ |
| $R^2$      | $$\text{BSS} / \text{TSS}$$ |
이 때 F-검정의 귀무가설은 $\text{BSS}=0$ 즉 $\text{WSS}=\text{TSS}$ 이다. 즉, 그룹간 차이가 없는 경우이다.
Can you write Python code for it?

import statsmodels.api as sm
model = sm.OLS.from_formula("MEDV ~ C(CHAS)", data=df_boston)
result = model.fit()
table = sm.stats.anova_lm(result)
table

model1 = sm.OLS.from_formula("MEDV ~ CRIM + ZN +INDUS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO + B + LSTAT", data=df_boston)
model2 = sm.OLS.from_formula("MEDV ~ CRIM + ZN +INDUS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO + B + LSTAT + C(CHAS)", data=df_boston)
result1 = model1.fit()
result2 = model2.fit()
table = sm.stats.anova_lm(result1, result2)
table


I am working on the file "Lecture/14. 선형 회귀 분석/8) patsy 패키지 소개.ipynb".
The first task is:
R-style formula
| 기호 | 설명 |
|-|-|
|+| 설명 변수 추가 |
|-| 설명 변수 제거 |
|1, 0| intercept. (제거시 사용) |
|:| interaction (곱) |
|*| a*b = a + b + a:b |
|/| a/b = a + a:b |
|~| 종속 - 독립 관계 |
Can you write Python code for it?

dmatrix("x1 - 1")

dmatrix("x1 + 0")

dmatrix("x1 + x2")

dmatrix("x1 + x2 - 1")

df = pd.DataFrame(np.array([x1, x2]).T, columns=["x1", "x2"])
df

dmatrix("x1 + x2 - 1", data=df)


I am working on the file "Lecture/14. 선형 회귀 분석/8) patsy 패키지 소개.ipynb".
The first task is:
변수 보호 I()

다른 formula 기호로부터 보호
Can you write Python code for it?

dmatrix("x1 + x2", data=df)

dmatrix("I(x1 + x2)", data=df)


I am working on the file "Lecture/14. 선형 회귀 분석/8) patsy 패키지 소개.ipynb".
The first task is:
카테고리 변수
Can you write Python code for it?


I am working on the file "Lecture/15. 과최적화와 정규화/1) 다항 회귀와 과최적화.ipynb".
The first task is:
Scikit-Learn을 이용한 다항 회귀
Scikit-Learn에서는 preprocessing 서브 패키지의 PolynomialFeatures 클래스를 사용하여 다항 회귀를 할 수 있다.
Can you write Python code for it?

from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline

def polyreg(degree, seed=0, plot=True):
    polynomial_features = PolynomialFeatures(degree=degree)
    linear_regression = LinearRegression()
    model = Pipeline([("polynomial_features", polynomial_features),
                      ("linear_regression", linear_regression)])

    np.random.seed(seed)
    n_samples = 30
    X = np.sort(np.random.rand(n_samples))
    y = np.cos(1.5 * np.pi * X) + np.random.randn(n_samples) * 0.1
    X = X[:, np.newaxis]

    model.fit(X, y)

    if plot:
        plt.scatter(X, y)
        xx = np.linspace(0, 1, 1000)
        plt.plot(xx, model.predict(xx[:, np.newaxis]))
        plt.ylim(-2, 2)
        plt.show()

    reg = model.named_steps["linear_regression"]
    return reg.coef_, reg.intercept_

polyreg(1)

polyreg(2)

polyreg(3)

polyreg(4)

polyreg(5)

polyreg(50)


I am working on the file "Lecture/15. 과최적화와 정규화/1) 다항 회귀와 과최적화.ipynb".
The first task is:
과최적화
모형을 특정 샘플 데이터에 대해 과도하게 최적화하는 것을 과최적화(overfitting)이라고 한다.
과최적화는
* 독립 변수 데이터 갯수에 비해 모형 모수의 수가 과도하게 크거나
* 독립 변수 데이터가 서로 독립이 아닌 경우에 발생한다.
이러한 상황에서는 같은 조건에 대해 답이 복수개 존재할 수 있기 때문이다.
과최적화가 문제가 되는 이유는 다음과 같다.

샘플이 조금만 변화해도 fitting 결과가 크게 달라지며
트레이닝에 사용되지 않은 새로운 독립 변수 값을 입력하면 오차가 커진다. (cross-validation 오차)
Can you write Python code for it?

polyreg(2, 0)

polyreg(2, 1)

polyreg(2, 2)

polyreg(50, 1)

polyreg(50, 2)

polyreg(50, 3)


I am working on the file "Lecture/15. 과최적화와 정규화/2) 교차 검증.ipynb".
The first task is:
ShuffleSplit

중복된 데이터를 허용
Can you write Python code for it?

from sklearn.cross_validation import ShuffleSplit
cv = ShuffleSplit(5)
for train_index, test_index in cv:
    print("test X:", X[test_index])
    print("=" * 20 )


I am working on the file "Lecture/15. 과최적화와 정규화/2) 교차 검증.ipynb".
The first task is:
Stratified K-Fold

target class가 어느 한 data set에 몰리지 않도록 한다
Can you write Python code for it?

from sklearn.cross_validation import StratifiedKFold
cv = StratifiedKFold(y, n_folds=3, random_state=0)
for train_index, test_index in cv:
    print("test X:\n", X[test_index])
    print("." * 80 )
    print("test y:", y[test_index])
    print("=" * 80 )


I am working on the file "Lecture/15. 과최적화와 정규화/3) 정규화 선형 회귀.ipynb".
The first task is:
Scikit-Learn의 정규화 회귀 모형
Scikit-Learn 패키지에서는 정규화 회귀 모형을 위한 Ridge, Lasso, ElasticNet 이라는 별도의 클래스를 제공한다. 각 모형에 대한 최적화 목적 함수는 다음과 같다.

http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Ridge.html

$$
\text{RSS} + \text{alpha} \sum w_i^2
$$

http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Lasso.html

$$
0.5 \times \text{RSS}/N + \text{alpha} \sum |w_i|
$$

http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.ElasticNet.html

$$
0.5 \times \text{RSS}/N + 0.5 \times \text{alpha} \times \big(0.5 \times  (1-\text{l1_ratio})\sum w_i^2 + \text{l1_ratio} \sum |w_i| \big)
$$
Can you write Python code for it?

def plot_sklearn(model):
    plt.scatter(X, y)
    xx = np.linspace(0, 1, 1000)
    plt.plot(xx, model.predict(xx[:, np.newaxis]))
    plt.show()

from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet

poly = PolynomialFeatures(3)

model = make_pipeline(poly, Ridge(alpha=0.01)).fit(X[:, np.newaxis], y)
plot_sklearn(model)

model = make_pipeline(poly, Lasso(alpha=0.01)).fit(X[:, np.newaxis], y)
plot_sklearn(model)

model = make_pipeline(poly, ElasticNet(alpha=0.01, l1_ratio=0.5)).fit(X[:, np.newaxis], y)
plot_sklearn(model)


I am working on the file "Lecture/15. 과최적화와 정규화/3) 정규화 선형 회귀.ipynb".
The first task is:
path 메서드
Lasso 와 ElasticNet  클래스는 하이퍼 모수 alpha 값의 변화에 따른 계수의 변화를 자동으로 계산하는 path 메서드를 제공한다.
lasso_path(), enet_path() 명령어도 path 메서드와 동일한 기능을 수행한다.
Can you write Python code for it?

lasso = Lasso()
alphas, coefs, _ = lasso.path(X, y, alphas=np.logspace(-6, 1, 8))
df = pd.DataFrame(coefs, columns=alphas)
df

df.T.plot(logx=True)
plt.show()


I am working on the file "Lecture/15. 과최적화와 정규화/3) 정규화 선형 회귀.ipynb".
The first task is:
정규화 모형의 장점
정규화 모형은 오차-분산 트레이드오프(bias-variance trade-off) 원리에 따라 분산을 감소시키는 효과를 가진다.
Can you write Python code for it?

X_train = np.c_[.5, 1].T
y_train = [.5, 1]
X_test = np.c_[-1, 3].T
np.random.seed(0)

models = {"LinearRegression": LinearRegression(),
          "Ridge": Ridge(alpha=0.1)}

for i, (name, model) in enumerate(models.iteritems()):
    ax = plt.subplot(1, 2, i+1)
    for _ in range(10):
        this_X = .1 * np.random.normal(size=(2, 1)) + X_train
        model.fit(this_X, y_train)
        ax.plot(X_test, model.predict(X_test), color='.5')
        ax.scatter(this_X, y_train, s=100, c='.5', marker='o', zorder=10)
        model.fit(X_train, y_train)
        ax.plot(X_test, model.predict(X_test), linewidth=3, color='blue', alpha=0.5)
        ax.scatter(X_train, y_train, s=100, c='r', marker='D', zorder=10)
        plt.title(name)
        ax.set_xlim(-0.5, 2)
        ax.set_ylim(0, 1.6)


I am working on the file "Lecture/15. 과최적화와 정규화/4) 최적 정규화.ipynb".
The first task is:
One Standard Error Rule
실제로 하이퍼 모수 값을 변경해가면서 최적 값은 오차가 존재하는 부정확한 값이다. 이러한 오차를 고려해서 표준 편차(1 standard deviation)  정도의 오차는 감수하더라도 더 단순한(정규화 모형에서는 더 제약 조건이 강한) 모형을 선택하는 것이 실용적이다.
Can you write Python code for it?

from sklearn.linear_model import LassoCV

alphas = np.logspace(-4, -.5, 50)
lasso_cv = LassoCV(alphas=alphas, cv=5)
lasso_cv.fit(X, y)

scores = -lasso_cv.mse_path_.mean(axis=1)
scores_std = lasso_cv.mse_path_.std(axis=1)
scores_std1 = scores + scores_std / np.sqrt(len(lasso_cv.mse_path_))
scores_std2 = scores - scores_std / np.sqrt(len(lasso_cv.mse_path_))

alpha_1se = lasso_cv.alphas_[np.argmax(scores_std1 > np.max(scores))]
print(alpha_1se)

plt.semilogx(lasso_cv.alphas_, scores)
plt.semilogx(lasso_cv.alphas_, scores_std1, 'o-')
plt.semilogx(lasso_cv.alphas_, scores_std2, 'o-')
plt.axhline(np.max(scores), linestyle=':')
plt.axvline(lasso_cv.alpha_ , linestyle=':')
plt.axvline(alpha_1se, linestyle=':')
plt.ylabel('CV score')
plt.xlabel('alpha')
plt.show()


I am working on the file "Lecture/15. 과최적화와 정규화/4) 최적 정규화.ipynb".
The first task is:
하이퍼 모수 최적화
하이퍼 모수가 바뀌는 경우에도 마찬가지로 오차-분산 트레이드오프가 성립하므로 최적의 하이퍼 모수를 찾는 작업이 필요하다.
Can you write Python code for it?

from sklearn.datasets import load_diabetes
from sklearn.linear_model import Lasso
from sklearn.cross_validation import cross_val_score

data = load_diabetes()
X = data.data[:200]
y = data.target[:200]

model = Lasso()
alphas = np.logspace(-4, -.5, 50)

scores = list()

for alpha in alphas:
    model.alpha = alpha
    this_scores = cross_val_score(model, X, y, "mean_squared_error", cv=5)
    scores.append(np.mean(this_scores))

plt.semilogx(alphas, scores)
plt.ylabel('CV score')
plt.xlabel('alpha')
plt.axhline(np.max(scores), linestyle=':')
plt.show()

from sklearn.linear_model import LassoCV

alphas = np.logspace(-4, -.5, 50)
lasso_cv = LassoCV(alphas=alphas, cv=5)
lasso_cv.fit(X, y)

print(lasso_cv.alpha_ )

scores = -lasso_cv.mse_path_.mean(axis=1)
plt.semilogx(lasso_cv.alphas_, scores)
plt.axhline(np.max(scores), linestyle=':')
plt.axvline(lasso_cv.alpha_ , linestyle=':')
plt.ylabel('CV score')
plt.xlabel('alpha')
plt.show()


I am working on the file "Lecture/16. 로지스틱 회귀분석/1) 로지스틱 회귀 분석.ipynb".
The first task is:
statsmodels 패키지의 로지스틱 회귀
statsmodels 패키지는 로지스틱 회귀 모형 Logit 를 제공한다. 사용방법은 OLS 와 동일하다. Scikit-Learn 패키지와 달리 Logit 클래스는 classification 되기 전의 값을 출력한다
Can you write Python code for it?

logit_mod = sm.Logit(y, X)
logit_res = logit_mod.fit(disp=0)
print(logit_res.summary())

xx = np.linspace(-3, 3, 100)
sigmoid = logit_res.predict(sm.add_constant(xx))
plt.plot(xx, sigmoid, lw=5, alpha=0.5)
plt.scatter(X0, y, marker='o', c=y, s=100)
plt.scatter(X0, logit_res.predict(X), marker='x', c=y, s=200, lw=2, alpha=0.5, cmap=mpl.cm.jet)
plt.xlim(-3, 3)
plt.show()


I am working on the file "Lecture/16. 로지스틱 회귀분석/1) 로지스틱 회귀 분석.ipynb".
The first task is:
예제 1: Michelin and Zagat 가이드 비교
다음 데이터는 뉴욕시의 레스토랑에 대한 두 개의 가이드북에서 발취한 것이다.

Food: Zagat Survey 2006 의 고객 평가 점수
InMichelin: 해당 고객 평가 점수를 받은 레스토랑 중 2006 Michelin Guide New York City 에 실린 레스토랑의 수
NotInMichelin: 해당 고객 평가 점수를 받은 레스토랑 중 2006 Michelin Guide New York City 에 실리지 않은 레스토랑의 수
mi: 해당 고객 평가 점수를 받은 레스토랑의 수
proportion: 해당 고객 평가 점수를 받은 레스토랑 중 2006 Michelin Guide New York City 에 실린 레스토랑의 비율
Can you write Python code for it?

df = pd.read_table("~/data/sheather/MichelinFood.txt")
df

df.plot(kind="scatter", x="Food", y="proportion", s=100)
plt.show()

X = sm.add_constant(df.Food)
y = df.proportion
model = sm.Logit(y, X)
result = model.fit()
print(result.summary())

df.plot(kind="scatter", x="Food", y="proportion", s=50, alpha=0.5)
xx = np.linspace(10, 35, 100)
plt.plot(xx, result.predict(sm.add_constant(xx)), "r", lw=4)
plt.xlim(10, 35)
plt.show()


I am working on the file "Lecture/17. 분류의 기초/4) 분류(classification) 성능 평가.ipynb".
The first task is:
Multi-Class 예제
Can you write Python code for it?

from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
iris = load_iris()
model = LogisticRegression().fit(iris.data, iris.target)

from sklearn.metrics import roc_curve
fpr0, tpr0, thresholds0 = roc_curve(iris.target, model.decision_function(iris.data)[:, 0], pos_label=0)
fpr1, tpr1, thresholds1 = roc_curve(iris.target, model.decision_function(iris.data)[:, 1], pos_label=1)
fpr2, tpr2, thresholds2 = roc_curve(iris.target, model.decision_function(iris.data)[:, 2], pos_label=2)

fpr0, tpr0, thresholds0

plt.plot(fpr0, tpr0, "r-", label="class 0 ")
plt.plot(fpr1, tpr1, "g-", label="class 1")
plt.plot(fpr2, tpr2, "b-", label="class 2")
plt.plot([0, 1], [0, 1], 'k--', label="random guess")
plt.xlim(-0.05, 1.0)
plt.ylim(0, 1.05)
plt.xlabel('False Positive Rate (Fall-Out)')
plt.ylabel('True Positive Rate (Recall)')
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
plt.show()

print(confusion_matrix(iris.target, model1.predict(iris.data)))

print(classification_report(iris.target, model1.predict(iris.data)))

from sklearn.preprocessing import label_binarize
yb0 = label_binarize(iris.target, classes=[0, 1, 2])
yb1 = label_binarize(model1.predict(iris.data), classes=[0, 1, 2])

print(yb0[:, 0].sum(), yb1[:, 0].sum())
plt.plot(yb0[:, 0], 'ro-', markersize=10, alpha=0.4, label="actual class 0")
plt.plot(yb1[:, 0], 'bs-', markersize=10, alpha=0.4, label="predicted class 0")
plt.legend()
plt.xlim(0, len(iris.target)-1);
plt.ylim(-0.1, 1.1);

print(yb0[:, 1].sum(), yb1[:, 1].sum())
plt.plot(yb0[:, 1], 'ro-', markersize=10, alpha=0.6, label="actual class 1")
plt.plot(yb1[:, 1], 'bs-', markersize=10, alpha=0.6, label="predicted class 1")
plt.legend()
plt.xlim(45, 145);
plt.ylim(-0.1, 1.1);


I am working on the file "Lecture/17. 분류의 기초/4) 분류(classification) 성능 평가.ipynb".
The first task is:
ROC 커브
ROC(Receiver Operator Characteristic) 커브는 클래스 판별 기준값의 변화에 따른 Fall-out과 Recall의 변화를 시각화한 것이다.
모든 이진 분류 모형은 판별 평면으로부터의 거리에 해당하는 판별 함수(discriminant function)를 가지며 판별 함수 값이 음수이면 0인 클래스, 양수이면 1인 클래스에 해당한다고 판별한다. 즉 0 이 클래스 판별 기준값이 된다. ROC 커브는 이 클래스 판별 기준값이 달라진다면 판별 결과가 어떻게 달라지는지는 표현한 것이다.
Scikit-Learn 의 Classification 클래스는 판별 함수 값을 계산하는 decision_function 메서드를 제공한다. ROC 커브는 이 판별 함수 값을 이용하여 다음과 같이 작성한다.

모든 표본 데이터에 대해 판별 함수 값을 계산한다.
계산된 판별 함수 값을 정렬한다.
만약 0이 아닌 가장 작은 판별 함수값을 클래스 구분 기준값으로 하면 모든 표본은 클래스 1(Positive)이 된다.
   이 때의 Fall-out과 Recall을 계산하면 Recall과 Fall-out이 모두 1이된다.
두번째로 작은 판별 함수값을 클래스 구분 기준값으로 하면 판별 함수 값이 가장 작은 표본 1개를 제외하고 나머지 표본은 클래스 1(Positive)이 된다. 마찬가지로 이 때의 Fall-out과 Recall을 계산하여 기록한다.
가장 큰 판별 함수값이 클래스 구분 기준값이 될 때까지 이를 반복한다. 이 때는 모든 표본이 클래스 0(Negative)으로 판별되며 Recall과 Fall-out이 모두 0이된다.

일반적으로 클래스 판별 기준이 변화함에 따라 Recall과 Fall-out은 같이 증가하거나 감소한다. Recall이 크고 Fall-out이 작은 모형은 좋은 모형으로 생각할 수 있다.
Can you write Python code for it?

from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
X, y = make_classification(n_features=1, n_redundant=0, n_informative=1, n_clusters_per_class=1, random_state=4)
model = LogisticRegression().fit(X, y)

print(confusion_matrix(y, model.predict(X)))

print(classification_report(y, model.predict(X)))

from sklearn.metrics import roc_curve
fpr, tpr, thresholds = roc_curve(y, model.decision_function(X))

plt.plot(fpr, tpr)
plt.plot([0, 1], [0, 1], 'k--', label="random guess")
plt.xlabel('False Positive Rate (Fall-Out)')
plt.ylabel('True Positive Rate (Recall)')
plt.title('Receiver operating characteristic example')
plt.show()


I am working on the file "Lecture/18. 문서 전처리/1) Python 문자열 인코딩.ipynb".
The first task is:
str에 encode 메소드를 적용:
내부적으로 유니코드로 변환 시도
unicode에 decode 메소드를 적용:
바이트열이 스트링이라고 가정해 버린다.

디폴트 인코딩
Can you write Python code for it?

u"가".encode("utf-8"), u"가".encode("cp949"), "가"

import sys
print(sys.getdefaultencoding())
print(sys.stdin.encoding)
print(sys.stdout.encoding)
import locale
print(locale.getpreferredencoding())


I am working on the file "Lecture/18. 문서 전처리/1) Python 문자열 인코딩.ipynb".
The first task is:
str에 encode 메소드를 적용하면 또는 unicode에 decode 메소드를 적용하면?
Can you write Python code for it?

"가".encode("utf-8")

unicode("가", "ascii").encode("utf-8")

u"가".decode("utf-8")

u"가".encode("ascii").decode("utf-8")


I am working on the file "Lecture/18. 문서 전처리/1) Python 문자열 인코딩.ipynb".
The first task is:
유니코드 인코딩(Encoding) / 디코딩(Decoding)

encode
unicode 타입의 메소드
unicode -> string (byte sequence)
decode
str 타입의 메소드
str -> unicode
Can you write Python code for it?

print(type(y))
z1 = y.encode("cp949")
print(type(z1))
print(z1)

print(type(y))
z2 = y.encode("utf-8")
print(type(z2))
print(z2)

print(type(z1))
y1 = z1.decode("cp949")
print(type(y1))
print(y1)

print(type(z2))
y2 = z2.decode("utf-8")
print(type(y2))
print(y2)


I am working on the file "Lecture/18. 문서 전처리/2) NLTK 자연어 처리 패키지 소개.ipynb".
The first task is:
토큰 생성(tokenizing)
문서를 분석하기 위해서는 우선 긴 문자열을 분석을 위한 작은 단위로 나누어야 한다. 이 문자열 단위를 토큰(token)이라고 한다.
Can you write Python code for it?

from nltk.tokenize import word_tokenize
word_tokenize(emma_raw[50:100])

from nltk.tokenize import RegexpTokenizer
t = RegexpTokenizer("[\w]+")
t.tokenize(emma_raw[50:100])

from nltk.tokenize import sent_tokenize
print(sent_tokenize(emma_raw[:1000])[3])


I am working on the file "Lecture/18. 문서 전처리/2) NLTK 자연어 처리 패키지 소개.ipynb".
The first task is:
형태소 분석
형태소 분석이란 어근, 접두사/접미사, 품사(POS, part-of-speech) 등 다양한 언어적 속성의 구조를 파악하는 작업이다. 구체적으로는 다음과 같은 작업으로 나뉜다.

stemming (어근 추출)
lemmatizing (원형 복원)
POS tagging (품사 태깅)

### Stemming and lemmatizing
Can you write Python code for it?

from nltk.stem import PorterStemmer
st = PorterStemmer()
st.stem("eating")

from nltk.stem import LancasterStemmer
st = LancasterStemmer()
st.stem("shopping")

from nltk.stem import RegexpStemmer
st = RegexpStemmer("ing")
st.stem("cooking")

from nltk.stem import WordNetLemmatizer
lm = WordNetLemmatizer()
print(lm.lemmatize("cooking"))
print(lm.lemmatize("cooking", pos="v"))
print(lm.lemmatize("cookbooks"))

print(WordNetLemmatizer().lemmatize("believes"))
print(LancasterStemmer().stem("believes"))


I am working on the file "Lecture/18. 문서 전처리/3) konlpy 한국어 처리 패키지 소개.ipynb".
The first task is:
명사 추출
Can you write Python code for it?

pprint(hannanum.nouns(c[:65]))

pprint(kkma.nouns(c[:65]))

pprint(twitter.nouns(c[:65]))


I am working on the file "Lecture/18. 문서 전처리/3) konlpy 한국어 처리 패키지 소개.ipynb".
The first task is:
품사 태깅
품사 태그표

https://docs.google.com/spreadsheets/d/1OGAjUvalBuX-oZvZ_-9tEfYD2gQe7hTGsgUpiiBSXI8/edit#gid=0
Can you write Python code for it?

pprint(hannanum.pos(c[:65]))

pprint(kkma.pos(c[:65]))

pprint(twitter.pos(c[:65]))


I am working on the file "Lecture/18. 문서 전처리/3) konlpy 한국어 처리 패키지 소개.ipynb".
The first task is:
한국어 처리 유틸리티
Can you write Python code for it?

x = [u"한글", {u"한글 키": [u"한글 밸류1", u"한글 밸류2"]}]
print(x)

from konlpy.utils import pprint
pprint(x)

from konlpy.utils import concordance
idx = concordance(u'대한민국', c, show=True)

idx


I am working on the file "Lecture/18. 문서 전처리/3) konlpy 한국어 처리 패키지 소개.ipynb".
The first task is:
형태소 분석
konlpy는 tag 서브패키지에서 형태소 분석을 위한 5개의 클래스를 제공한다.

Kkma
Hannanum
Twitter
Komoran
Mecab

이 클래스는 다음과 같은 메서드를 대부분 제공한다.

morphs : 형태소 추출
nouns : 명사 추출
pos : pos 태깅
Can you write Python code for it?

from konlpy.tag import *
hannanum = Hannanum()
kkma = Kkma()
twitter = Twitter()


I am working on the file "Lecture/18. 문서 전처리/4) 문서 전처리.ipynb".
The first task is:
Hashing Trick
CountVectorizer는 모든 작업을 in-memory 상에서 수행하므로 데이터 양이 커지면 속도가 느려지거나 실행이 불가능해진다. 이 때
HashingVectorizer를 사용하면 Hashing Trick을 사용하여 메모리 및 실행 시간을 줄일 수 있다.
Can you write Python code for it?

from sklearn.datasets import fetch_20newsgroups
twenty = fetch_20newsgroups()
len(twenty.data)

%time CountVectorizer().fit(twenty.data).transform(twenty.data)

from sklearn.feature_extraction.text import HashingVectorizer
hv = HashingVectorizer(n_features=10)

%time hv.transform(twenty.data)


I am working on the file "Lecture/18. 문서 전처리/4) 문서 전처리.ipynb".
The first task is:
TF-IDF
TF-IDF(Term Frequency – Inverse Document Frequency) 인코딩은 단어를 갯수 그대로 카운트하지 않고 모든 문서에 공통적으로 들어있는 단어의 경우 문서 구별 능력이 떨어진다고 보아 가중치를 축소하는 방법이다.
구제적으로는 문서 $d$(document)와 단어 $t$ 에 대해 다음과 같이 계산한다.
$$ \text{tf-idf}(d, t) = \text{tf}(d, t) \cdot \text{idf}(d, t) $$
여기에서

$\text{tf}(d, t)$: 단어의 빈도수
$\text{idf}(d, t)$ : inverse document frequency

$$ \text{idf}(d, t) = \log \dfrac{n_d}{1 + \text{df}(t)} $$

$n_d$ : 전체 문서의 수
$\text{df}(t)$:  단어 $t$를 가진 문서의 수
Can you write Python code for it?

from sklearn.feature_extraction.text import TfidfVectorizer

tfidv = TfidfVectorizer().fit(corpus)
tfidv.transform(corpus).toarray()


I am working on the file "Lecture/18. 문서 전처리/4) 문서 전처리.ipynb".
The first task is:
n-그램
n-그램은 단어장 생성에 사용할 토큰의 크기를 결정한다. 1-그램은 토큰 하나만 단어로 사용하며 2-그램은 두 개의 연결된 토큰을 하나의 단어로 사용한다.
Can you write Python code for it?

vect = CountVectorizer(ngram_range=(2,2)).fit(corpus)
vect.vocabulary_

vect = CountVectorizer(ngram_range=(1,2), token_pattern="t\w+").fit(corpus)
vect.vocabulary_


I am working on the file "Lecture/18. 문서 전처리/4) 문서 전처리.ipynb".
The first task is:
문서 처리 옵션
CountVectorizer는 다양한 인수를 가진다. 그 중 중요한 것들은 다음과 같다.

stop_words : 문자열 {‘english’}, 리스트 또는 None (디폴트)
stop words 목록.‘english’이면 영어용 스탑 워드 사용.
analyzer : 문자열 {‘word’, ‘char’, ‘char_wb’} 또는 함수
단어 n-그램, 문자 n-그램, 단어 내의 문자 n-그램
tokenizer : 함수 또는 None (디폴트)
토큰 생성 함수 .
token_pattern : string
토큰 정의용 정규 표현식
ngram_range : (min_n, max_n) 튜플
n-그램 범위
max_df : 정수 또는 [0.0, 1.0] 사이의 실수. 디폴트 1
단어장에 포함되기 위한 최대 빈도
min_df : 정수 또는 [0.0, 1.0] 사이의 실수.  디폴트 1
단어장에 포함되기 위한 최소 빈도
vocabulary : 사전이나 리스트
단어장

Stop Words
Stop Words 는 문서에서 단어장을 생성할 때 무시할 수 있는 단어를 말한다. 보통 영어의 관사나 접속사, 한국어의 조사 등이 여기에 해당한다. stop_words 인수로 조절할 수 있다.
Can you write Python code for it?

vect = CountVectorizer(stop_words=["and", "is", "the", "this"]).fit(corpus)
vect.vocabulary_

vect = CountVectorizer(stop_words="english").fit(corpus)
vect.vocabulary_


I am working on the file "Lecture/18. 문서 전처리/4) 문서 전처리.ipynb".
The first task is:
예
Can you write Python code for it?

import urllib2
import json
import string
from konlpy.utils import pprint
from konlpy.tag import Hannanum
hannanum = Hannanum()

req = urllib2.Request("https://www.datascienceschool.net/download-notebook/708e711429a646818b9dcbb581e0c10a/")
opener = urllib2.build_opener()
f = opener.open(req)
json = json.loads(f.read())
cell = ["\n".join(c["source"]) for c in json["cells"] if c["cell_type"] == u"markdown"]
docs = [w for w in hannanum.nouns(" ".join(cell)) if ((not w[0].isnumeric()) and (w[0] not in string.punctuation))]

vect = CountVectorizer().fit(docs)
count = vect.transform(docs).toarray().sum(axis=0)
plt.bar(range(len(count)), count)
plt.show()

pprint(zip(vect.get_feature_names(), count))


I am working on the file "Lecture/19. 나이브 베이즈/1) 나이브 베이즈 분류 모형.ipynb".
The first task is:
CountVectorize 사용
Can you write Python code for it?

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
from sklearn.metrics import classification_report

clf_1 = Pipeline([
            ('vect', CountVectorizer()),
            ('clf', MultinomialNB()),
        ])

%%time
clf_1.fit(X_train, y_train)

pprint(list(clf_1.named_steps["vect"].vocabulary_)[:10])

%%time
print(classification_report(y_test, clf_1.predict(X_test)))


I am working on the file "Lecture/19. 나이브 베이즈/1) 나이브 베이즈 분류 모형.ipynb".
The first task is:
예 1: 뉴스 그룹
Can you write Python code for it?

from sklearn.datasets import fetch_20newsgroups
from sklearn.cross_validation import train_test_split
news = fetch_20newsgroups(subset="all")
X_train, X_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.1, random_state=1)

from sklearn.feature_extraction.text import TfidfVectorizer, HashingVectorizer, CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline

clf_1 = Pipeline([
            ('vect', CountVectorizer()),
            ('clf', MultinomialNB()),
        ])
clf_2 = Pipeline([
            ('vect', TfidfVectorizer()),
            ('clf', MultinomialNB()),
        ])
clf_3 = Pipeline([
            ('vect', TfidfVectorizer(token_pattern=r"\b[a-z0-9_\-\.]+[a-z][a-z0-9_\-\.]+\b")),
            ('clf', MultinomialNB()),
        ])
clf_4 = Pipeline([
            ('vect', TfidfVectorizer(stop_words="english",
                                     token_pattern=r"\b[a-z0-9_\-\.]+[a-z][a-z0-9_\-\.]+\b")),
            ('clf', MultinomialNB()),
        ])
clf_5 = Pipeline([
            ('vect', TfidfVectorizer(stop_words="english",
                                     token_pattern=ur"\b[a-z0-9_\-\.]+[a-z][a-z0-9_\-\.]+\b")),
            ('clf', MultinomialNB(alpha=0.01)),
        ])

from sklearn.cross_validation import cross_val_score, KFold
from scipy.stats import sem

for i, clf in enumerate([clf_1, clf_2, clf_3, clf_4, clf_5]):
    scores = cross_val_score(clf, X_test, y_test, cv=5)
    print(("Model {0:d}: Mean score: {1:.3f} (+/-{2:.3f})").format(i, np.mean(scores), sem(scores)))


I am working on the file "Lecture/19. 나이브 베이즈/1) 나이브 베이즈 분류 모형.ipynb".
The first task is:
형태소 분석기 사용
Can you write Python code for it?

from konlpy.tag import Twitter
pos_tagger = Twitter()

def tokenize_pos(doc):
    return ['/'.join(t) for t in pos_tagger.pos(doc, norm=True, stem=True)]

clf_3 = Pipeline([
            ('vect', CountVectorizer(tokenizer=tokenize_pos)),
            ('clf', MultinomialNB()),
        ])

%%time
clf_3.fit(X_train, y_train)

pprint(list(clf_3.named_steps["vect"].vocabulary_)[:10])

%%time
print(classification_report(y_test, clf_3.predict(X_test), digits=4))

vect3 = clf_3.named_steps["vect"]
idx3 = np.array(np.argsort(vect3.transform(X_train).sum(axis=0)))[0]
voca3 = np.array(vect3.get_feature_names()).flatten()
pprint(voca3[idx3[-20:]].tolist())


I am working on the file "Lecture/19. 나이브 베이즈/1-1) 나이브 베이즈 분류 모형.ipynb".
The first task is:
1) 베르누이 분포 나이브 베이즈 모형

4개의 동전을 10번 던졌고, 클래스 0에 해당하는 곳이 3개, 클래스 1에 해당하는 곳이 7개 이다. 만약 x_new 값으로 [1,1,1,0] 일때 그것이 클래스 0과 클래스 1에 해당할 확률을 구해라.
Can you write Python code for it?

import numpy as np
from sklearn.naive_bayes import BernoulliNB

X = np.random.randint(2, size=(10, 4))
y = np.array([0,0,0,1,1,1,1,1,1,1])
print(X)
print(y)

clf_bern = BernoulliNB().fit(X, y)

clf_bern.classes_

clf_bern.class_count_

clf_bern.feature_count_

theta = np.exp(clf_bern.feature_log_prob_)
theta

x_new = np.array([1,1,1,0])

clf_bern.predict_proba([x_new])


I am working on the file "Lecture/23. PCA/1) 벡터 공간.ipynb".
The first task is:
단위 벡터
길이가 1인 벡터를 단위 벡터(unit vector)라고 한다. 예를 들어 다음과 같은 벡터들은 모두 단위 벡터이다.
$$
a = \begin{bmatrix}1 \ 0\end{bmatrix} ,\;\;
b = \begin{bmatrix}0 \ 1\end{bmatrix} ,\;\;
c = \begin{bmatrix} \dfrac{1}{\sqrt{2}} \ \dfrac{1}{\sqrt{2}} \end{bmatrix}
$$
Can you write Python code for it?

a = np.array([1, 0])
b = np.array([0, 1])
c = np.array([1/np.sqrt(2), 1/np.sqrt(2)])
np.linalg.norm(a), np.linalg.norm(b), np.linalg.norm(c)


I am working on the file "Lecture/23. PCA/1) 벡터 공간.ipynb".
The first task is:
벡터들의 선형 조합이 0이 되는 모두 0이 아닌 스칼라값들이 존재하지 않으면 그 벡터들은 선형 독립(linearly independent)이라고 한다.
$$ \alpha_1 a_1 + \cdots + \alpha_K a_K = 0  \;\;\;\; \leftrightarrow \;\;\;\; \alpha_1 = \cdots = \alpha_K = 0 $$
기저 벡터
벡터 공간에 속하는 벡터의 집합이 선형 독립이고 다른 모든 벡터 공간의 벡터들이 그 벡터 집합의 선형 조합으로 나타나면 그 벡터 집합을 벡터 공간의 기저 벡터(basis vector)라고 한다.
예를 들어 다음과 같은 두 벡터는 2차원 벡터 공간의 기저 벡터이다.
$$
a = \begin{bmatrix}1 \ 0\end{bmatrix} ,\;\;
b = \begin{bmatrix}0 \ 1\end{bmatrix} \;\;
$$
또는
$$
a = \begin{bmatrix}1 \ 1\end{bmatrix} ,\;\;
b = \begin{bmatrix}2 \ 3\end{bmatrix} \;\;
$$
다음과 같은 두 벡터는 2차원 벡터 공간의 기저 벡터가 될 수 없다.
$$
a = \begin{bmatrix}1 \ 2\end{bmatrix} ,\;\;
b = \begin{bmatrix}2 \ 4\end{bmatrix} \;\;
$$
열 공간
행렬은 열 벡터의 집합으로 볼 수 있다. 이 때 열 벡터들의 조합으로 생성되는 벡터 공간을 열 공간(column space)이라고 한다.
$$
A = \begin{bmatrix} 1 & 5 & 6 \ 2 & 6 & 8 \ 7 & 1 & 8 \end{bmatrix}
\;\;\;\; \rightarrow \;\;\;\;
\alpha_1 \begin{bmatrix} 1 \ 2 \ 7 \end{bmatrix} +
\alpha_2 \begin{bmatrix} 5 \ 6 \ 1 \end{bmatrix} +
\alpha_3 \begin{bmatrix} 6 \ 8 \ 8 \end{bmatrix}
\; \in \; \text{column space}
$$
열 랭크
행렬의 열 벡터 중 서로 독립인 열 벡터의 최대 갯수를 열 랭크(column rank) 혹은 랭크(rank)라고 한다.
예를 들어 다음 행렬의 랭크는 2이다.
$$
A = \begin{bmatrix} 1 & 5 & 6 \ 2 & 6 & 8 \ 3 & 11 & 14 \end{bmatrix}
$$
numpy의 linalg 서브 패키지의 matrix_rank 명령으로 랭크를 계산할 수 있다.
Can you write Python code for it?


I am working on the file "Lecture/23. PCA/1) 벡터 공간.ipynb".
The first task is:
벡터의 길이
벡터 $a$ 의 길이를 놈(norm) $\| a \|$ 이라고 하며 다음과 같이 계산할 수 있다.
$$ \| a \| = \sqrt{a^T a } = \sqrt{a_1^2 + \cdots + a_K^2} $$
numpy의 linalg 서브 패키지의 norm 명령으로 벡터의 길이를 계산할 수 있다.
Can you write Python code for it?


I am working on the file "Lecture/23. PCA/1) 벡터 공간.ipynb".
The first task is:
벡터의 선형 종속과 선형 독립
벡터들의 선형 조합이 0이 되는 모두 0이 아닌 스칼라값들이 존재하면 그 벡터들은 선형 종속(linearly dependent)이라고 한다.
$$
a = \begin{bmatrix}1 \ 2\end{bmatrix} ,\;\;
b = \begin{bmatrix}3 \ 3\end{bmatrix} \;\;
c = \begin{bmatrix}10 \ 14\end{bmatrix} \;\;
$$
$$
2a  + b - \frac{1}{2}c = 0
$$
Can you write Python code for it?


I am working on the file "Lecture/23. PCA/1) 벡터 공간.ipynb".
The first task is:
벡터의 합
벡터와 벡터의 합은 벡터가 된다.
$$
a = \begin{bmatrix}1 \ 2\end{bmatrix} ,\;\;
b = \begin{bmatrix}2 \ 1\end{bmatrix} \;\;\; \rightarrow \;\;\;
c = a + b = \begin{bmatrix}3 \ 3\end{bmatrix} \;\;
$$
Can you write Python code for it?

a = np.array([1, 2])
b = np.array([2, 1])
c = a + b

plt.annotate('', xy=a, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.annotate('', xy=b, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.annotate('', xy=c, xytext=(0,0), arrowprops=dict(facecolor='black'))

plt.plot(0, 0, 'ro', ms=10)
plt.plot(a[0], a[1], 'ro', ms=10)
plt.plot(b[0], b[1], 'ro', ms=10)
plt.plot(c[0], c[1], 'ro', ms=10)
plt.plot([a[0], c[0]], [a[1], c[1]], 'k--')
plt.plot([b[0], c[0]], [b[1], c[1]], 'k--')

plt.text(0.35, 1.15, "$a$", fontdict={"size": 18})
plt.text(1.15, 0.25, "$b$", fontdict={"size": 18})
plt.text(1.25, 1.45, "$c$", fontdict={"size": 18})

plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-1.4, 4.4)
plt.ylim(-0.6, 3.8)
plt.show()


I am working on the file "Lecture/23. PCA/1) 벡터 공간.ipynb".
The first task is:
좌표
벡터의 성분, 즉 좌표(coordinate)는 표준 기저 벡터들에 대한 해당 벡터의 투영(projection)으로 볼 수 있다.
Can you write Python code for it?

e1 = np.array([1, 0])
e2 = np.array([0, 1])
a = np.array([2, 2])

plt.annotate('', xy=e1, xytext=(0,0), arrowprops=dict(facecolor='green'))
plt.annotate('', xy=e2, xytext=(0,0), arrowprops=dict(facecolor='green'))
plt.annotate('', xy=a, xytext=(0,0), arrowprops=dict(facecolor='gray'))

plt.plot(0, 0, 'ro', ms=10)
plt.plot(a[0], a[1], 'ro', ms=10)

plt.text(1.05, 1.35, "$a$", fontdict={"size": 18})
plt.text(-0.2, 0.5, "$e_1$", fontdict={"size": 18})
plt.text(0.5, -0.2, "$e_2$", fontdict={"size": 18})

plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-1.5, 3.5)
plt.ylim(-0.5, 3)
plt.show()


I am working on the file "Lecture/23. PCA/1) 벡터 공간.ipynb".
The first task is:
투영
벡터 $a$를 다른 벡터 $b$에 직교하는 성분 $a_1$ 와 나머지 성분 $a_2 = a - a_1$로 분해할 수 있다. 이 때 $a_2$는 $b$와 평행하며 이 길이를 벡터 $a$의 벡터 $b$에 대한 투영(projection)이라고 한다.
벡터의 투영은 다음과 같이 내적을 사용하여 구할 수 있다.
$$ a = a_1 + a_2 $$
$$ a_1 \perp b \;\; \text{ and } \;\; a_2 = a - a_1 $$
이면
$$ \| a_2 \| = a^T\dfrac{b}{\|b\|} = \dfrac{a^Tb}{\|b\|} = \dfrac{b^Ta}{\|b\|} $$
이다.
또한 두 벡터 사이의 각도 $\theta$는 다음과 같이 구한다.
$$ \cos\theta = \dfrac{\| a_2 \|}{\| a \|} = \dfrac{a^Tb}{\|a\|\|b\|}$$
Can you write Python code for it?

a = np.array([1, 2])
b = np.array([2, 0])
a2 = np.dot(a, b)/np.linalg.norm(b) * np.array([1, 0])
a1 = a - a2

plt.annotate('', xy=a, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.annotate('', xy=b, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.annotate('', xy=a2, xytext=(0,0), arrowprops=dict(facecolor='green'))
plt.annotate('', xy=a1, xytext=(0,0), arrowprops=dict(facecolor='green'))

plt.plot(0, 0, 'ro', ms=10)
plt.plot(a[0], a[1], 'ro', ms=10)
plt.plot(b[0], b[1], 'ro', ms=10)

plt.text(0.35, 1.15, "$a$", fontdict={"size": 18})
plt.text(1.55, 0.15, "$b$", fontdict={"size": 18})
plt.text(-0.2, 1.05, "$a_1$", fontdict={"size": 18})
plt.text(0.50, 0.15, "$a_2$", fontdict={"size": 18})

plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-1.5, 3.5)
plt.ylim(-0.5, 3)
plt.show()


I am working on the file "Lecture/23. PCA/2) 고유분해와 특이값 분해.ipynb".
The first task is:
특이값 분해
정방 행렬이 아닌 행렬 $M$에 대해서도 고유 분해와 유사한 분해가 가능하다. 이를 특이값 분해(singular value decomposition)이라고 한다.

$M \in \mathbf{R}^{m \times n}$

$$M = U \Sigma V^T$$
여기에서
* $U \in \mathbf{R}^{m \times m}$
* $\Sigma  \in \mathbf{R}^{m \times n}$
* $V \in \mathbf{R}^{n \times n}$
이고 행렬 $U$와 $V$는 다음 관계를 만족한다.
$$ U^T U = UU^T = I $$
$$ V^T V = VV^T = I $$
예를 들어
$$\mathbf{M} = \begin{bmatrix}
                      1 & 0 & 0 & 0 & 2 \
                      0 & 0 & 3 & 0 & 0 \
                      0 & 0 & 0 & 0 & 0 \
                      0 & 2 & 0 & 0 & 0
                    \end{bmatrix}
$$
에 대한 특이값 분해 결과는 다음과 같다.
$$
\begin{align}
\mathbf{U} &= \begin{bmatrix}
               0 & 0 & 1 &  0 \
               1 & 0 & 0 &  0 \
               0 & 0 & 0 & -1 \
               0 & 1 & 0 &  0 \
             \end{bmatrix} \
\boldsymbol{\Sigma} &= \begin{bmatrix}
                        \sqrt{5} & 0 & 0 & 0 & 0 \
                        0 & 2 & 0 & 0 & 0 \
                        0 & 0 & 1 & 0 & 0 \
                        0 & 0 & 0 & 0 & 0
                      \end{bmatrix} \
\mathbf{V}^T &= \begin{bmatrix}
                           0 & 0 & \sqrt{0.2} & 0 & \sqrt{0.8} \
                           0 & 1 & 0 & 0 & 0 \
                           1 & 0 & 0 & 0 & 0 \
                           0 & 0 & -\sqrt{0.8} & 0 & \sqrt{0.2} \
                           0 & 0 & 0 & 1 & 0 \
               \end{bmatrix}
\end{align}$$
이는 다음과 같이 확인 할 수 있다.
$$\begin{align}
\mathbf{U} \mathbf{U^T} &=
   \begin{bmatrix}
               0 & 0 & 1 &  0 \
               1 & 0 & 0 &  0 \
               0 & 0 & 0 & -1 \
               0 & 1 & 0 &  0 \
             \end{bmatrix}
\cdot
  \begin{bmatrix}
               0 & 1 & 0 & 0 \
               0 & 0 & 0 & 1 \
               1 & 0 & 0 & 0 \
               0 & 0 & -1 & 0 \
             \end{bmatrix}
   =
  \begin{bmatrix}
    1 & 0 & 0 & 0 \
    0 & 1 & 0 & 0 \
    0 & 0 & 1 & 0 \
    0 & 0 & 0 & 1
  \end{bmatrix}
   = \mathbf{I}_4 \
\mathbf{V} \mathbf{V^T} &=
  \begin{bmatrix}
                          ...
Can you write Python code for it?

from pprint import pprint
M = np.array([[1,0,0,0,0],[0,0,2,0,3],[0,0,0,0,0],[0,2,0,0,0]])
print("\nM:"); pprint(M)
U, S0, V0 = np.linalg.svd(M, full_matrices=True)
print("\nU:"); pprint(U)
S = np.hstack([np.diag(S0), np.zeros(M.shape[0])[:, np.newaxis]])
print("\nS:"); pprint(S)
print("\nV:"); pprint(V)
V = V0.T
print("\nU.dot(U.T):"); pprint(U.dot(U.T))
print("\nV.dot(V.T):"); pprint(V.dot(V.T))
print("\nU.dot(S).dot(V.T):"); pprint(U.dot(S).dot(V.T))


I am working on the file "Lecture/25. 앙상블 방법론/1) 모형 결합.ipynb".
The first task is:
다수결 모형이 개별 모형보다 더 나은 성능을 보이는 이유는 다음 실험에서도 확인 할 수 있다.
만약 어떤 개별 모형이 오차를 출력할 확률이 $p$인 경우에 이러한 모형을 $N$ 개 모아서 다수결 모형을 만들면 오차를 출력할 확률이 다음과 같아진다.
$$ \sum_{k>\frac{N}{2}}^N \binom N k p^k (1-p)^{N-k} $$
Can you write Python code for it?

def total_error(p, N):
    te = 0.0
    for k in range(int(np.ceil(N/2)), N + 1):
        te += sp.misc.comb(N, k) * p**k * (1-p)**(N-k)
    return te

x = np.linspace(0, 1, 100)
plt.plot(x, x, 'g:', lw=3, label="individual model")
plt.plot(x, total_error(x, 10), 'b-', label="voting model (N=10)")
plt.plot(x, total_error(x, 100), 'r-', label="voting model (N=100)")
plt.xlabel("performance of individual model")
plt.ylabel("performance of voting model")
plt.legend(loc=0)
plt.show()


I am working on the file "Lecture/25. 앙상블 방법론/1) 모형 결합.ipynb".
The first task is:
배깅
배깅(bagging)은 동일한 모형과 모형 모수를 사용하는 대신 부트스트래핑(bootstrapping)과 유사하게 트레이닝 데이터를 랜덤하게 선택해서 다수결 모형을 적용한다.
트레이닝 데이터를 선택하는 방법에 따라 다음과 같이 부르기도 한다.

같은 데이터 샘플을 중복사용(replacement)하지 않으면: Pasting
같은 데이터 샘플을 중복사용(replacement)하면 Bagging
데이터가 아니라 다차원 독립 변수 중 일부 차원을 선택하는 경우에는: Random Subspaces
데이터 샘플과 독립 변수 차원 모두 일부만 랜덤하게 사용하면: Random Patches

성능 평가시에는 트레이닝용으로 선택한 데이터가 아닌 다른 데이터를 사용할 수도 있다. 이런 데이터를 OOB(out-of-bag) 데이터라고 한다.
Scikit-Learn 의  ensemble 서브패키지는 배깅 모형 결합을 위한 BaggingClassifier 클래스를 제공한다. 사용법은 다음과 같다.
sklearn.ensemble.BaggingClassifier(base_estimator=None, n_estimators=10, max_samples=1.0, max_features=1.0, bootstrap=True, bootstrap_features=False, oob_score=False, warm_start=False, n_jobs=1, random_state=None, verbose=0)

인수:
base_estimator:
기본 모형
n_estimators: 정수. 디폴트 10
모형 갯수
max_samples: 정수 혹은 실수. 디폴트 1.0
데이터 샘플 중 선택할 샘플의 수 혹은 비율
max_features: 정수 혹은 실수. 디폴트 1.0
다차원 독립 변수 중 선택할 차원의 수 혹은 비율
bootstrap: 불리언, 디폴트 True
데이터 중복 사용 여부
bootstrap_features: 불리언, 디폴트 False
차원 중복 사용 여부
oob_score: 불리언 디폴트 False
성능 평가시 OOB(out-of-bag) 샘플 사용 여부
Can you write Python code for it?

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.ensemble import BaggingClassifier

iris = load_iris()
X, y = iris.data[:, [0, 2]], iris.target

model1 = DecisionTreeClassifier().fit(X, y)
model2 = BaggingClassifier(DecisionTreeClassifier(), bootstrap_features=True, random_state=0).fit(X, y)

x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.1), np.arange(y_min, y_max, 0.1))

plt.figure(figsize=(8,12))

plt.subplot(211)
Z1 = model1.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
plt.contourf(xx, yy, Z1, alpha=0.6, cmap=mpl.cm.jet)
plt.scatter(X[:, 0], X[:, 1], c=y, alpha=1, s=50, cmap=mpl.cm.jet)

plt.subplot(212)
Z2 = model2.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
plt.contourf(xx, yy, Z2, alpha=0.6, cmap=mpl.cm.jet)
plt.scatter(X[:, 0], X[:, 1], c=y, alpha=1, s=50, cmap=mpl.cm.jet)

plt.tight_layout()
plt.show()


I am working on the file "Lecture/25. 앙상블 방법론/1) 모형 결합.ipynb".
The first task is:
에이다 부스트
에이다 부스트와 같은 부스트(boost) 방법은 미리 정해진 모형 집합을 사용하는 것이 아니라 단계적으로 모형 집합에 포함할 개별 모형을 선택한다. 부스트 방법에서 성능이 떨어지는 개별 모형을 weak classifier라고 한다.
또한 다수결 방법을 사용하지 않고 각 weak classifier $k$개에 대한 가중치를 주고 선형 결합하여 최종 모형인 boosted classifier $C$를 생성한다.
$$ C_{(m-1)}(x_i) = \alpha_1k_1(x_i) + \cdots + \alpha_{m-1}k_{m-1}(x_i) $$
$$ C_{m}(x_i) = C_{(m-1)}(x_i) + \alpha_m k_m(x_i) $$

$k_m$ 선택 방법

가중치 오차가 가장 적은 $k_m$
$$ E = \sum_{y_i \neq k_m(x_i)} w_i^{(m)} = \sum_{y_i \neq k_m(x_i)} e^{-y_i C_{m-1}(x_i)}$$

$\alpha_m$ 결정 방법

$$ \epsilon_m = \dfrac{\sum_{y_i \neq k_m(x_i)} w_i^{(m)} }{ \sum_{i=1}^N w_i^{(m)}} $$
$$ \alpha_m = \frac{1}{2}\ln\left( \frac{1 - \epsilon_m}{\epsilon_m}\right) $$

속도 조절을 위해 learning rate $\nu$를 추가

$$ C_{m}(x_i) = C_{(m-1)}(x_i) + \nu\alpha_m k_m(x_i) $$
에이다 부스트 클래스는 AdaBoostClassifier 이다.
Can you write Python code for it?

from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_gaussian_quantiles

# Construct dataset
X1, y1 = make_gaussian_quantiles(cov=2.,
                                 n_samples=200, n_features=2,
                                 n_classes=2, random_state=1)
X2, y2 = make_gaussian_quantiles(mean=(3, 3), cov=1.5,
                                 n_samples=300, n_features=2,
                                 n_classes=2, random_state=1)
X = np.concatenate((X1, X2))
y = np.concatenate((y1, - y2 + 1))

# Create and fit an AdaBoosted decision tree
bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=1),
                         algorithm="SAMME",
                         n_estimators=200)

bdt.fit(X, y)

plot_colors = "br"
plot_step = 0.02
class_names = "AB"

plt.figure(figsize=(12,6))

plt.subplot(121)
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, plot_step),
                     np.arange(y_min, y_max, plot_step))

Z = bdt.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
cs = plt.contourf(xx, yy, Z, cmap=plt.cm.Paired)
plt.axis("tight")

for i, n, c in zip(range(2), class_names, plot_colors):
    idx = np.where(y == i)
    plt.scatter(X[idx, 0], X[idx, 1],
                c=c, cmap=plt.cm.Paired,
                label="Class %s" % n)
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.legend(loc='upper right')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Decision Boundary')

twoclass_output = bdt.decision_function(X)
plot_range = (twoclass_output.min(), twoclass_output.max())
plt.subplot(122)
for i, n, c in zip(range(2), class_names, plot_colors):
    plt.hist(twoclass_output[y == i],
             bins=10,
             range=plot_range,
             facecolor=c,
             label='Class %s' % n,
             alpha=.5)
x1, x2, y1, y2 = plt.axis()
plt.axis((x1, x2, y1, y2 * 1.2))
plt.legend(loc='upper...


I am working on the file "Lecture01.ipynb".
The first task is:
Classification
We can ask SymPy to classify our ODE, e.g. show that it is first order):
Can you write Python code for it?


I am working on the file "Lecture01.ipynb".
The first task is:
Example: car breaking
During braking a car’s velocity is given by $v = v_{0} e^{−t/\tau}$. Calculate the distance travelled.
We first define the symbols in the equation ($t$, $\tau$ and $v_{0}$), and the function ($x$, for the displacement):
Can you write Python code for it?

t, tau, v0 = symbols("t tau v0")
x = Function("x")


I am working on the file "Lecture01.ipynb".
The first task is:
First, let's classify the ODE:
Can you write Python code for it?


I am working on the file "Lecture01.ipynb".
The first task is:
Specifying a value for $v_{0}$, we create an interactive plot of $x$ as a function of the parameter $\tau$:
Can you write Python code for it?

x = x.subs(v0, 100)

def plot(τ=1.0):
    x1 = x.subs(tau, τ)

    # Plot position vs time
    sympy.plot(x1.args[1], (t, 0.0, 10.0), xlabel="time", ylabel="position");

interact(plot, τ=(0.0, 10, 0.2));


I am working on the file "Lecture01.ipynb".
The first task is:
SymPy can verify that an expression is a solution to an ODE:
Can you write Python code for it?

print("Is v a solution to the ODE: {}".format(checkodesol(eqn, v)))


I am working on the file "Lecture01.ipynb".
The first task is:
We see that it is not linear, but it is separable. Using dsolve again,
Can you write Python code for it?


I am working on the file "Lecture02.ipynb".
The first task is:
Checking the order of the ODE:
Can you write Python code for it?

print("This order of the ODE is: {}".format(ode_order(eqn, y(t))))


I am working on the file "Lecture02.ipynb".
The first task is:
Mass-spring-damper system
The differential equation that governs an unforced, single degree-of-freedom mass-spring-damper system is
$$
m \frac{d^{2}y}{dt^{2}} + \lambda \frac{dy}{dt} + ky = 0
$$
To solve this problem using SymPy, we first define the symbols $t$ (time), $m$ (mass), $\lambda$ (damper coefficient) and $k$ (spring stiffness), and the function $y$ (displacement):
Can you write Python code for it?

t, m, lmbda, k = symbols("t m lambda k")
y = Function("y")


I am working on the file "Lecture02.ipynb".
The first task is:
Solving this equation,
Can you write Python code for it?


I am working on the file "Lecture02.ipynb".
The first task is:
The solution looks very complicated because we have not specified values for the constants $m$, $\lambda$ and $k$. The nature of the solution depends heavily on the relative values of the coefficients, as we will see later. We have four constants because the most general case the solution is complex, with two complex constants having four real coefficients.
Note that the solution is make up of expoential functions and sinusoidal functions. This is typical of second-order ODEs.
Second order, constant coefficient equation
We'll now solve
$$
\frac{d^{2}y}{dx^{2}} + 2 \frac{dy}{dx} - 3 y = 0
$$
The solution for this problem will appear simpler because we have concrete values for the coefficients.
Entering the differential equation:
Can you write Python code for it?

y = Function("y")
x = symbols("x")
eqn = Eq(Derivative(y(x), x, x) + 2*Derivative(y(x), x) - 3*y(x), 0)
display(eqn)


I am working on the file "Lecture02.ipynb".
The first task is:
and now classifying the ODE:
Can you write Python code for it?

print("Properties of the ODE are: {}".format(classify_ode(eqn)))


I am working on the file "Lecture02.ipynb".
The first task is:
and then compute the roots:
Can you write Python code for it?


I am working on the file "Lecture02.ipynb".
The first task is:
which is the general solution. As expected for a second-order equation, there are two constants.
Note that the general solution is of the form
$$
y = C_{1} e^{\lambda_{1} x} + C_{2} e^{\lambda_{2} x}
$$
The constants $\lambda_{1}$ and $\lambda_{2}$ are roots of the \emph{characteristic} equation
$$
\lambda^{2} + 2\lambda - 3 = 0
$$
This quadratic equation is trivial to solve, but for completeness we'll look at how to solve it using SymPy. We first define the quadratic equation:
Can you write Python code for it?

eqn = Eq(lmbda**2 + 2*lmbda -3, 0)
display(eqn)


I am working on the file "Lecture04.ipynb".
The first task is:
Now solve the non-homogeneous case for some $f(x)$:
Can you write Python code for it?

eqn = Eq(Derivative(y(x), x, x) + 2*Derivative(y(x), x) + y(x), f(x))
dsolve(eqn)


I am working on the file "Lecture04.ipynb".
The first task is:
We first solve the homogeneous equation:
Can you write Python code for it?

x = Symbol("x")
y = Function("y")
f = Function("f")
eqn = Eq(Derivative(y(x), x, x) + 2*Derivative(y(x), x) + y(x), 0)
display(eqn)
dsolve(eqn)


I am working on the file "Lecture05.ipynb".
The first task is:
General case
Below is the general case for a constant coefficient, second-order difference equation.
Can you write Python code for it?

n = Symbol("n", integer=True)
y = Function("y")

a, b, c = symbols("a b c")

f = a*y(n) - b*y(n - 1) + c*y(n - 2)
display(f)


I am working on the file "Lecture05.ipynb".
The first task is:
If we now specify the values for the constants, the solution can be plotted:
Can you write Python code for it?

eqn1 = eqn.subs('a', 4).subs('b', 1).subs('c', 2)
soln = rsolve(eqn1, y(n), init={y(0) : 1, y(1) : 2})
display(soln)

plot(soln, (n, 0, 12), xlabel="$n$", ylabel="$y_{n}$");


I am working on the file "Lecture05.ipynb".
The first task is:
Interactive solution
With an interactive plot, we can see how the form of the solution changes with changing constants in the difference equation.
We first define the difference equation:
Can you write Python code for it?

f = a*y(n) - b*y(n - 1) + c*y(n - 2)
eqn = Eq(f, 0)
display(eqn)


I am working on the file "Lecture05.ipynb".
The first task is:
Solving and plotting:
Can you write Python code for it?

def plot_solution(a=6, b=1, c=8):
    # Substitute in parameters
    eqn1 = eqn.subs('a', a).subs('b', b).subs('c', c)

    # Check roots
    roots = ((-b - sqrt(b**2 - 4*a*c))/(2*a), (-b + sqrt(b**2 - 4*a*c))/(2*a))
    print("Roots of characteristic eqn:")
    display(roots)

    # Solve
    soln = rsolve(eqn1, y(n), init={y(0) : 1, y(1) : 2})
    print("Solution:")
    display(soln)

    # Plot
    plot(soln, (n, 0, 20), xlabel="$n$", ylabel="$y_n$", axis_center="auto", adaptive=False, nb_of_points=21)

interact(plot_solution, a=(-10, 11, 2), b=(-2, 20, 1), c=(1, 10, 1), continuous_update=False);


I am working on the file "Lecture05.ipynb".
The first task is:
Solving for the homogeneous case,
Can you write Python code for it?

eqn = Eq(f, 0)
soln = rsolve(eqn, y(n))
display(soln)


I am working on the file "Lecture05.ipynb".
The first task is:
The above is a general solution. Solving for some initial conditions,
Can you write Python code for it?

soln = rsolve(eqn, y(n), init={y(0) : 2, y(1) : 1})
display(soln)


I am working on the file "Lecture05.ipynb".
The first task is:
The solution is the same as in the lecture notes.
We now consider the non-homogeneous case:
Can you write Python code for it?

# Create non-homogeneous equation
eqn = Eq(f, -63.685*(1.07**n))
display(eqn)


I am working on the file "Lecture06.ipynb".
The first task is:
The normal direction to the surface is given by $\nabla f$
$$
\nabla f = \frac{\partial f}{\partial x} \boldsymbol{e}{1} + \frac{\partial f}{\partial y} \boldsymbol{e}{2}
$$
evaluated at a point on the surface.
Can you write Python code for it?

x, y = symbols('x y')
f = Eq(x**2/a**2 + y**2/b**2, 1)
display(f)
grad_f = (diff(f.args[0], x), diff(f.args[0], y))
display(grad_f)


I am working on the file "Lecture07.ipynb".
The first task is:
If we consider a transformation matrix that is not diagonal, the transformed cube will not longer be a rectangular prism:
Can you write Python code for it?

# Create a transformation matrix (diagonal)
A = np.array([[0.8, 0.8, 0.8], [0.6, 1.0, 0.0], [-1.1, 0.0, 0.7]])

# Check determinant
print("Det A: {}".format(np.linalg.det(A)))

# Draw orginal cube and transformed shape
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect("equal")
r = [0, 1]
for s, e in combinations(np.array(list(product(r, r, r))), 2):
    if np.sum(np.abs(s - e)) == r[1] - r[0]:
        ax.plot3D(*zip(s, e), color="b", marker="o")

        s = A.dot(s)
        e = A.dot(e)
        ax.plot3D(*zip(s, e), color="r", marker="o")

# Create a transformation matrix (diagonal)
A = np.array([[2.0, 0.0, 0.0], [0.0, 1.1, 0.0], [0.0, 0.0, 1.1]])

# Check determinant
print("Det A: {}".format(np.linalg.det(A)))

# Draw orginal cube and transformed shape
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect("equal")
r = [0, 1]
for s, e in combinations(np.array(list(product(r, r, r))), 2):
    if np.sum(np.abs(s - e)) == r[1] - r[0]:
        ax.plot3D(*zip(s, e), color="b", marker="o")

        s = A.dot(s)
        e = A.dot(e)
        ax.plot3D(*zip(s, e), color="r", marker="o")


I am working on the file "Lecture07.ipynb".
The first task is:
Inverse and determinant
It is easy to compute the determinant and the inverse of a square matrix:
Can you write Python code for it?

# Compute determinant
detA = np.linalg.det(A)
print("Determinant of A: {}".format(detA))

# Compute inverse
Ainv = np.linalg.inv(A)
print("Inverse of A")
print(Ainv)

# Check that inverse is correct
print("A*A^-1: {}".format(A*Ainv))


I am working on the file "Lecture07.ipynb".
The first task is:
The determinant is greater than one, so we expect the volume of the transformed polyhedron (red lines) to be to larger. Applying $\boldsymbol{A}$ to the coordinate vector of each vertex of the unit cube, we see the effect of the transformation.
Can you write Python code for it?

# Draw orginal cube and transformed shape
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_aspect("equal")
r = [0, 1]
for s, e in combinations(np.array(list(product(r, r, r))), 2):
    if np.sum(np.abs(s - e)) == r[1] - r[0]:
        ax.plot3D(*zip(s, e), color="b", marker="o")

        s = A.dot(s)
        e = A.dot(e)
        ax.plot3D(*zip(s, e), color="r", marker="o")


I am working on the file "Lecture07.ipynb".
The first task is:
We can perform some basic operations, such at the dot product, matrix-vector multiplication and taking the transpose.
Can you write Python code for it?

# Dot product between two vectors
x = u.dot(v)
print("Dot product (u.v): {}".format(x))

# Product Au
x = A.dot(u)
print("Product Au: {}".format(x))

# Product A*A
x = A.dot(A)
print("Product AA: {}".format(x))

# Transpose A^T
At = np.transpose(A)
print("A^T: {}".format(At))


I am working on the file "Lecture08.ipynb".
The first task is:
The columns of $\boldsymbol{Q}$ are orthonormal, and $\boldsymbol{Q}^{T}$ is also a rotation matrix and has orthonormal columns. Therefore, the rows of $\boldsymbol{Q}$ are also orthonormal.
Can you write Python code for it?

# Compute dot product of row vectors q_{i} \cdot q_{j}
pairs = itertools.combinations_with_replacement(range(len(Q)), 2)
for p in pairs:
    row0, row1 = p[0], p[1]
    print ("Dot product of row vectors {}, {}: {}".format(row0, row1, Q[row0, :].dot(Q[row1, :])))


I am working on the file "Lecture09.ipynb".
The first task is:
We now apply the transformation defined by $\boldsymbol{R}$ to $\boldsymbol{A}$:
Can you write Python code for it?


I am working on the file "Lecture10.ipynb".
The first task is:
Non-symmetric matrices
In general, the eigenvalues and eigenvectors of a non-symmetric, real-valued matrix are complex. We can see this by example:
Can you write Python code for it?

B = np.random.rand(5, 5)
evalues, evectors = np.linalg.eig(B)

print("Eigenvalues: {}".format(evalues))
print("Eigenvectors: {}".format(evectors))


I am working on the file "Lecture11.ipynb".
The first task is:
After just 10 iterations, the estimated eigenvalue is very accurate.
We now demonstrate a case where the power iteration fails - namely, when the starting vector is orthogonal to the eigenvector associated with the largest eigenvalue. We compute a starting vector that is orthogonal to the eigenvector associated with the largest eigenvector, and then perform power iterations:
Can you write Python code for it?

# Create starting vector
x0 = np.random.rand(S.shape[0])

# Get eigenvector associated with maxiumum eigenvalue
eval_max_index = abs(lmbda).argmax()
evec_max = U[:,eval_max_index]

# Make starting vector orthogonal to eigenvector associated with maximum
x0 = x0 - x0.dot(evec_max)*evec_max

# Perform power iteration
for i in range(10):
    x0 = S.dot(x0)
    x0 = x0/np.linalg.norm(x0)
x1 = S.dot(x0)

# Print estimated max eigenvalue and error
max_eig_est = np.sign(x1.dot(x0))*np.linalg.norm(x1)/np.linalg.norm(x0)
print("Estimate of largest eigenvalue: {}".format(max_eig_est))
print("Error: {}".format(abs(max_eig - max_eig_est)))

# Get second largest eigenvalue
print("Second largest eigenvalue (exact): {}".format(lmbda[np.argsort(abs(lmbda))[-2]]))


I am working on the file "Lecture11.ipynb".
The first task is:
It is clear that in this case we have approached the second largest eigenvalue.
Computing the eigenvalue
A better way to compute the largest eigenvalue, given corresponding eigenvectors, is using the Rayleigh quotient. We want to find $\mu$ that minimises
$$
\| \boldsymbol{A} \boldsymbol{x}{n} - \mu \boldsymbol{x}{n}  \|
$$
It turns out that
$$
\mu = \frac{\boldsymbol{x}{n}^{T} \boldsymbol{A} \boldsymbol{x}{n}}{\boldsymbol{x}{n}^{T} \boldsymbol{x}{n}}
$$
which is known at the Rayleigh quotient. We can use this for the preceding power iteration:
Can you write Python code for it?

rayleigh_quotient = x1.dot(S).dot(x1)/(x1.dot(x1))
print("Rayleigh_quotient: {}".format(rayleigh_quotient))


I am working on the file "Lecture11.ipynb".
The first task is:
Next, we use power iterations:
Can you write Python code for it?

# Create starting vector
x0 = np.random.rand(A.shape[0])

# Perform power iteration
for i in range(10):
    x0 = A.dot(x0)
    x0 = x0/np.linalg.norm(x0)

# Normalise eigenvector using l1 norm
x0 = x0/np.linalg.norm(x0, 1)

# Print estimated eigenvector associated with largest eigenvalue
print("Estimate of eigenvector for the largest eigenvalue: {}".format(x0))

# Print estimated max eigenvalue (using Rayleigh quotient)
print("Estimate of largest eigenvalue: {}".format(x0.dot(A).dot(x0)/x0.dot(x0)))


I am working on the file "Lecture11.ipynb".
The first task is:
Note that the matrix Lambda ($\boldsymbol{\Lambda}$) is diagonal, and the diagonal entries are the eigenvalues.
Diagonalisation of symmetric matrices
In the above, we have only required that the eigenvectors be linearly independent. In this case, the matrix $\boldsymbol{U}$ can be inverted. For a symmetric matrix, we have proved in the lecture notes that the eigenvectors are orthogonal. Therefore, for a real, symmetric matrix $\boldsymbol{S}$, if the eigenvectors have been normalised the matrix $\boldsymbol{U}$ is an orthogonal matrix. In this case
$$
\boldsymbol{S} = \boldsymbol{U} \boldsymbol{\Lambda} \boldsymbol{U}^{T}
$$
In terms of the notation used for the rotation of matrices, $\boldsymbol{R} = \boldsymbol{U}^{T}$, where in this case $\boldsymbol{R}$ is used to change the basis to one aligned with the eigenvectors:
$$
\boldsymbol{S} = \boldsymbol{R}^{T} \boldsymbol{\Lambda} \boldsymbol{R}
$$
Since $\boldsymbol{R}$ is an orthogonal matrix,
$$
\boldsymbol{\Lambda} = \boldsymbol{R} \boldsymbol{S} \boldsymbol{R}^{T}
$$
We can test this for a given matrix:
Can you write Python code for it?

# Create a symmetric matrix
S = A + A.T

# Compute eigenvectors of S and print eigenvalues
lmbda, U = np.linalg.eig(S)
print(lmbda)

# R matrix
R = U.T

# Diagonalise S
Lambda = R.dot(S.dot(R.T))
print(Lambda)


I am working on the file "Lecture11.ipynb".
The first task is:
Sheep flock example
In the lecture, we considered the growth rate and composition of a sheep flock over  a large number of farming cycles. The equation of interests was
$$
\begin{bmatrix}
    x_{n+1} \
    y_{n+1} \
    z_{n+1}
\end{bmatrix}
=
\begin{bmatrix}
0      & 2   & 0.9633
\
0.545  & 0   & 0
\
0      & 0.8 & 0
\end{bmatrix}
\begin{bmatrix}
    x_{n} \
    y_{n} \
    z_{n}
\end{bmatrix}
$$
we can use power iterations to estimate the maximum eigenvalue and the corresponding eigenvector. First we, create the matrix:
Can you write Python code for it?


I am working on the file "Lecture11.ipynb".
The first task is:
The above matrix is diagonal, and the diagonal entries are the eigenvalues.
Power iteration
It was shown the lectures that the maximum eigenvalue, and associated eigenvector, can be estimated via repeated matrix-vector products. The method is known as power iterations. Below is sample code for the power iteration.
Can you write Python code for it?

# Create starting vector
x0 = np.random.rand(S.shape[0])

# Perform power iteration
for i in range(10):
    x0 = S.dot(x0)
    x0 = x0/np.linalg.norm(x0)
x1 = S.dot(x0)

# Get maxiumum exact eigenvalue (absolute value)
eval_max_index = abs(lmbda).argmax()
max_eig = lmbda[eval_max_index]

# Print estimated max eigenvalue and error
max_eig_est = np.sign(x1.dot(x0))*np.linalg.norm(x1)/np.linalg.norm(x0)
print("Estimate of largest eigenvalue: {}".format(max_eig_est))
print("Error: {}".format(abs(max_eig - max_eig_est)))


I am working on the file "Lecture11.ipynb".
The first task is:
The matrix A is non-symmetric, hence it is no surprise that the eigenvalues and eigenvectors are complex. The $i$th column of evectors (A[:,i]) is the $i$th eigenvector.
We can now verify that $\boldsymbol{\Lambda} = \boldsymbol{U}^{-1} \boldsymbol{A} \boldsymbol{U}$
Can you write Python code for it?

Lambda = np.linalg.inv(evectors).dot(A.dot(evectors))
print(Lambda)


I am working on the file "Lecture11.ipynb".
The first task is:
We can compute the eigenvectors and eigenvalues using the NumPy function linalg.eig
Can you write Python code for it?

# Compute eigenvectors of A
evalues, evectors = np.linalg.eig(A)

print("Eigenvalues: {}".format(evalues))
print("Eigenvectors: {}".format(evectors))


I am working on the file "Lecture1_Introduction.ipynb".
The first task is:
Physical parameters:
Can you write Python code for it?


I am working on the file "Lecture1_Introduction.ipynb".
The first task is:
Specify spatial grid in Python:
Can you write Python code for it?

L = 1.                                          # length of domain
J = 41                                          # number of grid points
dx = float(L)/float(J-1)                        # mesh size h = dx
#x_grid = np.array([j*dx for j in range(J)])   # spatial grid points
x_grid = np.linspace(0,1.0,J)                    #


I am working on the file "Lecture1_Introduction.ipynb".
The first task is:
That leaves us with two vectors:
'lbound', which has the indices for $x\geq 0.125$  and
'ubound', which has the indices for $ x\leq 0.5$.
To combine these two, we can use an intersection with np.intersect1d().
Can you write Python code for it?

bounds = np.intersect1d(lbound, ubound)
u[bounds]=2  #setting u = 2 between 0.5 and 1 as per our I.C.s

u0 = np.ones(J)

pyplot.plot(x_grid, u, color='#003366', ls='--', lw=3)
pyplot.ylim(0,2.5);

for n in range(N):
    u0 = u.copy()
    u[1:-1] = u0[1:-1] + a*dt/dx**2*(u0[2:] -2*u0[1:-1] +u0[0:-2])

    # Set Dirichlet boundary conditions
    u[0] = 1;  u[N] = 1

    if n%3 == 0:
        pyplot.plot(x_grid, u, color='#003366', ls='--', lw=3)
        pyplot.ylim(0,2.5);

pyplot.plot(x_grid, u, color='#003366', ls='--', lw=3)
pyplot.ylim(0.8,2.2);


I am working on the file "Lecture4-Main.ipynb".
The first task is:
2.1 Variable lifetime
Variables within functions exist only withing their namespaces. Once the function stops, all the variables inside it gets destroyed. For instance, the following won't work.
Can you write Python code for it?


I am working on the file "Lecture4-Main.ipynb".
The first task is:
8. Closures
Remember this example?
Can you write Python code for it?


I am working on the file "Lecture4-Main.ipynb".
The first task is:
8.1.1 Sorted

Python's sorted function can sort based on a key argument, key is a lambda function that deterimes how the data is sorted.
Can you write Python code for it?

student_tuples = [ #(Name, height(cms), weight(kg))
        ('john', 180, 85),
        ('doe', 177, 99),
        ('jane', 169, 69),
]

# Sort based on height
print 'Weight: ', sorted(student_tuples,  key=lambda stud: stud[1])

# Sort based on Name
print 'Name: ', sorted(student_tuples, key=lambda stud: stud[0])

# Sort based on BMI
print 'BMI: ', sorted(student_tuples, key=lambda stud: stud[2]*100/stud[1])


I am working on the file "Lecture4-Main.ipynb".
The first task is:
9.1 Logging and timing a function

Decorators can be classes, they can take input arguments/keyword args.

Lets build a decorator that logs and times another function
Can you write Python code for it?

import time
from pdb import set_trace

def logger(func):
    def inner(*args, **kwargs):
        print "Arguments were: %s, %s"%(args, kwargs)
        return func(*args, **kwargs)
    return inner

def timer(func):
    def inner(*args, **kwargs):
        tb=time.time()
        result = func(*args, **kwargs)
        ta=time.time()
        print "Time taken: %f sec"%(ta-tb)
        return result
    return inner

@logger
@timer
def foo(a=5, b=2):
    return a+b

@logger
@timer
def bar(a=10, b=1):
    time.sleep(0.1)
    return a-b

if __name__=='__main__': ## <----- Note
    foo(2,3)
    bar(5,7)


I am working on the file "Lecture4-Main.ipynb".
The first task is:
A common practice is to replace the original function with the decorated function
Can you write Python code for it?

def outer(func):
    def inner():
        "Inner"
        print 'Decorating...'
        ret = func()
        ret += 1
        return ret
    return inner

def foo():
    "I'm foo"
    return 1

print foo()
foo = outer(foo)

print foo()


I am working on the file "Lecture4-Main.ipynb".
The first task is:
All arg and kwarg conventions apply here

6.1 Overriding class methods
Lets try:
Can you write Python code for it?

class foo():
    def __init__(i, num):
        i.num = num

d = foo(2)
d()


I am working on the file "Lecture4-Main.ipynb".
The first task is:
Aside: __repr__, __call__,__getitem__,...  are all awesome.
Can you write Python code for it?

class foo():
    "Me is foo"
    def __init__(i, num):
        i.num = num
    def __add__(i, new):
        i.num += new
        return i
    def __sub__(i, new):
        i.num -= new
        return i
    def __repr__(i):
        return i.__doc__
    def __getitem__(i, num):
        print "Nothing @ %d"%(num)

FOO = foo(4)
FOO[2]


I am working on the file "Lecture4-Main.ipynb".
The first task is:
Declare global every time the global x needs changing

6. Classes

Define classes with the class keyword
Here's a simple class
Can you write Python code for it?

class foo():
    def __init__(i, arg1): # self can br replaced by anything.
        i.arg1 = arg1
    def bar(i, arg2): # Always use self as the first argument
        print i.arg1, arg2

FOO = foo(7)

FOO.bar(5)

print FOO.arg1


I am working on the file "Lecture4-Main.ipynb".
The first task is:
If you try and reassign a global variable inside a function, like so:
Can you write Python code for it?

aString = 'Global var'
def foo():
    aString = 'Local var'
    print aString

foo()


I am working on the file "Lecture4-Main.ipynb".
The first task is:
It follows that the variable a here is a class.
Can you write Python code for it?


I am working on the file "Lecture4-Main.ipynb".
The first task is:
Lets look at memory locations of the functions.
Can you write Python code for it?

def outer(func):
    def inner(*args):
        "Inner"
        print 'Decorating...'
        ret = func()
        ret += 1
        return ret
    print inner.__doc__, inner
    return inner

def foo():
    "I'm foo"
    return 1

print foo.__name__, foo

decorated_foo = outer(foo)

print decorated_foo.__name__, decorated_foo


I am working on the file "Lecture4-Main.ipynb".
The first task is:
Nested lambda is permitted (idk why you'd use them, still, worth a mention)
Can you write Python code for it?

foo = lambda x: lambda y: x+y
print foo(3)(5)


I am working on the file "Lecture4-Main.ipynb".
The first task is:
Never call args after kwargs

5. Nesting functions

You can nest functions.
Class nesting is somewhat uncommon, but can be done.
Can you write Python code for it?

def outer():
    x=1
    def inner():
        print x
    inner()

outer()


I am working on the file "Lecture4-Main.ipynb".
The first task is:
Other ways of calling:

All the following are legit:
Can you write Python code for it?

"Args"
def foo(x,y):
    print x+y

"kwargs"
def bar(x=5, y=8):
    print x-y

"Both"
def foobar(x,y=100):
    print x*y

"kwargs"
bar(5,8) # kwargs as args (default: x=5, y=8)
bar(5,y=8) # x=5, y=8
"Change the order of kwargs if you want"
bar(y=8, x=5)

"args as kwargs will also work"
foo(x=5, y=12)


I am working on the file "Lecture4-Main.ipynb".
The first task is:
Python uses @ to represent foo = outer(foo). The above code can be retwritten as follows:
Can you write Python code for it?

def outer(func):
    def inner():
        "Inner"
        print 'Decorating...'
        ret = func()
        ret += 1
        return ret
    return inner

@outer
def foo():
    "I'm foo"
    return 1

print foo()


I am working on the file "Lecture4-Main.ipynb".
The first task is:
Q. What happens if there is no return?
2. Scope

In python functions have their own scope (namespace).
Python first looks at the function's namespace first before looking at the global namespace.
Let's use locals() and globals() to see what happens:
Can you write Python code for it?

aString = 'Global var'
def foo():
    a = 'Local var'
    print locals()

foo()
print globals()


I am working on the file "Lecture4-Main.ipynb".
The first task is:
Q. will these two work?
Can you write Python code for it?

"Args"
def foo(x,y):
    print x+y

"kwargs"
def bar(x=5, y=8):
    print x-y

"Both"
def foobar(x,y=100):
    print x*y

bar(x=9, 7) #1
foo(x=5, 6) #2


I am working on the file "Lecture4-Main.ipynb".
The first task is:
There are many such redefinitions permitted by python. See Python Docs

6.2 Emulating numeric types

A very useful feature in python is the ability to emulate numeric types.

Would this work?
Can you write Python code for it?

class foo():
    def __init__(i, num):
        i.num = num
FOO = foo(5)
FOO += 1


I am working on the file "Lecture4-Main.ipynb".
The first task is:
This means:
Functions and Classes can be passed as arguments.
Functions can return other functions/classes.
Can you write Python code for it?

from pdb import set_trace # pdb is quite useful

def add(x,y): return x+y
def sub(x,y): return x-y
def foo(x,y,func=add):
    set_trace()
    return func(x,y)

foo(7,4,sub)


I am working on the file "Lecture4-Main.ipynb".
The first task is:
We know the __call__ raises an exception. Python lets you redefine it:
Can you write Python code for it?

class foo():
    def __init__(i, num):
        i.num = num
    def __call__(i):
        return i.num
d = foo(2)
d()


I am working on the file "Lecture4.ipynb".
The first task is:
2.1 Variable lifetime
Variables within functions exist only withing their namespaces. Once the function stops, all the variables inside it gets destroyed. For instance, the following won't work.
Can you write Python code for it?


I am working on the file "Lecture4.ipynb".
The first task is:
4. Function Arguments: args and kwargs

Python allows us to pass function arguments (duh..)
There arguments are local to the function. For instance:
Can you write Python code for it?


I am working on the file "Lecture4.ipynb".
The first task is:
8. Closures
Remember this example?
Can you write Python code for it?


I am working on the file "Lecture4.ipynb".
The first task is:
8.1.1 Sorted

Python's sorted function can sort based on a key argument, key is a lambda function that deterimes how the data is sorted.
Can you write Python code for it?

student_tuples = [ #(Name, height(cms), weight(kg))
        ('john', 180, 85),
        ('doe', 177, 99),
        ('jane', 169, 69),
]

# Sort based on height
print 'Weight: ', sorted(student_tuples,  key=lambda stud: stud[1])

# Sort based on Name
print 'Name: ', sorted(student_tuples, key=lambda stud: stud[0])

# Sort based on BMI
print 'BMI: ', sorted(student_tuples, key=lambda stud: stud[2]*100/stud[1])


I am working on the file "Lecture4.ipynb".
The first task is:
9. Decorators!

Decorators are callables that take a function as argument, and return a replacement function (with additional functionalities)
Can you write Python code for it?

def outer(func):
    def inner(*args):
        "Inner"
        print 'Decorating...'
        ret = func()
        ret += 1
        return ret
    return inner

def foo():
    "I'm foo"
    return 1

print foo()

decorated_foo = outer(foo)

print decorated_foo()


I am working on the file "Lecture4.ipynb".
The first task is:
9.1 Logging and timing a function

Decorators can be classes, they can take input arguments/keyword args.

Lets build a decorator that logs and times another function
Can you write Python code for it?

import time
from pdb import set_trace

def logger(func):
    def inner(*args, **kwargs):
        print "Arguments were: %s, %s"%(args, kwargs)
        return func(*args, **kwargs)
    return inner

def timer(func):
    def inner(*args, **kwargs):
        tb=time.time()
        result = func(*args, **kwargs)
        ta=time.time()
        print "Time taken: %f sec"%(ta-tb)
        return result
    return inner

@logger
@timer
def foo(a=5, b=2):
    return a+b

@logger
@timer
def bar(a=10, b=1):
    time.sleep(0.1)
    return a-b

if __name__=='__main__': ## <----- Note
    foo(2,3)
    bar(5,7)


I am working on the file "Lecture4.ipynb".
The first task is:
All arg and kwarg conventions apply here

6.1 Overriding class methods
Lets try:
Can you write Python code for it?

class foo():
    def __init__(i, num):
        i.num = num

d = foo(2)
d()


I am working on the file "Lecture4.ipynb".
The first task is:
All the namespace conventions apply here.

What would happen if I changed x inside inner()?
Can you write Python code for it?

def outer():
    x = 1
    def inner():
        x = 2
        print 'Inner x=%d'%(x)
    inner()
    return x

print 'Outer x=%d'%outer()


I am working on the file "Lecture4.ipynb".
The first task is:
Arguments in functions can be classified as:
Args
kwargs (keyword args)

When calling a function, args are mandatory. kwargs are optional.
Can you write Python code for it?

"Args"
def foo(x,y):
    print x+y

"kwargs"
def bar(x=5, y=8):
    print x-y

"Both"
def foobar(x,y=100):
    print x*y

"Calling with args"
foo(5,12)

"Calling with kwargs"
bar()

"Calling both"
foobar(10)


I am working on the file "Lecture4.ipynb".
The first task is:
Aside: __repr__, __call__,__getitem__,...  are all awesome.
Can you write Python code for it?

class foo():
    "Me is foo"
    def __init__(i, num):
        i.num = num
    def __add__(i, new):
        i.num += new
        return i
    def __sub__(i, new):
        i.num -= new
        return i
    def __repr__(i):
        return i.__doc__
    def __getitem__(i, num):
        print "Nothing @ %d"%(num)

FOO = foo(4)
FOO[2]


I am working on the file "Lecture4.ipynb".
The first task is:
Declare global every time the global x needs changing

6. Classes

Define classes with the class keyword
Here's a simple class
Can you write Python code for it?

class foo():
    def __init__(i, arg1): # self can br replaced by anything.
        i.arg1 = arg1
    def bar(i, arg2): # Always use self as the first argument
        print i.arg1, arg2

FOO = foo(7)

FOO.bar(5)

print FOO.arg1


I am working on the file "Lecture4.ipynb".
The first task is:
It follows that the variable a here is a class.
Can you write Python code for it?


I am working on the file "Lecture4.ipynb".
The first task is:
Lets look at memory locations of the functions.
Can you write Python code for it?

def outer(func):
    def inner(*args):
        "Inner"
        print 'Decorating...'
        ret = func()
        ret += 1
        return ret
    print inner.__doc__, inner
    return inner

def foo():
    "I'm foo"
    return 1

print foo.__name__, foo

decorated_foo = outer(foo)

print decorated_foo.__name__, decorated_foo


I am working on the file "Lecture4.ipynb".
The first task is:
Obviously, this fails. Why? As per variable lifetime rules (see 2.1), foo() has ceased execution, x is destroyed.
So how about this?
Can you write Python code for it?

def foo():
    x='Outer String'
    def bar():
        print x
    return bar

test = foo()

test()


I am working on the file "Lecture4.ipynb".
The first task is:
Python uses @ to represent foo = outer(foo). The above code can be retwritten as follows:
Can you write Python code for it?


I am working on the file "Lecture4.ipynb".
The first task is:
Q. What happens if there is no return?
2. Scope

In python functions have their own scope (namespace).
Python first looks at the function's namespace first before looking at the global namespace.
Let's use locals() and globals() to see what happens:
Can you write Python code for it?


I am working on the file "Lecture4.ipynb".
The first task is:
Q. will these two work?
Can you write Python code for it?


I am working on the file "Lecture4.ipynb".
The first task is:
This means:
Functions and Classes can be passed as arguments.
Functions can return other functions/classes.
Can you write Python code for it?


I am working on the file "Lecture4.ipynb".
The first task is:
This works. But it shouldn't, because x is local to foo(), when foo() has ceased execution, x must be destroyed. Right?
Turns out, Python supports a feature called function closure. This enables nested inner functions to keep track of their namespaces.
8.1 Aside: lambda functions and sorted

Anonymous functions in python can be defined using the lambda keyword.
The following two are the same:
Can you write Python code for it?

def foo(x,y): return x**y

bar = lambda x,y: x**y # <--- Notice no return statements

print foo(4,2)
print bar(4,2)


I am working on the file "Lecture4.ipynb".
The first task is:
What about global variables?
Can you write Python code for it?

x = 4
def outer():
    global x
    x = 1
    def inner():
        global x
        x = 2
        print 'Inner x=%d'%(x)
    inner()
    return x

print 'Outer x=%d'%outer()
print 'Global x=%d'%x


I am working on the file "LectureNotes/ExceptionsDebugging.ipynb".
The first task is:
And we want to execute the following function:
Can you write Python code for it?

def add_lines(filename):
    f = open(filename)
    lines = f.read().split()
    f.close()
    result = 0
    for line in lines:
        result += line
    return result

filename = 'numbers.dat'
total = add_lines(filename)
print(total)


I am working on the file "LectureNotes/ExceptionsDebugging.ipynb".
The first task is:
By printing some of the intermediate items, we see the problem: 0 * np.log(0) is resulting in a NaN.  Though mathematically it's true that $\lim_{x\to 0} [x\log(x)] = 0$, the fact that we're performing the computation numerically means that we don't obtain this result.
Often, inserting a few print statements can be enough to figure out what's going on.
Embedding an IPython instance
You can go a step further by actually embedding an IPython instance in your code.
This doesn't work from within the notebook, so we'll create a file and run it from
the command-line
Can you write Python code for it?

%%file test_script.py
import numpy as np

def entropy(p):
    p = np.asarray(p)  # convert p to array if necessary
    items = p * np.log(p)
    import IPython; IPython.embed()
    return -np.sum(items)

p = np.arange(5.)
p /= p.sum()
entropy(p)


I am working on the file "LectureNotes/ExceptionsDebugging.ipynb".
The first task is:
Even though the syntax error appears below the (valid) variable definition, the valid code is not executed.
Runtime Errors
Runtime errors occur when the code is valid python code, but are errors within the context of the program execution.  For example:
Can you write Python code for it?

print(Q)

x = 1 + 'abc'

X = 1 / 0

import numpy as np
np.add(1, 2, 3, 4)

x = [1, 2, 3]
print(x[100])