without haste but without rest
01. Data Exploration & Visualization 본문
0. 개요
1. 분석 전에 데이터를 살펴보는 방법
- 박스 플롯 & 바이올린 플롯
- 페어 플롯
- lm 플롯
2. 차원축소 (피쳐 엔지니어링)
- PCA
- LDA
1. 데이터 불러오기
(1) 데이터 로드
import pandas as pd
df = pd.read_csv("./data/iris.csv")
# sanity check with Pandas
print("shape of data in (rows, columns) is " + str(df.shape))
print(df.head())
df.describe().transpose()
df.describe() 는 데이터 프레임에 대한 기술을 하라는 메소드
transpose()는 전치 함수
(2) 속성 확인(attributes check)
print(df.columns)
print(df.index) # numeric data
print(df.dtypes) # object (범주형)
print(df.values)
print(type(df.values))
(3) 인덱싱, 슬라이싱
# indexing and slicing(selecting) data
print(df['species'])
print(df[0:50:1]) # 1은 단위 만약 2로 값을 주면 짝수번째만 출력
print(df.iloc[:, :4].head())
print(df.iloc[:, :4].shape)
(4) 기타 메소드
# methods
df.mean()
df.std()
뉴메릭 데이터만 대상이며 범주형 자료는 계산하지 않는다.
# 5 number summary
df.min()
df.max()
df.quantile(0.25)
df.quantile(0.75)
df.quantile([0.0, 0.25, 0.50, 0.75, 1.0]).values // 사분위수
df.hist() // 히스토그램
2. 정규화
정규화 함수 만들기
def normalize(df):
result = df.copy()
for feature_name in df.columns:
if feature_name != 'species':
mean_value = df[feature_name].mean()
std_value = df[feature_name].std()
result[feature_name] = (df[feature_name] - mean_value) / std_value
return result
1. 데이터 셋을 복사한 데이터 프레임을 새로 하나 만든다. / result
2. 컬럼(속성)을 하나씩 가져와서 해당 컬럼들의 평균, 분산을 구하고 정규화 한다
(데이터 - 평균) / 분산
R의 데이터 프레임처럼 판다스도 리스트에 값을 더하거나 빼면 개별적으로 전부 계산함
ndf = normalize(df) # ndf 는 df 를 정규화한 데이터 셋
print(ndf.tail())
3. 시각화
판다스의 plotting 메소드 이용
# plotting
import pandas.plotting
pandas.plotting.boxplot(df)
pandas.plotting.scatter_matrix(df)
Seaborn
씨본은 x, y, data 순으로 파라미터 값을 주는 듯
box plot, violin plot, lm plot, pair plot 정도를 실습 예제로 다뤄본다.
# explore with Seaborn pairplot
import seaborn as sns
# box plot
sns.boxplot(x = 'species', y = 'petal length in cm', data = df)
# violin plot
sns.violinplot(x = 'species', y = 'petal length in cm', data = df)
# plot bivariate scatter with Seaborn
sns.lmplot(x = 'petal length in cm', y = 'petal width in cm',
hue = "species", data = df, fit_reg = False,
palette = 'bright', markers = ['o','x','v'])
# pairplot
sns.pairplot(df, hue = 'species')
# add histograms to diagonals of Seaborn pairplot
sns.pairplot(df, hue = 'species', diag_kind = 'hist',
palette = 'bright', markers = ['o','x','v'])
# box plot
x축에는 품종, y 축에는 petal length 데이터가 위치한다.
박스 플롯에서 세토사는 확연히 구분되나 버지니카와 버지칼라의 데이터들이 4.5~5 정도 사이에서 혼재된 상태이다. 즉 완벽하게 구분할 수 없다.
# violin plot
x축에는 품종, y 축에는 petal length 데이터가 위치한다.
바이올린 플롯도 마찬가지로 버지칼라와 버지니카 두 품종의 데이터가 4~ 5.5 사이에 혼재되어 있어 확실하게 구분하기가 어렵다.
petal length 데이터로 세토사는 구분할 수 있을 것이다.
#lm plot (회귀)
lm plot은 데이터들을 선형에 분포한 것처럼 보여준다. 역시 여기서도 세토사는 쉽게 구분할 수 있으며, 버지칼라와 버지니카는 조금 혼재된 상태다.
그런데 이정도만 되어도 머신 러닝 모델에서는 꽤 정확도가 높을 것 같다.
#pair plot
페어 플롯은 이름처럼 짝을 지어서 각 속성들을 2차원 형태로 시각화한다. 각 피쳐들이 어떤 상관 관계를 가지고 있는지 한 눈에 보기가 좋다.
데이터 셋의 필드에는 petal length, petal width, sepal length, sepal width 로 총 4가지 속성들이 존재한다. pair plot은 이 속성들을 하나씩 짝 지어서 x, y 축에 위치시켰을 때의 모든 좌표를 보여준다.
대부분의 차트에서 세토사는 쉽게 구분할 수 있음을 확인할 수 있는데, 버지칼라와 버지니카의 데이터가 확실하게 구분되는 pair 가 없다.
petal length, petal width 데이터가 그나마 구분이 잘 되어 있는 편이다.
4. PCA & LDA
(1) PCA - Principle Component Analysis
주성분 분석이란?
ㅁㄴㅇㄻㄴㄹㄴㅁㄴㅇㄻㄴㅇㄹㄴㅁㅇㄹ
# reduce dimensions with PCA
from sklearn.decomposition import PCA
pca = PCA(n_components = 2) # n_components = 2 / 처음 2개의 주성분만 유지한다.
out_pca = pca.fit_transform(df[['sepal length in cm',
'sepal width in cm',
'petal length in cm',
'petal width in cm']])
print(out_pca)
df_pca = pd.DataFrame(data = out_pca, columns = ['pca1', 'pca2'])
print(df_pca.head())
df_pca = pd.concat([df_pca, df[['species']]], axis = 1)
print(df_pca.head())
sns.lmplot(x = "pca1", y = "pca2", hue = "species", data = df_pca, fit_reg = False)
sns.lmplot(x = "pca1", y = "pca2", hue = "species", data = df_pca, fit_reg = True)
# hue 는 범례 옵션인가?
*fit_reg 는 회귀 선 추가 옵션이다.
# lmplot
fit_reg 옵션을 주는 경우 아래 그래프처럼 생성할 수 있다. (오류가 있음 추후에 수정 요망-> 아나콘다 최신으로 설치해보기)
세토사는 쉽게 구분할 수 있고 버지칼라와 버지니카는 절편으로 구분할 수 있지 않을까라는 추측을 해볼 수 있다.?
(2) LDA - LinearDiscriminantAnalysis
판별분석 (피셔가 제안한..)이란?
ㅁㄴㅇㄻㄴㅇㄹㄴㅁㅇㄹㄴㅁㅇㄹ
# reduce dimensions with LDA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
lda = LinearDiscriminantAnalysis(n_components = 2)
# format dataframe
out_lda = lda.fit_transform(X = df.iloc[:,:4], y = df['species'])
df_lda = pd.DataFrame(data = out_lda, columns = ['lda1', 'lda2'])
df_lda = pd.concat([df_lda, df[['species']]], axis = 1)
# sanity check
print(df_lda.head())
# plot
sns.lmplot(x = "lda1", y = "lda2", hue = "species", data = df_lda, fit_reg = False)
sns.violinplot(x = 'species', y = 'pca1', data = df_pca).set_title("Violin plot: Feature = PCA_1")
sns.violinplot(x = 'species', y = 'lda1', data = df_lda).set_title("Violin plot: Feature = LDA_1")
# PCA와 LDA 의 성능 비교
LDA는 옆으로 더 분포가 넓은 데에 반해서 PCA는 위로 더 긴것을 확인할 수 있는데 이것이 무얼 의미하는가?
* 이거 용한이형한테 물어보기
#viloiln plot
두 그래프를 비교하면 LDA의 경우가 버지칼라와 버지니카 간의 겹치는 부분이 조금 덜 한 것을 확인할 수 있다. 따라서 LDA(선형판별분석)이 iris 데이터 셋에서 더 괜찮은 모델이라고 생각해볼 수 있다. (추후에 확인해서 확실히 하기)
+2020-05-01
바이올린 플롯을 보면 LDA는 중앙값에 분포가 집중되어 있는 반면에 PCA는 버지칼라와 버지니카의 분포가 중앙값에 집중되어 있지는 않다. 따라서 LDA가 차원축소가 더 잘된 경우라고 생각할 수 있다.
계층적 군집화(hierarchical Clustering)
# hierarchical clustering
sns.clustermap(ndf.iloc[:,:4])
sns.clustermap(ndf.iloc[:,:4])
일반적으로 계층적 군집화는 자료의 규모가 작은 경우에 시각적으로 좋은 정보를 제공한다.
정규화를 진행하지 않은 모델의 계층적 군집화다. sepal widhth, petal length 가 같은 군집으로 묶일 수 있고, 다시 이 두 군집과 petal widht 가 하나의 군집으로, 또 다시 sepal length와 군집으로 묶일 수 있다.
정규화를 진행한 데이터의 경우 색이 변했다. 색이 비슷할 수록 두 군집이 비슷하다는 의미다.
정리
1. 데이터 로드
2. 데이터 정규화
3. 시각화로 데이터의 특징을 탐색 / 차원 축소를 활용할 수도 있음
부족한 점
0. violin plot 의 특징 찾아보기
vilolin plot은 box plot과 유사한데, 각 속성들의 밀도를 더 깊이 파악할 수 있다.
1. PCA란?
파이썬 라이브러리를 활용한 데이터 분석 책에서 예제
2. LDA란?
https://blog.naver.com/pmw9440/221574212339
3. 계층적 군집화란?
https://ratsgo.github.io/machine%20learning/2017/04/18/HC/
'Homework > DataMining' 카테고리의 다른 글
06. Feature Selection (0) | 2020.05.01 |
---|---|
05. One-Hot Encoding (0) | 2020.05.01 |
04. Interpolation / Normalization & Standardization (0) | 2020.04.21 |
03. Visualization with Seabron (0) | 2020.04.14 |
02. Data Load with sqlite3 (0) | 2020.04.07 |