선형회귀
단순 선형 회귀(simple linear regression)
- 독립 변수 x(‘정보’) 하나로 종속 변수 y 값을 예측할 수 있는 경우의 분석 작업
코드
import numpy as np
import matplotlib.pyplot as plt
X = np.array([2, 4, 6, 8])
Y = np.array([81, 93, 91, 97])
plt.plot(X,Y,'o')
plt.xlabel('study time')
plt.title('Jumsu vs. study time')
plt.grid()
- $y=ax+b$를 결정하기 위해 기울기 a와 절편 b값은 최소제곱법으로 구할 수 있음
주어진 표에 제시한 테이터를 기반으로 예측선을 만들려고 한다
- 계산결과 : a=2.3, b=79.0
# 공부한 시간과 점수를 각각 x, y라는 이름의 넘파이 배열로 만듭니다.
X = np.array([2, 3, 4, 6, 8])
y = np.array([81,83, 93, 91, 97])
#x의 평균값과 y의 평균값을 구합니다.
mx = np.mean(X)
my = np.mean(y)
# 기울기 공식의 분모(divisor)와 분자(dividend)를 구합니다.
divisor = sum([(x_i - mx)**2 for x_i in X])
def top(x, mx, y, my):
d = 0
for i in range(len(x)):
d += (X[i] - mx) * (y[i] - my)
return d
dividend = top(X, mx, y, my)
# 기울기 a와 절편 b를 구합니다.
a = dividend / divisor
b = my - (mx*a)
# 출력으로 확인합니다.
print("기울기 a =", a)
print("y절편 b =", b)
# 공부한 시간은 2시간부터 8시간까지만 고려할 생각임.
x = np.arange(2, 9)
# 모델이 예측한 성적
y_hat = a*x + b
# 실 데이터와 예측한 데이터 출력
plt.plot(X,y,'o') # 공부 시간 vs. 취득 성적 그래프(점(o)로 표현)
plt.plot(x, y_hat) # 모델이 예상한 '공부 시간 vs. 취득 예상 성적' 그래프
plt.xlabel('study time')
plt.title('$\\hat{y}=%.1fx+%.1f$' % (a, b))
plt.xlim([1, 8])
plt.ylim([80, 100])
plt.grid()
- 최소 제곱법을 이용해 기울기 a와 y 절편 b를 편리하게 구했지만 이 공식만으로는 앞으로 만나게 될 모든 상황을 해결하기 어려움
- 여러 개의 입력값을 처리하기에는 무리가 있기때문
평균 제곱 오차( MSE )
import numpy as np
# 가상의 기울기 a와 y 절편 b를 정합니다.
fake_a=3
fake_b=76
# 공부 시간 x와 성적 y의 넘파이 배열을 만듭니다.
x = np.array([2, 4, 6, 8])
y = np.array([81, 93, 91, 97])
# y=ax + b에 가상의 a,b 값을 대입한 결과를 출력하는 함수입니다.
def predict(x):
return fake_a * x + fake_b# 예측 값이 들어갈 빈 리스트를 만듭니다.
predict_result = []
# 모든 x 값을 한 번씩 대입하여 predict_result 리스트를 완성합니다.
for i in range(len(x)):
predict_result.append(predict(x[i]))
print("공부시간=%.f, 실제점수=%.f, 예측점수=%.f" % (x[i], y[i], predict(x[i])))
# 평균 제곱 오차 함수를 각 y 값에 대입하여 최종 값을 구하는 함수입니다.
n=len(x)
def mse(y, y_pred):
return (1/n) * sum((y - y_pred)**2)
# 평균 제곱 오차 값을 출력합니다.
print("평균 제곱 오차: " + str(mse(y,predict_result)))
오차를 줄이는 방법 : 경사하강법
경사하강법
- 함수의 기울기(경사)를 구하고 경사의 반대 방향으로 계속 이동시켜 극값(기울기 0)에 이를 때까지 반복시키는 것이다.
import numpy as np
import matplotlib.pyplot as plt
x = np.array([2, 4, 6, 8])
y = np.array([81, 93, 91, 97])
N = len(x)
a = 3 # 임의의 예측 선의 기울기
b = 70 # 임의의 예측 선의 y절편
y_hat = a * x + b # 임의의 예측 선 생성
# 예측 선의 기울기 a가 3일 때 "에러 식(e)의 기울기".
a_diff = (2/N) * sum(-x*(y - y_hat) )
b_diff = (2/N) * sum(-(y - y_hat))
print( a_diff )
print( b_diff)
-48.0
-11.0
lr = 0.03 # 학습율
# 이 코드 cell를 반복해서 실행시키면서 a_diff와 b_diff의 값 변화를 관찰하시요
a = a - lr * a_diff # a_diff가 음수라면 다음 a 값은 이전 a 값 보다 커짐.
# a_diff가 양수라면 다음 a 값은 이전 a 값 보다 작아짐.
b = b - lr * b_diff
y_hat = a * x + b # 임의의 예측 선 생성
a_diff = (2/N) * sum(-x*(y - y_hat) )
b_diff = (2/N) * sum(-(y - y_hat))
print(a_diff)
print(b_diff)
# 1. 환경 준비
import numpy as np
import matplotlib.pyplot as plt
# 2. 데이터 준비 - 공부 시간 X와 성적 y의 넘파이 배열 생성
x = np.array([2, 4, 6, 8])
y = np.array([81, 93, 91, 97])
# 3. 데이터 확인 - 데이터의 분포를 그래프로 나타냅니다.
plt.scatter(x, y)
plt.show()
# 4. 실행을 위한 변수 설정
# 기울기 a와 y 절편 b의 값을 초기화합니다.
a = 0;b = 0
# 학습률을 정합니다.
lr = 0.03
# 몇 번 반복될지 설정
epochs = 2001
# 5. 경사하강법
# x 값이 총 몇 개인지 셉니다.
n=len(x)
# 경사 하강법을 시작
for i in range(epochs): # 에포크 수 만큼 반복 y_pred = a * x + b # 예측 값을 구하는 식
error = y - y_pred # 실제 값과 비교한 오차를 error로
a_diff = (2/n) * sum(-x * (error)) # 오차 함수를 a로 편미분한 값
b_diff = (2/n) * sum(-(error)) # 오차 함수를 b로 편미분한 값
a = a - lr * a_diff # 학습율을 곱해 기존의 a 값을 업데이트
b = b - lr * b_diff # 학습율을 곱해 기존의 b 값을 업데이트
if i % 100 == 0: # 100번 반복될 때마다 현재의 a 값, b 값을 출력
print("epoch=%.f, 기울기=%.04f, 절편=%.04f" % (i, a, b))
# 6. 그래프로 확인
# 앞서 구한 최종 a 값을 기울기로 b 값을 y 절편에 대입하여 그래프를 그림.
y_pred = a * x + b
# 그래프 출력
plt.scatter(x, y)
plt.plot(x, y_pred,'r')
plt.show()
다중 선형 회귀(multiple linear regression)
- y값을 예측하려고 할 때 독립 변수 x_1, x_2, x_3….(‘정보’)가 여러 개 필요한 경우의 분석 작업
코드
- 이전 공부시간만 가지고 성적을 사용하려면 약간의 오차가 발생
- 다른 요소가 성적에 영향을 미쳤기 때문에
공부한 시간 - 성적
# 경사하강법
import numpy as np
# 2. 데이터 준비
x1 = np.array([2, 4, 6, 8]) #공부한 시간
X2 = np.array([0, 4, 2, 3]) #과외 수업 횟수
y = np.array([81, 93, 91, 97])
# 3. 데이터 확인 - 데이터의 분포를 그래프로 나타냄
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x1, x2, y)
ax.set_xlabel('$x_1$')
ax.set_ylabel('$x_2$')
ax.set_zlabel('$y$')
plt.show()
# 4. 실행을 위한 변수 설정 --------------------------------------------
# 임의로 기울기 a1, a2 그리고 절편 b 값을 결정
a1 = 0
a2 = 0
b = 0
N = len(x1) # n은 데이터 개수, 이전 예제에서는 변수 이름으로 N을 사용하기도 했음.
lr = 0.01 # 학습율
epochs = 2001 # 몇 번 반복
# 5. 경사하강법
for i in range(epochs):
y_hat = a1 * x1 + a2 * x2 + b # 예측 식을 생성
error = y - y_hat # 에러, 즉 실제 값 - 예측 값
a1_diff = (2/N) * sum(-x1 * error) # a1_diff는 오차 함수를 a1로 편미분한 값
a2_diff = (2/N) * sum(-x2 * error) # a2_diff는 오차 함수를 a2로 편미분한 값
b_diff = (2/N) * sum(-error) # b_diff는 오차 함수를 b로 편미분한 값
a1 = a1 - lr * a1_diff
a2 = a2 - lr * a2_diff
b = b - lr * b_diff
if i % 100 == 0:
print('epoch=%.f, 기울기1=%.04f, 기울기2=%.04f, 절편=%.04f' % (i, a1, a2, b))
print('실제 점수 : ', y)
print('예측 점수: ', y_hat)
#Tensorflow 사용
# 1.환경 준비 - 모듈 import
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# 2.데이터 준비
x = np.array([2,4,6,8])
y = np.array([81,93,91,97])
# 3.텐서플로우를 이용한 딥러닝 모델 ‘구조’설계
model = Sequential()
model.add(Dense(1, input_dim=1, activation='linear'))
# 4.주어진 파마메타에 따라 모델 생성 그리고 모델 학습 실행(model.fit())
model.compile(optimizer='sgd', loss='mse')
model.fit(x, y, epochs=2000)
# 5. 실 데이터와 예측 데이터 비교
plt.scatter(x,y)
plt.plot(x, model.predict(x), 'sr')
plt.grid()
plt.show()
- Dense( ) 함수 / 첫 번째 인자 : 출력 개수 지정
- input_dim :입력 변수 개수 지정 / activation : 활성화 함수 종류 선택
model.compile( ) / 모델 생성을 위한 파라메타 지정
- 옵티마이저 저정 : optimizer = ‘sgd’(확율적 경사하강법)
- 손실 함수 지정 : loss=‘mse’(평균제곱오차)
model.fit() / 모델 학습
# 모델 테스트
import numpy as np
# 임의의 시간을 집어넣어 점수를 예측하는 모델을 테스트해 보겠습니다.
hour = 7
# Convert the input to a NumPy array with the correct shape
hour_array = np.array([[hour]], dtype=np.float32)
# Predict the score
prediction = model.predict(hour_array)
print('{}시간을 공부할 경우 예상 점수는 {}점입니다'.format(hour, prediction[0][0]))
import numpy as np
# 여러 시간을 집어넣어 점수를 예측하는 모델을 테스트해 보겠습니다.
hours = [7, 9]
# Convert the input list to a NumPy array with the correct shape
hours_array = np.array(hours).reshape(-1, 1).astype(np.float32)
# Predict the scores
predictions = model.predict(hours_array)
# Print the predictions
for i, pred in enumerate(predictions):
print(f'{hours[i]}시간 공부할 경우 예상 점수는 {pred[0]}점입니다')
[공부한 시간, 과오 횟수] - 성적
# 1. 환경 준비
import numpy as np
import matplotlib.pyplot as plt
# 텐서플로의 케라스 API에서 필요한 함수들을 불러옴
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# 2. 데이터 준비
# 2.데이터 준비
x = np.array([2,4,6,8])
y = np.array([81,93,91,97])
# 3. 모델 구조 설정
model = Sequential()
# 입력 변수가 2개(학습 시간, 과외 시간)이므로 input_dim에 2를 입력
model.add(Dense(1, input_dim=2, activation='linear'))
# 4. 모델 파라메타 지정
model.compile(optimizer='sgd' ,loss='mse')
# 모델 학습 실행
model.fit(x, y, epochs=2000)
# 5. 모델 테스트
# 임의의 학습 시간과 과외 시간을 집어넣어 점수를 예측하는 모델을 테스트
import numpy as np
hour = 7
private_class = 4
# Convert the inputs to a NumPy array with the correct shape and dtype
input_data = np.array([[hour, private_class]], dtype=np.float32)
# Predict the score
prediction = model.predict(input_data)
# Print the prediction
print(f"{hour}시간을 공부하고 {private_class}시간의 과외를 받을 경우, 예상 점수는 {prediction[0][0]}점입니다")
# 그래프에 출력한 x축 라벨 생성
x_labels =[]
for xi in x:
x_labels.append('(' + str(xi[0]) + ',' + str(xi[1]) +')')
x_labels
# 실제 값과 예측값 비교
plt.scatter(x_labels, y, label = 'real data') # 실제 데이터를 그래프로
plt.plot(model.predict(x),'sr', label='predicted data') # 예측 결과를 그래프로
plt.legend()
plt.xlabel('(hour, private_class)')
plt.grid()
plt.show()
'빅데이터 분석가 양성과정 > Python - 딥러닝' 카테고리의 다른 글
오류역전파 (0) | 2024.07.17 |
---|---|
퍼셉트론(XOR) (0) | 2024.07.17 |
로지스틱 회귀 (0) | 2024.07.17 |
딥러닝을 위한 기초 수학 (0) | 2024.07.17 |
개요 (0) | 2024.07.17 |