본문 바로가기

머신러닝

머신러닝 - ex09_2선형회귀(LinearRegression)

### 간단한 선형회귀 - 성적 데이터

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data = pd.DataFrame([[2,20],[4,40],[8,80],[9,90]],
                    index=['서연','경진','다희','정선'],
                    columns = ['시간','성적'])
data

#### 선형회귀 공식을 사용한 회귀
- 수학 공식을 이용한 해석적 모델 -> linearRegression


from sklearn.linear_model import LinearRegression

linear_model = LinearRegression()

linear_model.fit(data[['시간']],data['성적'])

# y = wx + b 
print('가중치 : ', linear_model.coef_)
print('절편 : ', linear_model.intercept_) # 0.00000007

# 준연 7시간 공부
linear_model.predict([[7]])

### MSE가 최소가 되는  최적의 w,b를 찾아내는 방법
- MSE : 평균제곱오차(mean Squared Error) -> 비용함수(cost)
- 1. 수학공식을 이용한 해석적 모델 -> Linear Regression 도구
- 2. 경사 하강법 -> SGD Regressor 도구 

#h(x) 가설함수 -> y = wx+b
def h(w,x):
    return w*x + 0

# mse(비용함수) 정의
# data : 문제값
# target : 실제값
# weight : 가중치
def cost(data, target, weight):
    # 예측
    y_pre = h(weight, data)
    # 평균제곱오차 => 예측값 - 실제값
    error = ((y_pre - target)**2).mean()
    return error

# 가중치에 따른 오차값 확인
cost(data['시간'],data['성적'],20)

cost(data['시간'],data['성적'],15)

cost(data['시간'],data['성적'],12)

cost(data['시간'],data['성적'],10)

cost(data['시간'],data['성적'],8)

cost_list = []
for w in range(-10, 31):
    e = cost(data['시간'],data['성적'], w)
    cost_list.append(e)
cost_list

# 가중치(w)변화에 따른 비용함수(mse)값의 변화 그래프 그리기
plt.plot(range(-10,31),cost_list)
plt.show()

# 분류 모델 score - 정확도
# 회귀 모델 scre - R2 score (유사도)
linear_model.score(data[['시간']],data[['성적']])

### 보스턴 주택 값 예측 실습

- 컬럼값들의 특징

<table border=0 align=left width=500>
  <tr><th>feature<th width=400>설명
  <tr><td>Crim<td>지역별 범죄 발생률
  <tr><td>ZN<td>25,000 평방 피트를 초과하는 거주 지역의 비율
  <tr><td>IDUS<td>비 상업 지역 넓이 비율
  <tr><td>CHAS<td>찰스강에 대한 더미 변수(강의 경계에 위치한 경우 1 아니면 0
  <tr><td>NOX<td>일산화질소 농도
  <tr><td>RM<td>거주할 수 있는 방 개수
  <tr><td>AGE<td>1940년 이전에 건축된 소유 주택의 비율
  <tr><td>DIS<td>5개 주요 고용센터까지의 가중 거리
  <tr><td>RAD<td>고속도로 접근 용이도
  <tr><td>TAX<td>10,000달러 당 재산세율
  <tr><td>PTRATIO<td>지역의 교사와 학생 수 비율
  <tr><td>B<td>지역의 흑인 거주 비율
  <tr><td>LSTAT<td>하위 계층의 비율
</table>      

# 데이터 로드
from sklearn.datasets import load_boston
boston = load_boston()
boston.keys()

boston['feature_names']

X = pd.DataFrame(boston.data, columns = boston.feature_names)
y = pd.DataFrame(boston.target)
df_boston = pd.concat([X,y],axis =1)
df_boston.head(5)

import seaborn as sb

plt.figure(figsize=(12,12))
sb.heatmap(df_boston.corr(), annot = True)

# 훈련데이터와 평가데이터로 분리
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X,y,test_size = 0.3,random_state = 777)
X_train.shape, X_test.shape, y_train.shape, y_test.shape

# 선형 회귀를 이용해서 집값 예측
from sklearn.linear_model import LinearRegression

linear_model.fit(X_train,y_train)

# score :  회귀모델에서는 R2 score를 구함 - 유사도
linear_model.score(X_train,y_train)


linear_model.score(X_test,y_test)

### 모델 저장

import pickle # 파이썬에 사용하는 데이터타입 그대로 저장

# 모델 저장
#wb : write
with open("./model.pickle",'wb') as f:
    pickle.dump(linear_model,f)

# 저장된 모델 불러와 사용
with open("./model.pickle","rb") as f :
    new_model = pickle.load(f)

new_model.score(X_train,y_train)

# 회귀모델 평가 - 오차,  R2 score (유사도)
from sklearn.metrics import mean_squared_error

pre_train = new_model.predict(X_train)
pre_test = new_model.predict(X_test)

print("훈련 오차 : ", mean_squared_error(pre_train,y_train))
print("평가 오차 : ", mean_squared_error(pre_test,y_test))

### 경사하강법 사용

# SGD REgressor 사용
from sklearn.linear_model import SGDRegressor # 경사하강법이 적용된 모델

# 데이터 - 시간성적 데이터


# 모델 생성
# max_iter : 학습횟수, 가중치 업데이트 반복 횟수(epochs)
# eta0 = 학습률(Learning rate) - 변동폭
# verbose : 학습과정 표시 - 0 은 출력하지 않고, 1은 자세히, 2는 함축적인 정보만 출력
sgd_model = SGDRegressor(max_iter = 5000, eta0 = 0.001,verbose= 1)

# 학습
# 반복횟수가 다 차지않더라도, 최적의 w,b 가 찾아지면 학습 멈춤
# Norm - 가중치, 기울기 -w
# Bias -절편 - b
# loss - 비용함수(MSE)
sgd_model.fit(data[['시간']],data['성적'])

# y = 9.79x+ 0.18
# y = 10x

#예측
sgd_model.predict([[7]])

# 가중치 출력
print(sgd_model.coef_)
#절편, 편향 출력
print(sgd_model.intercept_)

# R-squared, R2_score - 같은 의미

# 1에 가까울수록 예측을 잘 해내고 있음을 의미
# 회귀성능평가 - score -> R2 score
sgd_model.score(data[['시간']],data['성적'])

### 선형회귀의 문제점
- 데이터가 많아지면 속도가 느려짐
- 데이터가 많고 특성이 많아지면 과대적합이 발생
    - 해결하기 위해 규제를 사용(Ridge, Lasso)
    

from sklearn.linear_model import Ridge, Lasso

# alpha : 규제값
ridge  = Ridge(alpha= 0.1)
lasso= Lasso(alpha=0.1)

ridge.fit(X_train,y_train)
lasso.fit(X_train,y_train)

pre_ridge_train = ridge.predict(X_train)
pre_ridge_test = ridge.predict(X_test)

print("훈련오차 : ", mean_squared_error(pre_ridge_train,y_train))
print("평가오차 : ",mean_squared_error(pre_ridge_test,y_test))

pre_lasso_train = lasso.predict(X_train)
pre_lasso_test = lasso.predict(X_test)

print("훈련오차 : ", mean_squared_error(pre_lasso_train,y_train))
print("평가오차 : ",mean_squared_error(pre_lasso_test,y_test))

### 규제 파라미터 튜닝

train_error = []
test_error = []
alpha_list = ["0.001","0.01","0.1","1","10","100","1000"]

for i in alpha_list:
    ridge_model=Ridge(alpha =float(i)).fit(X_train,y_train)
    
    pre_train = ridge_model.predict(X_train)
    pre_test = ridge_model.predict(X_test)
    
    e1= mean_squared_error(pre_train,y_train)
    e2 = mean_squared_error(pre_test,y_test)
    
    train_error.append(e1)
    test_error.append(e2)
    print("alpha : ",i)
    print("Ridge 훈련오차 : ",e1)
    print("Ridge 평가오차 : ",e2)

Ridge(alpha=0.1)

e1
e2

plt.plot(alpha_list,train_error, label = "train")
plt.plot(alpha_list,test_error, label = "test")
plt.legend()

train_error = []
test_error = []
alpha_list = ["0.001","0.01","0.1","1","10","100","1000"]

for i in alpha_list:
    lasso_model=Lasso(alpha =float(i)).fit(X_train,y_train)
    
    pre_train = lasso_model.predict(X_train)
    pre_test = lasso_model.predict(X_test)
    
    e1= mean_squared_error(pre_train,y_train)
    e2 = mean_squared_error(pre_test,y_test)
    
    train_error.append(e1)
    test_error.append(e2)
    print("alpha : ",i)
    print("Ridge 훈련오차 : ",e1)
    print("Ridge 평가오차 : ",e2)

plt.plot(alpha_list,train_error, label = "train")
plt.plot(alpha_list,test_error, label = "test")
plt.legend()

from sklearn.linear_model import LogisticRegression


logggg = LogisticRegression()

logggg.fit(X_train,y_train)

이 코드는 데이터 분석 및 선형 회귀 모델링을 다루는 내용을 포함하고 있습니다.

데이터 프레임을 생성하고, linear regression과 SGD regressor를

사용한 선형 회귀 모델을 학습하고,

모델 저장과 불러오기를 다루며,

규제 모델(Ridge, Lasso)의 적용과 규제 파라미터 튜닝 방법을 다룹니다.

하지만 코드가 일부 불완전한 부분이 있어 수정이 필요합니다.

예를 들어, SGDRegressor 모델의 fit() 메서드 호출 시

train 데이터의 열을 선택할 때 '시간'이라는 이름 대신 'X_train'으로 선택해야 합니다.

또한, linear_model.score() 메서드를 호출할 때 실제 값인 data['성적']

대신, 예측 값인 linear_model.predict(data[['시간']])을 전달해야 합니다.