running-example.csv
0.00MB

 process mining 기본 코딩 자료

 

https://pm4py.fit.fraunhofer.de/getting-started-page

반응형

 아래 사이트에서 코드에 필요한 공식과 개념을 이해했다. 공식에 대해서는 피상적으로 이행하는 것과 실제 그것을 구현하는 것이 얼마나 차이가 있는지 알 수 있었던 좋은 기회이지 싶다.

https://medium.com/data-science-in-your-pocket/how-feature-importance-is-calculated-in-decision-trees-with-example-699dc13fc078

 

How feature importance is calculated in Decision Trees? with example

Understanding the math behind

medium.com

1. 필요한 라이브러리 불러오기

import pandas as pd

from sklearn.tree import DecisionTreeClassidifer

from sklearn.tree import export_text

import torch

 

2. train_data를 이용하여 Decision Tree model 생성

clf=DecisionTreeClassifier(random_state=2, max_depth=5, min_samples_split=2000, min_samples_leaf=10000)

clf.fit(X_train, y_train)

# 전체 모델 로직 확인

r=export_text(clf, feature_names=list(X_train.columns))

print(r)

torch.save(clf, "/DecisionMgmt/kp19983/dctl_v0_3.torch")

 

3. Model을 불러와서 수기로 계산


clf = torch.load("/DecisionMgmt/kp19983/dctl_v0_3.torch")

dtree = clf.tree_

# X_train 데이터 길이 확인
print(len(X_train))

df_t = pd.DataFrame(columns=['node', 'size', 'importance']

for i in range(dtree.node_count):
    node = i
    size = dtree.n_node_samples[i]
    if (dtree.children_left[i] == -1) and (dtree.children_right[i] == -1):
        importance = 0
    else:
        importance = (dtree.n_node_samples[i] / len(X_train) * dtree.impurity[i]) \
            - (dtree.n_node_samples[dtree.children_left[i]] / len(X_train)) * dtree.impurity[dtree.children_left[i]] \
            - (dtree.n_node_samples[dtree.children_right[i]] / len(X_train)) * dtree.impurity[dtree.children_right[i]]
    df_t=df_t.append({'node': node, 'size': size, 'importance': importance}, ignore_index = True)

df_t['node'] = df_t['node'].as_type(int)
df_t['size'] = df_t['size'].as_type(int)

# 수기로 계산된 각 노드별 feature_importance sum
print(df_t.sum())

# sklearn.DecisionTreeClassifier에서 제공하는 feature_importance DataFrame 생성
importances = clf.feature_importances_

feature_importances = pd.concat([pd.DataFrame(X_train.columns), pd.DataFrame(importances)], axis=1)
feature_importances.columns = ['feature_nm', 'importances']
feature_importances['calc_impt'] = feature_importances['importances'] * df_t.importance.sum()
feature_importances = feature_importances[feature_importances.importances > 0]
feature_importances.sort_values(by = ['importances'], ascending=False, inplace = True, ignore_index = True)

print(feature_importances)

# Sub Tree Model
fnl_xlist = feature_importances['feature_nme'].tolist()

df2 = pd.concat([df, pd.DataFrame(clf.apply(df[fnl_xlist], check_input=True), columns=['NODE']], axis = 1)

node6 = df2[df2['NODE']==6]
node6_X = node6[fnl_xlist]
node6_y = node6['TARGET']

clf_sub = DecisionTreeClassifier(random_state = 2, max_depth=3, min_samples_split = 20, min_samples_leaf = 20000)
clf_sub.fit(node6_X, node6_y)

dtree = clf_sub.tree_

torch.save(clf_sub, "/DecisionMgmt/kp19983/dctl_v0_3.torch")

clf_sub = torch.load("/DecisionMgmt/kp19983/dctl_v0_3.torch")

node6_df_t = pd.DataFrame(columns=['node', 'size', 'importance'])

for i in range(dtree.node_count):
    size = dtree.n_node_samples[i]
    if (dtree.children_left[i] == -1) and (dtree.children_right[i] == -1):
        importance = 0
    else:
        importance = (dtree.n_node_samples[i] / len(X_train) * dtree.impurity[i]) \
            - (dtree.n_node_samples[dtree.children_left[i]] / len(X_train)) * dtree.impurity[dtree.children_left[i]] \
            - (dtree.n_node_samples[dtree.children_right[i]] / len(X_train)) * dtree.impurity[dtree.children_right[i]]
    node6_df_t=node6_df_t.append({'node': node, 'size': size, 'importance': importance}, ignore_index = True)

node6_df_t['node'] = node6_df_t['node'].astype(int)
node6_df_t['size'] = node6_df_t['size'].astype(int)

print(node6_df_t)

node6_importances.columns = ['feature_nm', 'importances']
node6_feature_importances['calc_impt'] = node6_feature_importances['importances'] * node6_df_t.importance.sum()
node6_feature_importances = node6_feature_importances[node6_feature_importances.importances > 0]
node6_feature_importances.sort_values(by = ['importances'], ascending=False, inplace = True, ignore_index = True)

print(node6_feature_importances)

comb_feature_importances=pd.merge(feature_importances[['feature_nm', 'calc_impt']],
                                  node6_feature_importances.rename(columns = {'calc_impt': 'sub_calc_impt'})[['feature_nm', 'sub_calc_impt']],
                                  how='outer',
                                  on = ['feature_nm'],
                                  validate='m:m')

comb_feature_importances.fillna(0, inplace=True)
comb_feature_importances['fnl_calc_impt'] = comb_feature_importances['cal_impt'] + comb_feature_importances['sub_calc_impt']
comb_feature_importances['importances'] = comb_feature_importances['fnl_calc_impt'] / comb_feature_importances['fnl_calc_impt'].sum()
comb_feature_importances.sort_values(by = ['fnl_cal_impot'], ascending=False, inplace = True, ignore_index = True)

print(comb_feature_importances)

from matplotlib.pyplot as plt

plt.figure(figsize = (14, 10))
plt.title('Combined Feature Importances Top')
sns.barplot(x = comb_feature_importances.importances, y = comb_feature_importances.feature_nme)
반응형

'Python, PySpark' 카테고리의 다른 글

pm4py  (0) 2023.10.31
Python 날짜 스트링 전처리  (0) 2023.08.16
파이썬 한권으로 끝내기 - 234페이지 (credit_final.csv)  (0) 2023.05.28
rownumber() over () in python pandas  (0) 2023.05.01
cosine similarity 계산  (0) 2023.04.12

 SAS나 SQL에 익숙해져 있는 사람에게 가장 어려운 부분이 바로 pandas dataframe은 Series의 집합이므로 조건에 따라서 값을 변환하는 경우에는 정상적으로 작동하지 않는다. 아래 코드에서는 np.where() 가 SQL의 CASE WHEN TEN END 처럼 작동할 것이라고 생각했지만 그렇지 않다. 이렇게 row별로 컬럼의 값에 따라서 처리를 다르게 하기 위해서는 for row loop 문으로 처리해야 한다는 문제점이 있습니다. pandas dataframe 레벨에서 모든 문제를 해결하면 좋을텐데, 이게 그렇게 마음처럼 되지는 않으니까 루프문으로 데이터를 생성해야 하는 것입니다.

 np.where(), np.select() 함수는 사용자 정의 함수를 이용해서 작성하는 것보다 훨씬 더 빠릅니다. 예전에는 df.assign() 함수를 이용해서 코드를 변환했는데 이것도 모든 것을 해결할 수 없으므로 이렇게 별도의 사용자 함수를 사용할 수 밖에 없습니다.

 

1. 필요한 라이브러리를 불러옵니다.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
In [2]:

2. temp 데이터 프레임을 생성합니다. rgs_dt는 등록일인데, NULL 값일 때 '99999999'로 넣어준다.

temp=pd.DataFrame({'id': [1, 2, 3, 4, 5, 6],
                   'rgs_dt': ['20230101', '20230208', '20221208', '20221021', '20230331', '99999999']})

3. 기준월을 넣어 줍니다.

In [3]:
temp['bas_ym']='202303'

4. np.where()함수를 넣으면 정상 작동하지 않는다는 것을 알 수 있습니다. 에러 코드를 보면 pd.to_datetime()이 조건이 아니라 시리즈 전체에서 작동한다는 것을 알 수 있습니다.

In [4]:
temp['diff']=np.where(temp.rgs_dt=='99999999',
                      99999999,
                      pd.to_datetime(temp.bas_ym, format='%Y%m') - pd.to_datetime(temp.rgs_dt, format='%Y%m%d')
                      )
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-d51adba5b206> in <cell line: 1>()
      1 temp['diff']=np.where(temp.rgs_dt=='99999999',
      2                       99999999,
----> 3                       pd.to_datetime(temp.bas_ym, format='%Y%m') - pd.to_datetime(temp.rgs_dt, format='%Y%m%d')
      4                       )

/usr/local/lib/python3.10/dist-packages/pandas/core/tools/datetimes.py in to_datetime(arg, errors, dayfirst, yearfirst, utc, format, exact, unit, infer_datetime_format, origin, cache)
   1066             result = arg.map(cache_array)
   1067         else:
-> 1068             values = convert_listlike(arg._values, format)
   1069             result = arg._constructor(values, index=arg.index, name=arg.name)
   1070     elif isinstance(arg, (ABCDataFrame, abc.MutableMapping)):

/usr/local/lib/python3.10/dist-packages/pandas/core/tools/datetimes.py in _convert_listlike_datetimes(arg, format, name, tz, unit, errors, infer_datetime_format, dayfirst, yearfirst, exact)
    428 
    429     if format is not None:
--> 430         res = _to_datetime_with_format(
    431             arg, orig_arg, name, tz, format, exact, errors, infer_datetime_format
    432         )

/usr/local/lib/python3.10/dist-packages/pandas/core/tools/datetimes.py in _to_datetime_with_format(arg, orig_arg, name, tz, fmt, exact, errors, infer_datetime_format)
    536 
    537     # fallback
--> 538     res = _array_strptime_with_fallback(
    539         arg, name, tz, fmt, exact, errors, infer_datetime_format
    540     )

/usr/local/lib/python3.10/dist-packages/pandas/core/tools/datetimes.py in _array_strptime_with_fallback(arg, name, tz, fmt, exact, errors, infer_datetime_format)
    471 
    472     try:
--> 473         result, timezones = array_strptime(arg, fmt, exact=exact, errors=errors)
    474     except OutOfBoundsDatetime:
    475         if errors == "raise":

/usr/local/lib/python3.10/dist-packages/pandas/_libs/tslibs/strptime.pyx in pandas._libs.tslibs.strptime.array_strptime()

ValueError: unconverted data remains: 99

5. 2가지 변수를 추가해 줍니다. 

 A. 날짜의 차이는 아래와 같이 간단하게 ().days()로 계산이 가능합니다. :) 네, 아주 쉽지요.

 B. 월의 차이를 계산하려고, #으로 막아 놓은 코드는 정상 작동하지 않습니다. ().days() 와 같은 쉬운 함수가 존재하지 않습니다.

 C. 그래서 어쩔 수 없이 .year(), .month()를 갖고 계산하는 방법 외에는 없습니다. 

In [5]:
temp['diff']=[99999999 if temp.loc[j, 'rgs_dt'] == '99999999'
              else (pd.to_datetime(temp.loc[j, 'bas_ym'], format='%Y%m') - pd.to_datetime(temp.loc[j, 'rgs_dt'], format='%Y%m%d')).days
              for j in temp.index
              ]

#temp['mcn']=[99999999 if temp.loc[j, 'rgs_dt'] == '99999999'
#              else (pd.to_datetime(temp.loc[j, 'bas_ym'], format='%Y%m').to_period('M')
#              - pd.to_datetime(temp.loc[j, 'rgs_dt'], format='%Y%m%d').to_period('M'))
#              for j in temp.index
#              ]


temp['mcn']=[99999999 if temp.loc[j, 'rgs_dt'] == '99999999'
              else (pd.to_datetime(temp.loc[j, 'bas_ym'], format='%Y%m').year -  pd.to_datetime(temp.loc[j, 'rgs_dt'], format='%Y%m%d').year)*12
                   + pd.to_datetime(temp.loc[j, 'bas_ym'], format='%Y%m').month - pd.to_datetime(temp.loc[j, 'rgs_dt'], format='%Y%m%d').month
              for j in temp.index
              ]
In [ ]:
temp
Out[ ]:
idrgs_dtbas_ymdiffmcnmcn1012345
1 20230101 202303 59 <2 * MonthEnds> 2
2 20230208 202303 21 <MonthEnd> 1
3 20221208 202303 83 <3 * MonthEnds> 3
4 20221021 202303 131 <5 * MonthEnds> 5
5 20230331 202303 -30 <0 * MonthEnds> 0
6 99999999 202303 99999999 99999999 99999999
In [ ]:
temp['mcn'].info()
<class 'pandas.core.series.Series'>
RangeIndex: 6 entries, 0 to 5
Series name: mcn
Non-Null Count  Dtype 
--------------  ----- 
6 non-null      object
dtypes: object(1)
memory usage: 176.0+ bytes
In [ ]:
pd.to_datetime('19010101', format='%Y%m%d')
 
Out[ ]:
Timestamp('1901-01-01 00:00:00')

 예전에도 이렇게 코드를 어떻게 해서든 가볍게 짜려고 했지만, 오늘 반나절을 보내고 나서 왜 문제였는지 겨우 알 수 있게 되었습니다. 몇 번이나 코드를 수정했지만 뭔가 개선되는 것은 그리 많지 않았습니다. 그래도 이렇게 파이썬하고도 친해질 수 있어서 다행입니다. 예전에는 SAS나 임팔라만 써서 불안한 점이 있었는데, 지금은 참 이것저것 하는 일도 많고 데이터도 많아서 좋습니다.

반응형

credit_final.csv
0.05MB

 정말 간신히 찾아서 올려본다. 혹시 나처럼 삽질하는 사람이 없기를 바라면서 csv 파일 올립니다.

 

https://cafe.naver.com/bigteacher/100?art=ZXh0ZXJuYWwtc2VydmljZS1uYXZlci1zZWFyY2gtY2FmZS1wcg.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjYWZlVHlwZSI6IkNBRkVfVVJMIiwiY2FmZVVybCI6ImJpZ3RlYWNoZXIiLCJhcnRpY2xlSWQiOjEwMCwiaXNzdWVkQXQiOjE2ODUyMDU3NTY0NjN9.eSt9d2IaOzEGrZM4Cs--YmuTYRBKUVT2-GQoTL0ldUg

반응형

 

 

https://stackoverflow.com/questions/17775935/sql-like-window-functions-in-pandas-row-numbering-in-python-pandas-dataframe

반응형

 

1. 기존의 

 

2.scikitlearn n_jobs를 이용하는 방법 

https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.pairwise_kernels.html

 

sklearn.metrics.pairwise.pairwise_kernels

 

scikit-learn.org

3. numpy product를 이용하는 방법

https://stackoverflow.com/questions/34890861/how-to-run-a-large-matrix-for-cosine-similarity-in-python

 

How to run a large matrix for cosine similarity in Python?

I want to calculate cosine similarity between articles. And I am running into the problem that my implementation approach would take a long time for the size of the data that I am going to run. from

stackoverflow.com

 

 

 

 

 

반응형

+ Recent posts