본문 바로가기

Python/머신러닝(ML)

Python(20)- 선형회귀(Linear Regression)

*이 글을 읽기전에 작성자 개인의견이 있으니, 다른 블로그와 교차로 읽는것을 권장합니다.*

1. Rent 데이터셋

import numpy as np
import pandas as pd
import seaborn as sns
rent_df = pd.read_csv('/content/drive/MyDrive/KDT/6. 머신러닝과 딥러닝/Data/rent.csv')
rent_df

rent_df.info()
# null값이 몇개 있고, object type이기에 라벨인코딩 필요

각 column 설명

  • Posted On: 매물 등록 날짜
  • BHK: 베드, 홀, 키친의 갯수
  • Rent: 월세
  • Size: 집 크기
  • Floor: 총 층수 중 몇층
  • Area Type: 공유 공간을 포함하는지, 집의 면적만 포함하는지
  • Area Locality: 지역
  • City: 도시
  • Furnishing Status: 풀옵션 여부
  • Tenant Preferred: 선호하는 가족형태
  • Bathroom: 화장실 갯수
  • Point of Contact: 연락할 곳
rent_df.describe()
# BHK는 평균 2개, max 6개
# Rent비는 실수형태, 평균 35000

# 뒤에 소숫점 둘째자리까지 반올림
round(rent_df.describe(), 2)

rent_df['BHK']

# 막대그래프
sns.displot(rent_df['BHK'])

# 한쪽으로 치우친 그래프
# 정렬시켜 다시 보기
sns.displot(rent_df['Rent'])

rent_df['Rent'].sort_values()

sns.boxplot(y=rent_df['Rent'])
# 3.5에 OutLier 발생 확인

sns.boxplot(y=rent_df['BHK'])

# null값 확인
rent_df.isna().sum()

rent_df.isna().mean()
# null값 얼마안되니 제거

rent_df.dropna(subset=['BHK'])
# subset = 특정 열 선택

# Size열의 null값 index 출력
na_index = rent_df[rent_df['Size'].isna()].index
na_index

# null값인 index에 평균 대입
rent_df.fillna(rent_df.median(numeric_only=True)).loc[na_index]

rent_df = rent_df.fillna(rent_df.median(numeric_only=True))
rent_df.isna().mean()


렌트비가 얼마나 오르고 내리는지 예측하는 프로젝트

rent_df.info()
# 관련있는 column들이 모두 object이기에 어떤 값인지 확인 필요

# 각 value값마다 빈도수 계산
rent_df['Floor'].value_counts()

열의 각 값이 몇 번씩 나타나는지 확인

# 각 value값마다 빈도수 계산
rent_df['Area Type'].value_counts()

'unique()' 함수는 해당 열에 있는 중복되지 않는 고유한 값들을 반환

# column을 리스트로 뽑아서 종류 가져오기
rent_df['Area Type'].unique()

rent_df['Area Type'].nunique()

열에 있는 고유한 값의 개수를 반환

# for문으로 각 column 종류
for i in ['Floor', 'Area Type', 'Area Locality', 'City', 'Furnishing Status', 'Tenant Preferred', 'Point of Contact']:
    print(i, rent_df[i].nunique())

rent_df.drop(['Floor', 'Area Locality', 'Tenant Preferred', 'Point of Contact', 'Posted On'], axis=1, inplace=True)
rent_df.info()

rent_df = pd.get_dummies(rent_df, columns=['Area Type', 'City', 'Furnishing Status'])
rent_df.head()

X = rent_df.drop('Rent', axis=1) # 독립변수
y= rent_df['Rent'] # 종속변수
# 관례상 다차원은 대문자로 표현, 1차원 행벡터는 소문자로 표현
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2024)
X_train.shape, X_test.shape

y_train.shape, y_test.shape


2. 선형 회귀(Linear Regression)

  • 데이터를 통해 데이터를 가장 잘 설명할 수 있는 직선으로 데이터를 분석하는 방법
    • 단순 선형 회귀분석(단일 독립변수를 이용)
    • 다중 선형 회귀분석(다중 독립변수를 이용)
from sklearn.linear_model import LinearRegression

선형회귀모델 모듈 가져오기

입력 변수와 출력 변수 사이의 선형 관계를 모델링하고 예측하는 데 사용

lr = LinearRegression()

선형 회귀 모델 객체를 할당

lr.fit(X_train, y_train)
# 학습을 한다는 것: 데이터를 삽입하고 오차(los)를 줄여나가는 과정
# 가중치와 편향 찾는 것에 다양한 정답이 있다.

학습완료

fit() 메서드는 입력 데이터 X_train과 출력 데이터 y_train을 사용하여 모델의 계수(coeficients)와 절편(intercept)을 최적화, 모델이 학습된 후에는 새로운 입력 데이터에 대한 예측을 수행

pred = lr.predict(X_test)
pred
# 데이터를 넣었을 때, 예측값을 뽑을때 원래값, 오차가 발생

모델학습은 train으로,  예측값은 test로


3. 평가 지표 만들기

3-1. MSE(Mean Squared Error): 평균제곱오차

  • 예측값과 실제값의 차이에 대한 제곱에 대해 평균을 낸 값(예측값 - 실제값)
  • 오차 제곱의 평균
  • (1/n)∑ni=1(yi−xi)2
  • MSE( θ ^ )=E[(θ− θ ^ ) 2 ]
p = np.array([3,4,5]) # 예측값
act = np.array([1,2,3]) # 실제값
def my_mse(pred, actual):
    return((pred-actual) **2).mean()
my_mse(p, act)
# {(3-1)+(4-2)+(5-3)}^2 / 평균(3)

3-2. MAE(Mean Absolute Error)

  • 예측값과 실제값의 차이에 대한 절대값에 대해 평균을 낸 값
  • 절대값은 미분할 수 없기에 머신러닝에 적합하지 않으므로 사용하지 않음.
  • (1/n)∑ni=1|yi−xi|
def my_mad(pred, actual):
    return np.abs(pred-actual).mean()
my_mad(p,act)

3-3. RMSE(Root Mean Squared Error)

  • 예측값과 실제값의 차이에 대한 제곱에 대해 평균을 낸 후 루트를 씌운 값
  • (1/n)∑ni=1(yi−xi)2
def my_rmse(pred, actual):
    return np.sqrt(my_mse(pred, actual))
my_rmse(p, act)
# MSE에 sqrt만 쓴거랑 다른게...?

from sklearn.metrics import mean_absolute_error, mean_squared_error

MAE와 MSE 평가지표 모듈 가져오기

mean_absolute_error(p, act)

# mean_squared_error(xi = 실제값, yi = 예측값)
mean_squared_error(p, act)

mean_squared_error(p, act, squared=False) #RMSE

3-4. 데이터에 평가지표 적용하기

mean_squared_error(y_test, pred)

mean_absolute_error(y_test, pred)

mean_squared_error(y_test, pred, squared=False)

# 아웃라이어로 생각되는 데이터를 삭제
# 아웃라이어가 없다면 에러발생
X_train.drop(1837, inplace=True)
y_train.drop(1837, inplace=True)

아웃라이어(Outlier) : 데이터셋에서 다른 데이터 포인트들과 현저히 다르게 나타나는 포인트. 전처리 과정에서 반드시 발견하고 전처리 필요.

lr.fit(X_train, y_train)

pred = lr.predict(X_test)
mean_squared_error(y_test, pred, squared=False)
# RMSE

# 1837 삭제 전: 37765.125980605386
# 1837 삭제 후: 37731.275512059074
37765.125980605386 - 37731.275512059074
# 33.8504685463 만큼 오차가 줄었음