Data Traveler
Tantum videmus quantum scimus

2021-03-31

Author: 98hyun

Published: 2021-03-31

Tags: 데이터분석 통계 시각화

Share :


  정규표현식과 NLP

규칙과 함수가 있다면 빠르게 접근 가능하다.

import re

s='https://98hyun.github.io/ here'
p=re.compile(r'https\S+')
print(p.sub(r'',s))
# _here

# 자주 사용하는 축약어. 거의 escape와 [] 이거 많이 사용한다.


  latex와 python

빼놓을 수 없다. 특히, matplotlib 와 연계로. 참고

code


import numpy as np
import matplotlib.pyplot as plt

# 실행하면 
x=np.linspace(-10,10,100)
y=np.tanh(x)

plt.figure()
plt.plot(x,y)
plt.xlabel('$x$')
plt.ylabel('$\\tanh(x)$')
plt.title('쌍곡탄젠트함수',fontproperties=fontprop)
plt.suptitle(r'정의역 : 모든실수, 치역 : [-1,1]',fontproperties=fontprop,x=0.34,y=0.8)
plt.grid();

code

# 이거는 그냥 jupyter 환경에서 실행하면 latex형태로 표현한다.  
from sympy import *

x,u=symbols('x u')
u=sin(x)

diff(u,x)
# 참고해서 그린 그림.


  파이썬 스킬.

공부하면서 배운 파이썬 스킬.

code


# 블록체인 내용 중. 
# class내에 구현된 hash함수. snip
# 작용하는것은 class안에서도 self.hash(last_block)로 접근 가능하다.  

@staticmethod
def hash(block):
    block_string = json.dumps(block, sort_keys=True).encode()
    return hashlib.sha256(block_string).hexdigest()

# 그 외로 classmethod가 있는데. 참고. https://dojang.io/mod/page/view.php?id=2380 
# cls 인자를 꼭 받는다. 굳이 필요있나 싶다.  

# cls로 class 속성에 접근할 수 있다. 
@classmethod
def print_count(cls):
    print('{0}명 생성되었습니다.'.format(cls.count))

# 다른 문법 
# 출력 : 2 
print(False or 2)

# 간혹 데이터베이스 만질 때나 github에 push 할때 secret key 같은거. 저장할 때 팁. 
# config.py 파일을 하나 만들고 안에 변수로 작성. 
# app.py 같은 flask 안에서. https://mingrammer.com/ways-to-manage-the-configuration-in-python/  
import config

print(config.PASSWORD) # 123456 이런식으로 접근. 

  통계 개념 참고

modality mode는 최빈값 즉, modality는 최빈값이 될수있는 이라고 해석하면 될것같다.

unimodal - 하나 bimodal - 둘 multimodal - 셋 이상.

code


import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns 

f, ax = plt.subplots(nrows=1, ncols=3, figsize=(18, 4))

# Unimodal
sns.distplot(np.random.normal(10, 5, 10000), ax=ax[0], hist=False, color='blue')
ax[0].set_title('Unimodal', fontsize=14)
ax[0].set_yticklabels([])
ax[0].set_xticklabels([])

# Bimodal
sample_bimodal = pd.DataFrame({'feature1' : np.random.normal(10, 5, 10000),
                   'feature2' : np.random.normal(40, 10, 10000),
                   'feature3' : np.random.randint(0, 2, 10000),
                  })

sample_bimodal['combined'] = sample_bimodal.apply(lambda x: x.feature1 if (x.feature3 == 0 ) else x.feature2, axis=1)

sns.distplot(sample_bimodal['combined'].values, ax=ax[1], color='blue', hist=False)

ax2 = ax[1].twinx()  # instantiate a second axes that shares the same x-axis

sns.distplot(sample_bimodal.feature1, ax=ax2, color='blue', kde_kws={'linestyle':'--'}, hist=False)
sns.distplot((sample_bimodal.feature2), ax=ax2, color='blue', kde_kws={'linestyle':'--'}, hist=False)

f.tight_layout()  # otherwise the right y-label is slightly clipped

ax[1].set_title('Bimodal', fontsize=14)
ax[1].set_yticklabels([])
ax[1].set_xticklabels([])
ax2.set_yticklabels([])


# Multimodal
sample_multi = pd.DataFrame({'feature1' : np.random.normal(10, 5, 10000),
                   'feature2' : np.random.normal(40, 10, 10000),
                   'feature3' : np.random.randint(0, 3, 10000),
                               'feature4' : np.random.normal(80, 4, 10000),
                  })

sample_multi['combined'] = sample_multi.apply(lambda x: x.feature1 if (x.feature3 == 0 ) else (x.feature2 if x.feature3 == 1 else x.feature4), axis=1 )

sns.distplot(sample_multi['combined'].values, ax=ax[2], color='blue', hist=False)

ax3 = ax[2].twinx()  # instantiate a second axes that shares the same x-axis

sns.distplot(sample_multi.feature1, ax=ax3, color='blue', kde_kws={'linestyle':'--'}, hist=False)
sns.distplot((sample_multi.feature2), ax=ax3, color='blue', kde_kws={'linestyle':'--'}, hist=False)
sns.distplot((sample_multi.feature4), ax=ax3, color='blue', kde_kws={'linestyle':'--'}, hist=False)

f.tight_layout()  # otherwise the right y-label is slightly clipped

ax[2].set_title('Multimodal', fontsize=14)
ax[2].set_yticklabels([])
ax[2].set_xticklabels([])
ax3.set_yticklabels([])

plt.show()

normality test. 오른쪽이 qqplot. 빨간선에 분포할수록 정규성을 띈다.

왼쪽은 단순 분포 확인. 가우시안 분포를 그릴때 정규성을 띈다.

code

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import kstest

# 정규분포 
temp1=np.random.normal(5,0.01,size=1000)

fig,ax=plt.subplots(1,2,figsize=(10,4),dpi=200)

sns.kdeplot(temp1,ax=ax[0]);
res=probplot(temp1,plot=ax[1])
kstest(temp1,'norm')

# 비정규 분포 - 어떤파일을 임의로 한것. 
scaler=StandardScaler()

temp1=temp['평당가격'].values

fig,ax=plt.subplots(1,2,figsize=(10,4),dpi=200)

sns.kdeplot(temp1,ax=ax[0]);
res=probplot(temp1,plot=ax[1])
temp1=scaler.fit_transform(temp1.reshape(-1,1))
kstest(temp1,'norm')

표본수가 2000개 이하면 shapiro test를 사용한다. 반대라면 Kolmogorov를 사용한다.

H0 : 귀무가설. 귀무가설이 틀릴확률을 유의수준 0.05라고 정했을 때, p-value(이상값)를 구했는데 이상값 나올 확률보다 귀무가설이 틀릴확률이 높으면 귀무가설을 기각한다. 보통 기존을 유지하는것을 귀무가설. 변화를 지켜보는 쪽을 대립가설(H1)을 한다.

그래서 분석에 필요한 여러 분석을 거친뒤에 모델을 정하는데 가장 간단한 선형회귀도 4가지 가정이 있다.

(1) 선형성 : 독립변수와 종속변수의 scatter plot을 그려 선형성을 파악.
(2) 독립성 : 독립변수들간에 상관관계가 없는지. 다중회귀에서 쓰인다.
(3) 등분산성 : 종속변수의 분산이 같은지. 주체는 잔차. 만약 골고루 퍼져있지않다면 연결하기 위한 매개변수가 필요하다.
(4) 정규성 : 정규분포를 띄는지.

그래서 보통 선형회귀가 맞는데 찾기가 어렵다. 그래서 비모수 통계 모델을 많이 사용한다.

k-최근접 알고리즘, randomforest, 의사결정트리 같은 모델들이 있다.

약간, semi-모수 통계 모델이라고 하는 Support Vector Machine, 인공신경망이 있다.

변수의 확률 분포를 신경쓰는지 여부에 따라 구분했다. 참고

나중에 인공지능 파트에서도 layer normalization과 batch normalization 같은 정규화 기법을 볼 수 있는데, tabular 에서도 볼 수 있다.

code


# normalization
# 기본 parameter로 되서 다른건 안만지면 된다.
# 참고사이트 https://www.kaggle.com/raphael2711/customer-segmentation-with-gmm-clustering
from sklearn.preprocessing import StandardScaler,normalize

scaler=StandardScaler()

X_std=scaler.fit_transform(X) # 표준화 -> 각 열에 대해서 독립
X=normalize(X_std) # 정규화 -> 각 행에 대해서 독립

피처 공학은 모델 잘 설명할 수 있는 features를 만드는게 목적이다.
그 중 범주형 변수들을 다루는 좋은 라이브러리가 있다. categorical 변수 다루기 참고

code


from category_encoders import LeaveOneOutEncoder

loo = LeaveOneOutEncoder()
# train 데이터의 categorical columns들과 일대일 대응인 target들을 맞춰줍니다. 
# leave one out encoder은 현재 target을 제외한 타겟들의 평균을 계산하여 feature를 만듭니다. 
loo.fit(train_df[cat_cols], train_df['target'])  
train_df[new_feature] = loo.transform(train_df[cat_cols])

  시각화

이런식으로 알고리즘임을 알리고, 알기 쉽게 입력변수와 출력 변수, 과정을 알기 쉽게 한다.

Algorithm array_sum
input : array
output : sum of array elements

sum <- 0
for all elements in array do
    sum <- sum + each element

return sum

kaggle에는 세계의 많은 분들이 저마다의 재밌고 유용한 스킬들을 보여준다.
참고 했던 사이트다. 참고

팁들을 적어보면

code


# Order for plotting categorical vars

ab_order = ['10 ~ 20', '20 ~ 30', '30 ~ 40','40 ~ 50','50 ~ 60' ,'60 ~ 70', '70 ~ 80']

data = df['age_band'].value_counts()[ab_order]

# Plot

color_map = ['#d4dddd' for _ in range(9)]
color_map[2] = color_map[1] = '#244747' # color highlight

fig, ax = plt.subplots(1,1, figsize=(9, 6))
ax.bar(data.index, data, width=0.5, 
       edgecolor='darkgray',
       linewidth=0.6,color=color_map)


# annotations
for i in data.index:
    ax.annotate(f"{data[i]}", 
                   xy=(i, data[i] + 3), #i like to change this to roughly 5% of the highest cat
                   va = 'center', ha='center',fontweight='light', fontfamily='serif')

# Remove border from plot

for s in ['top', 'left', 'right']:
    ax.spines[s].set_visible(False)

# Tick labels

ax.set_xticklabels(data.index, fontfamily='serif', rotation=0)

# Title and sub-title

fig.text(0.09, 1, 'Distribution by age band', fontsize=15, fontweight='bold', fontfamily='serif')
fig.text(0.09, 0.95, 'The two most numerous age bands have been highlighted.', fontsize=12, fontweight='light', fontfamily='serif')

fig.text(1.185, 1.01, 'Insight', fontsize=15, fontweight='bold', fontfamily='serif')

fig.text(1.185, 0.715, '''
The two most frequent age bands are 20-30 
and 30-40. In the early stages of our 
exploratory analysis, we can already start
to think about who our most important customers
are and, importantly, how we might tailor our
marketing activities or promotional offers based
on customer segments.
''', fontsize=12, fontweight='light', fontfamily='serif')

ax.grid(axis='y', linestyle='-', alpha=0.4)   

grid_y_ticks = np.arange(0, 75, 10) # y ticks, min, max, then step
ax.set_yticks(grid_y_ticks)
ax.set_axisbelow(True)

plt.xlabel("Age banding", fontsize=12, fontweight='light', fontfamily='serif',loc='left',y=-1.5)
plt.axhline(y = 0, color = 'black', linewidth = 1.3, alpha = .7)

# line 
import matplotlib.lines as lines
l1 = lines.Line2D([1.05, 1.05], [0, 1.05], transform=fig.transFigure, figure=fig,color='black',lw=0.2)
fig.lines.extend([l1])

plt.show()

code


fig=plt.figure(figsize=(15,3))
gs=fig.add_gridspec(1,3)
gs.update(wspace=0.3)

ax1 = fig.add_subplot(gs[0, 0]) # row 0, col 0
ax1 = sns.distplot(df["Age"],color='#244747',hist_kws=dict(edgecolor="white", linewidth=1,alpha=0.8))

ax2 = fig.add_subplot(gs[0, 1]) # row 0, col 1
ax2 = sns.distplot(df["Spending Score (1-100)"],color='#244747',hist_kws=dict(edgecolor="white", linewidth=1,alpha=0.8))

ax3 = fig.add_subplot(gs[0, 2]) # row 1, span all columns
ax3 = sns.distplot(df["Annual Income (k$)"],color='#244747',hist_kws=dict(edgecolor="white", linewidth=1,alpha=0.8))

fig.text(0.09, 1.09, 'Numeric variable distribution', fontsize=15, fontweight='bold', fontfamily='serif')
fig.text(0.09, 1, 'Our data appears to be relatively normal, therefore we will not transform it.', fontsize=12, fontweight='light', fontfamily='serif')

sns.despine()
plt.show()


html 공부중 알게 됐다. &#60; 는 < 를 의미한다. 참고


github 혹은 kaggle 또는 글에 🔥 이렇게 쓸 수 있는 emoji 들이다. 참고


  macOS

맥북도 공부한다.

맥북은 command키로 쉽게 조작이 가능하다.
그 중 괜찮은 스킬이다.

command+space : spotlight 검색. (어플 실행 시 자주사용)
ctrl+command+f : 전체화면. (전체화면 후 터치패드 세손가락으로 왔다갔다가 제일 좋다.)
command+shift+l : 읽기목록 옆에 키우기. 아래 코드와 연계다. 
command+shift+d : 현재 페이지 저장. 
command+l : 주소 검색 (구글로 설정 하면 검색이 쉬워진다.)
i : insert 
u : undo
dd : 복사 혹은 라인 삭제 
x : delete from front
p : 붙여넣기 
h,j,k,l : 왼,아래,위,오른쪽으로 
b : 한 단어 뒤로
e : 한 단어 앞으로
/{search word} : find first seacrh word 
v : 긁는것. 드래그.   

ctrl+w : 한 단어씩 지우기 
option+< : 한 단어씩 건너 뛰기  
command+k : 현재 line 두고 clear하기 

  git

git을 사용하다보면 여러 상황이 발생한다.

1번 컴퓨터에서 작업 중 새로운 new_branch branch로 remote에 push. 
2번 컴퓨터에서 new_branch branch를 가져오고 싶다. 하지만, 2번 컴퓨터는 master branch 밖에 안뜬다. 

# new_branch 라는 branch를 직접 가져오기보다 
# draft 아래 파일들만 가져오고 싶다. 
git checkout origin/new_branch -- draft/

# new_branch를 가져오겠다. 물론, 2번 컴퓨터에 new_branch가 생성되고 거기서 수정한 파일도 넘어온다. 
git checkout -b new_branch 
모든 작업은 A에서 멈춰있었다. 
1번 컴퓨터에서 B위치로 commit과 push를 했다. 현재 remote의 위치는 B다. 
2번 컴퓨터는 A에서 작업을 하고 C위치로 작업을 마쳤다. 

위 상황을 diverged 했다라고 한다. 
---A---B(remote - origin/master)
    \
     C(master)

# merge - 두 줄 다 살리기(현업에서는 기록을 남기기위해 ) 자기 마음.
git merge origin/master
# rebase - 한줄로 합치기(local에서는 깔끔하게 하기 위해 ) 자기 마음.
git rebase origin/master 

Contact Form