<빅데이터 분석> 9. 선형대수와 신경망 기초

정지인·2025년 6월 6일

✅ Section 01. 벡터

##1. 스칼라와 벡터


넘파이를 np라는 이름으로 불러오고 버전을 출력합니다.

import numpy as np
a=[1, 2]

넘파이를 np라는 이름으로 불러오고 버전을 출력합니다.

import numpy as np
a1=np.array([1, 2])
a1

✅ 벡터의 합과 차


리스트나 데이터프레임을 넘파이 배열로 변환합니다.

# 벡터의 합
a=np.array([1, 2])
b=np.array([3, 4])
c=a+b
c

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

# 벡터의 차
a=np.array([1, 2])
b=np.array([3, 4])
c=a-b
c

✅ 리스트 합과 벡터 합


넘파이 배열 관련 기능을 시연합니다.

# 리스트의 합
a=[1, 2]
b=[3, 4]
a+b

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

# 벡터의 합
a1=np.array([1, 2])
b1=np.array([3, 4])
a1+b1

✅ 2. 벡터의 연산

❶ 리스트 원소끼리 각각 더하기


넘파이 배열 관련 기능을 시연합니다.

Hong1=[80, 90]
Jung1=[70, 80]
Score=[]
for i in range(len(Hong1)): # len(Hong1)=2
 Score.append(Hong1[i]+Jung1[i])
print(Score)

❷ 넘파이를 이용해 더하기

넘파이를 np라는 이름으로 불러오고 버전을 출력합니다.

import numpy as np
npHong1=np.array(Hong1)
npJung1=np.array(Jung1)
npHong1+npJung1

✅ 벡터의 차

넘파이 배열 관련 기능을 시연합니다.

def vector_sub(*args):# 각 성분끼리 더하기
  return [vi - wi for vi, wi in zip(*args)]
sub=vector_sub(Hong1, Jung1)
sub

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

npHong1=np.array(Hong1)
npJung1=np.array(Jung1)
npHong1-npJung1

✅ 3. 벡터의 선형조합

스칼라와 벡터의 곱

❶ 넘파이 배열 사용

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

x1=np.array([1, 2])
x2=np.array([3, 4])
x3=0.5*x1 + 0.5*x2
x3

✅ ❷ map 함수 사용

넘파이 배열 관련 기능을 시연합니다.

A=[1, 2, 3, 4, 5]
scalar_multiply=list(map(lambda x: x*2, A))
print(scalar_multiply)

✅ 선형조합의 예

❶ sum 함수, zip 함수 이용


넘파이 배열 관련 기능을 시연합니다.

Hong1=[80, 90]
Jung1=[70, 80]
a=0.5
avg=[a*sum(i) for i in zip(Hong1, Jung1)]
avg

✅ ❷ 넘파이를 이용한 스칼라와 벡터의 곱

넘파이를 np라는 이름으로 불러오고 버전을 출력합니다.

import numpy as np
npHong1=np.array(Hong1)
npJung1=np.array(Jung1)
np_S= npHong1+npJung1
a=0.5
a*np_S

✅ 4. 벡터의 내적

함수를 만들어 벡터의 내적 구하기

넘파이 배열 관련 기능을 시연합니다.

def dot(v, w):
 return sum(v_i * w_i for v_i, w_i in zip(v, w))
A=[4, 3]
B=[6, 0]
dot(A, B)

넘파이 배열 관련 기능을 시연합니다.

x1=[1, 2, 3]
y1=[4, 5, 6]
dot(x1, y1)

✅ 넘파이로 벡터의 내적 구하기

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

npx1=np.array([1, 2, 3])
npy1=np.array([4, 5, 6])
sum(npx1*npy1)

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

a=np.array([1, 2, 3, 4, 5])
b=np.array([2, 4, 6, 8, 10])
print(a*b)
print(sum(a*b))
print(np.sum(a*b))

✅ 넘파이 브로드캐스팅으로 벡터의 내적 구하기

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

np_Hong1=np.array([80, 90, 10, 9])
np_Jung1=np.array([70, 80, 9, 8])
v=np_Hong1+np_Jung1
w=[0.5, 0.5, 0.5, 0.5]
[i * j for i, j in zip(v, w)]

✅ ❶ 넘파이 브로드캐스팅 실습

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

avg=[75.0, 85.0, 9.5, 8.5]
avg1=np.array(avg)
W1=np.array([0.4, 0.4, 1, 1])
print(avg1*W1)

✅ ❷ 벡터의 내적 실습

넘파이 배열 관련 기능을 시연합니다.

Final=avg1*W1
print(Final.sum())

✅ 5. 벡터의 길이

넘파이 함수로 벡터의 길이 구하기

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

a1=np.array([1, 2])
np.linalg.norm(a1)

넘파이 배열 관련 기능을 시연합니다.

def dot(v, w):
 return sum(v_i * w_i for v_i, w_i in zip(v, w))
def sum_of_squares(v):
 return dot(v, v)
v=[1, 2]
sum_of_squares(v)

넘파이 배열 관련 기능을 시연합니다.

def sum_of_squares1(v, w):
 return dot(v, w)
v=[1, 2]
w=[3, 4]
sum_of_squares1(v, w)

넘파이 배열 관련 기능을 시연합니다.

import math
def magnitude(v):
  return math.sqrt(sum_of_squares(v))
v=[1, 2]
magnitude(v)

✅ 벡터 간의 거리(유클리드 거리) 구하기

넘파이 배열 관련 기능을 시연합니다.

def vector_subtract(v, w):
  return [v_i - w_i for v_i, w_i in zip(v, w)]
def squared_distance(v, w):
  return sum_of_squares(vector_subtract(v, w))
v=[1, 2]
w=[3, 4]
squared_distance(v, w)

넘파이 배열 관련 기능을 시연합니다.

def distance(v, w):
 return math.sqrt(squared_distance(v, w))
def distance1(v, w):
 return magnitude(vector_subtract(v, w))
v=[1, 2]
w=[3, 4]
print(distance(v, w))
print(distance1(v, w))

✅ 6. 벡터를 이용한 평균 제곱 오차와 평균 제곱근 오차

평균 제곱 오차

넘파이를 np라는 이름으로 불러오고 버전을 출력합니다.

y=[1, 1, 0, 1, 0, 1, 0, 1, 0, 0] # 실제값
t=[0, 0, 1, 0, 0, 1, 0, 1, 0, 0] # 예측값
import numpy as np
def mean_squared_error(y, t):
 return 0.5 * np.sum((y-t)**2)
mean_squared_error(np.array(y), np.array(t))

평균 제곱근 오차

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

c=np.array([1, 2, 3, 4, 5])
d=np.array([2, 4, 6, 8, 10])
print((sum((c-d)**2)/len(c))**(1/2))

✅ Section 02. 행렬

1. 행렬의 표기

넘파이 배열 관련 기능을 시연합니다.

Hong=[[80, 90, 20, 18], [70, 80, 18, 16]] # 홍길동 성적을 리스트로 표시
Lee=[(90, 80, 18, 20), (100, 95, 20, 18)] # 이몽룡 성적을 튜플로 표시
Kim={'m': (100, 95), 'f':(95, 100), 'a':(20, 20), 'r':(19, 18)} # 김철수 성적을 딕셔너리로 표시
Kim

넘파이를 np라는 이름으로 불러오고 버전을 출력합니다.

import numpy as np
A=[[1, 2, 3],
 [4, 5, 6]]
B=[[1, 2],
 [3, 4],
 [5, 6]]
A1=np.array(A)
A1.shape
np.shape(A)

✅ 2. 행렬의 연산

행렬의 덧셈, 뺄셈

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

x=np.array([10, 11, 12, 13, 14])
y=np.array([0, 1, 2, 3, 4])
x+y
x-y

✅ 행렬의 곱셈

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

x=np.array([[1], [2], [3]])
y=np.array([[4], [5], [6]])
x*y

배열의 전치(transpose)를 구합니다.

x.shape, y.shape # (3, 1), (3, 1)
x.T # array([[1, 2, 3]])
x.T.shape # (1, 3)
x.T*y

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

x_T=np.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])
y=np.array([[4, 4, 4], [5, 5, 5], [6, 6, 6]])
x_T*y

배열의 전치(transpose)를 구합니다.

x=np.array([[1], [2], [3]]) # 3*1
y=np.array([[4], [5], [6]]) # 3*1
print(x.T@y)
print(x@y.T)

배열의 전치(transpose)를 구합니다.

print(np.dot(x.T, y))
print(np.dot(x, y.T))

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

A=np.array([[1, 2, 3], [4, 5, 6]])
A.shape # (2, 3)
B=np.array([[1, 2], [3, 4], [5, 6]])
B.shape # (3, 2)
A*B

배열의 전치(transpose)를 구합니다.

A=np.array([[1, 2, 3], [4, 5, 6]])
A.shape # (2, 3)
B=np.array([[1, 2], [3, 4], [5, 6]])
B.shape # (3, 2)
print(A.T*B)
print(A*B.T)
print(A@B)

✅ Section 03. 신경망 기초

1. 시그모이드 함수

넘파이를 np라는 이름으로 불러오고 버전을 출력합니다.

import numpy as np
import matplotlib.pylab as plt
def sigmoid(x):
 return 1 / (1 + np.exp(-x))
X=np.arange(-5.0, 5.0, 0.1)
Y=sigmoid(X)
plt.plot(X, Y)
plt.ylim(-0.1, 1.1)
plt.show()

2. 순전파 신경망 구현

넘파이 배열 관련 기능을 시연합니다.

input=[0.2, 0.9] # 2개의 입력층
weight1=[[0.05,0.01], [-0.01,0.03], [0.02,-0.01]] #가중치 값
bias1=[-0.3,0.2,0.05]
weight2=[0.01,0.05,0.015] # 은닉층에서 출력층으로 가는 가중치
bias2=[-0.015] # 출력층으로 가는 바이어스

✅ 입력층에서 은닉층으로 신호 전달

넘파이 배열 관련 기능을 시연합니다.

# 입력층의 첫 번째 노드에서 은닉층의 첫 번째 노드로 신호 전달
def dot(v, w):
  return sum(i * j for i, j in zip(v, w))
input=[0.2,0.9]
w=[0.05,0.01]
dot(input,w)+bias1[0] # 0.2*0.05 +0.9*0.01 + (-0.3)

넘파이 배열 관련 기능을 시연합니다.

# 입력층에서 은닉층 노드로 보내는 신호값
N3=dot(input,weight1[0])+bias1[0]
N4=dot(input,weight1[1])+bias1[1]
N5=dot(input,weight1[2])+bias1[2]
N3, N4, N5

넘파이를 np라는 이름으로 불러오고 버전을 출력합니다.

# 시그모이드 함수를 이용해 N3, N4, N5 노드에서 출력하는 값
import numpy as np
def sigmoid(x):
 return 1 / (1 + np.exp(-x))
outputN3=sigmoid(N3)
outputN4=sigmoid(N4)
outputN5=sigmoid(N5)
outputN3, outputN4, outputN5

✅ 은닉층에서 출력층으로 신호 전달

넘파이 배열 관련 기능을 시연합니다.

Z1=[outputN3, outputN4, outputN5]
N6=dot(Z1, weight2)+bias2
outputN6=sigmoid(N6)
outputN6

✅ 넘파이를 활용한 순전파 신경망 계산

넘파이를 np라는 이름으로 불러오고 버전을 출력합니다.

# 입력층에서 첫 번째 은닉층으로 신호 전달
import numpy as np
input=np.array([[0.2, 0.9]]) # 1*2 행렬
weight1=np.array([[0.05,0.01], [-0.01,0.03], [0.02,-0.01]]) # 3*2 행렬
bias1=np.array([-0.3,0.2,0.05])
A1=np.dot(input, weight1.T) + bias1 # weight1.T는 weight의 전치 행렬
Z1=sigmoid(A1)
Z1

배열의 전치(transpose)를 구합니다.

weight2=np.array([[0.01, 0.05, 0.015]])
bias2=np.array([[-0.015]])
A2=np.dot(Z1, weight2.T)+bias2
Z2=sigmoid(A2)
Z2

넘파이 배열 관련 기능을 시연합니다.

def identity_function(x):
 return x
Y=identity_function(A2) # 또는 Y=A2
Y

✅ 순전파 구현 정리

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

def init_network():
  network={}
  network['W1']=np.array([[0.05, -0.01, 0.02],[0.01, 0.03, -0.01]])
  network['b1']=np.array([-0.3,0.2,0.05])
  network['W2']=np.array([0.01,0.05,0.015])
  network['b2']=np.array([-0.015])
  return network

def forward(network, x):
  W1, W2=network['W1'], network['W2']
  b1, b2=network['b1'], network['b2']
  a1=np.dot(x, W1) + b1
  z1=sigmoid(a1)
  a2=np.dot(z1, W2) + b2
  z2=sigmoid(a2) # 시그모이드 함수 사용
  # z2=identity_function(a2) # 항등 함수 사용
  return z2

network=init_network()

input=np.array([0.2, 0.9])
Z=forward(network, input)
Z

✅ 3. 역전파 신경망 구현

넘파이 배열 관련 기능을 시연합니다.

y=Z
t=1
E=y-t
E

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

# 출력층에서 은닉층으로의 역전파 시 가중치 업데이트
# 이전의 가중치
weight2_old=np.array([0.01,0.05,0.015])
bias2_old=np.array([-0.015])
delta=(1-y)*y*(y-t) # 업데이트 되는 가중치
learning_rate=0.01 # 학습률
learning_rate=0.01
bias2_new=bias2_old+learning_rate*delta # 바이어스
weight36=weight2_old[0]+learning_rate*delta*Z1[0][0] # weight2_new[0]
weight46=weight2_old[1]+learning_rate*delta*Z1[0][1] # weight2_new[1]
weight56=weight2_old[2]+learning_rate*delta*Z1[0][2] # weight2_new[2]
print(weight36, weight46, weight56, bias2_new)

리스트나 데이터프레임을 넘파이 배열로 변환합니다.

#이전의 가중치
weight1_old=np.array([[0.05, -0.01, 0.02],[0.01, 0.03, -0.01]])
bias1_old=np.array([[-0.3, 0.2, 0.05]])
#업데이트되는 가중치
learning_rate=0.01 # 학습률
X=np.array([[0.2, 0.9]])
bias13_new=bias1_old[0][0]+learning_rate*delta # 바이어스
bias14_new=bias1_old[0][1]+learning_rate*delta # 바이어스
bias15_new=bias1_old[0][2]+learning_rate*delta # 바이어스
weight13=weight1_old[0][0]+learning_rate*delta*X[0][0] # weight1_new[0][0]
weight14=weight1_old[0][1]+learning_rate*delta*X[0][0] # weight2_new[0][1]
weight15=weight1_old[0][2]+learning_rate*delta*X[0][0] # weight3_new[0][2]
weight23=weight1_old[1][0]+learning_rate*delta*X[0][1] # weight1_new[1][0]
weight24=weight1_old[1][1]+learning_rate*delta*X[0][1] # weight2_new[1][1]
weight25=weight1_old[1][2]+learning_rate*delta*X[0][1] # weight3_new[1][2]
print(weight13,weight14,weight15,weight23,weight24,weight25)
print(bias13_new,bias14_new,bias15_new)

✅ 4. 사이킷런을 이용한 신경망 구현

넘파이 배열 관련 기능을 시연합니다.

import pandas as pd
url='https://raw.githubusercontent.com/sehakflower/data/main/TinyData.csv'
data= pd.read_csv(url,sep=',') # 또는 data=pd.read_csv('TinyData.csv')
data

넘파이 배열 관련 기능을 시연합니다.

predictors=['Fat', 'Salt']
outcome='Acceptance'
X=data[predictors]
y=data[outcome]
classes=sorted(y.unique())
from sklearn.neural_network import MLPClassifier
clf=MLPClassifier(hidden_layer_sizes=(3,), activation='logistic', solver='lbfgs', random_state=1)
clf.fit(X, y)
clf.predict(X)
print('바이어스 값')
print(clf.intercepts_)
print('가중치 값')
print(clf.coefs_)
print(pd.concat([data, pd.DataFrame(clf.predict_proba(X), columns=classes)], axis=1))
profile
멋쟁이사자 13기 백엔드

0개의 댓글