반응형
Stopwatch

StopWatch

00:00:00.000
반응형
mysql query

MySQL Query

Select

두 개의 테이블(또는 Self Table)에서 다른 값 찾기

TABLEA 테이블에서 키가 COMPARE_ID이고, F98 필드에 대해서 같은 테이블의 같은 키, 같은 필드의 필드값이 다른 것을 찾는 쿼리
(두 개의 테이블로 할 경우는 테이블 명과 where 조건절만 수정하면 된다.)
비교할 대상의 테이블 두 개를 UNION해서 같은 키 에 대해 정렬하고 그룹별 카운팅을 하면 2개씩 나와야 정상인데, 1개인 것이 바로 다른 부분이다.

SELECT COMPARE_ID, F98
FROM (
SELECT T1.COMPARE_ID, T1.F98 FROM TABLEA T1 WHERE T1.AP_ID='A08v25'
 UNION ALL SELECT T2.COMPARE_ID, T2.F98  FROM TABLEA T2 WHERE T2.AP_ID='A10v25'
 ) t
 GROUP BY COMPARE_ID, F98
 HAVING COUNT(*) = 1
 ORDER BY COMPARE_ID
 

Written with StackEdit.

반응형
crazyj7 kaggle EDA start

Kaggle EDA Start

데이터 분석 / 그래프 작성 / 통계 정보 등

Author: crazyj7@gmail.com

In [1]:
# 경고 무시 (쓸데없는 로그 출력금지)
import warnings
warnings.filterwarnings('ignore')

import numpy as np
import pandas as pd

# 그래프 관련 
import matplotlib.pyplot as plt
import seaborn as sns
In [2]:
# plot 환경설정 기본값과 달라진 점
class DictDiffer(object):
    """
    Calculate the difference between two dictionaries as:
    (1) items added
    (2) items removed
    (3) keys same in both but changed values
    (4) keys same in both and unchanged values
    """
    def __init__(self, current_dict, past_dict):
        self.current_dict, self.past_dict = current_dict, past_dict
        self.set_current, self.set_past = set(current_dict.keys()), set(past_dict.keys())
        self.intersect = self.set_current.intersection(self.set_past)
    def added(self):
        return self.set_current - self.intersect 
    def removed(self):
        return self.set_past - self.intersect 
    def changed(self):
        return set(o for o in self.intersect if self.past_dict[o] != self.current_dict[o])
    def unchanged(self):
        return set(o for o in self.intersect if self.past_dict[o] == self.current_dict[o])
In [3]:
# make default graph configure
# 그래프 설정값을 디폴트로 리셋해 준다. 
# (가끔 앞의 그래프 설정 변경으로 잘 나오던 그래프가 이상하게 나올때 사용)
def pltconfig_default():
    sns.reset_defaults()
    %matplotlib inline
    
pltconfig_default()
In [4]:
def pltconfig_check():
    d=DictDiffer(plt.rcParams, plt.rcParamsDefault)
    for it in d.changed():
        print(it, plt.rcParamsDefault[it], plt.rcParams[it])
        
pltconfig_check()
figure.edgecolor white (1, 1, 1, 0)
figure.dpi 100.0 72.0
figure.figsize [6.4, 4.8] [6.0, 4.0]
figure.facecolor white (1, 1, 1, 0)
interactive False True
figure.subplot.bottom 0.11 0.125

load data

In [5]:
inputdir='./'
outputdir='./'

df_train = pd.read_csv(inputdir+'train.csv')
df_test = pd.read_csv(inputdir+'test.csv')

데이터 탐색

head(n), describe(), info(), columns, index
value_counts()

data explore

In [6]:
# 데이터의 일부를 관찰. (파라미터가 없으면 디폴트로 5개)
df_train.head(3)
Out[6]:
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
In [7]:
# 데이터의 분포를 간략히 요약. 
# 개수, 평균, 표준편차, 사분위수(최소, 최대) 등.
df_train.describe()
# 개수를 보면 어느 필드에 빠진 데이터들이 있는지 알 수 있음.
Out[7]:
PassengerId Survived Pclass Age SibSp Parch Fare
count 891.000000 891.000000 891.000000 714.000000 891.000000 891.000000 891.000000
mean 446.000000 0.383838 2.308642 29.699118 0.523008 0.381594 32.204208
std 257.353842 0.486592 0.836071 14.526497 1.102743 0.806057 49.693429
min 1.000000 0.000000 1.000000 0.420000 0.000000 0.000000 0.000000
25% 223.500000 0.000000 2.000000 20.125000 0.000000 0.000000 7.910400
50% 446.000000 0.000000 3.000000 28.000000 0.000000 0.000000 14.454200
75% 668.500000 1.000000 3.000000 38.000000 1.000000 0.000000 31.000000
max 891.000000 1.000000 3.000000 80.000000 8.000000 6.000000 512.329200
In [8]:
# info는 필드들의 정보. 데이터타입. 개수 등
df_train.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId    891 non-null int64
Survived       891 non-null int64
Pclass         891 non-null int64
Name           891 non-null object
Sex            891 non-null object
Age            714 non-null float64
SibSp          891 non-null int64
Parch          891 non-null int64
Ticket         891 non-null object
Fare           891 non-null float64
Cabin          204 non-null object
Embarked       889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
In [9]:
df_test.head()
Out[9]:
PassengerId Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 892 3 Kelly, Mr. James male 34.5 0 0 330911 7.8292 NaN Q
1 893 3 Wilkes, Mrs. James (Ellen Needs) female 47.0 1 0 363272 7.0000 NaN S
2 894 2 Myles, Mr. Thomas Francis male 62.0 0 0 240276 9.6875 NaN Q
3 895 3 Wirz, Mr. Albert male 27.0 0 0 315154 8.6625 NaN S
4 896 3 Hirvonen, Mrs. Alexander (Helga E Lindqvist) female 22.0 1 1 3101298 12.2875 NaN S

NULL (Missing) 데이터 검사

In [10]:
df_train.isnull().sum()
Out[10]:
PassengerId      0
Survived         0
Pclass           0
Name             0
Sex              0
Age            177
SibSp            0
Parch            0
Ticket           0
Fare             0
Cabin          687
Embarked         2
dtype: int64
In [11]:
# 데이터 분포도
# 히스토그램으로 구간별 카운팅
# 박스플롯으로 어느 지점에 데이터가 밀집해 있는지 알 수 있다. 
fig, axs = plt.subplots(1,2)
df_train.Fare.plot.hist(ax=axs[0])
df_train.boxplot(['Fare', 'Age', 'SibSp', 'Parch'], ax=axs[1])  # 파라미터 지정이 없으면,  주어진 dataframe의 모든 컬럼별 데이터 분포
Out[11]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f29002a30b8>
In [12]:
# 평균 , 표준편차
print('fare mean=', df_train.Fare.mean(), df_train.Fare.std())
# 표준 편차는 정규분포를 따를때,  평균에서 +- 1 표준편차는 전체의 65% 정도가 해당되고,
# # +-2표준편차는 95%, +-3표준편차는 99%정도로 본다. (1.96이 95%, 2.58이 99%)
# 사분위수
print('quantile = ', df_train.Fare.quantile(0), df_train.Fare.quantile(0.25), df_train.Fare.quantile(0.5), df_train.Fare.quantile(0.75), 
                  df_train.Fare.quantile(0.99), df_train.Fare.quantile(1))
fare mean= 32.204207968574636 49.6934285971809
quantile =  0.0 7.9104 14.4542 31.0 249.00622000000033 512.3292

데이터 수정/병합

In [13]:
# df3 = pd.concat([df1 , df2], axis=0)  
# df3 = df1.append(df2, ignore_index=True)  
# df4.drop(columns='age', inplace=True)  

df_train.head()
print(df_train.shape)
(891, 12)
In [14]:
df_test.head()
df_test.shape
Out[14]:
(418, 11)
In [15]:
# train, test 데이터가 survived를 제외하고 동일함. 합쳐서 전처리 작업을 할 수 도 있다.
# drop은 columns or rows를 삭제할 수 있다. (array로 여러개 지정 가능)
# concat은 병합. axis로 방향. 다른 방법으로는 df_train.append(df_test)을 리턴으로 받으면 된다.
# iloc는 array index로 filtering
# inplace는 자체 수정 여부. (False이면 자체수정없이 수정된것을 반환.)
# ignore_index=True 옵션을 주면, 인덱스를 0부터 새로 매긴다. False이면 인덱스 값이 중복되더라도 유지한다.

# df_all = pd.concat([df_train.iloc[:,2:], df_test.iloc[:,1:]], axis=0)
# or
df_all = pd.concat([df_train.drop(columns='Survived'), df_test], axis=0)
In [16]:
# passengerid는 의미없으므로 제거.
df_all.drop(columns='PassengerId', inplace=True)
In [17]:
df_all.head()
Out[17]:
Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
In [18]:
# 컬럼 타입별로 구분. 숫자와 숫자 아닌 것. 위에 info()에 마지막에 dtypes 참고.
df_num = df_all.select_dtypes(include=['int64', 'float64'])
df_str = df_all.select_dtypes(include=['object'])

df_num.describe()
Out[18]:
Pclass Age SibSp Parch Fare
count 1309.000000 1046.000000 1309.000000 1309.000000 1308.000000
mean 2.294882 29.881138 0.498854 0.385027 33.295479
std 0.837836 14.413493 1.041658 0.865560 51.758668
min 1.000000 0.170000 0.000000 0.000000 0.000000
25% 2.000000 21.000000 0.000000 0.000000 7.895800
50% 3.000000 28.000000 0.000000 0.000000 14.454200
75% 3.000000 39.000000 1.000000 0.000000 31.275000
max 3.000000 80.000000 8.000000 9.000000 512.329200
In [19]:
# 스트링 컬럼으로 보면, 클래스 개수(unique참조), 전체 개수 파악(미싱제외)
df_str.describe()
Out[19]:
Name Sex Ticket Cabin Embarked
count 1309 1309 1309 295 1307
unique 1307 2 929 186 3
top Kelly, Mr. James male CA. 2343 C23 C25 C27 S
freq 2 843 11 6 914
In [20]:
# 필드값별로 카운팅
df_train['Survived'].value_counts()
Out[20]:
0    549
1    342
Name: Survived, dtype: int64
In [21]:
# ## 스트링 필드를 분할하여 추가 컬럼들을 만들기

lstPath = ['img100_GENUINE.jpg', 'img101_FRAUD.jpg', 'img102_GENUINE.jpg', 'img103_FRAUD.jpg', 'img104_FRAUD.jpg', 'img105_GENUINE.jpg']
dfSample = pd.DataFrame({'path':lstPath})
dfSample
Out[21]:
path
0 img100_GENUINE.jpg
1 img101_FRAUD.jpg
2 img102_GENUINE.jpg
3 img103_FRAUD.jpg
4 img104_FRAUD.jpg
5 img105_GENUINE.jpg
In [22]:
# expand를 True로 하면 n개의 컬럼으로 리턴.
# expand를 False로 하면 1개의 컬럼내에 list로 리턴.
dfSplit = dfSample['path'].str.split('_', expand=False)
print(dfSplit[0][0], dfSplit[0][1])
print(dfSplit[1][0], dfSplit[1][1])
img100 GENUINE.jpg
img101 FRAUD.jpg
In [23]:
dfSplit = dfSample['path'].str.split('_', expand=True)

dfSample['name'] = dfSplit[0]
dfSample['tf'] = dfSplit[1].str.replace('.jpg', '')

dfSample
Out[23]:
path name tf
0 img100_GENUINE.jpg img100 GENUINE
1 img101_FRAUD.jpg img101 FRAUD
2 img102_GENUINE.jpg img102 GENUINE
3 img103_FRAUD.jpg img103 FRAUD
4 img104_FRAUD.jpg img104 FRAUD
5 img105_GENUINE.jpg img105 GENUINE

Submission 데이터만들기

In [24]:
df_submit = pd.read_csv(inputdir+'gender_submission.csv')
print(df_submit.head())
print(df_submit.columns)
   PassengerId  Survived
0          892         0
1          893         1
2          894         0
3          895         0
4          896         1
Index(['PassengerId', 'Survived'], dtype='object')
In [25]:
# 필드값 바꿔서 제출하기
# df_submit.describe()
print('record count=', df_submit.shape[0])
dfsubmit2 = df_submit.copy()
# 원하는 필드값을 변경한다.
dfsubmit2['Survived'] = np.zeros(df_submit.shape[0], dtype=int)
print(dfsubmit2.head())
# dfsubmit2.to_csv('result.csv')
record count= 418
   PassengerId  Survived
0          892         0
1          893         0
2          894         0
3          895         0
4          896         0
In [26]:
# 샘플을 참고하지 않고 직접 만들어 제출하기
pids = df_submit['PassengerId'].values
surv = df_submit['Survived'].values
print(pids.shape)
print(surv.shape)
(418,)
(418,)
In [27]:
dfresult = pd.DataFrame({'PassengerId':pids, 'Survived':surv})
print('columns=', dfresult.columns)
print('index=', dfresult.index)
print(dfresult.head())
columns= Index(['PassengerId', 'Survived'], dtype='object')
index= RangeIndex(start=0, stop=418, step=1)
   PassengerId  Survived
0          892         0
1          893         1
2          894         0
3          895         0
4          896         1
In [28]:
# 경우에 따라 인덱스를 특정 필드로 지정해줘야 되는 서미션도 있음. 제출형식을 확인해야 함.
dfresult.set_index('PassengerId', inplace=True)
print('columns=', dfresult.columns)
print('index=', dfresult.index)
print(dfresult.head())
columns= Index(['Survived'], dtype='object')
index= Int64Index([ 892,  893,  894,  895,  896,  897,  898,  899,  900,  901,
            ...
            1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309],
           dtype='int64', name='PassengerId', length=418)
             Survived
PassengerId          
892                 0
893                 1
894                 0
895                 0
896                 1

matplotlib plot

matplotlib 그래프 좌표축의값 없애기

plt.axis('off')
 axarr[uid].axis('off')
 axarr[uid].set_xticks(p[])
 plt.xticks([])

박스 제거

 ax1 = plt.axes(frameon=False)   # remove box
 or
 ax1 = plt.axes() ;
 ax1.set_frame_on(False)

y축 뒤집기

plt.gca().invert_yaxis()
 # or
 ax=plt.gca()
 ax.set_ylim(ax.get_lim()[::-1])

그래프간 간격 조정

plt.subplots_adjust(hspace=0.5, wspace=0.4)

가로/세로 비율 유지(좌표값을 절대적 기준)

ax.set_aspect('equal', 'box')

직선 그리기 (by 기울기)

def abline(slope, intercept):
     axes = plt.gca()
     x_vals = np.array( axes.get_xlim())
     y_vals = intercept+slope*x_vals
     plt.plot(x_vals, y_vals, 'r--')

plot 파라미터/함수

     lw : 선 두께
     c : 색깔
     s : 사이즈
     alpha : 투명도 (0일 수록 투명. 1일수록 불투명)
     label : legend 출력시 표시
     marker : 표시도형 o, x 등 
     'r--' : 빨간 점선
     'g^' : green 세모
     'ro' : 빨간 o
     'bs' : 파란 네모

     plt.title()
     plt.xlabel()
     plt.ylabel()
     plt.xlim(0,10) : x 범위
     plt.ylim(20,30) : y 범위
     plt.grid() : 눈금 표시
     plt.plot() : 꺽은선 그래프. 좌표들을 연결. lw, c, alpha, label
     plt.scatter() : 산점도 그래프. 좌표에 점(마커)를 찍는다. marker, c, alpha, label, s
     plt.legend() : 비고 박스, edgecolor='r' 로 박스라인 색깔지정 가능

     plt.tight_layout() : 여백없앰
     plt.scatter(x,y, linewidth=1, marker='o', facecolors='none', edgecolors='r')  : 빈 원 그리기
     plt.axhline(y, color='r') : 가로선
     plt.axvline(x, color='b') : 세로선

plot 저장

 plt.figure()
 plt.plot...
 plt.savefig('aaa.png') # 파일로 저장. 화면 출력여부는 아래코드
 plt.show() # 이것을 생략하면 화면 출력 안됨.
 plt.close()

ax 함수

ax.set_title()
 ax.set_xlabel()
 ax.set_ylabel()
 ax.set_xlim()
 ax.set_ylim()

개수 분포 그래프

  • dataframe.value_counts().plot.bar() / plot.pie()
  • sns.countplot()
In [29]:
# scatter 그래프

plt.figure()
# plt.grid('on')
plt.title('age and fare')
flagman=df_train['Sex']=='male'
plt.scatter( df_train.loc[flagman]['Age'], df_train.loc[flagman]['Fare'], c='blue', alpha=0.3, label='male')
flagfemale = ~flagman
plt.scatter( df_train.loc[flagfemale]['Age'], df_train.loc[flagfemale]['Fare'], marker='x', c='red', alpha=0.3, label='female')
plt.axhline(y=200)
plt.xlabel('Age')
plt.ylabel('Fare')
plt.legend(edgecolor='red')  # 비고박스(legend) 외곽라인 색 지정 가능 
plt.show()
plt.close()
In [30]:
# plot . x 라벨 지정 및  회전 
x = [1, 2, 3, 4]
y = [1, 4, 9, 6]
labels = ['Frogs', 'Hogs', 'Bogs', 'Slogs']
plt.plot(x, y)
# You can specify a rotation for the tick labels in degrees or with keywords.
plt.xticks(x, labels, rotation='vertical')
# Pad margins so that markers don't get clipped by the axes
plt.margins(0.2)
# Tweak spacing to prevent clipping of tick-labels
plt.subplots_adjust(bottom=0.15)
plt.show()
plt.close()
In [31]:
# 개수 분포, 그래프
df_train['Survived'].value_counts().plot.bar()
Out[31]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f28ffba2160>
In [32]:
# 카테고리 분포 
df_train['Embarked'].value_counts().plot.pie(autopct='%.2f %%')
plt.legend()
Out[32]:
<matplotlib.legend.Legend at 0x7f28ffb96e80>
In [33]:
# 카테고리 분포. 그룹별. stack bar
dfembarkedsurv = df_train.groupby(['Embarked', 'Survived'])['Survived'].count().unstack('Survived').fillna(0)
dfembarkedsurv.plot(kind='bar', stacked=True)
Out[33]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f28ffafc9b0>
In [34]:
# 여러 그래프를 한 번에 그리기.
# 두 가지 방법이 있다.
# plt.subplots 와 plt.subplot 
#  subplots는 리턴받아 사용. subplot은 리턴값 안받고 그때그때 사용.
# 
# ex) subplot(행,열, 현재번호)
# plt.subplot(1,2,1)
# plot...
# plt.subplot(1,2,2)
# plot...
# ex) f,ax = subplots(행,열)
# plots... by ax[인덱스번호]
# 
# 생존자 비율
# plt.figure()
f, ax = plt.subplots(1,2)

df_train['Survived'].value_counts().plot.pie(explode=[0, 0.1], autopct='%.2f%%', ax=ax[0], shadow=True)
ax[0].set_title('Survived ratio')
ax[0].set_ylabel('')

# Survived 컬럼 카운트 (dataframe plot보다 이쁨)
sns.countplot('Survived', data=df_train, ax=ax[1])
Out[34]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f28ffa24b38>
In [35]:
# 위와 같은 그림을 다른 방식으로
plt.figure(figsize=(2*5,5))
plt.suptitle('Bit Title', fontsize='x-large')

plt.subplot(1,2,1)
plt.title('title1')
xs = df_train['Survived'].value_counts()
print(xs.values)
df_train['Survived'].value_counts().plot.pie(autopct='%.2f %%', labels=['Dead', 'Survived'])  #autopct='%.2f %%'

plt.subplot(1,2,2)
plt.title('title2')
sns.countplot('Survived', data=df_train)

plt.show()
[549 342]
In [36]:
# 가로축에 값이 많은 경우, 글씨가 안보임. 글씨 회전
import random
# 랜덤 스트링 분포도
rs=[]
rs2=[]
for i in range(1000):
    c = chr(np.random.randint(0, 26)+ord('A'))  # 주의! random.randint(0,26) 이 아니다. np.random.randint와 사용방식이 다름!
    rs.append(c)
    c = chr(random.randint(0, 25)+ord('A'))  # random.randint는 마지막값이 범위에 포함된다!!! 
    rs2.append(c)
# print(rs)
# print(rs2)

from collections import Counter

# +
counter1 = Counter(rs)
dfc1 = pd.DataFrame([ [x1,x2] for x1,x2 in counter1.items() ], columns=['Letter', 'Count'])
dfc1 = dfc1.sort_values('Count', ascending=False)

plt.figure()
# sns.barplot(dfc1['Letter'], dfc1['Count'], color='blue', label='LetterCount')
sns.barplot(dfc1['Letter'], dfc1['Count'], label='LetterCount') # 색상이 없으면 무지개색 
plt.show()
In [37]:
# x 축을 일치시키고 y값 비교하기 / x축 회전 rotation

dfc1 = dfc1.sort_values('Letter', ascending=True)

counter2 = Counter(rs2)
dfc2 = pd.DataFrame([ [x1,x2] for x1,x2 in counter2.items() ], columns=['Letter', 'Count'])
dfc2 = dfc2.sort_values('Letter', ascending=True)
xvalue = dfc1['Letter']

plt.figure(figsize=(8, 6))
plt.title('Letter Count')
plt.xticks(rotation=90)   # x 라벨 회전. (글자가 겹칠때 유용함)
sns.barplot(xvalue, dfc1['Count'], color='blue', alpha=0.5, label='by np')
sns.barplot(xvalue, dfc2['Count'], color='red', alpha=0.5, label='by random')
plt.legend()
plt.show()
    
# -

그룹별 카운팅

  • dataframe.groupby() : array로 여러개 가능
  • sns.countplot() : hue
  • dataframe.crosstab() : 표생성. 세로필드, 가로필드. (세로필드를 array로 어러개 가능)
  • sns.factorplot(x,y,hue) : y평균값 그래프. hue로 지정된 필드의 종류만큼 라인이 그려짐.
  • sns.violinplot(x,y,hue) : y값의 범위와 분포를 알 수 있는 그래프.
In [38]:
# 성별과 생존 관계
df_train.groupby(['Sex', 'Survived'])['Survived'].count()
Out[38]:
Sex     Survived
female  0            81
        1           233
male    0           468
        1           109
Name: Survived, dtype: int64
In [39]:
sns.countplot('Sex', hue='Survived', data=df_train)
Out[39]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f28ff7fa278>
In [40]:
sns.countplot('Embarked', hue='Sex', data=df_train)
Out[40]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f28ff78f898>
In [41]:
pltconfig_check()
figure.edgecolor white (1, 1, 1, 0)
figure.dpi 100.0 72.0
figure.figsize [6.4, 4.8] [6.0, 4.0]
figure.facecolor white (1, 1, 1, 0)
interactive False True
figure.subplot.bottom 0.11 0.125
In [42]:
# 두 개의 기준으로 groupby한 카운팅
pd.crosstab(df_train['Sex'], df_train['Survived'], margins=True).style.background_gradient(cmap='summer_r')
Out[42]:
Survived 0 1 All
Sex
female 81 233 314
male 468 109 577
All 549 342 891
In [43]:
## 피클래스와 생존 관계
pd.crosstab(df_train['Pclass'], df_train['Survived'], margins=True).style.background_gradient(cmap='summer_r')
Out[43]:
Survived 0 1 All
Pclass
1 80 136 216
2 97 87 184
3 372 119 491
All 549 342 891
In [44]:
sns.countplot('Pclass', hue='Survived', data=df_train)
Out[44]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f28ff1d3828>
In [45]:
## 성별과 피클래스에 따른 생존
In [46]:
pd.crosstab([df_train.Sex, df_train.Pclass], df_train.Survived, margins=True).style.background_gradient(cmap='summer_r')
Out[46]:
Survived 0 1 All
Sex Pclass
female 1 3 91 94
2 6 70 76
3 72 72 144
male 1 77 45 122
2 91 17 108
3 300 47 347
All 549 342 891
In [47]:
pd.crosstab([df_train.Sex, df_train.Survived], df_train.Pclass, margins=True).style.background_gradient(cmap='summer_r')
Out[47]:
Pclass 1 2 3 All
Sex Survived
female 0 3 6 72 81
1 91 70 72 233
male 0 77 91 300 468
1 45 17 47 109
All 216 184 491 891
In [48]:
## 평균 꺽은선 그래프
In [49]:
sns.factorplot('Pclass', 'Survived', hue='Sex', data=df_train)
Out[49]:
<seaborn.axisgrid.FacetGrid at 0x7f28ff75a278>
In [50]:
sns.factorplot('Pclass', 'Age', hue='Sex', data=df_train)
Out[50]:
<seaborn.axisgrid.FacetGrid at 0x7f2935cdef60>
In [51]:
sns.violinplot('Pclass', 'Age', hue='Survived', data=df_train, split=True)
Out[51]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f2934c07a90>
In [52]:
pltconfig_check()
figure.edgecolor white (1, 1, 1, 0)
figure.dpi 100.0 72.0
figure.figsize [6.4, 4.8] [6.0, 4.0]
figure.facecolor white (1, 1, 1, 0)
interactive False True
figure.subplot.bottom 0.11 0.125

히스토그램

  • dataframe.plot.hist(bins=count, color='blue')
  • sns.FaceGrid(data, hue), map, plt.hist : hue를 주면 hue로 지정된 필드의 종류별로 겹침.
In [53]:
# +
# df_train['Age'].value_counts()

# +
# 히스토그램. 두 개 비교.

# 연령대별 생존자 수, 사망자 수 2개 그래프 겹침 
grid = sns.FacetGrid(df_train, hue='Survived', size=4)
# bins는 개수로 지정할 수 도 있지만, 구간을 입력할 수도 있다.
grid.map(plt.hist, 'Age', alpha=.6, rwidth=0.8, bins=[0,10,20,30,40,50,60,70,80,90,100])
# bins 구간에 맞추어 x tick을 지정해 준다.
xlist=list(range(0, 110, 10))
print(xlist)
plt.xticks(xlist)
grid.add_legend()
[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
Out[53]:
<seaborn.axisgrid.FacetGrid at 0x7f2934ba26d8>
In [54]:
# 위 히스토그램을 각각 그리기
grid = sns.FacetGrid(df_train, col='Survived', size=4, margin_titles=True)
grid.map(plt.hist, 'Age', bins=[0,10,20,30,40,50,60,70,80,90,100], color='green', histtype='step') # histtype 생략시(default='bar') 색칠한 일반 모양
# title을 value로 지정
# grid.set_titles(row_template='{row_name}', col_template='{col_name}')  # 이것을 생략하면 제목은 알아서 column=value가 된다. 
Out[54]:
<seaborn.axisgrid.FacetGrid at 0x7f28ffcd70b8>
In [55]:
# 히스토그램. 
df_train[ df_train['Survived']==0 ].Age.plot.hist(bins=20, color='red', rwidth=0.9)  
# rwidth (0~1)범위로 가로크기 비율을 정해 여백을 줄 수 있다.
xlist = list(range(0, 85, 5))
plt.xticks(xlist)
plt.margins(x=0)  # 안쪽 x 마진 제거
plt.show()
In [56]:
# FacetGrid로 가로로 여러 그래프 그리기(그룹/컬럼별)
grid = sns.FacetGrid(df_train, col='Embarked', size = 3)
grid.map(sns.barplot, 'Sex', 'Survived', palette='deep', order=['female','male'])  
# order가 없으면 male, female 순으로 나온다. 
Out[56]:
<seaborn.axisgrid.FacetGrid at 0x7f28ff811cf8>

상관계수

In [57]:
# Dataframe 상관계수 테이블 correlation 
df_num.corr()
Out[57]:
Pclass Age SibSp Parch Fare
Pclass 1.000000 -0.408106 0.060832 0.018322 -0.558629
Age -0.408106 1.000000 -0.243699 -0.150917 0.178740
SibSp 0.060832 -0.243699 1.000000 0.373587 0.160238
Parch 0.018322 -0.150917 0.373587 1.000000 0.221539
Fare -0.558629 0.178740 0.160238 0.221539 1.000000
In [58]:
# 상관계수 히트맵 
sns.heatmap( df_train.drop('PassengerId', axis=1).corr(), annot=True)
Out[58]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f28ff880ac8>
In [59]:
cols = ['Survived', 'SibSp', 'Parch', 'Fare']
cm = np.corrcoef(df_train[cols].values.T)
sns.set(font_scale=1.25)
hm = sns.heatmap(cm, cbar=True, annot=True, square=True, 
  fmt='.2f', annot_kws={'size':10} , yticklabels=cols, xticklabels=cols)
In [60]:
# 컬럼별 2차원 데이터 분포도. scatter, histogram.
sns.set()
cols=['Age', 'Survived', 'Fare']
sns.pairplot(df_train[cols], size=2.5)
plt.show()

pltconfig_check()
grid.color #b0b0b0 white
patch.force_edgecolor False True
lines.solid_capstyle projecting round
ytick.color black .15
xtick.minor.width 0.6 1.0
patch.edgecolor black w
font.size 10.0 12.0
xtick.labelsize medium 11.0
ytick.major.size 3.5 6.0
axes.titlesize large 12.0
axes.linewidth 0.8 1.25
xtick.color black .15
axes.facecolor white #EAEAF2
axes.prop_cycle cycler('color', ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf']) cycler('color', [(0.2980392156862745, 0.4470588235294118, 0.6901960784313725), (0.8666666666666667, 0.5176470588235295, 0.3215686274509804), (0.3333333333333333, 0.6588235294117647, 0.40784313725490196), (0.7686274509803922, 0.3058823529411765, 0.3215686274509804), (0.5058823529411764, 0.4470588235294118, 0.7019607843137254), (0.5764705882352941, 0.47058823529411764, 0.3764705882352941), (0.8549019607843137, 0.5450980392156862, 0.7647058823529411), (0.5490196078431373, 0.5490196078431373, 0.5490196078431373), (0.8, 0.7254901960784313, 0.4549019607843137), (0.39215686274509803, 0.7098039215686275, 0.803921568627451)])
text.color black .15
interactive False True
xtick.minor.size 2.0 4.0
ytick.major.width 0.8 1.25
xtick.bottom True False
ytick.minor.width 0.6 1.0
figure.edgecolor white (1, 1, 1, 0)
figure.dpi 100.0 72.0
axes.labelsize medium 12.0
figure.figsize [6.4, 4.8] [6.0, 4.0]
axes.axisbelow line True
grid.linewidth 0.8 1.0
font.sans-serif ['DejaVu Sans', 'Bitstream Vera Sans', 'Computer Modern Sans Serif', 'Lucida Grande', 'Verdana', 'Geneva', 'Lucid', 'Arial', 'Helvetica', 'Avant Garde', 'sans-serif'] ['Arial', 'DejaVu Sans', 'Liberation Sans', 'Bitstream Vera Sans', 'sans-serif']
legend.fontsize medium 11.0
figure.subplot.bottom 0.11 0.125
xtick.major.width 0.8 1.25
axes.edgecolor black white
ytick.labelsize medium 11.0
axes.grid False True
patch.facecolor C0 (0.2980392156862745, 0.4470588235294118, 0.6901960784313725)
ytick.minor.size 2.0 4.0
axes.labelcolor black .15
ytick.left True False
xtick.major.size 3.5 6.0
image.cmap viridis rocket

Evaluation

In [61]:
#  confusion_matrix( real, predict ) : real vs predict 결과 비교. 대각선이 많을수록 맞춘것임.

from sklearn.metrics import confusion_matrix

y_real=[]
y_predict=[]
for i in range(1000):
    v = np.random.randint(0, 10)
    y_real.append(v)
    if np.random.rand()<0.8:
        y_predict.append( np.random.randint(0, 10))
    else:
        y_predict.append(v)
cm = confusion_matrix(y_real, y_predict)  # row=real, column=predict
cm
Out[61]:
array([[21,  8,  7,  8,  9,  7,  7,  7,  6,  7],
       [12, 15,  4,  9,  6, 10, 10, 12,  6,  2],
       [ 7, 10, 33,  5, 10,  8,  8,  6,  9,  8],
       [ 9, 13,  7, 27,  9,  8,  9,  6, 14, 10],
       [ 6, 10, 10,  7, 41, 13, 12,  6,  8,  8],
       [ 6,  9,  9,  7,  3, 29,  9,  8, 14,  5],
       [14,  7,  6, 11,  7, 12, 23, 10,  7,  7],
       [15, 10, 11,  8,  7,  4,  6, 22,  4,  6],
       [ 9,  5,  8,  6,  5,  9,  4,  8, 34, 11],
       [ 6,  8,  4,  6,  9,  7, 12,  8,  4, 31]])
In [62]:
# draw confusion matrix with seaborn
df_cm = pd.DataFrame(cm, index=range(10),
                  columns=range(10))
# plt.figure(figsize = (10,7))
# sns.set(font_scale=1.4)  # for label size. 변경시 다른 plot도 전부 영향을 받음.
sns.heatmap(df_cm, annot=True,annot_kws={"size": 10})  # font size
# sns.set(font_scale=1.0) # back to the default font size.... 
# 설정 변경시 이후 다른 plot 환경 변화로 문제가 발생.
Out[62]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f29349d73c8>
In [63]:
pltconfig_check()
grid.color #b0b0b0 white
patch.force_edgecolor False True
lines.solid_capstyle projecting round
ytick.color black .15
xtick.minor.width 0.6 1.0
patch.edgecolor black w
font.size 10.0 12.0
xtick.labelsize medium 11.0
ytick.major.size 3.5 6.0
axes.titlesize large 12.0
axes.linewidth 0.8 1.25
xtick.color black .15
axes.facecolor white #EAEAF2
axes.prop_cycle cycler('color', ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf']) cycler('color', [(0.2980392156862745, 0.4470588235294118, 0.6901960784313725), (0.8666666666666667, 0.5176470588235295, 0.3215686274509804), (0.3333333333333333, 0.6588235294117647, 0.40784313725490196), (0.7686274509803922, 0.3058823529411765, 0.3215686274509804), (0.5058823529411764, 0.4470588235294118, 0.7019607843137254), (0.5764705882352941, 0.47058823529411764, 0.3764705882352941), (0.8549019607843137, 0.5450980392156862, 0.7647058823529411), (0.5490196078431373, 0.5490196078431373, 0.5490196078431373), (0.8, 0.7254901960784313, 0.4549019607843137), (0.39215686274509803, 0.7098039215686275, 0.803921568627451)])
text.color black .15
interactive False True
xtick.minor.size 2.0 4.0
ytick.major.width 0.8 1.25
xtick.bottom True False
ytick.minor.width 0.6 1.0
figure.edgecolor white (1, 1, 1, 0)
figure.dpi 100.0 72.0
axes.labelsize medium 12.0
figure.figsize [6.4, 4.8] [6.0, 4.0]
axes.axisbelow line True
grid.linewidth 0.8 1.0
font.sans-serif ['DejaVu Sans', 'Bitstream Vera Sans', 'Computer Modern Sans Serif', 'Lucida Grande', 'Verdana', 'Geneva', 'Lucid', 'Arial', 'Helvetica', 'Avant Garde', 'sans-serif'] ['Arial', 'DejaVu Sans', 'Liberation Sans', 'Bitstream Vera Sans', 'sans-serif']
legend.fontsize medium 11.0
figure.subplot.bottom 0.11 0.125
xtick.major.width 0.8 1.25
axes.edgecolor black white
ytick.labelsize medium 11.0
axes.grid False True
patch.facecolor C0 (0.2980392156862745, 0.4470588235294118, 0.6901960784313725)
ytick.minor.size 2.0 4.0
axes.labelcolor black .15
ytick.left True False
xtick.major.size 3.5 6.0
image.cmap viridis rocket
In [64]:
pltconfig_default()
pltconfig_check()
figure.edgecolor white (1, 1, 1, 0)
figure.dpi 100.0 72.0
figure.figsize [6.4, 4.8] [6.0, 4.0]
figure.facecolor white (1, 1, 1, 0)
interactive False True
figure.subplot.bottom 0.11 0.125
In [65]:
import itertools

def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    plt.figure()
    plt.grid('off')
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]

    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, cm[i, j],
                 horizontalalignment="center", verticalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
In [66]:
plot_confusion_matrix(cm, classes=range(10))
plt.show()
plt.close()
In [67]:
pltconfig_check()
figure.edgecolor white (1, 1, 1, 0)
figure.dpi 100.0 72.0
figure.figsize [6.4, 4.8] [6.0, 4.0]
figure.facecolor white (1, 1, 1, 0)
interactive False True
figure.subplot.bottom 0.11 0.125
In [ ]:
 
In [ ]:
 
반응형
googledriveapi

Upload File to Google Drive

Prepare

구글 사이트에서 준비 작업이 필요하다.
https://console.developers.google.com/flows/enableapi?apiid=drive
프로젝트 생성
Google Drive API 사용.
Credential에서 OAuth 화면.
Product Name 입력.
json 파일 다운 로드 (client_drive.json).
작업디렉터리로 파일 이동.

# 파이썬 패키지 설치
pip install google-api-python-client

토큰 생성

from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

scopes = 'https://www.googleapis.com/auth/drive.file'
store = file.Storage('storage.json')
creds = store.get()

try :
    import argparse
    flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args()
except ImportError:
    flags = None

if not creds or creds.invalid:
    print('make new cred')
    flow = client.flow_from_clientsecrets('client_drive.json', scopes)
    creds = tools.run_flow(flow, store, flags) if flags else tools.run_flow(flow, store)


콘솔로 위의 파일을 실행하면, 웹브라우저가 뜨고, 구글 인증/로그인을 하면 된다. 현재 폴더에 storage.json 이라는 토큰이 생김. 보안 파일이므로 중요보관.

파일 업로드

from oauth2client.client import GoogleCredentials
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client import file, client, tools

store = file.Storage('storage.json')
creds = store.get()
drive = build('drive', 'v3', http=creds.authorize(Http()))
uploadfiles=( ('a.txt'),)
for f in uploadfiles:
    fname = f
    metadata={'name':fname, 'mimeType':None}
    res = drive.files().create(body=metadata, media_body=fname).execute()
    if res:
        print('upload %s'%fname)
        

파일 다운로드

파일ID는 구글드라이브에서 해당 파일 공유하기해서 링크 주소를 얻어오면 id값이 들어있다.

import io
from apiclient.http import MediaIoBaseDownload

results = drive.files().list(pageSize=10,fields="nextPageToken, files(id, name)").execute()
items = results.get('files', [])
if not items:
    print('No files found.')
else:
    print('Files:')
    for item in items:
        print(item)
        print('{0} ({1})'.format(item['name'], item['id']))

#https://drive.google.com/open?id=1SY8FS1QcGTknYJjEUgaqj1ucWEtESTn3
# request = drive.files().export_media(fileId='a.txt', mimeType=EXCEL)
request = drive.files().get_media(fileId='1SY8FS1QcGTknYJjEUgaqj1ucWEtESTn3')
fh = io.FileIO('b.txt', 'wb')
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
    status, done = downloader.next_chunk()
    print('Download %d%%.' % int(status.progress() * 100))
        

CoLab에서 구글 드라이브 파일 가져오기


# Install the PyDrive wrapper & import libraries.  
# This only needs to be done once per notebook. 
!pip install -U -q PyDrive 
from pydrive.auth import GoogleAuth 
from pydrive.drive import GoogleDrive 
from google.colab import auth 
from oauth2client.client import GoogleCredentials 

# Authenticate and create the PyDrive client.  
# This only needs to be done once per notebook. 
auth.authenticate_user() 
gauth = GoogleAuth() 
gauth.credentials = GoogleCredentials.get_application_default() 
drive = GoogleDrive(gauth) 

# Download a file based on its file ID.  
#  
# A file ID looks like: laggVyWshwcyP6kEI-y_W3P8D26sz 
file_id = 'REPLACE_WITH_YOUR_FILE_ID' 
downloaded = drive.CreateFile({'id': file_id}) print('Downloaded content "{}"'.format(downloaded.GetContentString()))  

  


Written with StackEdit.

'Python' 카테고리의 다른 글

Jupyter Notebook 멀티라인출력  (0) 2019.09.19
진행(progress)바/ tqdm  (2) 2019.08.28
Fourier Transform Python  (1) 2019.08.02
[UI] Qt5  (0) 2019.05.17
두 선분의 교차여부 체크  (0) 2019.04.11
반응형
java_rsa_test

JAVA RSA Test

RSA 알고리즘으로 JAVA에서 키쌍(공개키, 개인키)를 생성해 보고,
암복호화 및 서명 검증 테스트를 해보자.

package test_tryexcept;

import java.io.*;
import java.security.*;
import java.security.spec.*;
import javax.crypto.*;
import org.apache.commons.codec.binary.Base64;

public class RSATest {

	public static void main(String[] args) throws IllegalBlockSizeException, BadPaddingException {

		// Create Key Pair . (public key, private key)
		System.out.println("1. create key pair -----------------------------");
		PublicKey publicKey1 = null;
		PrivateKey privateKey1 = null;

		SecureRandom secureRandom = new SecureRandom();
		KeyPairGenerator keyPairGenerator;
		try {
			keyPairGenerator = KeyPairGenerator.getInstance("RSA");
			keyPairGenerator.initialize(512, secureRandom);

			KeyPair keyPair = keyPairGenerator.genKeyPair();
			publicKey1 = keyPair.getPublic();
			privateKey1 = keyPair.getPrivate();

			KeyFactory keyFactory1 = KeyFactory.getInstance("RSA");
			RSAPublicKeySpec rsaPublicKeySpec = keyFactory1.getKeySpec(publicKey1, RSAPublicKeySpec.class);
			RSAPrivateKeySpec rsaPrivateKeySpec = keyFactory1.getKeySpec(privateKey1, RSAPrivateKeySpec.class);
			System.out.println("Public  key modulus : " + rsaPublicKeySpec.getModulus());
			System.out.println("Public  key exponent: " + rsaPublicKeySpec.getPublicExponent());
			System.out.println("Private key modulus : " + rsaPrivateKeySpec.getModulus());
			System.out.println("Private key exponent: " + rsaPrivateKeySpec.getPrivateExponent());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		}

		// 2. key save to file. (base64 encoding)
		System.out.println("\n2. save key file -----------------------------");
		byte[] bPublicKey1 = publicKey1.getEncoded();
		String sPublicKey1 = Base64.encodeBase64String(bPublicKey1);
		byte[] bPrivateKey1 = privateKey1.getEncoded();
		String sPrivateKey1 = Base64.encodeBase64String(bPrivateKey1);

		try {
			BufferedWriter bw1 = new BufferedWriter(new FileWriter("PublicKey.txt"));
			bw1.write(sPublicKey1);
			bw1.newLine();
			bw1.close();
			BufferedWriter bw2 = new BufferedWriter(new FileWriter("PrivateKey.txt"));
			bw2.write(sPrivateKey1);
			bw2.newLine();
			bw2.close();
			System.out.println("PublicKey.txt, PrivateKey.txt file saved.") ;
		} catch (IOException e) {
			e.printStackTrace();
		}

		// 3. load key file
		System.out.println("\n3. load key file -----------------------------");
		String sPublicKey2 = null;
		String sPrivateKey2 = null;

		BufferedReader brPublicKey = null;
		BufferedReader brPrivateKey = null;
		try {
			brPublicKey = new BufferedReader(new FileReader("PublicKey.txt"));
			sPublicKey2 = brPublicKey.readLine();
			brPrivateKey = new BufferedReader(new FileReader("PrivateKey.txt"));
			sPrivateKey2 = brPrivateKey.readLine();
			System.out.println("load PubilcKey.txt, PrivateKey.txt");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (brPublicKey != null)
					brPublicKey.close();
				if (brPrivateKey != null)
					brPrivateKey.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		// key string to key data. 
		byte[] bPublicKey2 = Base64.decodeBase64(sPublicKey2.getBytes());
		PublicKey publicKey2 = null;
		byte[] bPrivateKey2 = Base64.decodeBase64(sPrivateKey2.getBytes());
		PrivateKey privateKey2 = null;
		try {
			KeyFactory keyFactory2 = KeyFactory.getInstance("RSA");
			X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(bPublicKey2);
			publicKey2 = keyFactory2.generatePublic(publicKeySpec);
			PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(bPrivateKey2);
			privateKey2 = keyFactory2.generatePrivate(privateKeySpec);
		} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
			e.printStackTrace();
		}

		// 4. encrypt test
		System.out.println("\n4. encrypt test -----------------------------");

		String sPlain1 = "This is an example.";
		String sPlain2 = null;
		try {
			Cipher cipher = Cipher.getInstance("RSA");
			System.out.println("input:"+ sPlain1);
			// 공개키 이용 암호화
			cipher.init(Cipher.ENCRYPT_MODE, publicKey2);
			byte[] bCipher1 = cipher.doFinal(sPlain1.getBytes());
			String sCipherBase64 = Base64.encodeBase64String(bCipher1);
			System.out.println("encrypt(pubkey):"+sCipherBase64);

			// 개인키 이용 복호화
			byte[] bCipher2 = Base64.decodeBase64(sCipherBase64.getBytes());
			cipher.init(Cipher.DECRYPT_MODE, privateKey2);
			byte[] bPlain2 = cipher.doFinal(bCipher2);
			sPlain2 = new String(bPlain2);
			System.out.println("decrypt(prikey):"+sPlain2);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}

		///////////////////////////////////////////////////////////////////////
		// 5. digital sign test
		System.out.println("\n5. digital sign test -----------------------------");
		try {
			Cipher cipher = Cipher.getInstance("RSA");
			
			// sign
			Signature rsa = Signature.getInstance("SHA1withRSA"); 
			rsa.initSign(privateKey2);
			rsa.update(sPlain1.getBytes());
			byte[] ds = rsa.sign();
			
			String dsBase64 = Base64.encodeBase64String(ds) ;
			System.out.println("signature:"+dsBase64);
			
			// verify by pubkey
			rsa.initVerify(publicKey2);
			rsa.update(sPlain1.getBytes());
			boolean bret = rsa.verify(ds);
			System.out.println("verify:"+bret);
			
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (SignatureException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

결과

1. create key pair -----------------------------
Public  key modulus : 8248696551746632304090375750090525095455249159692340933778807179048823058050266268679997440009797868855529133651252439721233111988778274617606294142148157
Public  key exponent: 65537
Private key modulus : 8248696551746632304090375750090525095455249159692340933778807179048823058050266268679997440009797868855529133651252439721233111988778274617606294142148157
Private key exponent: 7921703957617548721899753716754620427893524678607141706686365641426276369846256193464100508658766225776306979668612467878281049443630080785215985430577793

2. save key file -----------------------------
PublicKey.txt, PrivateKey.txt file saved.

3. load key file -----------------------------
load PubilcKey.txt, PrivateKey.txt

4. encrypt test -----------------------------
input:This is an example.
encrypt(pubkey):NHeP0KvZpgqd/yE5HEbh5v/kuOP6jvKE8+y9wJb1p7Nt0SOlJrFrtkn+i+75h2d2EiSBZBxBAMErsG7wp6BN3A==
decrypt(prikey):This is an example.

5. digital sign test -----------------------------
signature:KSsmktqxCDjmy4mHMxT+aUb/y2m7b4B9zq1jxMixGs7J8dPTqyKD5LJkXgNwIm4pY6JIn9YotxwyWUP3hjzaXA==
verify:true

Written with StackEdit.

반응형
TensorBoardRemote

Jupyter Lab/ TensorBoard remote monitoring through firewall

서버 방화벽으로 6006포트가 막힌 원격 PC에서 서버의 텐서보드를 모니터링하는 방법! & 같은 방법으로 서버의 jupyter lab을 원격 PC에서 여러 개 접속하기

서버 환경에서 python 코드를 돌려 tensorboard 로그가 쌓이고 있는 상황에서 서버에서 tensorboard를 보려면 일단 텐서보드 서버를 아래와 같이 실행한다. (로그 경로 지정)

$ tensorboard --logdir="./log"

이렇게 로그 폴더만 지정해 주고, 서버의 웹 브라우저에서
http://localhost:6006 으로 접속하면 된다.

그리고 해당 서버의 6006 포트가 방화벽으로 막혀 있지 않다면 원격 PC에서 위 http 주소에 localhost대신 서버 ip를 지정해주면 볼 수 있다.

만약 방화벽으로 막혀있으면 당연 접속이 안될 것인데, 우회하는 방법이 있다.

원리는 바로 ssh로 port forwarding을 이용하는 것이다. (당연히 서버에 ssh 포트는 방화벽으로 열려있어야 한다.)

위와 같은 조건에서 PC에 16006 포트를 만들고 이 포트와 서버의 6006 포트를 ssh로 연결한다.

PC에서 서버로 ssh 접속을 다음과 같이 한다. (윈도우면 cmd창을 띄우고 작업)

 ssh -L 16006:localhost:6006 [ID]@[ServerIP]

서버의 ssh 포트번호가 22가 아니면 -p [port] 를 추가한다.
ssh 접속이 완료되면, PC에서 브라우저를 띄우고 아래 주소로 접속
http://localhost:16006
이미지 001

Jupyter Lab Remote Connect

Jupyter Lab이나 Jupyter Notebook도 마찬가지로 서버의 로컬에서만 접속 가능한 경우에 원격 접속을 위해 동일하게 처리할 수 있다.
먼저 안전하게 설정 파일 생성과 접속암호를 아래와 같이 만든다.

$jupyter notebook --generate-config
$jupyter notebook password
암호 입력

암호 설정 방법은 수동으로도 할 수 있다. ~/.jupyter/ 폴더 내에 생성된 설정 파일을 보면 복잡하지만 가능하다. 간단하게 하려면 위 방식을 이용하자.

서버에서 작업할 디렉터리로 이동 후, 쥬피터 랩 실행

$ jupyter lab
... http://localhost:port ...

위와 같이 포트 번호를 안내해 준다. 이미 할당되어 있으면 변경되므로 확인.
(쥬피터를 디렉터리를 달리하여 여러 개 실행할 수도 있다.)

PC에서 서버로 ssh 접속을 다음과 같이 한다. (윈도우면 cmd창을 띄우고 작업) -L 뒤에 PC포트:localhost:서버포트
서버 포트는 서버 연결포트이니 당연히 쥬피터 포트를 보고 입력해 준다.

 ssh -L 8890:localhost:8890 [ID]@[ServerIP]

PC에서 로컬호스트의 생성한 PC포트로 접속한다. (위와 같이 PC포트 서버 포트가 일치할 필요는 없다. 로컬 포트는 할당되지 않은 임의의 포트로 지정해도 된다.)
http://localhost:8890
암호를 입력하고 연결하면 된다.

jupyterlab

Written with StackEdit.

반응형
fourier_transform

Fourier Transform

푸리에 변환

푸리에 변환은 연속적인 시계열 데이터를 sin, cos 함수들과 같은 파형들의 합으로 나타내는 것으로 여러 개의 주파수 성분들로 분해하는 작업이다.
주로 신호 처리나 사운드, 이미지와 같은 데이터의 주파수 변환에 많이 사용한다.
그렇다면 어떻게 분해를 할 수 있는 것일까?
여기서는 이론적인 이해가 아닌 프로그래밍 구현측면에서 접근하도록 한다.
drawingfft2
위 그림은 도형 이미지를 시간에 따른 x, y 좌표 리스트로 나누어 x, y 각각을 주파수 분해한 다음 분해된 주파수들을 하나씩 결합하여 그린 모양이다. 주파수를 하나씩 더 했을 때 점점 원본에 닮아가는 것을 확인할 수 있다.
노이즈가 섞인 원본 신호라면 주파수 분해 후 적절한 신호의 재결합을 통해 노이즈가 제거되는 효과도 나타날 수 있을 것이다.

도구

가장 쉽게 접근할 수 있는 것은 python의 numpy나 scipy 라이브러리로 쉽게 원하는 작업을 할 수 있다. cpp로 된 라이브러리도 google에서 검색하면 금방 찾을 수 있다.

해결하려는 문제

시계열 데이터를 주파수 성분으로 분해하고 분해된 수치 정보만으로 원본을 복구하는 작업을 수행하고자 한다.

알 수 없는 시그널

시간값과 신호크기만 있는 시계열 데이터가 있다고 하자.
fft02

'''  
foutier transform  
'''  
  
import numpy as np  
import matplotlib.pyplot as plt  
  
txlist = [(0.0, -0.1729957805907173), (0.0045871559633027525, -0.189873417721519), (0.009174311926605505, -0.2236286919831224), (0.013761467889908258, -0.2742616033755274), (0.01834862385321101, -0.3080168776371308), (0.022935779816513763, -0.3502109704641351), (0.027522935779816515, -0.4092827004219409), (0.03211009174311927, -0.4345991561181435), (0.03669724770642202, -0.47679324894514763), (0.04128440366972477, -0.510548523206751), (0.045871559633027525, -0.5527426160337553), (0.05045871559633028, -0.5864978902953586), (0.05504587155963303, -0.620253164556962), (0.05963302752293578, -0.6371308016877637), (0.06422018348623854, -0.6540084388185654), (0.06880733944954129, -0.6793248945147679), (0.07339449541284404, -0.6877637130801688), (0.0779816513761468, -0.6877637130801688), (0.08256880733944955, -0.6877637130801688), (0.0871559633027523, -0.6708860759493671), (0.09174311926605505, -0.6540084388185654), (0.0963302752293578, -0.6286919831223629), (0.10091743119266056, -0.5949367088607596), (0.10550458715596331, -0.5864978902953586), (0.11009174311926606, -0.5527426160337553), (0.11467889908256881, -0.5274261603375527), (0.11926605504587157, -0.5021097046413502), (0.12385321100917432, -0.4345991561181435), (0.12844036697247707, -0.4092827004219409), (0.13302752293577982, -0.3502109704641351), (0.13761467889908258, -0.24894514767932485), (0.14220183486238533, -0.11392405063291144), (0.14678899082568808, 0.029535864978903037), (0.15137614678899083, 0.03797468354430378), (0.1559633027522936, 0.139240506329114), (0.16055045871559634, 0.28270042194092837), (0.1651376146788991, 0.4430379746835442), (0.16972477064220184, 0.5021097046413503), (0.1743119266055046, 0.5527426160337552), (0.17889908256880735, 0.620253164556962), (0.1834862385321101, 0.6624472573839661), (0.18807339449541285, 0.6962025316455696), (0.1926605504587156, 0.729957805907173), (0.19724770642201836, 0.7805907172995781), (0.2018348623853211, 0.8227848101265822), (0.20642201834862386, 0.8481012658227849), (0.21100917431192662, 0.8481012658227849), (0.21559633027522937, 0.8312236286919832), (0.22018348623853212, 0.7974683544303798), (0.22477064220183487, 0.7890295358649788), (0.22935779816513763, 0.7721518987341771), (0.23394495412844038, 0.7552742616033756), (0.23853211009174313, 0.7215189873417722), (0.24311926605504589, 0.7046413502109705), (0.24770642201834864, 0.6877637130801688), (0.25229357798165136, 0.6540084388185654), (0.25688073394495414, 0.620253164556962), (0.26146788990825687, 0.5611814345991561), (0.26605504587155965, 0.4599156118143459), (0.2706422018348624, 0.36708860759493667), (0.27522935779816515, 0.31645569620253156), (0.2798165137614679, 0.24894514767932496), (0.28440366972477066, 0.1898734177215189), (0.2889908256880734, 0.11392405063291133), (0.29357798165137616, 0.09704641350210963), (0.2981651376146789, 0.029535864978903037), (0.30275229357798167, -0.04641350210970463), (0.3073394495412844, -0.18143459915611815), (0.3119266055045872, -0.24894514767932485), (0.3165137614678899, -0.19831223628691985), (0.3211009174311927, -0.13080168776371304), (0.3256880733944954, -0.06329113924050633), (0.3302752293577982, 0.012658227848101333), (0.3348623853211009, 0.08860759493670889), (0.3394495412844037, 0.139240506329114), (0.3440366972477064, 0.2067510548523206), (0.3486238532110092, 0.240506329113924), (0.3532110091743119, 0.2742616033755274), (0.3577981651376147, 0.31645569620253156), (0.3623853211009174, 0.33333333333333326), (0.3669724770642202, 0.35021097046413496), (0.37155963302752293, 0.3586497890295359), (0.3761467889908257, 0.39240506329113933), (0.38073394495412843, 0.40928270042194104), (0.3853211009174312, 0.4008438818565401), (0.38990825688073394, 0.2911392405063291), (0.3944954128440367, 0.23206751054852326), (0.39908256880733944, 0.1898734177215189), (0.4036697247706422, 0.14767932489451474), (0.40825688073394495, 0.08016877637130793), (0.41284403669724773, 0.021097046413502074), (0.41743119266055045, -0.08860759493670889), (0.42201834862385323, -0.16455696202531644), (0.42660550458715596, -0.24894514767932485), (0.43119266055045874, -0.3502109704641351), (0.43577981651376146, -0.4008438818565401), (0.44036697247706424, -0.49367088607594933), (0.44495412844036697, -0.5780590717299579), (0.44954128440366975, -0.6455696202531646), (0.4541284403669725, -0.6455696202531646), (0.45871559633027525, -0.4683544303797469), (0.463302752293578, -0.36708860759493667), (0.46788990825688076, -0.24894514767932485), (0.4724770642201835, -0.08860759493670889), (0.47706422018348627, 0.00421940928270037), (0.481651376146789, 0.13080168776371304), (0.48623853211009177, 0.2742616033755274), (0.4908256880733945, 0.38396624472573837), (0.4954128440366973, 0.4345991561181435), (0.5, 0.6118143459915613), (0.5045871559633027, 0.6793248945147679), (0.5091743119266054, 0.6877637130801688), (0.5137614678899083, 0.7805907172995781), (0.518348623853211, 0.7805907172995781), (0.5229357798165137, 0.6793248945147679), (0.5275229357798165, 0.5696202531645569), (0.5321100917431193, 0.5443037974683544), (0.536697247706422, 0.4599156118143459), (0.5412844036697247, 0.39240506329113933), (0.5458715596330275, 0.31645569620253156), (0.5504587155963303, 0.21518987341772156), (0.555045871559633, 0.1223628691983123), (0.5596330275229358, 0.06329113924050622), (0.5642201834862385, -0.021097046413502074), (0.5688073394495413, -0.08016877637130804), (0.573394495412844, -0.08860759493670889), (0.5779816513761468, -0.18143459915611815), (0.5825688073394495, -0.21518987341772156), (0.5871559633027523, -0.2573839662447257), (0.591743119266055, -0.24894514767932485), (0.5963302752293578, -0.2236286919831224), (0.6009174311926605, -0.21518987341772156), (0.6055045871559633, -0.2067510548523207), (0.6100917431192661, -0.189873417721519), (0.6146788990825688, -0.189873417721519), (0.6192660550458715, -0.18143459915611815), (0.6238532110091743, -0.18143459915611815), (0.6284403669724771, -0.18143459915611815), (0.6330275229357798, -0.18143459915611815), (0.6376146788990825, -0.18143459915611815), (0.6422018348623854, -0.18143459915611815), (0.6467889908256881, -0.2067510548523207), (0.6513761467889908, -0.21518987341772156), (0.6559633027522935, -0.21518987341772156), (0.6605504587155964, -0.2236286919831224), (0.6651376146788991, -0.2236286919831224), (0.6697247706422018, -0.2236286919831224), (0.6743119266055045, -0.2236286919831224), (0.6788990825688074, -0.21518987341772156), (0.6834862385321101, -0.21518987341772156), (0.6880733944954128, -0.2236286919831224), (0.6926605504587156, -0.36708860759493667), (0.6972477064220184, -0.5021097046413502), (0.7018348623853211, -0.6286919831223629), (0.7064220183486238, -0.7383966244725738), (0.7110091743119266, -0.8396624472573839), (0.7155963302752294, -0.9409282700421941), (0.7201834862385321, -1.0), (0.7247706422018348, -0.9915611814345991), (0.7293577981651376, -0.9915611814345991), (0.7339449541284404, -0.9915611814345991), (0.7385321100917431, -1.0), (0.7431192660550459, -1.0), (0.7477064220183486, -0.9831223628691983), (0.7522935779816514, -0.9662447257383966), (0.7568807339449541, -0.9578059071729957), (0.7614678899082569, -0.9578059071729957), (0.7660550458715596, -0.9578059071729957), (0.7706422018348624, -0.9662447257383966), (0.7752293577981652, -0.9831223628691983), (0.7798165137614679, -0.9831223628691983), (0.7844036697247706, -0.8818565400843882), (0.7889908256880734, -0.8481012658227848), (0.7935779816513762, -0.6455696202531646), (0.7981651376146789, -0.49367088607594933), (0.8027522935779816, -0.4008438818565401), (0.8073394495412844, -0.26582278481012656), (0.8119266055045872, -0.09704641350210974), (0.8165137614678899, -0.05485232067510548), (0.8211009174311926, 0.012658227848101333), (0.8256880733944955, 0.1223628691983123), (0.8302752293577982, 0.240506329113924), (0.8348623853211009, 0.33333333333333326), (0.8394495412844036, 0.38396624472573837), (0.8440366972477065, 0.5358649789029535), (0.8486238532110092, 0.6624472573839661), (0.8532110091743119, 0.7383966244725739), (0.8577981651376146, 0.7468354430379747), (0.8623853211009175, 0.8987341772151898), (0.8669724770642202, 0.9578059071729959), (0.8715596330275229, 0.9831223628691983), (0.8761467889908257, 0.9831223628691983), (0.8807339449541285, 0.9831223628691983), (0.8853211009174312, 0.9831223628691983), (0.8899082568807339, 0.9746835443037976), (0.8944954128440367, 0.9746835443037976), (0.8990825688073395, 0.9746835443037976), (0.9036697247706422, 0.9578059071729959), (0.908256880733945, 0.9578059071729959), (0.9128440366972477, 0.9578059071729959), (0.9174311926605505, 0.9578059071729959), (0.9220183486238532, 0.9578059071729959), (0.926605504587156, 0.9746835443037976), (0.9311926605504587, 0.9831223628691983), (0.9357798165137615, 1.0), (0.9403669724770642, 0.9156118143459915), (0.944954128440367, 0.7046413502109705), (0.9495412844036697, 0.5527426160337552), (0.9541284403669725, 0.4430379746835442), (0.9587155963302753, 0.29957805907172985), (0.963302752293578, 0.139240506329114), (0.9678899082568807, 0.06329113924050622), (0.9724770642201835, -0.04641350210970463), (0.9770642201834863, -0.11392405063291144), (0.981651376146789, -0.189873417721519), (0.9862385321100917, -0.19831223628691985), (0.9908256880733946, -0.21518987341772156), (0.9954128440366973, -0.2067510548523207), (1.0, -0.19831223628691985)]  
txlist = np.asarray(txlist)  
  
plt.figure()  
plt.scatter(txlist[:,0], txlist[:,1])  
plt.savefig('fft02.jpg')  
plt.show()

위와 같은 그래프로 표현되는 원본 시그널이 있을 때, 수집된 샘플 데이터의 수가 부족할 수도 있다. 이 때는 보간법으로 점들 사이의 데이터들을 추정하여 채울 수 있다.
일정한 시간간격으로 추정된 위치값을 보간법으로 구해 데이터 수를 확장해 보자.

보간법

우리가 필요한 샘플링 주기는 최대 주파수 설정에 따른다.
최대 500Hz까지를 검사하여 성분 분석을 하려면 그 두배인 1000Hz를 maxfreq로 설정한다.
(나중에 나오지만 주파수 스펙트럼을 그려보면 중앙을 기준으로 좌우 대칭으로 나온다. 따라서 최대 주파수 *2를 해준다.)
1000Hz를 maxfreq로 잡으면 샘플링 주기는 1/1000 sec로 한다.
일정한 시간간격 (1ms)마다의 신호크기를 추정해 다시 그려보자.

from scipy.interpolate import splrep, splev  
  
spl = splrep(txlist[:,0], txlist[:,1])
fs = 1000 # max 500Hz *2  
dt = 1/fs   # 0.001  
spl = splrep(txlist[:,0], txlist[:,1])  
newt = np.arange(0, 1, dt)  
newx = splev(newt, spl)  
print(newt)  
print(newx)  
if True:  
    plt.figure()  
    plt.scatter(newt, newx)  
    plt.savefig('fft02_2.jpg')  
    plt.show()

fft02_2

FFT

위 신호를 분해해 보자.
먼저 주파수 스펙트럼을 구해서 어떤 주파수를 사용해야 하는지를 분석한다. 스펙트럼 그래프에서 높은 값을 가진 성분의 주파수를 선택하면 된다.

  
# 주파수 생성  
nfft = len(newt)  # number of sample count.  
print('nfft = ', nfft)  
df = fs/nfft    # 주파수 증가량 = max freq / 샘플개수  
k = np.arange(nfft)  
f = k*df      # 0부터~최대주파수까지의 범위 (sample count 개수 만큼, df증가량으로 분포)  
  
# 주파수 스펙트럼은 중앙을 기준으로 대칭이 된다. 반만 구한다.  
nfft_half = math.trunc(nfft/2)  
f0 = f[range(nfft_half)]      # only half size check for get hz.  
y = np.fft.fft(newx)/nfft * 2 # 증폭을 두 배로 한다. (반만 계산해서 에너지가 반으로 줌)  
y0 = y[range(nfft_half)]       # one side.  
amp = abs(y0)  # 벡터(복소수) norm 측정. 신호 강도. 
if True:  
    plt.figure()  
    plt.plot(f0, amp)  
    plt.savefig('fft02_3.jpg')  
    plt.show()

fft02_3
위 그래프의 가로축은 주파수이고 세로축은 신호 강도이다.
작은 값을 버리고 강도가 센 주파수만 선별하면 된다.
top N개를 설정해서 몇 개만 할 수 도 있지만, 몇 개가 최적인지 알 수 없기에 사분위수의 극단점을 이용해 보았다. (데이터 분포의 25%~75%범위의 끝에서 해당 크기의 1.5배 이상 떨어진 데이터)
굳이 이렇게까지 할 필요는 없고 특정 개수로 (예를 들면 10개로) 설정해도 된다.

  
# outlier 찾기. 사분위수 사용. boxplot.  
ampsort = np.sort(amp)  
q1, q3 = np.percentile(ampsort, [25, 75])  
iqr = q3-q1  
upper_bound = q3+1.5*iqr  
print('q1=',q1, 'q3=',q3, 'upper_bound=', upper_bound)  
outer = ampsort[ampsort>upper_bound]  
print('outer cnt=', len(outer))  
topn = len(outer)  
print(outer)

1000 개중에 특이하게 높은 값 101개를 찾았다.

nfft =  1000
q1= 2.7017249783348636e-05 q3= 0.00031241349163501486 upper_bound= 0.0007405078544125142
outer cnt= 101
[0.00081545 0.00085501 0.00086458 0.00090005 0.00090194 0.00091519
 0.00091733 0.00093784 0.00096499 0.00097396 0.00099638 0.00104299
 0.00107283 0.00126076 0.00126265 0.00127681 0.00129231 0.00131356....]

상위 101개의 주파수를 찾는다.

idxy = np.argsort(-amp)  
for i in range(topn):  
    print('freq=', f0[idxy[i]], 'amp=', y[idxy[i]])

마지막으로 주파수만으로 원본을 추정해 그려본다.

  
# recover  
newy = np.zeros((nfft,))  
arfreq = []  
arcoec = []  
arcoes = []  
for i in range(topn):  
    freq = f0[idxy[i]]  
    yx = y[idxy[i]]  
    coec = yx.real  
    coes = yx.imag * -1  
  print('freq=', freq, 'coec=', coec, ' coes', coes)  
    # newy += coec * np.cos( 2*np.pi*freq*newt+ang) + coes * np.sin( 2*np.pi*freq*newt+ang)  
  newy += coec * np.cos(2 * np.pi * freq * newt) + coes * np.sin(2 * np.pi * freq * newt)  
    arfreq.append(freq)  
    arcoec.append(coec)  
    arcoes.append(coes)  
  
plt.figure()  
plt.plot(txlist[:,0], txlist[:,1], c='r', label='orginal')  
plt.plot(newt, newy, c='b', label='fft')  
plt.legend()  
plt.savefig('fft02_4.jpg')  
plt.show()

fft02_4

거의 복원된 모습을 확인할 수 있다.

주성분 주파수를 하나씩 추가하여 변화하는 모습을 확인해 보자.

  
# progress ...  
plt.figure()  
plti = 0  
ncnt = 15  
  
newy = np.zeros((nfft,))  
for i in range(ncnt+1):  
    freq = f0[idxy[i]]  
    yx = y[idxy[i]]  
    coec = yx.real  
    coes = yx.imag * -1  
  print('freq=', freq, 'coec=', coec, ' coes', coes)  
    newy += coec * np.cos(2 * np.pi * freq * newt) + coes * np.sin(2 * np.pi * freq * newt)  
  
    plti+=1  
  plt.subplot(4,4, plti)  
    plt.title("N={}".format(i+1))  
    plt.plot(newt, newy)  
  
plt.savefig('fft02_5.jpg')  
plt.show()

fft02_5
주파수를 추가할 때 마다 점점 원본의 모습으로 바뀌어진다.

Authors: crazyj7@gmail.com
Written with StackEdit.

'Python' 카테고리의 다른 글

진행(progress)바/ tqdm  (2) 2019.08.28
Google Drive file upload/download  (0) 2019.08.20
[UI] Qt5  (0) 2019.05.17
두 선분의 교차여부 체크  (0) 2019.04.11
두 선분의 교점 찾기  (0) 2019.04.11
반응형
calculus_int_ln_gamma

01ln(Γ(x))dx \int_{0}^{1} ln(\Gamma(x))dx


We know this.
Γ(x)=0tx1etdtΓ(x)Γ(1x)=πsin(πx) \Gamma(x) = \int_{0}^{\infty}t^{x-1}e^{-t} dt \\ \Gamma(x) \Gamma(1-x) = \frac {\pi}{sin(\pi x)}
take log.
ln(Γ(x)Γ(1x))=lnπsin(πx)ln(Γ(x))+ln(Γ(1x))=lnπln(sin(πx)) ln(\Gamma(x) \Gamma(1-x)) = ln { \frac {\pi}{sin(\pi x)} }\\ ln(\Gamma(x))+ln(\Gamma(1-x)) = ln \pi - ln (sin(\pi x))
take integral.
ln(Γ(x))+ln(Γ(1x))=lnπln(sin(πx))01ln(Γ(x))dx+01ln(Γ(1x))dx=01lnπdx01ln(sin(πx))dx01ln(Γ(x))dx+01ln(Γ(u))du=01lnπ01ln(sin(πx))201ln(Γ(x))dx=01lnπdx01ln(sin(πx))dx201ln(Γ(x))dx=lnπ01ln(sin(πx))dx \int ln(\Gamma(x))+ \int ln(\Gamma(1-x)) = \int ln \pi - \int ln (sin(\pi x))\\ \int_0^1 ln(\Gamma(x)) dx+\int_0^1 ln(\Gamma(1-x)) dx = \int_0^1 ln \pi dx- \int_0^1 ln (sin(\pi x)) dx \\ \int_0^1 ln(\Gamma(x))dx+\int_0^1 ln(\Gamma(u)) du=\int_0^1 ln \pi - \int_0^1 ln (sin(\pi x))\\ 2\int_0^1 ln(\Gamma(x))dx=\int_0^1 ln \pi dx- \int_0^1 ln (sin(\pi x))dx\\ 2\int_0^1 ln(\Gamma(x))dx=ln\pi - \int_0^1 ln (sin(\pi x))dx
And watch the last part.
01ln(sin(πx))dx(u=πx,du=πdx)=0πln(sin(u))1πdu=1π0πln(sin(u))du \int_0^1 ln (sin(\pi x))dx\\ (u=\pi x , du=\pi dx) \\ =\int_0^{\pi} ln(sin(u)) \frac{1}{\pi} du\\ =\frac{1}{\pi} \int_0^{\pi} ln(sin(u)) du
We know
0π2ln(sin(x))dx=π2ln2 \int_0^{\frac{\pi}{2}}ln(sin(x))dx = -\frac{\pi}{2}ln2
So,
1π0πln(sin(u))du=1π20π2ln(sin(x))dx=1π2(π2ln2)=ln201ln(sin(πx))dx=ln2 \frac{1}{\pi} \int_0^{\pi} ln(sin(u)) du=\frac{1}{\pi} 2 \int_0^{\frac{\pi}{2}}ln(sin(x))dx \\ =\frac{1}{\pi} 2 (-\frac{\pi}{2}ln2) \\ = - ln 2\\ \int_0^1 ln (sin(\pi x))dx=-ln2
So,
201ln(Γ(x))dx=lnπ01ln(sin(πx))dx=lnπ(ln2)=lnπ+ln2 2\int_0^1 ln(\Gamma(x))dx=ln\pi - \int_0^1 ln (sin(\pi x))dx\\ =ln\pi - (-ln2) = ln \pi + ln 2
01ln(Γ(x))dx=lnπ+ln22=ln(2π)2 \therefore \int_0^1 ln(\Gamma(x))dx = \frac {ln \pi + ln 2} {2} = \frac {ln(2\pi)}{2}

Author
crazyj7@gmail.com
Written with StackEdit.

'Math' 카테고리의 다른 글

Integral100 [11-20]  (0) 2019.10.13
Integral100 [1-10]  (2) 2019.10.12
integral ln sin  (0) 2019.08.01
Gaussian integration  (0) 2019.07.26
적분 순서 치환방법 정리  (0) 2019.05.05
반응형
ASN1C

ASN.1 c/cpp code

What is ASN.1

Abstract Syntax Notation One 이란 뜻.
ITU에서 네트웍 데이터 교환을 정의한 프로토콜로 사용하는 표준화 포맷임. (X.680, X.681, X.682, X.683, X.690, X.691, X.692, X.693 등에 설명)
이 기종 장치들 간의 데이터 교환시 표준화가 필요하다. (byte ordering 등 여러가지 문제)
여러가지 ISO 표준 문서에서 사용하는 자료 구조 형태를 보면 ASN.1 문법으로 사용한다.
ASN.1 에서는 자료 구조들을 정의하는데, 길이라던지 범위라던지 등의 제약 조건 등도 포함된다. 자료 구조를 정의하는 문법의 문서 형태라서 소프트웨어 구현시에는 자체로 사용할 수 없고, ASN.1을 인코딩하여 사용한다. 이런 인코딩 들을 하기 위한 작업을 개발 언어별로 소스를 자동으로 만들어 주는 역할을 하는 것이 ASN.1 컴파일러 이다.

BER는 ASN.1의 기본 인코딩 규칙을 나타낸다. ASN.1 데이터를 인코딩하는 다른 방법으로는 DER, CER, PER 등이 있다.

ASN.1 compiler는 ASN.1 문법으로 작성된 문서를 읽어 원하는 언어의 소스 파일로 만들어 주는 역할을 한다. (asn1c는 c 소스 코드를 생성한다.)

compiler download

Download asn1c(Compiler) source code and build.
버전에 따라 생성되는 코드가 다를 수 있다. 가장 최신 버전을 사용하는 것이 좋다. 상용으로 컴파일러를 파는 곳도 많다.

# wget https://lionet.info/soft/asn1c-0.9.28.tar.gz
# tar xvfz asn1c-0.9.28.tar.gz
# cd asn1c-0.9.28
./configure
./make
./make install
# asn1c -h
ASN.1 Compiler, v0.9.28

# Installation path may be /usr/local/bin.

Syntax

문법은 ASN.1 Syntax 검색하여 자세한 것은 찾아보고, 여기서는 간단한 예제 맛 보기.

Order ::= SEQUENCE {
  header Order-header,
  items SEQUENCE OF Order-line
  }
Order-header ::= SEQUENCE {
  number Order-number,
  date	Date,
  client Client,
  payment Payment-method
}

Certificate ::= SEQUENCE {
  tbsCertificate TBSCertificate,
  signatureAlgorithm AlgorithmIdentifier,
  signatureValue BIT STRING
}

TBSCertificate ::= SEQUENCE {
  version 	[0] EXPLICIT Version DEFAULT v1,
  serialNumber CertificateSerialNumber,
  signature	AlgorithmIdentifier,
  issuer	Name,
  validity	Validity,
  ...
}

Test ASN1c

asn 파일을 만들었으면 asn1c로 c코드를 생성한다.
Makefile을 만들어 사용하기.

--build.sh
#!/bin/sh
make -f Makefile.asn

--Makefile.asn
CC=cc
CPP=g++

.SUFFIXES=.c .o
.SUFFIXES=.cpp .o

all:
	asn1c format_iso.asn
	-rm converter-sample.c converter-sample.o
	$(CC) -c -fPIC -g *.c -I.
	$(CPP) -c -fPIC -g *.cpp -I.
#	$(CPP) -o a.out *.o

--Makefile.api
...
all:
	$(CC) -c -fPIC *.c -I.
	$(CPP) -c -fPIC asnapi.cpp -I . -D_LITTLE_ENDIAN_

test:
	$(CPP) -c -fPIC asnapitest.cpp -I.
	$(CPP) -o a.out *.o 
		

위에서 converter-sample.c를 참고하여 인코딩을 하는 것을 쉽게 따라해 볼 수 있다.
실제 사용하지는 않을 테니까 rm으로 빌드시 삭제하였다.

ASN api wrapper

ASN1 문서가 asn1c에 의해 컴파일되면 소스 코드들이 잔뜩 생긴다. 정의한 자료구조마다 헤더파일과 소스 파일이 각각 생성되어 생성된 소스 파일들이 너무 많다.
자료구조들을 사용하기 위해서는 wrapper하여 변환하는 함수를 만드는 것이 좋다.
ASN1 문서에 자료 구조 정의한 이름으로 소스 파일들이 생성되니, 최상위에 정의한 자료구조 명으로된 헤더 파일을 include하여 작성한다. 타입은 자료구조명에 _t가 붙어서 자동으로 생성된다.

wrapper example)

-- asnapi.h
#include "myData.h"
...
myData_t* mynotation2iso(string mynote) ;
myData_t* xer2iso(string mynote) ;
string iso2xer(myData_t *mydata) ;
myData_t* bin2iso(char *bin) ;
char* iso2bin(myData_t *mydata, OUT int *retbufsize) ;
...

--asnapi.cpp
위 wrapper 함수들을 구현

ASN 자료구조 생성

mynotation2iso():
mydata_t *mydata ;
// 메모리 초기화
mydata = (mydata_t*) calloc(1, sizeof *mydata) ;
// 메모리 해제 함수 연결. 메모리 해제시 내부의 리스트 엘리먼트들에 할당한 
// 메모리들이 있을 때는 수동으로 메모리 해제 함수를 만든다.
mydata->bodies.list.free = free_body ;

// 스트링 할당. 4바이트. 마지막 null 포함하여 octet string자료 구조내에 저장. 
// 내부에서 contents 메모리 할당이 발생함. free 필요.  
OCTET_STRING_fromBuf(&mydata->header.formatId, "abc", 4) ;
mydata->header.number = 1 ;

Body_t* body=NULL;
body = (Body_t*) calloc(1, sizeof *body) ;
body->reprenentation.qualityRecord.qualityBlock.list.free=free_qualityBlock ;

// 버퍼에서 스트링을 읽어 자료구조 octet 스트링에 복사. 일반 바이너리값 
// 바이트 어레이도 이렇게 저장 가능.  
OCTET_STRING_fromBuf( &body->representation.captureDateTime, 
	(const char*)&utc, 9) ;
QualityBlock_t *qb=NULL ;
qb = (QualityBlock_t*) calloc(1, sizeof *qb) ;
..
// 리스트 구조(sequence of)는 이렇게 추가한다.
asn_sequence_add(&body->representation.qualityRecord.qualityBlocks, qb) ;
...
int zero=0 ;

// new_fromBuf로 하면 octet 스트링 자료구조 메모리가 할당되어 반환된다. 
body->representationBody.extendedData = 
	OCTET_STRING_new_fromBuf(&asn_DEF_OCTET_STRING, (const char*)&zero, 2) ;
asn_sequence_add(&mydata->bodies, body) ;

// XER 포맷으로 변환하여 스트링 출력
xer_fprintf(stdout, &asn_DEF_mydata, mydata) ;
return mydata ;

free_body(Body_t *b):
free_scd(b->representation.channelDescription.descriptions.x) ;

// 리스트 해제. 내부에 free 지정 콜백이 돌아가면서 내부의 메모리 해제.
asn_sequence_empty(&b->representation.qualityRecord.qualityBlocks)

// 내부 버퍼 메모리 해제 및 OCTET_STRING 구조체 메모리도 해제.
// extendedData 자체가 OCTET_STRING* 타입. 별도 할당(new_fromBuf)한 
// 메모리 해제가 필요하여 마지막 플래그값으로 0이로 설정. 
OCTET_STRING_free(&asn_DEF_OCTET_STRINTG, b->representationBody.extendedData,0) ;

// 마지막플래그는 contents_only로 1이면 contents만 해제한다. 
// octet_string 구조체(컨테이너) 메모리는 해제하지 않음.
// captureDateTime 자체가 OCTET_STRING 타입으로 별도 할당한 메모리가 아니라
// 상위 구조체 할당시 잡힌 영역임. 여기서 해제 불필요.
OCTET_STRING_free(&asn_DEF_OCTET_STRINTG, &b->representation.captureDateTime,1) ;
free(b);

set_nodefree(mydata_t *mydata):
mydata->bodies.list.free=free_body ;
asn_anonymous_sequence_ *ss = _A_SEQUENCE_FROM_VOID( &mydata->bodies) ;
for (int j=0; j<ss->count; j++) {
	Body_t *body = (Body_t*)ss->array[j] ;
	body->representation.qualityRecord.qualityBlocks.list.free = 
		free_qualityBlock ;
}

위의 예제를 보면 복잡해 보인다. 실제 생성된 소스코드들을 분석해야지만 사용할 수 가 있다. 특히 리스트 사용이나 스트링 처리, 메모리 관리가 처음에 어려울 수 있다. 위의 예제를 참고하면 스트링이나 리스트 사용시 도움이 될 것이다. (주의: asn1c는 버전에 따라 Integer_t에 int 값 할당하는 것도 에러가 날 수 있다.)


Example

original page http://lionet.info/asn1c/examples.html

  • MyModule.asn1
MyModule DEFINITIONS ::=
BEGIN

MyTypes ::= SEQUENCE {
    myObjectId   OBJECT IDENTIFIER,
    mySeqOf      SEQUENCE OF MyInt,
    myBitString  BIT STRING {
                        muxToken(0), 
                        modemToken(1)
                 }
}

MyInt ::= INTEGER (0..65535)

END
  • asn1c MyModule.asn1

  • create structure files.

  • my-program.c

#include <stdio.h>	/* for stdout */
#include <stdlib.h>	/* for malloc() */
#include <assert.h>	/* for run-time control */
#include "MyTypes.h"	/* Include MyTypes definition */

int main() {
	/* Define an OBJECT IDENTIFIER value */
	int oid[] = { 1, 3, 6, 1, 4, 1, 9363, 1, 5, 0 }; /* or whatever */

	/* Declare a pointer to a new instance of MyTypes type */
	MyTypes_t *myType;
	/* Declare a pointer to a MyInt type */
	MyInt_t *myInt;

	/* Temporary return value */
	int ret;

	/* Allocate an instance of MyTypes */
	myType = calloc(1, sizeof *myType);
	assert(myType);	/* Assume infinite memory */

	/*
	 * Fill in myObjectId
	 */
	ret = OBJECT_IDENTIFIER_set_arcs(&myType->myObjectId,
			oid, sizeof(oid[0]), sizeof(oid) / sizeof(oid[0]));
	assert(ret == 0);

	/*
	 * Fill in mySeqOf with a couple of integers.
	 */

	/* Prepare a certain INTEGER */
	myInt = calloc(1, sizeof *myInt);
	assert(myInt);
	*myInt = 123;	/* Set integer value */

	/* Fill in mySeqOf with the prepared INTEGER */
	ret = ASN_SEQUENCE_ADD(&myType->mySeqOf, myInt);
	assert(ret == 0);

	/* Prepare another integer */
	myInt = calloc(1, sizeof *myInt);
	assert(myInt);
	*myInt = 111222333;	/* Set integer value */

	/* Append another INTEGER into mySeqOf */
	ret = ASN_SEQUENCE_ADD(&myType->mySeqOf, myInt);
	assert(ret == 0);

	/*
	 * Fill in myBitString
	 */

	/* Allocate some space for bitmask */
	myType->myBitString.buf = calloc(1, 1);
	assert(myType->myBitString.buf);
	myType->myBitString.size = 1;	/* 1 byte */

	/* Set the value of muxToken */
	myType->myBitString.buf[0] |= 1 << (7 - myBitString_muxToken);

	/* Also set the value of modemToken */
	myType->myBitString.buf[0] |= 1 << (7 - myBitString_modemToken);

	/* Trim unused bits (optional) */
	myType->myBitString.bits_unused = 6;

	/*
	 * Print the resulting structure as XER (XML)
	 */
	xer_fprint(stdout, &asn_DEF_MyTypes, myType);

	return 0;
}
  • $ cc -o a.out -I. *.c
  • ./a.out
<MyTypes>
    <myObjectId>1.3.6.1.4.1.9363.1.5.0</myObjectId>
    <mySeqOf>
        <MyInt>123</MyInt>
        <MyInt>111222333</MyInt>
    </mySeqOf>
    <myBitString>11</myBitString>
</MyTypes>
  • my-program2.c
#include <stdio.h>	/* for stdout */
#include <stdlib.h>	/* for malloc() */
#include <assert.h>	/* for run-time control */
#include "MyTypes.h"	/* Include MyTypes definition */

int main(int argc, char *argv[]) {
	char buf[1024];	/* Hope, sufficiently large buffer */
	MyTypes_t *myType = 0;
	asn_dec_rval_t rval;
	char *filename;
	size_t size;
	FILE *f;

	/*
	 * Target variables.
	 */
	int *oid_array;	/* holds myObjectId */
	int oid_size;
	int *int_array;	/* holds mySeqOf */
	int int_size;
	int muxToken_set;	/* holds single bit */
	int modemToken_set;	/* holds single bit */

	/*
	 * Read in the input file.
	 */
	assert(argc == 2);
	filename = argv[1];
	f = fopen(filename, "r");
	assert(f);
	size = fread(buf, 1, sizeof buf, f);
	if(size == 0 || size == sizeof buf) {
		fprintf(stderr, "%s: Too large input\n", filename);
		exit(1);
	}

	/*
	 * Decode the XER buffer.
	 */
	rval = xer_decode(0, &asn_DEF_MyTypes, &myType, buf, size);
	assert(rval.code == RC_OK);

	/*
	 * Convert the OBJECT IDENTIFIER into oid_array/oid_size pair.
	 */
	/* Figure out the number of arcs inside OBJECT IDENTIFIER */
	oid_size = OBJECT_IDENTIFIER_get_arcs(&myType->myObjectId,
			0, sizeof(oid_array[0]), 0);
	assert(oid_size >= 0);
	/* Create the array of arcs and fill it in */
	oid_array = malloc(oid_size * sizeof(oid_array[0]));
	assert(oid_array);
	(void)OBJECT_IDENTIFIER_get_arcs(&myType->myObjectId,
			oid_array, sizeof(oid_array[0]), oid_size);

	/*
	 * Convert the sequence of integers into array of integers.
	 */
	int_size = myType->mySeqOf.list.count;
	int_array = malloc(int_size * sizeof(int_array[0]));
	assert(int_array);
	for(int_size = 0; int_size < myType->mySeqOf.list.count; int_size++)
		int_array[int_size] = *myType->mySeqOf.list.array[int_size];

	if(myType->myBitString.buf) {
		muxToken_set   = myType->myBitString.buf[0]
					& (1 << (7 - myBitString_muxToken));
		modemToken_set = myType->myBitString.buf[0]
					& (1 << (7 - myBitString_modemToken));
	} else {
		muxToken_set = modemToken_set = 0;	/* Nothing is set */
	}

	return 0;
}

Authors
crazyj7@gmail.com
Written with StackEdit.

반응형
calculus_int_ln_sin

0π2ln(sin(x))dx \int_{0}^{\frac{\pi}{2}} ln(sin(x))dx


We know,
sinx=cos(π2x) sin x = cos( \frac{\pi}{2}-x)
I=0π2ln(sin(x))dx=0π2ln(cos(π2x))dx(u=π2x,du=dx)=π20ln(cos(u))du=0π2ln(cos(u))du I = \int_{0}^{\frac{\pi}{2}} ln(sin(x))dx \\ = \int_{0}^{\frac{\pi}{2}} ln( cos( \frac{\pi}{2}-x))dx \\ (u = \frac{\pi}{2}-x, du = -dx) \\ = \int_\frac{\pi}{2}^{0}ln(cos(u))-du\\ = \int_{0}^{\frac{\pi}{2}}ln(cos(u))du
So,
I=0π2ln(sin(x))dx=0π2ln(cos(u))du I = \int_{0}^{\frac{\pi}{2}} ln(sin(x))dx = \int_{0}^{\frac{\pi}{2}}ln(cos(u))du
2I=0π2ln(sin(x))dx+0π2ln(cos(x))dx=0π2ln(sin(x))+ln(cos(x))dx=0π2ln(sin(x)cos(x))dx=0π2ln(12sin(2x))dx=0π2ln(12)dx+0π2ln(sin(2x))dx=π2ln(12)+0π2ln(sin(2x))dx=π2ln(2)+0π2ln(sin(2x))dx(u=2x,du=2dx) 2I = \int_{0}^{\frac{\pi}{2}} ln(sin(x))dx + \int_{0}^{\frac{\pi}{2}}ln(cos(x))dx\\ =\int_{0}^{\frac{\pi}{2}} ln(sin(x))+ln(cos(x))dx\\ =\int_{0}^{\frac{\pi}{2}} ln(sin(x)cos(x))dx \\ =\int_{0}^{\frac{\pi}{2}} ln(\frac{1}{2} sin(2x))dx \\ = \int_{0}^{\frac{\pi}{2}} ln(\frac{1}{2})dx + \int_{0}^{\frac{\pi}{2}} ln(sin(2x))dx \\ =\frac{\pi}{2}ln(\frac{1}{2})+ \int_{0}^{\frac{\pi}{2}} ln(sin(2x))dx \\ =-\frac{\pi}{2}ln(2)+ \int_{0}^{\frac{\pi}{2}} ln(sin(2x))dx \\ (u=2x, du=2dx)

=π2ln(2)+120πln(sin(u))du =-\frac{\pi}{2}ln(2)+ \frac{1}{2}\int_{0}^{\pi} ln(sin(u))du
The ln area of Sin from 0 to pi is 2 times of the area of sin from 0 to pi/2.
=π2ln(2)+0π2ln(sin(u))du2I=π2ln(2)+II=0π2ln(sin(x))dx=π2ln(2) =-\frac{\pi}{2}ln(2)+ \int_{0}^{\frac{\pi}{2}} ln(sin(u))du \\ 2I=-\frac{\pi}{2}ln(2)+ I \\ \therefore I = \int_{0}^{\frac{\pi}{2}} ln(sin(x))dx = -\frac{\pi}{2}ln(2)

Author
crazyj7@gmail.com
Written with StackEdit.

'Math' 카테고리의 다른 글

Integral100 [1-10]  (2) 2019.10.12
integral ln gamma  (0) 2019.08.01
Gaussian integration  (0) 2019.07.26
적분 순서 치환방법 정리  (0) 2019.05.05
미분 곡률 테일러시리즈  (0) 2019.05.05

+ Recent posts