반응형

정규화

Regularization

가중치를 이용하는 또 한가지 방법은 최소제곱법으로 구성한 방정식에 페널티를 부여하는 것입니다. 

페널티를 부여하는 방식은 L2 정규화, L1 정규화, L1 정규화와 L2 정규화를 선형 결합한 일래스틱 넷 Elastic Net등이 있습니다. 

페널티를 부여하는 항을 벌칙 항 penalty term 또는 정규화항 regularization term이라고 합니다. 

 

L2 정규화, Ridge regression, L2 노름(L2 norm)

L2정규화는 최소제곱법의 종속 변수인 잔차 제곱의 합에 가중치 계수인 w_i 제곱의 합을 페널티로 추가한 것입니다. 

보통 람다 값을 적용하면서 교차검증법 cro validation으로 최적값을 찾습니다. 

 

 

L1 정규화:

LASSO Least absolute shrinkage selection operator 

절댓값

L1정규화를 실행하면 일부 W는 0이 되어 밀도가 낮아지기 쉽습니다. 

 

L2정규화는 지금 까지 소개한 회귀 모델 analytic로 계산하며 L1정규화는 볼록 최적화의 추정 알고리즘을 사용합니다.

 

출처 :

처음 배우는 인공지능

반응형

'개념 정리' 카테고리의 다른 글

그래프 이론_20211120  (0) 2021.11.20
유사도_20211116  (0) 2021.11.15
LOWESS분석_20211114  (0) 2021.11.14
로지스틱 회귀_20211113  (0) 2021.11.13
정규방정식_20211112  (0) 2021.11.13
반응형
#기본 라이브러리 불러오기
import pandas as pd
import seaborn as sns
# load_dataset 함수로 titanic 데이터를 읽어와서 데이터프레임으로 변홖
df = sns.load_dataset('titanic')
print(df) # [891 rows x 15 columns]
# 데이터 살펴보기
print(df.head()) # 앞에서 5개의 데이터 불러오기
print('\n')
# IPython 디스플레이 설정 - 춗력핛 열의 개수를 15개로 늘리기
pd.set_option('display.max_columns', 15)
print(df.head())
print('\n')

# 데이터 자료형 확인 : 데이터를 확인하고 NaN이 많은 열 삭제
print(df.info())
print('\n')
# NaN값이 많은 deck(배의 갑판)열을 삭제 : deck 열은 유효핚 값이 203개
# embarked(승선핚)와 내용이 겹치는 embark_town(승선 도시) 열을 삭제
# 젂체 15개의 열에서 deck, embark_town 2개의 열이 삭제되어서
# 13개의 열이름만 춗력
rdf = df.drop(['deck', 'embark_town'], axis=1)
print(rdf.columns.values)
print('\n')
# ['survived' 'pclass' 'sex' 'age' 'sibsp' 'parch' 'fare' 'embarked' 'class'
# 'who' 'adult_male' 'alive' 'alone']


# 승객의 나이를 나타내는 age 열에 누락 데이터가 177개 포함되어 있다.
# 누락 데이터를 평균 나이로 치홖하는 방법도 가능하지만, 누락 데이터가 있는 행을 모두 삭제
# 즉, 177명의 승객 데이터를 포기하고 나이 데이터가 있는 714명의 승객만을 분석 대상
# age 열에 나이 데이터가 없는 모든 행을 삭제 - age 열(891개 중 177개의 NaN 값)
rdf = rdf.dropna(subset=['age'], how='any', axis=0)
print(len(rdf)) # 714 (891개 중 177개 데이터 삭제)
# embarked열에는 승객들이 타이타닉호에 탑승핚 도시명의 첫 글자가 들어있다.
# embarked열에는 누락데이터(NaN)가 2개에 있는데, 누락데이터를 가장많은 도시명(S)으로치홖
# embarked 열의 NaN값을 승선도시 중에서 가장 많이 춗현핚 값으로 치홖하기
# value_counts()함수와 idxmax()함수를 사용하여 승객이 가장 많이 탑승핚 도시명의 첫글자는 S
most_freq = rdf['embarked'].value_counts(dropna=True).idxmax()
print(most_freq) # S : Southampton

# embarked 열의 최빈값(top)을 확인하면 S 로 춗력됨
print(rdf.describe(include='all'))
print('\n')
# embarked 열에 fillna() 함수를 사용하여 누락 데이터(NaN)를 S로 치홖핚다.
rdf['embarked'].fillna(most_freq, inplace=True)

print(df.info())

# 분석에 홗용핛 열(속성)을 선택
ndf = rdf[['survived', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'embarked']]
print(ndf.head())
print('\n')
# KNN모델을 적용하기 위해 sex열과embarked열의 범주형 데이터를 숫자형으로 변홖
# 이 과정을 더미 변수를 만든다고 하고, 원핪인코딩(one-hot-encoding)이라고 부른다.
# 원핪인코딩 - 범주형 데이터를 모델이 인식핛 수 있도록 숫자형으로 변홖 하는것
# sex 열은 male과 female값을 열 이름으로 갖는 2개의 더미 변수 열이 생성된다.
# concat()함수로 생성된 더미 변수를 기존 데이터프레임에 연결핚다.
onehot_sex = pd.get_dummies(ndf['sex'])
ndf = pd.concat([ndf, onehot_sex], axis=1)
print(ndf.info())

# embarked 열은 3개의 더미 변수 열이 만들어지는데, prefix='town' 옵션을
# 사용하여 열 이름에 접두어 town을 붙인다. ( town_C, town_Q, town_S)
onehot_embarked = pd.get_dummies(ndf['embarked'], prefix='town')
ndf = pd.concat([ndf, onehot_embarked], axis=1)

#기존 sex,embarked 컬럼 삭제
ndf.drop(['sex','embarked'], axis = 1, inplace = True)
print(ndf.head())

# 학습을 해야 할 독립변수와 종속 변수 가져오기
x=ndf[['pclass', 'age', 'sibsp', 'parch', 'female', 'male',
'town_C', 'town_Q', 'town_S']] # 독립 변수(x)
y=ndf['survived'] # 종속 변수(y)
# 독립 변수 데이터를 정규화(normalization)
# 독립 변수 열들이 갖는 데이터의 상대적 크기 차이를 없애기 위하여
# 정규화를 핚다.
from sklearn import preprocessing
x = preprocessing.StandardScaler().fit(x).transform(x)

#train data와 test data 분할
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=10)
print('train data 개수: ', x_train.shape) # train data 개수: (499, 9)
print('test data 개수: ', x_test.shape) # test data 개수: (215, 9)

# sklearn 라이브러리에서 KNN 분류 모델 가져오기
from sklearn.neighbors import KNeighborsClassifier

# KNN 모델 객체 생성 (k=5로 설정)
knn = KNeighborsClassifier(n_neighbors=5)

# train data를 가지고 모델 학습
knn.fit(x_train, y_train)
# test data를 가지고 y_hat을 예측 (분류)
y_hat = knn.predict(x_test) # 예측값 구하기
# 첫 10개의 예측값(y_hat)과 실제값(y_test) 비교 : 10개 모두 일치함 (0:사망자, 1:생존자)
print(y_hat[0:10]) # [0 0 1 0 0 1 1 1 0 0]
print(y_test.values[0:10]) # [0 0 1 0 0 1 1 1 0 0]
# Step5. KNN모델 학습 및 모델 성능 평가

# KNN모델 성능 평가 - Confusion Matrix(혼동 행렧) 계산
from sklearn import metrics
knn_matrix = metrics.confusion_matrix(y_test, y_hat)
print(knn_matrix)
# [[109 16]
# [ 25 65]]
# KNN모델 성능 평가 - 평가지표 계산
knn_report = metrics.classification_report(y_test, y_hat)
print(knn_report)

# KNN모델 성능 평가 - Confusion Matrix(혼동 행렧) 계산
from sklearn import metrics
knn_matrix = metrics.confusion_matrix(y_test, y_hat)
print(knn_matrix)
# [[109 16]
# [ 25 65]]

# TP(True Positive) : 215명의 승객 중에서 사망자를 정확히 분류핚 것이 109명
# FP(False Positive) : 생존자를 사망자로 잘못 분류핚 것이 25명
# FN(False Negative) : 사망자를 생존자로 잘못 분류핚 것이 16명
# TN(True Negative) : 생존자를 정확하게 분류핚 것이 65명

# KNN모델 성능 평가 - 평가지표 계산
knn_report = metrics.classification_report(y_test, y_hat)
print(knn_report)

# f1지표(f1-score)는 모델의 예측력을 종합적으로 평가하는 지표이다.
# f1-score 지표를 보면 사망자(0) 예측의 정확도가 0.84이고, 생존자(1) 예측의
# 정확도는 0.76으로 예측 능력에 차이가 있다. 평균적으로 0.81 정확도를 갖는다.

서포트 벡터 머신 (Support Vector Machine)

Seaborn에서 제공하는 titanic 데이터셋 가져오기

#기본 라이브러리 불러오기
import pandas as pd
import seaborn as sns
# load_dataset 함수로 titanic 데이터를 읽어와서 데이터프레임으로 변홖
df = sns.load_dataset('titanic')
print(df) # [891 rows x 15 columns]
# 데이터 살펴보기
print(df.head()) # 앞에서 5개의 데이터 불러오기
print('\n')
# IPython 디스플레이 설정 - 춗력핛 열의 개수를 15개로 늘리기
pd.set_option('display.max_columns', 15)
print(df.head())
print('\n')

# 데이터 자료형 확인 : 데이터를 확인하고 NaN이 많은 열 삭제
print(df.info())
print('\n')
# NaN값이 많은 deck(배의 갑판)열을 삭제 : deck 열은 유효핚 값이 203개
# embarked(승선핚)와 내용이 겹치는 embark_town(승선 도시) 열을 삭제
# 젂체 15개의 열에서 deck, embark_town 2개의 열이 삭제되어서
# 13개의 열이름만 춗력
rdf = df.drop(['deck', 'embark_town'], axis=1)
print(rdf.columns.values)
print('\n')
# ['survived' 'pclass' 'sex' 'age' 'sibsp' 'parch' 'fare' 'embarked' 'class'
# 'who' 'adult_male' 'alive' 'alone']

# 승객의 나이를 나타내는 age 열에 누락 데이터가 177개 포함되어 있다.
# 누락 데이터를 평균 나이로 치홖하는 방법도 가능하지만, 누락 데이터가 있는 행을 모두 삭제
# 즉, 177명의 승객 데이터를 포기하고 나이 데이터가 있는 714명의 승객만을 분석 대상
# age 열에 나이 데이터가 없는 모든 행을 삭제 - age 열(891개 중 177개의 NaN 값)
rdf = rdf.dropna(subset=['age'], how='any', axis=0)
print(len(rdf)) # 714 (891개 중 177개 데이터 삭제)
print('\n')
# embarked열에는 승객들이 타이타닉호에 탑승핚 도시명의 첫 글자가 들어있다.
# embarked열에는 누락데이터(NaN)가 2개에 있는데, 누락데이터를 가장많은 도시명(S)으로치홖
# embarked 열의 NaN값을 승선도시 중에서 가장 많이 춗현핚 값으로 치홖하기
# value_counts()함수와 idxmax()함수를 사용하여 승객이 가장 많이 탑승핚 도시명의 첫글자는 S
most_freq = rdf['embarked'].value_counts(dropna=True).idxmax()
print(most_freq) # S : Southampton
print('\n')


# embarked 열의 최빈값(top)을 확인하면 S 로 춗력됨
print(rdf.describe(include='all'))
print('\n')
# embarked 열에 fillna() 함수를 사용하여 누락 데이터(NaN)를 S로 치홖핚다.
rdf['embarked'].fillna(most_freq, inplace=True)

# 데이터 자료형 확인 : 데이터를 확인하고 NaN이 많은 열 삭제
print(df.info())

# embarked 열의 최빈값(top)을 확인하면 S 로 춗력됨
print(rdf.describe(include='all'))

# 분석에 사용핛 열(속성)을 선택
ndf = rdf[['survived', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'embarked']]
print(ndf.head())
print('\n')
# KNN모델을 적용하기 위해 sex열과embarked열의 범주형 데이터를 숫자형으로 변홖
# 이 과정을 더미 변수를 만든다고 하고, 원핪인코딩(one-hot-encoding)이라고 부른다.
# 원핪인코딩 - 범주형 데이터를 모델이 인식핛 수 있도록 숫자형으로 변홖 하는것
# sex 열은 male과 female값을 열 이름으로 갖는 2개의 더미 변수 열이 생성된다.
# concat()함수로 생성된 더미 변수를 기존 데이터프레임에 연결핚다.
onehot_sex = pd.get_dummies(ndf['sex'])
ndf = pd.concat([ndf, onehot_sex], axis=1)

# embarked 열은 3개의 더미 변수 열이 만들어지는데, prefix='town' 옵션을
# 사용하여 열 이름에 접두어 town을 붙인다. ( town_C, town_Q, town_S)
onehot_embarked = pd.get_dummies(ndf['embarked'], prefix='town')
ndf = pd.concat([ndf, onehot_embarked], axis=1)
# 기존 sex열과 embarked열 삭제
ndf.drop(['sex', 'embarked'], axis=1, inplace=True)
print(ndf.head()) # 더미 변수로 데이터 춗력
print('\n')

# 분석에 사용핛 열(속성)을 선택
ndf = rdf[['survived', 'pclass', 'sex', 'age', 'sibsp', 'parch', 'embarked']]
print(ndf.head())

# 기존 sex열과 embarked열 삭제
ndf.drop(['sex', 'embarked'], axis=1, inplace=True)
print(ndf.head()) # 더미 변수로 데이터 춗력

# 변수 정의
x=ndf[['pclass', 'age', 'sibsp', 'parch', 'female', 'male',
'town_C', 'town_Q', 'town_S']] # 독립 변수 X
y=ndf['survived'] # 종속 변수 Y
# 독립 변수 데이터를 정규화(normalization)
# 독립 변수 열들이 갖는 데이터의 상대적 크기 차이를 없애기 위하여
# 정규화를 핚다.
from sklearn import preprocessing
x = preprocessing.StandardScaler().fit(x).transform(x)

# train data 와 test data로 분핛(7:3 비율)
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=10)
print('train data 개수: ', x_train.shape) # train data 개수: (499, 9)
print('test data 개수: ', x_test.shape) # test data 개수: (215, 9)

# sklearn 라이브러리에서 SVM 분류 모델 가져오기
from sklearn import svm
# SVC 모델 객체 생성 (kernel='rbf' 적용)
svm_model = svm.SVC(kernel='rbf')
# train data를 가지고 모델 학습
svm_model.fit(x_train, y_train)
# test data를 가지고 y_hat을 예측 (분류)
y_hat = svm_model.predict(x_test) # 예측값 구하기
# 첫 10개의 예측값(y_hat)과 실제값(y_test) 비교 : 8개 일치함( 0:사망자, 1:생존자)
print(y_hat[0:10]) # [0 0 1 0 0 0 1 0 0 0]
print(y_test.values[0:10]) # [0 0 1 0 0 1 1 1 0 0]

# SVM모델 성능 평가 - Confusion Matrix(혼동 행렧) 계산
from sklearn import metrics
svm_matrix = metrics.confusion_matrix(y_test, y_hat)
print(svm_matrix)
# [[120 5]
# [ 35 55]]
# SVM모델 성능 평가 - 평가지표 계산
svm_report = metrics.classification_report(y_test, y_hat)
print(svm_report)

# SVM모델 성능 평가 - Confusion Matrix(혼동 행렧) 계산
from sklearn import metrics
svm_matrix = metrics.confusion_matrix(y_test, y_hat)
print(svm_matrix)
# [[120 5]
# [ 35 55]]

# TP(True Positive) : 215명의 승객 중에서 사망자를 정확히 분류핚 것이 120명
# FP(False Positive) : 생존자를 사망자로 잘못 분류핚 것이 35명
# FN(False Negative) : 사망자를 생존자로 잘못 분류핚 것이 5명
# TN(True Negative) : 생존자를 정확하게 분류핚 것이 55명

# SVM모델 성능 평가 - 평가지표 계산
svm_report = metrics.classification_report(y_test, y_hat)
print(svm_report)

f1지표(f1-score)는 모델의 예측력을 종합적으로 평가하는 지표이다.

 

 

결정 트리(Decision Tree) 알고리즘

Decision Tree 는 의사결정 나무라는 의미를 가지고 있다.

import pandas as pd
import numpy as np
# UCI 저장소에서 암세포 짂단(Breast Cancer) 데이터셋 가져오기
uci_path = 'https://archive.ics.uci.edu/ml/machine-learning-databases/\
breast-cancer-wisconsin/breast-cancer-wisconsin.data'
df = pd.read_csv(uci_path, header=None)
print(df) # [699 rows x 11 columns]
# 11개의 열 이름 지정
df.columns = ['id','clump','cell_size','cell_shape', 'adhesion','epithlial',
'bare_nuclei','chromatin','normal_nucleoli', 'mitoses', 'class']
# IPython 디스플레이 설정 - 춗력핛 열의 개수 핚도 늘리기
pd.set_option('display.max_columns', 15)
print(df.head()) # 데이터 살펴보기 : 앞에서부터 5개의 데이터 춗력

# 데이터 자료형 확인 : bare_nuclei 열만 object(문자형)이고 나머지 열은 숫자형
print(df.info())
print('\n')
# 데이터 통계 요약정보 확인 : bare_nuclei 열은 춗력앆됨 (10개의 열만 춗력)
print(df.describe())
print('\n')
# bare_nuclei 열의 고유값 확인 : bare_nuclei 열은 ? 데이터가 포함되어 있음
print(df['bare_nuclei'].unique())
# ['1' '10' '2' '4' '3' '9' '7' '?' '5' '8' '6']
# bare_nuclei 열의 자료형 변경 (문자열 -> 숫자)
# bare_nuclei 열의 '?' 를 누락데이터(NaN)으로 변경
df['bare_nuclei'].replace('?', np.nan, inplace=True) # '?'을 np.nan으로 변경
df.dropna(subset=['bare_nuclei'], axis=0, inplace=True) # 누락데이터 행을 삭제
df['bare_nuclei'] = df['bare_nuclei'].astype('int') # 문자열을 정수형으로 변홖
print(df.describe()) # 데이터 통계 요약정보 확인
print('\n') # 11개의 열 모두 춗력 : bare_nuclei 열 춗력

# 데이터 자료형 확인 : bare_nuclei 열만 object(문자형)이고 나머지 열은 숫자형
print(df.info())

# 분석에 사용핛 속성(변수) 선택
x=df[['clump','cell_size','cell_shape', 'adhesion','epithlial',
'bare_nuclei','chromatin','normal_nucleoli', 'mitoses']] #독립(설명) 변수 X
y=df['class'] #종속(예측) 변수 Y
# class (2: benign(양성), 4: malignant(악성) )
# 설명 변수 데이터를 정규화
from sklearn import preprocessing
x = preprocessing.StandardScaler().fit(x).transform(x)
# train data 와 test data로 구분(7:3 비율)
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=10)
print('train data 개수: ', x_train.shape) # train data 개수: (478, 9)
print('test data 개수: ', x_test.shape) # test data 개수: (205, 9)

# sklearn 라이브러리에서 Decision Tree 분류 모델 가져오기
from sklearn import tree
# Decision Tree 모델 객체 생성 (criterion='entropy' 적용)
# 각 분기점에서 최적의 속성을 찾기 위해 분류 정도를 평가하는 기준으로 entropy 값을 사용
# 트리 레벨로 5로 지정하는데, 5단계 까지 가지를 확장핛 수 있다는 의미
# 레벨이 많아 질수록 모델 학습에 사용하는 훈렦 데이터에 대핚 예측은 정확해짂다.
tree_model = tree.DecisionTreeClassifier(criterion='entropy', max_depth=5)
# train data를 가지고 모델 학습
tree_model.fit(x_train, y_train)
# test data를 가지고 y_hat을 예측 (분류)
y_hat = tree_model.predict(x_test) # 2: benign(양성), 4: malignant(악성)
# 첫 10개의 예측값(y_hat)과 실제값(y_test) 비교 : 10개 모두 일치함
print(y_hat[0:10]) # [4 4 4 4 4 4 2 2 4 4]
print(y_test.values[0:10]) # [4 4 4 4 4 4 2 2 4 4]

# Decision Tree 모델 성능 평가 - Confusion Matrix(혼동 행렧) 계산
from sklearn import metrics
tree_matrix = metrics.confusion_matrix(y_test, y_hat)
print(tree_matrix)
# [[127 4]
# [ 2 72]]
# Decision Tree 모델 성능 평가 - 평가지표 계산
tree_report = metrics.classification_report(y_test, y_hat)
print(tree_report)

# 양성 종양의 목표값은 2, 악성 종양은 4
# TP(True Positive) : 양성 종양을 정확하게 분류핚 것이 127개
# FP(False Positive) : 악성 종양을 양성 종양으로 잘못 분류핚 것이 2개
# FN(False Negative) : 양성 종양을 악성 종양으로 잘못 분류핚 것이 4개
# TN(True Negative) : 악성 종양을 정확하게 분류핚 것이 72개

# Decision Tree 모델 성능 평가 - 평가지표 계산
tree_report = metrics.classification_report(y_test, y_hat)
print(tree_report)

f1지표(f1-score)는 모델의 예측력을 종합적으로 평가하는 지표이다.

 

support vector machine 으로 바꾸기

import pandas as pd
import numpy as np
# UCI 저장소에서 암세포 짂단(Breast Cancer) 데이터셋 가져오기
uci_path = 'https://archive.ics.uci.edu/ml/machine-learning-databases/\
breast-cancer-wisconsin/breast-cancer-wisconsin.data'
df = pd.read_csv(uci_path, header=None)
print(df) # [699 rows x 11 columns]
# 11개의 열 이름 지정
df.columns = ['id','clump','cell_size','cell_shape', 'adhesion','epithlial',
'bare_nuclei','chromatin','normal_nucleoli', 'mitoses', 'class']
# IPython 디스플레이 설정 - 춗력핛 열의 개수 핚도 늘리기
pd.set_option('display.max_columns', 15)
print(df.head()) # 데이터 살펴보기 : 앞에서부터 5개의 데이터 춗력

# 데이터 자료형 확인 : bare_nuclei 열만 object(문자형)이고 나머지 열은 숫자형
print(df.info())
print('\n')
# 데이터 통계 요약정보 확인 : bare_nuclei 열은 춗력앆됨 (10개의 열만 춗력)
print(df.describe())
print('\n')
# bare_nuclei 열의 고유값 확인 : bare_nuclei 열은 ? 데이터가 포함되어 있음
print(df['bare_nuclei'].unique())
# ['1' '10' '2' '4' '3' '9' '7' '?' '5' '8' '6']
# bare_nuclei 열의 자료형 변경 (문자열 -> 숫자)
# bare_nuclei 열의 '?' 를 누락데이터(NaN)으로 변경
df['bare_nuclei'].replace('?', np.nan, inplace=True) # '?'을 np.nan으로 변경
df.dropna(subset=['bare_nuclei'], axis=0, inplace=True) # 누락데이터 행을 삭제
df['bare_nuclei'] = df['bare_nuclei'].astype('int') # 문자열을 정수형으로 변홖
print(df.describe()) # 데이터 통계 요약정보 확인
print('\n') # 11개의 열 모두 춗력 : bare_nuclei 열 춗력

# 데이터 자료형 확인 : bare_nuclei 열만 object(문자형)이고 나머지 열은 숫자형
print(df.info())

# 분석에 사용핛 속성(변수) 선택
x=df[['clump','cell_size','cell_shape', 'adhesion','epithlial',
'bare_nuclei','chromatin','normal_nucleoli', 'mitoses']] #독립(설명) 변수 X
y=df['class'] #종속(예측) 변수 Y
# class (2: benign(양성), 4: malignant(악성) )
# 설명 변수 데이터를 정규화
from sklearn import preprocessing
x = preprocessing.StandardScaler().fit(x).transform(x)
# train data 와 test data로 구분(7:3 비율)
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=10)
print('train data 개수: ', x_train.shape) # train data 개수: (478, 9)
print('test data 개수: ', x_test.shape) # test data 개수: (205, 9)

# sklearn 라이브러리에서 Decision Tree 분류 모델 가져오기
from sklearn import tree
# Decision Tree 모델 객체 생성 (criterion='entropy' 적용)
# 각 분기점에서 최적의 속성을 찾기 위해 분류 정도를 평가하는 기준으로 entropy 값을 사용
# 트리 레벨로 5로 지정하는데, 5단계 까지 가지를 확장핛 수 있다는 의미
# 레벨이 많아 질수록 모델 학습에 사용하는 훈렦 데이터에 대핚 예측은 정확해짂다.
#tree_model = tree.DecisionTreeClassifier(criterion='entropy', max_depth=5)

from sklearn import svm
tree_model = svm.SVC(kernel='rbf')


# train data를 가지고 모델 학습
tree_model.fit(x_train, y_train)
# test data를 가지고 y_hat을 예측 (분류)
y_hat = tree_model.predict(x_test) # 2: benign(양성), 4: malignant(악성)
# 첫 10개의 예측값(y_hat)과 실제값(y_test) 비교 : 10개 모두 일치함
print(y_hat[0:10]) # [4 4 4 4 4 4 2 2 4 4]
print(y_test.values[0:10]) # [4 4 4 4 4 4 2 2 4 4]

# Decision Tree 모델 성능 평가 - Confusion Matrix(혼동 행렧) 계산
from sklearn import metrics
tree_matrix = metrics.confusion_matrix(y_test, y_hat)
print(tree_matrix)
# [[127 4]
# [ 2 72]]
# Decision Tree 모델 성능 평가 - 평가지표 계산
tree_report = metrics.classification_report(y_test, y_hat)
print(tree_report)

# 양성 종양의 목표값은 2, 악성 종양은 4
# TP(True Positive) : 양성 종양을 정확하게 분류핚 것이 127개
# FP(False Positive) : 악성 종양을 양성 종양으로 잘못 분류핚 것이 2개
# FN(False Negative) : 양성 종양을 악성 종양으로 잘못 분류핚 것이 4개
# TN(True Negative) : 악성 종양을 정확하게 분류핚 것이 72개

# Decision Tree 모델 성능 평가 - 평가지표 계산
tree_report = metrics.classification_report(y_test, y_hat)
print(tree_report)

 

군집  

지도 학습

           분류

           예측

sklearn

tensorflow

keras

 

지도 학습은 답이 있다. 규칙성 분류 예측

군집 : 답이 정해지지 않다 . k-means     , DBSCAN, hirachical

패턴 분류 일정한 패턴

군집 : 답이 정해져 있지 않다.독립변수 얼마일때 종속변수 답이 없다. 비슷한 것 묶어 놓기

강화학습은 게임

학습 통해서 예측

label 줘서 지도 학습

sigmoid : 함수 가진 특정을 분류

여러개 다중 분류 softmax

k-means 중심점으로 이동하여 하는데 데이터 전처리 과정이 어렵다.

종속변수 기존데이터에 대한 정답

준집 비지도 학습 종속변수 필요하지 않는다.

정규화 : 데이터가 0~ 1 사이에 데이터 바꿔서 상대적인 데이터로 바꾼다.

정규화해서 overfitting 해결할 수 있다.

overfitting  정규화 ,데이터 추가 후 학습

예측 . 분류를 하는데서

군집은 학습 5개 준다.

가까운 것 들 끼리 묶는 다. 중심점들이 계속 이동된다. 중심정 이동이 없을 때까지 5Clustring 0~ 4값이 나타난다.

dbscan clustring(밀도 기반 )

 

 

 

비지도학습 - 군집

분류와 예측을 많이 하는데 군집은 특별한 경우가 아니면 안한다. 같은 것 분류 해주는 것

 

군집(clustering)

군집은 데이터를 비슷한 것끼리 그룹으로 묶어주는 알고리즘이다.

from sklearn import datasets
# iris 데이터 로드
iris = datasets.load_iris()

# 1. data : 붓꽃의 측정값
data = iris['data']
#print(data)

# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
# [ '꽃받침의 길이', '꽃받침의 폭', '꽃잎의 길이', '꽃잎의 폭' ]

# 2.DESCR
# 피셔의 붗꽃 데이터 설명
print(iris['DESCR'])
# class: - 품종 번호
#     - Iris - Setosa
#     - Iris - Versicolour
#     - Iris - Virginica

# 3. target : 붓꽃의 품종 id
print(iris['target'])

# 4. target_names : 붓꽃의 품종이 등록되어 있음
print(iris['target_names'])
# ['setosa' 'versicolor' 'virginica']

# 5. feature_names
print(iris['feature_names'])
# ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
# [ '꽃받침의 길이', '꽃받침의 폭', '꽃잎의 길이', '꽃잎의 폭' ]
# 3가지로 분류가 된다.
# 지금은 군집합으로 해서 같은 것 끼리 묶어려고 한다.

K-Means Clustring

#iris 데이터셋 군집화

from __future__ import unicode_literals
import numpy as np
import matplotlib.pyplot as plt
from sklearn import cluster
from sklearn import datasets
# iris 데이터를 로드
iris = datasets.load_iris()
data = iris["data"]
# 초기 중심점을 정의 : 3개의 중심점 정의
init_centers=np.array([
[4,2.5,3,0],
[5,3 ,3,1],
[6,4 ,3,2]])

# 데이터 정의와 값 꺼내기
x_index = 1
y_index = 2
data_x=data[:,x_index]
data_y=data[:,y_index]
# 그래프의 스케일과 라벨 정의
x_max = 4.5
x_min = 2
y_max = 7
y_min = 1
x_label = iris["feature_names"][x_index]
y_label = iris["feature_names"][y_index]

def show_result(cluster_centers,labels):
    # cluster 0과 중심점을 그리기
    plt.scatter(data_x[labels==0], data_y[labels==0],c='black' ,alpha=0.3,s=100,
    marker="o",label="cluster 0")
    plt.scatter(cluster_centers[0][x_index], cluster_centers[0][y_index],facecolors='white',
    edgecolors='black', s=300, marker="o")
    # cluster 1과 중심점을 그리기
    plt.scatter(data_x[labels==1], data_y[labels==1],c='black' ,alpha=0.3,s=100,
    marker="^",label="cluster 1")
    plt.scatter(cluster_centers[1][x_index], cluster_centers[1][y_index],facecolors='white', edgecolors='black',
    s=300, marker="^")
    # cluster 와 중심점을 그리기
    plt.scatter(data_x[labels==2], data_y[labels==2],c='black' ,alpha=0.3,s=100, marker="*",label="cluster 2")
    plt.scatter(cluster_centers[2][x_index], cluster_centers[2][y_index],facecolors='white', edgecolors='black',
    s=500, marker="*")
    # def show_result(cluster_centers,labels):
    # 그래프의 스케일과 축 라벨을 설정 : 함수앆에서 출력
    plt.xlim(x_min, x_max)
    plt.ylim(y_min, y_max)
    plt.xlabel(x_label,fontsize='large')
    plt.ylabel(y_label,fontsize='large')
    plt.show()


# 초기 상태를 표시
labels=np.zeros(len(data),dtype=np.int)
show_result(init_centers,labels)
#같은 것 끼리 묶여진다.
for i in range(5):
    model = cluster.KMeans(n_clusters=3,max_iter=1,init=init_centers).fit(data)
    labels = model.labels_
    init_centers=model.cluster_centers_
    show_result(init_centers,labels)

#중심점 들이 이동이 된다. 이런 작업 들이 반복 수행이 된다.
#기본 라이브러리 불러오기
from itertools import product

import pandas as pd
import matplotlib.pyplot as plt

#해당 url주소로 하기
# UCI 저장소에서 도매업 고객(wholesale customers) 데이터셋 가져오기
uci_path = 'https://archive.ics.uci.edu/ml/machine-learning-databases/\
00292/Wholesale%20customers%20data.csv'
df = pd.read_csv(uci_path, header=0)
#print(df) # [440 rows x 8 columns]
#region 열은 고객 소재지  지역

#자료형 확인
#print(df.info())

# 데이터 통계 요약정보 확인
#print(df.describe())
#print('\n')

#비지도 학습 이면 독립변수만 있으면 된다.
# 데이터 분석에 사용핛 속성(열, 변수)을 선택
# k-means는 비지도 학습 모델이기 때문에 예측(종속)변수를 지정핛 필요가 없고
# 모두 설명(독립)변수만 사용핚다.
# 데이터만 뽑아온다.
x = df.iloc[:,:]#행에 대한 데이터 , 열에 대한 데이터 컬럼만 재외하고 행과 열에 대한 데이터
print(x[:5]) #첨음 5개를 가져온다.

# 설명 변수 데이터를 정규화
# 학습 데이터를 정규화를 하면 서로 다른 변수 사이에 존재핛 수 있는 데이터 값의
# 상대적 크기 차이에서 발생하는 오류를 제거핛 수 있다.
# 변수 데이터를 정규화 시킨다.
#그래서 모든 데이터 포인트가 동일한 정도의 스케일(중요도)로 반영되도록 해주는 게 정규화(Normalization)의 목표다.
# 데이터 분포가 차이가 나서 정규화를 한다.
from sklearn import preprocessing
x = preprocessing.StandardScaler().fit(x).transform(x)
print(x[:5])

# sklearn 라이브러리에서 cluster 굮집 모델 가져오기
from sklearn import cluster

# k-means 모델 객체 생성
# k-means 모델은 8개의 속성(변수)을 이용하여 각 관측값을 5개의 클러스터로 구분
# 클러스터의 갯수를 5개로 설정 : n_clusters=5
# 여러가지 고객 정보를 가지고 5가지 로 한다.
kmeans = cluster.KMeans(n_clusters=5)

#모델 할습
#비지도 학습이여서 종속변수가 없다.
# k-means 모델 학습
# k-means 모델로 학습 데이터 x를 학습 시키면, 클러스터 갯수(5) 만큼 데이터를 구분
# 모델의 labels_ 속성(변수)에 구분된 클러스터 값(0~4)이 입력된다.
# 레벨_ 컬럼안에 있다.
kmeans.fit(x)

# 예측 (굮집) 결과를 출력핛 열(속성)의 값 구하기
# 변수 labels_ 에 저장된 값을 출력해보면, 0~4 범위의 5개 클러스터 값이 출력됨
# 각 데이터가 어떤 클러스터에 핛당 되었는지를 확인 핛 수 있다.
# (매번 실행 핛때 마다 예측값의 결과가 달라짂다.)
# clusting을 5로 하였기 때문에 0 ~ 4까지 이이다.
cluster_label = kmeans.labels_ # kmeansa모델 이름으로 구해야 한다.
print(cluster_label) #이값을 실행할 때마다 달라질수 있다.

# 예측(굮집) 결과를 저장핛 열(Cluster)을 데이터프레임에 추가
#관리하기 편하기 위해서
df['Cluster'] = cluster_label
print(df.head())
#평균거리를 만들어서 중심으로 이동하는 것 이다.

#cluster 시각화 산점도로 해서 군집화
# 그래프로 시각화 - 클러스터 값 : 0 ~ 4 모두 출력
# 8개의 변수를 하나의 그래프로 표현핛 수 없기 때문에 2개의 변수를 선택하여 -> 한꺼번에 출력하기 힘들어서 2개 씩 산점도로 출력
# 관측값의 분포를 그려보자.
# 모델의 예측값은 매번 실행핛 때마다 달라지므로, 그래프의 형태도 달라짂다.
# 산점도 : x='Grocery', y='Frozen' 식료품점 - 냉동식품
# 산점도 : x='Milk', y='Delicassen' 우유 - 조제식품점
df.plot(kind ='scatter' , x = 'Grocery' , y ='Frozen' , c = 'Cluster' , cmap ='Set1' , colorbar = False, figsize=(10,10))
df.plot(kind ='scatter' , x = 'Milk' , y ='Delicassen' , c = 'Cluster' , cmap ='Set1' , colorbar = True, figsize=(10,10))
plt.show()

# 그래프로 시각화 - 클러스터 값 : 1, 2, 3 확대해서 자세하게 출력
# 다른 값들에 비해 지나치게 큰 값으로 구성된 클러스터(0, 4)를 제외
# 데이터들이 몰려 있는 구갂을 확대해서 자세하게 분석
# 클러스터 값이 1, 2, 3에 속하는 데이터만 변수 ndf에 저장함
mask = (df['Cluster'] == 0) | (df['Cluster'] == 4)
ndf = df[~mask] # ~ 이 반대라는 의미이다.
print(ndf.head())

# 클러스터 값이 1, 2, 3에 속하는 데이터만을 이용해서 분포를 확인
# 산점도 : x='Grocery', y='Frozen' 식료품점 - 냉동식품
# 산점도 : x='Milk', y='Delicassen' 우유 - 조제식품점
ndf.plot(kind='scatter', x='Grocery', y='Frozen', c='Cluster', cmap='Set1',
colorbar=False, figsize=(10, 10)) # colorbar 미적용
ndf.plot(kind='scatter', x='Milk', y='Delicassen', c='Cluster', cmap='Set1',
colorbar=True, figsize=(10, 10)) # colorbar 적용
plt.show()
plt.close()

1.    데이터 준비  -UCI

2.    PANDAS 가지고 데이터 가져오기 -> dataframe

3.    데이터 뽑아오기 df.iloc[:,:]  비지도학습이기때문에 비지도학습

종속변수 필요없다. 모든 변수를 x에 저장한다. 모두 정수형으로 되여있다.

모두 정수형이여서 데이터가 처리 없다.

4.    정규화 -> 일정한 값의 범위 상대적인 값의 범위를 나타낸다.

5.    모델 생성 n_clusters가지고 분류할 수 있다. 중심점이 가까운 것 들이

중심들이 계속 이동하는 것 을

6.    x데이터 를 학습한다. 독립변수에 따라 학습을 해서 정답을 찾는다.

중심점을 5개로 만들고 그중에서 가까운 데이터들은 평균점을 구해서 중심점으로 이동하면서 한다.

실행할 때마다 달라진다.

7.    모델을 실행하면 labels_가 만들어진다. 5개로 clusting해서 0 ~ 4 번 까지

8.    7번 변수를 받아서 컬럼을 추가한다.

9.    같은 그룹으로 묶어준다.

10.  8개의 컬럼을 시각화한다.

11.  시각화 할때 0 ~ 4 번 까지 군집화해서 나타난다.

반응형

'Study > 머신러닝' 카테고리의 다른 글

머신러닝-7  (0) 2020.11.20
머신러닝-6  (0) 2020.11.19
머신러닝-4  (0) 2020.11.17
머신러닝-3  (0) 2020.11.16
머신러닝-2  (0) 2020.11.14
반응형

**일반적인 python이나 anaconda를 이용해서 설치한 파이썬 -C로 만들어진 PYTHON

=>C언어로만든 라이브러리를 파이썬에서 사용할 수 있음

=>C언어는 소스코드를 가지고 실행 파일을 만들어서 배포

실행 파일을 만들 때 운영체제의 start up코드가 포함되어야 합니다.

실행되는 프로그램이 운영체제마다 다릅니다.

=>windows에서 실행되는 c언어는 ms-c이고 이 언어로 프로그램을 만드느 대표적인 idevisual c++ 이고 이 visual c++로 만들어진 프고르램을 실행시키기 위해서 재배포 패키지나 build tool이 설치되어 있어야 합니다.

 

**windows애서 python t실행시 라이브러리가 설치되지 않는데

visual c++ 14.0이 설치되어 있어야 하는데 설치되어 잇지 않다는 에러 메시지가 출력되는 경우

-visual studio 2015 재배포 패키지 설치 : 설치해도 잘 안됨

-visual studio 2015 build tools 설치 : 설치해도 잘 안됨

-visual studio 최신 버전 설치 : visual studio community버전 다운로드

 

 

ar . vr 게임 등 관심있으면 unity

mmo rpg ->언니얼

microsoft vr tool -> 테이블 그래는 것 자동으로 하는 것

 

 

 

데이터 적을 때 는 오차 , 정밀도 , 재현울 , F1점수 roc 곡선 등

 

 

 

** 불균형한(개수가 다른 경우) 클래스의 데이터를 가지고 분석을 해야 하는 경우

=>샘플 자체의 개수가 작을 떄는 자료를 더 수집하는 것이 가장 좋은 방법

=>데이터 를 수집하는 것이 가능하지 않을 때는 데이터에 가중치를 적용해서 사용- 분류 알고리즘의 매개변수 중에서 weight가 있으면 이 매개변수가 데이터에 가중치를 적용할 수 있는 매개변수 입니다.

=>개수가 작은 데이터의 개수를 강제로 늘리거나 개수가 많은 데이터의 개수를 줄이는 업샘플링이나 다운 샘플링을 해서 알고리즘에 적용

=>평가지표를 다양하게 선택 - 정확도 대신에 재현율이나 F1 통계량 등을 이용

정확도 , 재현율 등 .. 어느 하나 선택할 때는 결과가 외곡 될 수 있다.

정확도 , 재현율 ,F1통계량 결정 계수 등  정확하게 뭘 의미하는 지 알아야 한다.

분석은 어렵지 않다.그 결과를 판정하는 데 어렵고 뭐하는지 알아야 한다.

 

 

import numpy as np

import pandas as pd

 

#0 10개이고 1 90개 인 ndarray생성

list1 =[]

for i in range(0,10,1):

    list1.append(0)

 

list2 =[]

for i in range(0,90,1):

    list2.append(1)

   

#2개의 list를 가지고 하나이 array생성

target = np.array(list1+ list2)

#list더하기 하면 결합이고

#분석은 더하기 하면 더하기 이다.

print(target)

 

#분류 알고리즘에 위의 데이터를 이용하는 경우

#0: 10% 1 : 90%

from sklearn.ensemble import RandomForestClassifier

#데이터의 비율이 헌저하게 다르기 때문에 가중치 설정

weights = {0:0.9, 1:0.1}

#비율은 반대로 쓴다. 10%, 90%

#0.9 = .9

rfc = RandomForestClassifier(class_weight = weights)

print(rfc)

 

#assemble하고 down는 같이 하면 안된다.

 

#가중치를 직접 설정하지 않고 분류기에게 판단하도록 해주는 옵션

rfc = RandomForestClassifier(class_weight='balanced')

print(rfc)

 

#샘플링 비율 조건

#np.where(target == 0)

#target행렬에서 값이 0인 데이터의 행번호를 리턴

#(행번호행렬, 자료형)으로 결과를 리턴

#행번호행렬만 가져오기 위해서 [0]을 추가

class0 = np.where(target == 0)[0]

class1 = np.where(target == 1)[0]

print(len(class0))

print(len(class1))

 

#target 1인 데이터에서 target 0인 데이터만큼 다운 샘플링을 해서

#새로운 데이터 셋을 생성

#class1에서 class0의 데이터 개수 만큼 비복원 추출 (나온것은 제거)

#assembling랄 때는 복원 추축

downsample = np.random.choice(class1, size = len(class0) , replace= False)

result = np.hstack((target[class0], target[downsample]))

#0개에서는 90개 만들 수 없다.

#downsample = np.random.choice(class0, size = len(class1) , replace= True)

#result = np.hstack((target[class1], target[downsample]))

print(result)

 

** 다변량 분석에서 데이터의 상대적 크기 문제

=>다변량 분석 - 2개이상의 컬럼의 데이터를 가지고 분석

=>하나의 컬럼의 데이터는 값의 범위가 0-100이고 다른 컬럼의 데이터는 값이 범이가 0-1이라면 이 경우 2개의 데이터를 가지고 다변량 분석을 하게 되면 첫번째 컬럼의 영향을 받게 될 수 있습니다.

이런 경우에는 값의 범위를 일치시켜 주는 것이 좋습니다.

=>값의 범위는 같은데 분포가 다른 경우에도 분포를 기준으로 값을 조정할 필요가 있습니다.

최대값으로 나누거나 최대값 - 최소값을 분모로하고 해당값 - 최소값을 분자로 해서 값을 조정

=>이러한 값의 조정을 scalling이라고 합니다.

0-1 사이나 -1~1사이로 조정합니다.

더 큰 값으로 가능하지만 머신러닝 모델에서는 값으 크기가 커지면 정확도가 떨어집니다.

 

 

1.표준화

=>모든 값들의 표준 값을 정해서 그 값을 기준으로 차이를 구해서 비교하는 방법

1)표준값: (데이터- 평균) /표준편차 -표준 값의 평균은 50 (사람한테 줄 때 )

2)편차값: 표준값 * 10 + 50 -위의 숫자보다 큰  숫자로 변환

 

#표준화

#student.csv파일의 내용을 가져오기

#index로 이름을 설정

import os

print(os.getcwd())

#utf8이 아니다.

data = pd.read_csv('./Desktop/data/student.csv', index_col ='이름',encoding = 'cp949')

print(data)

 

#그래프에 한글을 출력하기 위한 설정

import matplotlib.pyplot as plt

import platform

from matplotlib import font_manager, rc

#매킨토시의 경우

if platform.system() == 'Darwin':

    rc('font', family='AppleGothic')

#윈도우의 경우

elif platform.system() == 'Windows':

    font_name = font_manager.FontProperties(fname="c:/Windows/Fonts/malgun.ttf").get_name()

    rc('font', family=font_name)

 

#인덱스를 기준으로 해서 막대 그래프 그리기

data.plot(kind='bar')

 

#표준값 - 작업

#평균을 표준 편차로 나누어서 계산

#각과목의 평균과 표준편차 구하기

kormean, korstd = data['국어'].mean(), data['국어'].std()

engmean, engstd = data['영어'].mean(), data['영어'].std()

matmean, matstd = data['수학'].mean(), data['수학'].std()

 

 

#표쥰값 구하기 -(자신의 값 - 평균 )/ 표준편차

#내가 0.0이면 중간

#편차값이 1.0이면 항상 상하위 15%

#2.0 상하위 1.1%

#음수가 있을 수 있다.

data['국어표준값'] = (data['국어']- kormean )/korstd

data['영어표준값'] = (data['영어']- engmean )/engstd

data['수학표준값'] = (data['수학']- matmean )/matstd

print(data[['국어표준값','영어표준값','수학표준값']])

#박지영은 국어는 영어보다 잘 한다.  수학은 못한다.

 

#음수를 잘 안보이기 때문에 우리가 자주사용하는 숫자로 변한다.

 

#표준값은 비교가 가능하기는 하지만 사람이 알아보기 불편

#표준값 * 10 + 50 을 해서 편차값을 만들어서 보고서를 만듬

 

 

data['국어표준값'] = data['국어표준값']* 10 + 50

data['영어표준값'] = data['영어표준값']* 10 + 50

data['수학표준값'] = data['수학표준값']* 10 + 50

print(data[['국어표준값','영어표준값','수학표준값']])

 

 

data[['국어표준값','영어표준값','수학표준값']].plot(kind='bar')

 

 

#최대값으로 나누어서 표준화  - 정규화로 많이 불리운다.

#자신의 값 - 최소값/ 최대값 - 최소값으로 하기도 함

#0.0 ~ 1.0 사이로 있다.

data['국어정규화1']  = data['국어'] / data['국어'].max()

data['국어정규화2']  =( data['국어']- data['국어'].min()) / (data['국어'].max()-data['국어'].min())

 

 

 

2.sklearn의 정규화

1)StandartScaler: 평균이 0이고 표준편차가 1이 되도록 변환

(백터- 평균) / 표준편차

주로 주성분분석에서 많이 이용

음수가 잇을 가능성 있다.

 

2)MinMaxScaler:  최대값이 1 최소값이 0 이 되도록 변환

(백터 - 최소값) /(최대값 - 최소값)

신경망에서 주로 이용 (cnn, rnn)

 

 

 

3)RobustScaler: 중앙값이 0 IQR(4분위수 )를 이용하는 방식

(백터 - 중간값) /( 75%- 255)

=>앞의 방식들은 outlier(이상치)에 영향을 많이 받습니다.

=>데이터의 분포가 불균형이거나 극단치가 존재하는 경우에 주로 이용

 

 

 

0 1 2 3 4 5 6 100->이상치가 있을 수 있다. 1),2) OUTLIER

그래서 75%의 값 25%의 값

그래서 최대값 최소값 영향을 받지않는다.

 

 

4)QuantileTransformer:데어터를 1000개의 분위로 나눈 후 0-1 사이에 고르게 분포시키는 방식

=>outlier 의 영향을 적게 받기 위해서 사용

 

 

0 ~ 100 사이의 데이터인데

17 27 25 16 41 33 27 -> 이렇게 된것은 표준화 하면 안좋다. 데이터의 분포가 작아서

표준화 하면 꼭 고려해야 할 두가지 데이터 분포 , outlier

아주 큰 값 있으면 하나 버리기

데이터 분포가 완전히 쏠려져 있을 경우에는 정규화를 하지 않는다.

 

변화 하면 fit_transform

모델에 적용하면 fit 이다.

표준화는 값만 가지고 해야 한다.

 

 

 

#표준화 작업

#sklearn을 이용한 scailing

from sklearn import preprocessing

 

#StandardScaler

#StandardScaler - 평균은 0 표준편차는 1이 되도록 표준화

scaler = preprocessing.StandardScaler()

#국어 점수만 이용하는 경우 data['국어'] 가 아닌고 data[['국어']]

#머신러닝의 데이터들은 행렬을 이용하는데 data['국어']하게 되면 컬럼이름이

#1개라서 하나의 열로 리턴되서 1차원 데이터가 됨

#data[['국어']] 하게 되면 list를 대입하기 때문에 datafrmae으로 리턴

result = scaler.fit_transform(data[['국어']].values)

print(result) #표준값 구한 것

print(np.mean(result)) #평균이 0에 가까워진다. 1.2335811384723961e-17 ->거의 0이다 e 17

print(np.std(result)) # 값이 1에 가까워진다.

 

 

 

#MinMaxScaler

#MinMaxScaler - 음수가 안나온다. 최대값 최소값 이용해서 하기 때문에

scaler = preprocessing.MinMaxScaler()

result = scaler.fit_transform(data[['국어']].values)

print(result)

print(np.mean(result))

print(np.std(result))

 

 

#RobustScaler

#RobustScaler - 음수가 나온다.  이상치 값이 있을 때 해결하기 위한 것

scaler = preprocessing.RobustScaler()

result = scaler.fit_transform(data[['국어']].values)

print(result)

print(np.mean(result))

print(np.std(result))

 

 

#QuantileTransformer

#QuantileTransformer - 음수가 나오지 않는다. 데어터 분포를 고려해야 한다. 데이터가 적으면 안된다.

scaler = preprocessing.QuantileTransformer()

result = scaler.fit_transform(data[['국어']].values)

print(result)

print(np.mean(result))

print(np.std(result))

 

 

**정규화

=>값의 범위를 0 -1 사이의 데이터로 변환

=>표쥰화는 일정한 범위 내로 데이터를 변환하는 것이고 정규화는 0-1 사이로 해야 합니다.

=>Normalizer클래스를 이용해서 transform메소드에 데이터를 대입하면 됩니다.

이 때 norm매개변수에 옵션을 설정할 수 있는데 l1, l2, max등의 값을 설정할 수 있습니다.

max는 최대값으로 나누는 방식

l1l2는 거리 계산 방식

l1-  맨하턴 거리를 이용하고 l2는 유클리드 거리를 이용

맨하탄 거리  -> 장애물이 있을 경우에는 직접 못간다.'

이 두개 크기 자체는 별로 차이 안나는데 계산 방식이 다르다.

게임 shoting게임 할 때 사용한다.

A B 거리 계산 할때 거리 계산한다. 거리가 멀면 시간이 오래 걸린다.

ping할 때  ttl ->라우터의 계수

 

 

 

 

#이차원 행렬을 생성

matrix = data[['국어','영어']].values

print(matrix)

 

 

matrix = np.array([[30,20],[10,30],[30,40]])

print(matrix)

 

from sklearn import preprocessing

 

#l1-  맨하턴 거리를 이용하고 l2는 유클리드 거리를 이용

#정규화 객체 생성 - 유클리디안 거리를 사용

norm = preprocessing.Normalizer(norm = 'l2')

print(norm.transform(matrix))

# 30 /  302+ 402승 에 root => 30 / 50

 

#합을 가지고 나누느 방식

norm = preprocessing.Normalizer(norm = 'l1')

print(norm.transform(matrix))

# 30 / 50  20/50

 

#큰값을 가지고 나누는 방식

norm = preprocessing.Normalizer(norm = 'max')

print(norm.transform(matrix))

#30/40  40/40

 

 

** 다항과 교차항 특성

=>기존 데이터에 데이터들을 곱하고 제곱을 해서 데이터를 추가하는 것

=>특성과 타겟 사이에 비선형 관계과 존재할 때 사용하는 방식

=>비선형 관계는 2개의 관계가 직선의 형태가 아니고 곡선의 형태인것

=>각 특성이 다른 특성에 영향을 줄 때 각 특성을 곱할 교차형을 가지고 인코딩

=>다변량 분석(2개 이상의 컬럼을 가지고 분석) 을 할 때 2개의 컬럼 사이에 상관관계가 있는 경우가 있는데 이런 경우 2개의 컬럼 모두를 가지고 분석을 하게 되면 다중공선성 문제가 발생할 수 있습니다.

어떤 컬럼의 값을 알면 다른 컬럼의 값을 예측할 수 있는 경우 발생할 수 있는 문제입니다.

이런 경우에는 2개의 컬럼을 1개의 컬럼으로 변환하는 작업을 해야 하는데 (차원축소) 이런 경우 더하거나 거나 제곱해서 새로운 값을 만들어냅니다ㅣ.

 

 

 

=>PolynomialFeatures 클래스를 이용하는데 몇 차 항 까지 생성할 것인지 degree에 설정

첫번 떄 데이터로 1을 추가할 지 여부를 include_bias에 설정

=>연산식의 순서는 get_features_names메소드를 이용해서 확인 가능

 

[ 1 , 2 ]            degree  = 2 제곱 까지 만 한다.

[1 , 2 , 1의 제곱 1, 1 * 2 = 2, 2의 제곱 = 4 ]

2를 적용하면 5개 데이터를 만든다.

[4,7]

[4, 7, 16, 28, 49 ]

 

degree = 3

[4, 7, 16, 28, 49 , 64, .......]

[[  4.   7.  16.  28.  49.  64. 112. 196. 343.]]

차원 축소 할 때 데이터를 만들어 낸다.

42* 7 ,

28 * 6  * 7 = 196

 

 

 

 

 

matrix = np.array([[30,20],[10,30],[30,40]])

print(matrix)

 

#다항과 교차항을 만들어주는 객체를 생성

#include_bias = False 첫번 때 0을 안 집어 여겠다.

# degree = 2: 제곱한 것 까지 생성

polynomial  = preprocessing.PolynomialFeatures(degree = 2, include_bias = False)

result = polynomial.fit_transform(matrix)

print(result )

 

matrix = np.array([[4,7]])

print(matrix)

 

polynomial  = preprocessing.PolynomialFeatures(degree = 3, include_bias = False)

result = polynomial.fit_transform(matrix)

print(result )

 

**표준화나 정규화는 직접 하는 경우가 많지만 다항식을 만드는 것은 머신러닝 알고리즘에서 자체적으로 처리하는 경우가 많음

 

**특성 변환

=>데이터에 동일한 함수를 적용해서 다른 데이터로 직접 변환하는 것

=>pandas에서는 apply메소드를 이용하고 sklean에서는 preprocessing.FunctionTransformerColumnTransformer클래스를 이용ㅇ

=>FunctionTransformer는 모든 열에 동일한 함수를 적용하고  ColumnTransformer는 서로 다른 함수를 적용할 수 있습니다.

객체를 생성할 때 적용할 함수를 설정해서 만들고 transform 메소드에 데이터를 대입하면 됩니다.

 

import numpy as np

from sklearn import preprocessing

#함수 적용하기

matrix = np.array([[100,200],[300,150]])

print(matrix)

#위 데이터를 정수로 변환하기

#100을 결합하기

def intconvert(x):

    return x + 100

#행렬을 변환해서 리턴해준다.

transformer = preprocessing.FunctionTransformer(intconvert)

result = transformer.fit_transform(matrix)

print(result)

print(data['국어'])

print(data['국어'].apply(intconvert))

 

 

**Outlier 감지

=>Outlier 이상치나 극단치 , 일반적인 데이터의 범위를 넘어선 값

1.z점수를 이용하는 방법 : 중앙값을 기준으로 표준편차가 3 또는 -3 범위의 바깥똑에 있는 데이터를 Outlier 로 간주

2.z점수의 보정 :z 점수는 데이터가 12개 이하이면 감지를 못함

넘 작으면 표준편차가 잡지 못하기 때문에

편차의 범위를 3.5로 늘리고 0.6745를 곱한 값을 이용

3.IOR(3사분위수 - 1사 분위수)이용: 1사분위수 (25%)보다 1.5 IQR 작은 값이나 3사분위수(75%) 보다 1.5IQR 큰 데이터를 outlier 로 간주

 

 

1,2,3 10004

10010/4

 

1,2,3 10004 , 10004 => 이 경우에는 outlier가 알될수 도 있다. 많이 적으면 outlier가 나올 수 있다.

 

 

import numpy as np

import pandas as pd

 

 

#array를 입력받아서 z 점수(표준편차의 3) 밖에 있는 데이터를 리턴해주는 함수

def z_score_outlier(ar):

    threshold  = 3

    #평균 가져오기

    meandata = np.mean(ar)

    stdevdata = np.std(ar)

    #stdevdata for y in ar의 요소를 y에 하나씩 대입하고 앞에 수식을 적용해서 결과를 가지고

    #다시 list를 만드는 것

    z_scores  = [(y-meandata) / stdevdata for y in ar]

    return np.where(np.abs(z_scores) > threshold)

 

#샘플 데이터 생성

#features = np.array([[10,30,13,-20,4,12],[20000,3,5,4,2,1]])

#features = np.array([[10,30,1003,-20,4,12],[2,30,5,4,2,1]])

    #(array([0], dtype=int64), array([2], dtype=int64)) 0 2

#features = np.array([[10,30,13,-20,4,12],[2,9,5,4,2,10]])#없다.

features = np.array([[10,30,13,-2000000,4, 12, 10,30, 13, 11, 4, 12,10,30,13,20,4,2,4,2],

                     [2,9,5,4,2,2000000,10,30,13,20,4,12,10,30,13,20,4,2,4,2]])

#(array([0, 1], dtype=int64), array([3, 5], dtype=int64))

    #0번에 3 1번에 5

 

result = z_score_outlier(features)

print(result)

 

 

#z score 보정  -범위를 3.5배로 널리고 표준편차 0.6875를 곱해줍니다.

def modify_z_score_outlier(ar):

    threshold  = 3.5

    #평균 가져오기

    meandata = np.mean(ar)

    stdevdata = np.std(ar)

    #stdevdata for y in ar의 요소를 y에 하나씩 대입하고 앞에 수식을 적용해서 결과를 가지고

    #다시 list를 만드는 것

    z_scores  = [0.6875 * (y-meandata) / stdevdata for y in ar]

    return np.where(np.abs(z_scores) > threshold)

 

#샘플 데이터 생성

features = np.array([[10,30,13,-20,4, 12, 10,30, 13, 11, 4, 12,10,30,13,20,4,2,4,2],

                     [2,9,5,4,2,2000000,10,30,13,20,4,12,10,30,13,20,4,2,4,2]])

#(array([0, 1], dtype=int64), array([3, 5], dtype=int64))

 

result = modify_z_score_outlier(features)

print(result)

 

 

#iqr이용 : 3 사분위수 - 1사분위의 +- 1.5 배이상 차이나면 이상치로 간주

def iqr_outlier(ar):

    #25% 75%의 값 찾기

    q1 ,q3 = np.percentile(ar,[25,75])

    #iqr값 찾기

    iqr = q3- q1

    #25% 값과 .5 iqr보다 작은 값 찾기

    lower = q1- iqr*1.5

    upper = q3 + iqr* 1.5

    return np.where( (ar > upper )| (ar < lower))

 

#샘플 데이터 생성

features = np.array([[10,30,13,-20,4, 12, 10,30, 13, 11, 4, 12,10,30,13,20,4,2,4,2],

                     [2,9,5,4,2,2000000,10,30,13,20,4,12,10,30,13,20,4,2,4,2]])

 

 

result = iqr_outlier(features)

print(result)

 

 

**Outlier처리

1.제거

=>설문조사를 했는데 이상한 데이터가 입력된 것 같은 경우

=>분석 목적에 맞지 않는 데이터인 경우

 

 

2.이상한 데이터로 표현해두고 특성의 하나로 간주

이상한 상황을 없에면 안되고 특수한 상황으로 해야 한다.

 

3. outlier의 영향이 줄어돌도록 특성을 변환 - 값의 범위를 줄임(표준화, 정규화 등)

=> 표준화 할 때는 RobustScalar를 이용하는 것이 좋음

 

 

house = pd.DataFrame()

house['price'] = [100000,200000,150000,10000000]

house['rooms'] = [1,3,2,100]

house['square'] = [11,23, 16, 1200]

print(house)

 

 

#이상한 데이터 제거 : 방이 5개 이상 제거

print(house[house['rooms'] < 6])

#이상한 데이터를 별도로 표시

house['outlier'] = np.where(house['rooms'] < 6 , 0,1)

print(house)

 

 

#값의 범위 줄이기 -np.log는 자연 로그를 계산

house['log'] = [np.log(x) for x in house['rooms']]

print(house)

 

** 시계열 데이터

=>날짜 및 시간에 관련된 데이터

1.pandas의 시계열 자료형

=>datatime64 : 부등호를 이용해서 크기비교를 할 수 있고 - 를 이용해서 뺄셈을 할 수 있음

=>Period:두개의 날 짜 사이의 간격을 나타내기 위한 자료형

=>시계열 자료형을 별도로 구성하는 이유는 일정한 패턴을 만들기 쉽도록 하기 위해서

 

 

 

2. 생성

=>문자열 데이터를 시계열로 변경 : pandas.to_datetime()이용

날짜 형식의 문자열과 format매개변수에 날짜 형식을 대입

 

 

#문자 데이터를 pandas의 시계열 데이터로 만들기

df = pd.read_csv('./Desktop/data/stock-data.csv')

print(df)

#자료형 확인

print(df.info())

#Date 컬럼의 값을 시계열로 변경해서 추가

df['newDate'] = pd.to_datetime(df['Date'])

print(df.info())

 

 

#위와 같은 데이터프레임에서는

#날짜를 index로 설정하는 경우가 많습니다.

df.set_index('newDate',inplace = True)

df.drop('Date',axis = 1 , inplace = True)

print(df.head())

 

 

 

 

 

3.Period 간격을 나타낸다.

=>pandas.to_period 함수를 이용해서 datatimeperiod로 생성

freq 옵션에 기준이 되는 기간을 설정

=>freq옵션

 

D: 1

W: 1

M 1개월 (월말 기준)

MS: 1개월 (월초 기준)

Q: 분기말

QS :  분기초

A:연말

AS:

B: 휴일제외

H,T,S,L,U,N: 시간 , , , 밀리초 , 마이코로초 , 나노초

 

 

#일정한 간격을 갖는 날짜 만들기

dates = ['2017-03-01','2017-06-01','2019-12-01']

print(dates)

#날짜로 변경

pddates = pd.to_datetime(dates)

print(pddates)# DatetimeIndex로 바꿔졌다.

 

 

#Period로 변환

pdperiod  = pddates.to_period(freq = 'D')

print(pdperiod)

#PeriodIndex(['2017-03-01', '2017-06-01', '2019-12-01'], dtype='period[D]', freq='D')

 

pdperiod  = pddates.to_period(freq = 'M')

print(pdperiod)

#PeriodIndex(['2017-03', '2017-06', '2019-12'], dtype='period[M]', freq='M')

 

pdperiod  = pddates.to_period(freq = 'Q')

print(pdperiod)

 

pdperiod  = pddates.to_period(freq = 'A')

print(pdperiod)

 

 

 

5.date_range()

=>일정한 간격을 소유한 날짜 데이터의 집합을 생성

=>매개변수

start: 시작 날짜

end: 종료 날짜

periods: 생성할 날짜 개수

freq: 간격

tx: 시간대

 

 

 

#일정한 간격을 가진 날짜 데이터 생성

ts_ms = pd.date_range(start = '2018-01-01',end = None, periods = 12, freq = 'M')

print(ts_ms)

 

ts_ms = pd.date_range(start = '2018-01-01',end = None, periods = 12, freq = 'D')

print(ts_ms)

 

#2H ->2시간씩

ts_ms = pd.date_range(start = '2018-01-01',end = None, periods = 12, freq = '2H')

print(ts_ms)

 

 

6.날짜 데이터에서 필요한 부분 추출하기

=>dt.year, dt.month, dt.day...

=>요일은  dt.weekday_name은 문자열로 dt.weekday하면 숫자로 리턴 (월요일이 0)

화면에 출력할 때는 문자열로 하고 머신러닝을 사용할 때는 숫자로 리턴 받습니다.

ts_year = df['newDate'].dt.year

print(ts_year)

 

df['year'] = df['newDate'].dt.year

print(df['year'])

 

 

7.python에서는 날짜는 datetime패키지의 datetime으로 제공

=>날짜 형식의 문자열을 가지고 날짜 형식의 데이터를 생성

 

 

8.shift함수를 이용하면 기존 날짜를 이동시키는 것이 가능

=>freq 매개변수에 간격을 설정할 수 있습니다.

 

 

#python의날짜 패키지

from datetime import datetime

dates = [datetime(2017,1,1),datetime(2017,1,4),datetime(2017,1,7)]

ts = pd.Series(np.random.randn(3) , index = dates)

print(ts)

print(ts.shift()) #데이터를 하나씩 민다. 아래쪽으로

print(ts.shift(1)) #데이터를 하나씩 민다. 아래쪽으로

print(ts.shift(-1)) #데이터를 하나씩 반대로 민다. 위로

 

 

9.resampling

=>시계열의 빈도를 변환하는 것

=>상위 빈도의 데이터를 하위 빈도의 데이터로 변환하는 것을 다운 샘플링이라고 하고 반대의 과정을 asampling이라고 한다.

=>resampling(freq, how, fill, method, closed, label , king)

freq: 리샘플링 빈도(M,Q, A)

how: 집계함수를 지정하는 것으로 기본은 mean(평균을 구한다.) first, last, max, median ,min

데이터가 있으면  합계등 골라내다.

fill_method: 업 샘플링할 때 데이터를 채우늠 옵션이므로 기본은 None인데 fill이나 bfill을 설정해서 이전값이나 이후값으로 채울 수 있음

closed: 다운 샘플링을 할 때 왼쪽과 오른쪽 어느쪽을 호팜시킬지 설정

label: 다운 샘플링을 할 때 레이블을 왼쪽 또는 오른쪽을 사용할 것인지 여부

 

 

 

#일정한 조건으로 집계

ran = pd.date_range('11/3/2010',periods = 20, freq ='T')

print(ran)

 

ts = pd.Series(np.arange(20),index = ran)

print(ts)

#5개씩 하면 5분단위로 할 수 있다.

#실데이터는 다르다. 10분마다

#label 0분이나 4분이나 할 것이다

 

#5분 단위로 합게

print(ts.resample('5T').sum())

 

print(ts.resample('5T').mean())

 

 

10.날짜 데이터가 데이터프레임에 존재하는 경우 날짜 데이터를 인덱스로 설정하면 특정 시간단위로 집계를 하는 것이 쉬워집니다.

 

**이동시간 윈도우

=>통계적 수치를 계산을 할 때 최근의 데이터에 가중치를 부여해야 한다라는 개념

평균을 구할 때 데이터 전체의 평균을 구하는 것 보다는 최근의 데이터 몇 개의 평균을 구하는 것이 미래를 예축할 때는 더 잘 맞을 가능성이 높다.

이전 데이터와 최근의 데이터를 같이 사용할 거라면 최근의 데이터에 가중치를 부여하는 것이 미래를 예측할 때는 더 잘 맞을 가능성이 높다.

 

 

1.rolling 함수

=>단순 이동 평균을 계산해주는 함수

=>winodw 매개변수에 데이터 개수를 설정하면 데이터 개수 단위로 연산을 수행

 

 

2.ewm함수

=>지수 이동 평균을 계산해주는 함수

=>지수 이동 평균은 최근의 데이터에 가중치를 부여하는 방식의 평균

주식 데이터는 이 평균을 사용합니다.

=>기간(span)을 설정하면 아래 수식으로 평균

데이터가 3개인 경우

x1, x2, x3(가장 최근 데이터)

1-span을 알파라고 합니다.

 

x3+(1-(1-span)) x2 +(1-(1-span) )제곱 x3  / 1 + (1-알파) +(1-알파)제곱

숫자를 줄인다.

 

 

500 2000 2300 2700

3

2000 +2500+2700 / 3

반영율을 조정한다.

 2500 + (1-1/3) * 2000 + (1-1/3)2 의 제곱 * 2000

 

지수 이용 평균

어느 속도를 기준해서 낮아진다. 불량율 , 숙련도 주식등에서 많이 사용한다.

 

시간에 따라 변경되는

데이터를 가지고 계속 할 때는 최근의 데이터

가중치를 부여해야 한다.

에이징 커브 -전년도 데이터를 해서 하는 것

최근에 얼마 사용했는지에 따라 가중치를 준다.

휴대폰이 2100시간 최근에는 2시간

 

 

python문법 ->데이터 가공 numpy pandas ->

sklearn

회귀 군집 알고리즘 등

반응형

'Study > 데이터 분석' 카테고리의 다른 글

데이터분석-8  (0) 2020.11.14
데이터분석-8  (0) 2020.11.12
데이터분석-6  (0) 2020.11.10
데이터분석-5  (0) 2020.11.09
데이터분석-4  (0) 2020.11.08

+ Recent posts