Hard skills/Python (32)

Pandas 변수 정렬하기


Python에서 데이터 핸들링시 가장 많이 이용하는 Pandas 패키지를 이용하여 변수를 정렬하는 예제입니다. 예를 들어 아래와 같은 데이터셋이 있다고 합시다.


cluster  org      time
   1      a       8
   1      a       6
   2      h       34
   1      c       23
   2      d       74
   3      w       6 
cluster org time 1 a 8 1 a 6 2 h 34 1 c 23 2 d 74 3 w 6

출처: http://3months.tistory.com/195 [Deep Play]
import pandas as pd
data = pd.DataFrame({"cluster" : [1,1,2,1,2,3], "org":['a','a','h','c','d','w'], "time":[8,6,34,23, 74,6]})


출처: http://3months.tistory.com/195 [Deep Play]
import pandas as pd
data = pd.DataFrame({"cluster" : [1,1,2,1,2,3], "org":['a','a','h','c','d','w'], "time":[8,6,34,23, 74,6]})


출처: http://3months.tistory.com/195 [Deep Play]


이를 pandas DataFrame 객체로 읽기 위해서는 아래와 같은 구문으로 읽으면 됩니다.

import pandas as pd
data = pd.DataFrame({"cluster" : [1,1,2,1,2,3], "org":['a','a','h','c','d','w'], "time":[8,6,34,23, 74,6]})


이후에는 DataFrame 객체에 있는 sort_values를 호출하면 해당 변수에 대해 정렬을 할 수 있습니다. ascending 파라미터는 오름차순으로 정렬할지 여부를 결정합니다. 또한 여러개의 변수에 대해서 정렬하고 싶으면 list 자료구조에 변수를 넣어주기만 하면 됩니다.

data = data.sort_values(["time"], ascending=[False])

cluster org time
4 2 d 74
2 2 h 34
3 1 c 23
0 1 a 8
1 1 a 6
5 3 w 6


그러면 이와같이 결과가 나오는데 인덱스가 뒤죽박죽이 되어있다는 것을 알 수 있습니다. 기존 데이터셋의 인덱스를 그대로 갖고 있는 것입니다. 이로인해 plot을 할 때 문제가 생길 수 있으므로 인덱스를 초기화 하는 작업을 해줍니다. default는 drop=False인데 이렇게 하게 되면 기존의 인덱스가 하나의 컬럼으로 남게 됩니다. 많은 경우 기존의 인덱스는 필요없으므로 drop=True로 설정해줍니다.


data = data.reset_index(drop=True)

cluster org time
0 2 d 74
1 2 h 34
2 1 c 23
3 1 a 8
4 1 a 6
5 3 w 6


PANDAS 그룹별 평균 구하기



통계분석에서 전체 평균을 구하는 것뿐만 아니라, 그룹간의 평균을 구하고 이를 비교하는 것은 매우 중요한 주제중 하나라고 할 수 있습니다. sas에서는 proc means by 구문을 통해 구할 수 있고, R에서는 aggregates 함수 등을 이용해 구할 수 있는데요. 파이썬에서는 R의 Data.Frame 과 비슷한 형태로 자료를 핸들링 할 수 있는 pandas라는 패키지가 있습니다. 이 패키지 함수를 통해 그룹별 평균을 구하는 방법을 알아보겠습니다.


cluster  org      time
   1      a       8
   1      a       6
   2      h       34
   1      c       23
   2      d       74
   3      w       6 


예를 들어, 위와 같은 데이터가 있다고 가정합시다. 참고로 이걸 파이썬에서 읽어오는 방법은 아래와 같이 하시면 됩니다.


import pandas as pd
data = pd.DataFrame({"cluster" : [1,1,2,1,2,3], "org":['a','a','h','c','d','w'], "time":[8,6,34,23, 74,6]})


아래 구문은 'cluster' 변수를 그룹으로 하여 모든 숫자형 변수의 평균을 계산해 줍니다. as_index=False 구문은 이 그룹을 인덱스로 지정할 것인지 여부인데, 인덱스로 지정하면 두 번째 테이블처럼 그룹이 인덱스로 들어가게됩니다. 


data.groupby(['cluster'], as_index=False).mean()


cluster time
0 1 12.333333
1 2 54.000000
2 3 6.000000



time
cluster
1 12.333333
2 54.000000
3 6.000000

아래 구문은 cluster와 org를 그룹으로 하여 평균을 계산해줍니다. 예를 들어, cluster가 지역, org가 성별이라고 생각해볼 수 있습니다. 그러면 이 구문은 지역과 성별 별로 변수들의 평균을 구하는 구문이 됩니다.

data.groupby(['cluster', 'org'], as_index=False).mean()

cluster org time
0 1 a 7
1 1 c 23
2 2 d 74
3 2 h 34
4 3 w 6


  • 2020.03.16 13:39

    평균은 구했는데, index 1~10이 한꺼번에 출력돼서.. 인덱스 2번만의 평균은 어케 가져올까요?
    df_cell.groupby(['CELLID'], as_index=False).mean()
    여기서 index=2 이렇게 쓰는 방법이 있나요?

Python으로 빈도표 만들기 (Pandas Crosstab)



파이썬에서 빈도표(Frequency Table)를 만드는 방법은 여러가지가 있지만, 그 중 하나가 pandas의 crosstab 함수를 이용하는 방법이다. 아래처럼 dataframe의 컬럼(Series 데이터타입)을 파라미터로 넘겨주면 빈도표를 만들어준다.

import pandas as pd

raw_data = {'regiment': ['Nighthawks', 'Nighthawks', 'Nighthawks', 'Nighthawks', 'Dragoons', 'Dragoons', 'Dragoons', 'Dragoons', 'Scouts', 'Scouts', 'Scouts', 'Scouts'], 'company': ['infantry', 'infantry', 'cavalry', 'cavalry', 'infantry', 'infantry', 'cavalry', 'cavalry','infantry', 'infantry', 'cavalry', 'cavalry'], 'experience': ['veteran', 'rookie', 'veteran', 'rookie', 'veteran', 'rookie', 'veteran', 'rookie','veteran', 'rookie', 'veteran', 'rookie'], 'name': ['Miller', 'Jacobson', 'Ali', 'Milner', 'Cooze', 'Jacon', 'Ryaner', 'Sone', 'Sloan', 'Piger', 'Riani', 'Ali'], 'preTestScore': [4, 24, 31, 2, 3, 4, 24, 31, 2, 3, 2, 3], 'postTestScore': [25, 94, 57, 62, 70, 25, 94, 57, 62, 70, 62, 70]} df = pd.DataFrame(raw_data, columns = ['regiment', 'company', 'experience', 'name', 'preTestScore', 'postTestScore']) df


2x2 테이블


regiment를 기준으로 하여 company의 빈도를 구한다.

pd.crosstab(df.regiment, df.company, margins=True)


company cavalry infantry All
regiment


Dragoons 2 2 4
Nighthawks 2 2 4
Scouts 2 2 4
All 6 6 12



변수 3개 테이블


company, experience를 기준으로하여 regiment의 빈도를 구한다.

pd.crosstab([df.company, df.experience], df.regiment,  margins=True)



regiment Dragoons Nighthawks Scouts All
company experience



cavalry rookie 1 1 1 3
veteran 1 1 1 3
infantry rookie 1 1 1 3
veteran 1 1 1 3
All
4 4 4 12



만들어진 crosstab에 접근하는법


crosstab을 통해 생성한 객체는 dataframe 타입이고, regiment를 제외한 company와 experience는 multi index로 지정되어있다. 따라서 인덱스 값으로 해당 인덱스의 원소값을 얻는 loc 함수를 통해 crosstab 원소에 접근할 수 있다.


cross_tab = pd.crosstab([df.company, df.experience], df.regiment, margins=True)
cross_tab.loc[[('cavalry', 'rookie')]]


참고

https://chrisalbon.com/python/pandas_crosstabs.html

강화학습 Q-learning on non-deterministic worlds



출처



Frozen Lake 게임이 non-deterministic인 경우 Q를 어떻게 학습하는지 알아보겠습니다. 이 포스팅은 Frozen Lake 게임과 강화학습의 기본 개념을 안다는 전제로 김성훈 교수님의 강화학습 강의를 제 나름대로 정리한 포스팅입니다. 우선 non-deterministic이 무슨 의미인지부터 살펴보면 non-deterministic 이라는 것은 원하는대로 되지 않는다는 의미입니다. (stochastic이라고도 합니다.) 이런 경우에는 무조건 Q가 가라는 대로 가는 것보다는 "기존의 믿음" 을 차근 차근 업데이트 해나가는 것이 Q 학습이 더 잘 된다고 합니다. 이는 현실 세계와도 많이 닮아있습니다. 이를 멘토에 비교해볼 수 있는데, 무조건 멘토가 하라는 대로 하기보다는 결국 무언가를 하기 위해서는 타인의 조언 보다는 자기 자신의 신념이 더 중요하다고 할 수 있습니다.


이를 식으로 표현하면 기존 알고리즘은  


Q(state, action) = R + λmax(Q(new state)) (λ < 1)


이었는데


Q(state, action) = (1-a)Q(state, action) + a(R+λmax(Q(new state)) (a = learning rate)

Q(state, action) = R + max(Q(new state))

출처: http://3months.tistory.com/173 [Deep Play]


사용하게 됩니다. learning rate 개념을 통해 Q를 한 번에 업데이트 하지 않고, 기존에 믿음을 토대로 조금씩 업데이트 해나가는 것입니다. 이를 구현하는 코드를 보겠습니다. 기존 코드에서 Q 업데이트 하는 부분만 달라지기 때문에 크게 다르지는 않습니다.



라이브러리 로드

import gym
import numpy as np
import matplotlib.pyplot as plt 
from gym.envs.registration import register
import random as pr


environment 생성 및 하이퍼 파라미터 초기화

env = gym.make('FrozenLake-v0')
# Q-table 초기화
Q = np.zeros([env.observation_space.n, env.action_space.n])

# Learning Rate
learning_rate = 0.85

# discount factor
dis = .99
    
# learning 횟수
num_episodes = 2000

# 학습 시 reward 저장
rList = []


Q-learning 알고리즘

for i in range(num_episodes):
    
    # env 리셋
    state = env.reset()
    rAll = 0
    done = False
    
    #decaying E-greedy
    e = 1./((i//100)+1)
    
    # Q-table Learning algorithm
    while not done:
        
        # Choose an action by e greedy
        '''
        if np.random.rand(1) < e:
            action = env.action_space.sample()
        else:
            action = np.argmax(Q[state, :])
        '''
        
        # add Random noise
        action = np.argmax(Q[state, :]+ np.random.randn(1, env.action_space.n)/(i + 1))
        
        # new_state, reward 업데이트 
        new_state, reward, done, _ = env.step(action)
        
        # update Q-table
        Q[state, action] = (1-learning_rate) * Q[state, action] + learning_rate*(reward + dis*np.max(Q[new_state, :]))
        
        rAll += reward
        state = new_state

    rList.append(rAll)

action을 선택하는 부분에서 e-greedy 방법을 사용하는 방법과 random noise를 사용하는 방법이 있는데 둘 다 exploit & exploration을 구현한 것으로 둘 중 하나를 사용하면 됩니다. 밑에 #update Q-table 부분에 Q를 업데이트하는 코드를 볼 수 있습니다. learning rate를 통해 기존의 믿음을 얼마나 받아들일지, Q의 판단을 얼마나 받아들일지를 조정합니다.

print('success rate: ', str(sum(rList)/num_episodes))
print('Final Q-table values')
print(Q)
plt.bar(range(len(rList)), rList, color = 'blue')
plt.show()

('success rate: ', '0.4135')
Final Q-table values
[[  6.05216575e-01   4.77802714e-03   7.66890982e-03   1.14402756e-02]
 [  1.89070559e-04   2.71412272e-05   2.94641678e-03   6.06539650e-01]
 [  6.20782244e-03   3.96037865e-03   2.02160738e-03   5.88158391e-01]
 [  1.38851811e-04   1.81853506e-04   1.08700028e-03   3.36662917e-01]
 [  5.63057417e-01   1.35053120e-03   4.64530097e-04   1.81633578e-03]
 [  0.00000000e+00   0.00000000e+00   0.00000000e+00   0.00000000e+00]
 [  8.64124213e-05   2.51760080e-04   7.21585211e-02   3.41902605e-05]
 [  0.00000000e+00   0.00000000e+00   0.00000000e+00   0.00000000e+00]
 [  3.70706358e-05   1.37044981e-03   2.40643636e-04   7.95889822e-01]
 [  1.09162680e-04   5.60870413e-01   9.16914837e-04   2.64997619e-04]
 [  9.20012820e-01   5.54630225e-05   7.32392792e-05   0.00000000e+00]
 [  0.00000000e+00   0.00000000e+00   0.00000000e+00   0.00000000e+00]
 [  0.00000000e+00   0.00000000e+00   0.00000000e+00   0.00000000e+00]
 [  4.37606936e-04   4.03103644e-04   9.16837079e-01   3.65822303e-04]
 [  0.00000000e+00   0.00000000e+00   2.34205607e-03   9.98477546e-01]
 [  0.00000000e+00   0.00000000e+00   0.00000000e+00   0.00000000e+00]]

success rate는 0.4135인데, 이는 0.4135의 확률로 Goal에 도착한다는 것입니다. non-deterministic world 에서는 상당히 높은 성공률입니다. 또 이 부분에서 중요한 점은 이 non-deterministic world에서의 강화학습 알고리즘의 성공률은 사람의 성공률 보다 높을 수 있다는 것입니다. 왜냐하면 deterministic world에서는 사람이 한 눈에 게임의 rule을 알 수 있고, 매우 쉽게 Goal을 찾을 수 있는 반면, non-deterministic world에서는 사람에게는 Goal을 찾아가는 것이 쉽지 않습니다. 하지만 non-deterministic world에서도 확률적으로 패턴이 존재하고, 이 사람이 이해하기 힘든 패턴속에서 강화학습 알고리즘은 에러를 최소화할 최적의 경로를 찾는다는 것입니다. 이 부분이 진정한 강화학습의 강점이 아닐까 생각해보았습니다.



  • 안녕하세요 2018.01.13 15:24

    질문하나만 해도될까요?

강화학습 Q-Learning 기초 실습



Q-Learning을 통해 Frozen Lake 문제를 해결하는 방법에 대한 포스팅입니다. 실습 코드의 내용 및 출처는 김성훈 교수님의 강화학습강의( https://www.youtube.com/watch?v=VYOq-He90bE&feature=youtu.be) 입니다.



이 코드를 이해하기 위해서는 강화학습에 대한 기본적인 내용과 Frozen Lake 문제에 대하여 알아야합니다. Frozen Lake 문제는 간단히 말하면 위와 같은 상황에서 state를 이동하여 H(Hall)에 빠지지 않고 G(Goal)로 이동하는 문제입니다. 이 포스팅에서 강화학습에 대한 기본 내용들은 다루지 않겠고, 코드만 정리하여 포스팅 하려고 합니다.



환경 세팅


실습에서 사용하는 환경은 gym 패키지 환경인데, 이 환경에서 강화학습으로 해결할만한 여러 toy example들을 로드할 수 있습니다.

gym이 설치되지 않은 경우 pip install gym 으로 설치하시면 됩니다.

import gym
import numpy as np
import matplotlib.pyplot as plt
from gym.envs.registration import register

register(
    id='FrozenLake-v3',
    entry_point = 'gym.envs.toy_text:FrozenLakeEnv',
    kwargs={'map_name':'4x4',
           'is_slippery':False}
)

env = gym.make('FrozenLake-v3')

위와 같이 FrozenLake 게임을 로드할 수 있습니다.



Q-Table 초기화 및 하이퍼 파라미터 초기화

# Q Table을 모두 0으로 초기화 한다. : 2차원 (number of state, action space) = (16,4)
Q = np.zeros([env.observation_space.n, env.action_space.n])

# discount 정의 => 미래의 reward를 현재의 reward 보다 조금 낮게 본다.
dis = 0.99

# 몇 번 시도를 할 것인가 (에피소드)
num_episodes = 2000

# 에피소드마다 총 리워드의 합을 저장하는 리스트
rList = []


Q-learning은 결국 Q 를 배우는 것입니다. Q는 주어진 state에서 어떤 action을 취할 것인가에 대한 길잡이입니다. 이 문제에서 Q라는 2차원 배열에는 현재 state에서 action을 취할 때 얻을 수 있는 reward를 저장하고 있습니다. 이 Q 2차원 배열에서 argmax 함수를 이용하면 어떤 action을 취할지를 얻어낼 수 있는 것이죠. 이 문제에서 state는 16, action은 4입니다. (4x4 Frozen Lake 그리고 action은 위, 아래, 왼쪽, 오른쪽 4개)


Q-learning 알고리즘에서 Q를 업데이트하는 것


Q(state, action) = R + max(Q(new state)) 로 업데이트하게 됩니다. R은 reward로 게임 내부에서 지정되는 값입니다. 현재 state에서의 어떤 action을 취할 때의 Q 값은 그 action을 통해 얻어지는 reward와 action으로 변화된 state에서 얻을 수 있는 reward의 최댓값을 더한 것입니다. 즉 의미는 현재 리워드와 미래에 가능한 리워드의 최대치를 더하는 것입니다.


근데 이 때, Q(state, action) = R + discount * max(Q(new state)) 로 미래 가능한 리워드에 1 미만의 discount factor를 곱해주어(이 실습에서는 0.99) 미래 리워드에 약간의 패널티를 주기도 하는데 이런 방식을 통해 Q가 조금 더 optimal한 방법으로 learning 될 수 있습니다. 이 때 discount는 하이퍼 파라미터(hyperparameter)로 여러번 시도하면서 좋은 값을 찾을 수 있습니다.



Q-learning 알고리즘에서 Action을 고르는 것


강화학습에서 action 을 고르는 것은 이슈중 하나입니다. 이 실습에서는 두 가지 방법을 쓰는데 첫 번째, random noise 방식, 두 번째, E-Greedy 방식입니다. 둘 다 exploit & exporation 방법을 구현한 것으로 볼 수 있는데 약간의 차이가 있습니다. 둘의 공통적인 아이디어는 '무조건 Q 가 시키는대로만 가지말고 새로운 길로도 가보자는 것' 입니다. 왜냐하면 Q가 시키는 것이 optimal한 것이 아닐 수 있기 때문입니다.



1. random noise 방식


random noise 방식이란 현재 state에서 가능한 action에 따른 Q값(총 4가지)에 random noise를 주어서, 이 것이 최대값이 되는 action을 action으로 선택하게 됩니다. 그러면 무조건 최대 Q 값만 따르지 않고 가끔은 다른 action을 취하기도 합니다. random noise를 (i+1)로 나누는 것은 여러번 해보면서 어느 정도 Q 값이 optimal하게 될 것이기 때문에 exploration을 줄이고 exploit 위주로 한다는 것입니다.

for i in range(num_episodes) : 
    state = env.reset()
    rAll = 0
    done = False
    
    # Q learning 알고리즘
    while not done : 
        # Action 중에 가장 R(Reward)이 큰 Action을 고른다. 
        # 이 때, random noise 방식으로 decaying Exploit & Exploration 구현 
        action = np.argmax(Q[state, :] + np.random.randn(1, env.action_space.n) / (i+1))
        
        # 해당 Action을 했을 때 environment가 변하고, 새로운 state, reward, done 여부를 반환 받음
        new_state, reward, done, _ = env.step(action)
        
        # Q = R + Q 
        Q[state, action] = reward + dis * np.max(Q[new_state, :])
        
        rAll += reward
        state = new_state
        
    rList.append(rAll)

2. E-greedy 방식


E-Greedy 방식은 어떠한 확률값 e를 주어, e의 확률로 exploration한다는 것입니다. 예를 들어 e=0.99 이면 99%의 확률로 exploration 하고, 1%의 확률로 exploit해서 새로운 길을 찾게 됩니다. 이 값을 (i/100) 으로 나눈 것은 위 1번과 마찬가지로 여러버 해보면서 Q 값이 optimal 해질 것이기 때문에 exploration을 줄이면서 exploit 위주로 한다는 뜻입니다.

for i in range(num_episodes) : 
    state = env.reset()
    rAll = 0
    done = False
    
    # exploration의 확률 (decaying)
    e = 1./((i / 100) + 1)
    
    # Q learning 알고리즘
    while not done : 
        
        # E-Greedy 알고리즘으로 action 고르기
        if np.random.rand(1) < e :
            action = env.action_space.sample()
        else : 
            action = np.argmax(Q[state, :])
        
        # 해당 Action을 했을 때 environment가 변하고, 새로운 state, reward, done 여부를 반환 받음
        new_state, reward, done, _ = env.step(action)
        
        # Q = R + Q 
        Q[state, action] = reward + dis * np.max(Q[new_state, :])
        
        rAll += reward
        state = new_state
        
    rList.append(rAll)

최종 결과


Success rate는 Goal까지 실패 안하고 갈 확률입니다. 그래프를 보면 초반에만 실패하고 나중에는 다 성공하도록 Q 가 학습되어 나간다는 것을 볼 수 있습니다.

print("Success rate : "+str(sum(rList) / num_episodes))
print("Final Q-Table Values")
print(Q)

plt.bar(range(len(rList)), rList, color="blue")
plt.show()
Success rate : 0.807
Final Q-Table Values
[[ 0.94148015  0.95099005  0.95099005  0.94148015]
 [ 0.94148015  0.          0.96059601  0.95099005]
 [ 0.95099005  0.970299    0.95099005  0.96059601]
 [ 0.96059601  0.          0.95099005  0.        ]
 [ 0.95099005  0.96059601  0.          0.94148015]
 [ 0.          0.          0.          0.        ]
 [ 0.          0.9801      0.          0.96059601]
 [ 0.          0.          0.          0.        ]
 [ 0.96059601  0.          0.970299    0.95099005]
 [ 0.96059601  0.9801      0.9801      0.        ]
 [ 0.970299    0.99        0.          0.970299  ]
 [ 0.          0.          0.          0.        ]
 [ 0.          0.          0.          0.        ]
 [ 0.          0.9801      0.99        0.970299  ]
 [ 0.9801      0.99        1.          0.9801    ]
 [ 0.          0.          0.          0.        ]]




Python Scaling 방법 정리


/* 2017.8.27 by. 3months */


머신러닝에서 데이터를 모델에 트레이닝할 때, 일반적으로 데이터를 Scaling 해서 사용한다. Scaling을 통해 데이터의 Scale을 맞추면 Weight의 scale도 일관성 있도록 맞출 수 있을 것이다.


MinMax Scaling은 최댓값 = 1, 최솟값 = 0으로 하여, 그 사에 값들이 있도록 하는 방법이다.

즉 데이터 X의 scaling된 값 Xscale은 아래와 같다.


Xscale = (X-Xmin) / (Xmax-Xmin)


from sklearn.preprocessing import MinMaxScaler
a = [[10], [9], [8], [6], [2]]
scaler = MinMaxScaler(feature_range=(0,1))
a = scaler.fit_transform(a)
print(a)

결과

[[ 1.   ]
 [ 0.875]
 [ 0.75 ]
 [ 0.5  ]
 [ 0.   ]]



StandardScaling은 평균=0과 표준편차=1이 되도록 Scaling 하는 방법이다. 이는 표준화라고도 부른다.


Xscale = (X-X_mean) / Xstd


from sklearn.preprocessing import StandardScaler
a = [[10], [9], [8], [6], [2]]
scaler = StandardScaler()
a = scaler.fit_transform(a)
print(a)
print(a.mean())
print(a.std())

결과

[[ 1.06066017]
 [ 0.70710678]
 [ 0.35355339]
 [-0.35355339]
 [-1.76776695]]
0.0
1.0




아나콘다에서 제공하는 IDE인 Spyder를 아나콘다 virtual environment 위에서 실행하기 위해서는 Spyder를 virtual environment 안에도 설치를 해야한다.

conda install -n myenv spyder

myenv는 직접 지정한 virtual environment 이름이다. 위 명령어를 통해 virtual environment 상에 spyder를 설치하게 되고, 그 환경에서 spyder를 실행할 수 있다.


설치 후,


윈도우의 경우


activate myenv spyder

명령어를 통해 해당 virtual environment 안에서 spyder를 실행할 수 있다.


(MAC은 activate 대신에 source activate)

/* 2017.6.29

파이썬 선형회귀분석 

by 3개월

*/


파이썬 선형회귀분석 (sklearn 라이브러리 사용)



필요한 라이브러리 임포트

import pandas as pd
from sklearn import datasets, linear_model
import matplotlib.pyplot as plt
import numpy as np


데이터 모양 출력

birth = pd.read_csv("C:/workspace/python/data/birth.csv")
print birth.head()
   case  gram  weeks  smoke
0     1  3147     40      0
1     2  2977     41      0
2     3  3119     38      0
3     4  3487     38      0
4     5  4111     39      0


데이터를 간단히 설명하면 산모의 임신주차(weeks)와 흡연여부(smoke)변수를 통해 태아의 몸무게(gram)을 예측하기 위한 예제 데이터입니다. 관측치(row)는 100개가 있습니다.



데이터 나누기

# split data
print len(birth)
birth_train = birth[0:90]
birth_test = birth[91:100]


90%의 데이터를 트레이닝 데이터, 10%의 데이터를 테스트 데이터로 쓰겠습니다.


# basic linear regression
model1 = linear_model.LinearRegression()
x_vars1 = ["weeks", "smoke"]
model1.fit(birth_train[x_vars1], birth_train["gram"])
print model.coef_, model.intercept_

x = np.linspace(25,50,100)

plt.scatter(birth_train['weeks'], birth_train['gram'], c=birth_train["smoke"])
plt.plot(x, x*model.coef_[0]+model.coef_[1]+model.intercept_)
plt.plot(x, x*model.coef_[0]+model.intercept_)
plt.show()


첫 번째 모델 : gram = W1*weeks + W2*smoke + Intercept



우선 교호작용을 고려하지 않은 첫번째 모델입니다. smoke는 0, 1만 갖는 이진 변수이므로 smoke=1 일 때만, W2*smoke는 하나의 상수가 됩니다. smoke=0 인 경우 W2*smoke는 0입니다. 그러므로 smoke=1일 때 W2 값만큼 회귀식의 절편이 이동합니다.


[ 123.76004061 -283.69489986] -1504.60207489


다음 결과를 통해 W1 = 123.76004, W2 = -283.69, Intercept = -1504.60임을 알 수 있습니다.




따라서 결과 플롯은 위와 같습니다. smoke=1일때가 밑에있는 주황색 선입니다. 또한 보라색 점은 smoke=0인 사람을 나타낸 것이고 노란색 점은 smoke=1 인 사람을 나타낸 것입니다.



교호작용을 고려한 모델


# with interaction term
birth["weekssmoke"] = birth["weeks"]*birth["smoke"]
birth_train = birth[0:90]
birth_test = birth[91:100]
model2 = linear_model.LinearRegression()
x_vars2 = ["weeks", "smoke", "weekssmoke"]
model2.fit(birth_train[x_vars2], birth_train["gram"])
print model.coef_, model.intercept_

x = np.linspace(25,50,100)

plt.scatter(birth_train['weeks'], birth_train['gram'], c=birth_train["smoke"])
plt.plot(x, x*(model.coef_[0]+model.coef_[2])+model.coef_[1]+model.intercept_)
plt.plot(x, x*model.coef_[0]+model.intercept_)
plt.show()


교호작용은 effect modification 이라고도 불리며, 한 변수에 의해 다른 변수의 효과가 변하는 것을 말합니다. 이 경우 모델의 식은 아래와 같습니다.



두 번째 모델 : gram = W1*weeks + W2*smoke + W3*(weeks*smoke) + Intercept


왜 weeks*smoke를 곱한 텀을 넣어주나면 이를 통해 weeks의 gram에 대한 effect를 변화시킬 수 있기 때문입니다. smoke=1인경우 (W1+W3)*weeks가 되기 때문에 smoke에 의한 weeks의 effect의 변화를 고려할 수 있게 됩니다.



[  132.01926109  1316.00125169   -41.03706632] -1820.91949297

위 결과를 통해 coefficient와 intercept를 알 수 있습니다.




Mean Squared Error 구하기

print "Model1 Training Mean squared error: %.2f" % np.mean((model1.predict(birth_train[x_vars1]) - birth_train['gram']) ** 2)
print "Model2 Training Mean squared error: %.2f" % np.mean((model2.predict(birth_train[x_vars2]) - birth_train['gram']) ** 2)

print "Model1 Test Mean squared error: %.2f" % np.mean((model1.predict(birth_test[x_vars1]) - birth_test['gram']) ** 2)
print "Model2 Test Mean squared error: %.2f" % np.mean((model2.predict(birth_test[x_vars2]) - birth_test['gram']) ** 2)

마지막으로 Training MSE와 test MSE를 구하는 코드입니다.


Model1 Training Mean squared error: 227136.45
Model2 Training Mean squared error: 223972.58
Model1 Test Mean squared error: 220233.22
Model2 Test Mean squared error: 226638.72


이 포스트는 아래 포스팅을 참고한 포스팅입니다.

https://www.dataquest.io/blog/jupyter-notebook-tips-tricks-shortcuts/


Jupyter Notebook


기존에는 IPython Notebook으로 알려졌던 Jupyter Notebook은 코드, 이미지, 분석 결과, 코멘트, 수식 등을 분석자가 "노트북"처럼 Keep할 수 있게하여 다른 사람들이 분석의 흐름을 읽기 쉽게 만들 수 있는 유연하고 강력한 툴입니다. Jupyter Notebook은 여러가지 언어를 지원합니다. (Python, R, Julia 등) 또한 어떤 컴퓨터에서든지 쉽게 호스팅할 수 있습니다. http나 ssh로 접속하기만 하면 됩니다. 또 무엇보다도 Jupyter Notebook은 무료입니다. IPython 프로젝트에서부터 시작된 Juypter Notebook는 Julia, Python, R의 앞 글자를 따시 지어졌고, 파이썬 이외의 여러가지 언어를 지원하기 위하여 시작되었습니다. 주피터에서 파이썬 코드를 실행할 때 내적으로는 IPython Kernel이 돌아가게 됩니다.


1. 키보드 단축키


Help > Keyboard Shortcuts에 가면 키보드 단축키들을 확인할 수 있습니다. 아시다시피 키보드 단축키는 개발에서 시간을 많이 단축해줍니다. 위 메뉴를 주피터가 업데이트될 때마다 확인하시면 좋은데, 키보드 단축키들이 자주 추가되기 때문입니다.


또는 Cmd + Shift + P (또는 Ctrl + Shift + P 리눅스, 윈도우의 경우) 을 누르면 대화창이 뜨는데 키보드 단축키들을 이름으로 검색해서 실행시킬 수 있습니다. 키보드 단축키가 생각나지 않으실 때는 이 기능을 활용하시면 좋습니다.


몇 가지 유용한 단축키롤 소개합니다. 


esc : command 모드로 변경한다.


command 모드 안에서

  • A : 현재 셀의 위에 새로운 셀을 추가한다.
  • B : 현재 셀 밑에 새로운 셀을 추가한다.
  • M : 현재 셀을 markdown 모드로 변경한다. 
  • Y : markdown 모드를 다시 code 모드로 변경한다.
  • D+D : 현재 셀을 삭제한다.
  • Enter : command 모드에서 edit 모드로 변경한다.
  • F : 코드를 find and replace 한다.
  • O : Output을 toggle한다.
shift + tab : 객체의 docstring(documentation)을 출력한다. 

복수의 셀을 선택하기
  • Shift J 나 Shift down(키보드 방향키)을 누르면 아래방향으로 복수의 셀을 선택할 수 있다. Shift K나 Shift Up을 누르면 위 방향으로 복수의 셀을 선택한다. 
  • 복수의 셀이 선택되면 마찬가지로 delete, copy, cut, paste, run을 할 수 있다. 
  • Shift M을 누르면 선택된 셀들을 merge 한다.

2. 변수를 이쁘게 출력하기


가장 널리쓰이는 방법은 print 문을 안 쓰고 그냥 변수명만 셀에 쓴 다음에 run을 하는 것입니다. 그러면 IPython Kernel이 해당 객체를 이쁘게 나타내주는데 예를 들어 pandas DataFrame을 출력할 때 유용한 방법입니다. 


덜 알려진 방법은 kernel 의 세팅을 바꾸면 여러개의 변수명에 대해서 output을 내줄 수 있다는 것인데

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
import pandas as pd


위와 같이 세팅하면


data = pd.DataFrame({'a':("A", "B","C","D","E","F","G"), 'b':(1,2,3,4,5,6,7)}) data.head() data.tail()

Out[11]:
ab
0A1
1B2
2C3
3D4
4E5
Out[11]:
ab
2C3
3D4
4E5
5F6
6G7


위와 같이 여러개의 statement가 있어도 그 statement의 수만큼의 output을 내줍니다. (세팅을 안 하게 되면 가장 마지막 output 만 나타내줍니다.)


~/.ipython/profile_default/ipython_config.py

 

일일이 세팅을 해주기 귀찮으면 위의 코드를


c = get_config()

# Run all nodes interactively
c.InteractiveShell.ast_node_interactivity = "all"

이렇게 바꾸어주면 일일이 코드상에서 세팅해주지 않아도 됩니다.



3. 라이브러리 도큐먼트를 쉽게 찾기


Help 메뉴에 가시면 Scipy, Numpy, Matplotlib, Pandas와 같은 흔히 쓰이는 라이브러이의 도큐먼트를 확인할 수 있습니다. 또한 코드상에서 ? 접두사를 붙여서 라이브러리의 도큐먼트를 확인할 수도 있습니다.


?str.replace()


Docstring:
S.replace(old, new[, count]) -> str

Return a copy of S with all occurrences of substring
old replaced by new.  If the optional argument count is
given, only the first count occurrences are replaced.
Type:      method_descriptor




문제

ImportError: No module named cv2


해결


파이썬 opencv 가 설치되어있지 않아서 생기는 문제로 이를 해결하기 위해 conda install opencv, pip install opencv 등을 해보았지만 제대로 되지 않았습니다. 그래서 opencv 홈페이지에서 직접 윈도우즈용 opencv를 설치하였고 설치된 폴더, opencv\build\python\2.7\x64 이곳에서 파이썬 모듈 cv2.pyd를 Anaconda2\Lib\site-packages에 복사하였더니 문제가 해결되었습니다. 

 

http://speark.tistory.com/9


위 블로그를 참고하였습니다.

  • -- 2018.04.30 15:44

    opencv 폴더 내 파이썬의 버전과 윈도우즈의 버전이 일치하는 폴더가 없을경우 아나콘다 콘솔에서 다음 명령어를 사용해주세요.
    conda install --channel https://conda.anaconda.org/anaconda opencv