People-Analytics201

코멘트 유사도를 활용한 조직 네트워크 분석(Organizational Network Analysis) 본문

People Insight

코멘트 유사도를 활용한 조직 네트워크 분석(Organizational Network Analysis)

2023. 4. 9. 08:32

본 포스팅은 PA201 구성원 "G1000"님에 의해 작성된 글입니다.


조직마다 기능과 문화가 다르기에 우리는 협업에 앞서 여러 가지 고려해야 할 사항들이 존재합니다.
조직 간의 신뢰 형성에 시간을 쏟을 수 있으며 예상치 못한 갈등과 오해를 줄여나가기 위해 정보의 격차를 줄여야 합니다.
조직 네트워크 분석업무 협업에 있어 조직간의 상호작용을 조금이라도 이해하는 데 도움이 되는 방법입니다.
이 글에서는 조직 간의 상하관계 혹은 기능적 구조를 확인할 수 있는 조직도를 넘어,
동료평가 자료를 활용한 조직 네트워크 분석을 다뤄보겠습니다.


가정

“조직 구성원들이 평가받은 코멘트 내용이 타 조직과 유사하면 해당 조직 간의 협업 잠재력이 높을 것이다”


요약

  • 분석의 접근방법은 상기한 가정이 전제되어 있습니다.
  • 각 조직의 구성원들이 평가받은 동료평가 코멘트를 조직별로 통합하였습니다.
  • 조직별로 통합된 코멘트들을 형태소로 분리하고 불용어 처리 작업을 진행했습니다.
  • 전처리된 조직별 코멘트들을 활용하여 타 조직과 유사성을 측정하였습니다.
  • 조직간의 유사성을 네트워크 척도로 사용함으로써 조직(Node), 유사성(Edge) 네트워크 시각화 그래프를 생성했습니다.

1.  자료수집 및 전처리

1. 1 데이터 소개

동료평가 코멘트 [raw] 예시입니다.

피평가자 조직 피평가자 이름 평가자 조직 평가자 이름 코멘트
개발1팀 박연진 사업1팀 장원영 일정을 잘 지키며, 결과물의 퀄리티도 뛰어납니다. 가끔 이슈가 발생 시에도 매우 적극적인 태도를 보이고 있습니다.
개발1팀 김철수 사업2팀 김태연 힘든 부분이 있어도 크게 내색없이 잘 처리해주셔서 좋았던 것 같습니다. 결과물의 퀄리티도 뛰어납니다.
사업2팀 김태연 데이터팀 임지연 책임감있게 일하고, 경력만큼 실력도 뛰어나십니다. 또한, 매우 적극적인 태도가 모범이 됩니다.
재무실 김동현 개발1팀 김철수 결과물의 퀄리티를 보이시며 함께 일할 수 있어서 좋았습니다. 앞으로도 계속 함께 일할 수 있었으면 좋겠습니다.

각 조직의 구성원이 평가받은 코멘트를 조직별로 취합합니다.

#조직별 그룹화(피평가자 기준)
total_group = raw.drop_duplicates(['코멘트'],ignore_index = True) ##코멘트 중복제거
total_group = total_group.groupby('피평가자조직')['코멘트'].apply(list).reset_index() #Groupby x 인덱스 리셋
total_피평가자조직 = pd.DataFrame(total_group).dropna(subset=["코멘트"]) #코멘트 없는 행 삭제
total_피평가자조직

조직별 Groupby된 자료[total_피평가자조직] 예시입니다.

피평가자조직 코멘트

피평가자 조직 코멘트
개발1팀 [일정을 잘 지키며, 결과물의 퀄리티도 뛰어납니다. 가끔 이슈가 발생 시에도 매우 적극적인 태도를 보이고 있습니다. , 힘든 부분이 있어도 크게 내색없이 잘 처리해주셔서 좋았던 것 같습니다. 결과물의 퀄리티도 뛰어납니다. ]
사업2팀 [책임감있게 일하고, 경력만큼 실력도 뛰어나십니다. 또한, 매우 적극적인 태도가 모범이 됩니다. , …]
재무실 [결과물의 퀄리티를 보이시며 함께 일할 수 있어서 좋았습니다. 앞으로도 계속 함께 일할 수 있었으면 좋겠습니다. …]

1. 2 자연어처리

조직마다 구성원의 코멘트들을 모았다면 Okt 형태소 분석기를 활용하여 조직마다 자주 나오는 형태소, 키워드들을 군집화하여 유사도를 측정합니다. 분석하기 전에 불용어, 특수 문자와 같은 노이즈를 제거하기 위해 데이터를 한번 더 정제하였습니다.

target_dataframe = total_피평가자조직

# 전처리용 Dictionary 불러오기 (불용어)
stopword_list = pd.read_excel('stopword_list.xlsx')

# 한 글자 키워드 불러오기
one_char_keyword = pd.read_excel('one_char_list.xlsx')

# 불용어 제거함수 생성
def remove_stopword(tokens):
    temporary = []
    for token in tokens:
        # 토큰의 글자 수가 2글자 이상인 경우
        if 1 < len(token):
            # 토큰이 불용어가 아닌 경우만 분석용 리뷰 데이터로 포함
            if token not in list(stopword_list['stopword']):
                temporary.append(token)
        # 토큰의 글자 수가 1글자인 경우
        else:
            # 1글자 키워드에 포함되는 경우만 분석용 리뷰 데이터로 포함
            if token in list(one_char_keyword['one_char_keyword']):
                temporary.append(token)
    return temporary

# 형태소 추출, 불용어 제거
from konlpy.tag import Okt
t = Okt()

target_dataframe['코멘트(불용어제거)'] = ''
number = 0
total_count = 0

for number in target_dataframe.index:
    comments_for_vectorize = '' # 만들 문장 초기화
    
    #형태소 추출 
    contents_tokens = [t.morphs(row) for row in target_dataframe.iloc[number]['코멘트']]
    
    #불용어 제거
    treatened_contents_tokens = list(map(lambda tokens : remove_stopword(tokens), contents_tokens))
    
    #하나의 문장으로 만들기(띄어쓰기로 구분)
    comments_for_vectorize = []
    
    for comments in treatened_contents_tokens:
            sentence = ''     # 만들 문장 초기화
            for word in comments:      # 단어 하나하나 뽑아서 공백과 합쳐주기
                sentence = sentence + ' ' + word    
            comments_for_vectorize.append(sentence)

    target_dataframe.loc[total_count,'코멘트(불용어제거)'] = ''.join(s for s in comments_for_vectorize) #list를 str으로 변환해서 데이터프레임에 삽입
    total_count = total_count+1    
    
target_dataframe

불용어, 특수 문자와 같은 노이즈를 제거한 [target_dataframe] 예시입니다.

피평가자 조직 코멘트 코멘트(불용어 제거)
개발1팀 [일정을 잘 지키며, 결과물의 퀄리티도 뛰어납니다. 가끔 이슈가 발생 시에도 매우 적극적인 태도를 보이고 있습니다. , 힘든 부분이 있어도 크게 내색없이 잘 처리해주셔서 좋았던 것 같습니다. 결과물의 퀄리티도 뛰어납니다. ] 일정 잘 지키 결과물 퀄리티 뛰어납니다 가끔 이슈 발생 매우 적극적 태도 보이고 있습니다 힘든 부분 크게 내색없이 처리 좋았 것 같습니다 결과물 퀄리티 뛰어납니다
사업2팀 [책임감있게 일하고, 경력만큼 실력도 뛰어나십니다. 또한, 매우 적극적인 태도가 모범이 됩니다. , …] 책임감있게 일하고 경력 실력 뛰어나십니다 적극적 태도 모범 됩니다….
재무실 [결과물의 퀄리티를 보이시며 함께 일할 수 있어서 좋았습니다. 앞으로도 계속 함께 일할 수 있었으면 좋겠습니다. …] 결과물 퀄리티 함께 일할 수 있어 좋았습니다 계속 함께 일할 수 있었으면 좋겠습니다

1.3 조직별 유사도 측정

앞서 전처리한 조직간 코멘트들의 유사성을 파악하고 측정한 유사도를 가중치로 두어 네트워크 분석도를 그려볼 예정입니다. 유사도 분석은 여러가지 방법이 존재하나 오늘은 SequenceMatcher 유사도 분석으로 접근할 예정입니다.

유사도 측정 방식의 장단점(by GPT)


    1. 자카드 유사도

    서로 다른 문자열 사이의 교집합을 구하는 원리
    집합 A={1,2,3,4,5}와 집합 B={3,4,5,6,7}를 비교하는 경우, 자카드 유사도는 다음과 같이 계산됩니다.

  1. A와 B의 합집합 C={1,2,3,4,5,6,7} 를 구합니다.
  2. A와 B에 공통으로 있는 원소들은 {3,4,5}입니다. 따라서 교집합의 크기는 3입니다.
  3. A와 B에 있는 원소들의 개수 합은 9입니다. 합집합의 크기는 7입니다.
  4. 자카드 유사도는 3/7로 계산됩니다.

    장점
    - 집합(set)의 원소 간 유사도를 측정하기 때문에 간단하고 빠르게 계산할 수 있습니다.
    - 원소의 존재 여부만 고려하므로, 텍스트의 문맥 정보가 필요 없으며, 희소한(sparse) 벡터에도 잘 동작합니다.

    단점
    - 단순히 원소의 존재 여부만을 고려하기 때문에, 유사도 측정이 좀 더 복잡한 문제에서는 정확도가 떨어질 수 있습니다.
       (+텍스트 길이의 차이가 클수록 정확도 하락)
    - 예를 들어, 'love'와 'like'는 의미가 비슷하다고 볼 수 있지만, 자카드 유사도는 완전히 다른 단어로 처리할 수 있습니다.

    2. 코사인 유사도


    서로 다른 문자열의 벡터 간 내적을 각 벡터의 크기의 곱으로 나눈 값으로, 두 벡터가 얼마나 비슷한 방향을 가졌는지를 나타내는 원리

    벡터 A=[1,2,3,4,5]와 벡터 B=[3,4,5,6,7]를 비교하는 경우, 코사인 유사도는 다음과 같이 계산됩니다.

  1. 두 벡터 A와 B의 내적은 (13)+(24)+(35)+(46)+(5*7)=85입니다.
  2. 벡터 A의 크기는 √(1²+2²+3²+4²+5²)=7.416, 벡터 B의 크기는 √(3²+4²+5²+6²+7²)=11.224입니다.
  3. 코사인 유사도는 85 / (7.416 * 11.224) = 0.906으로 계산됩니다.

    장점
    - 텍스트의 길이가 달라도 잘 작동합니다.
    - 단어 빈도수만을 기반으로 하기 때문에, 단어의 순서나 문법적인 정보는 고려하지 않아도 됩니다.
    - 벡터 공간 모델 (Vector Space Model)에서 가장 널리 사용되는 유사도 측정 방법의 하나입니다.

    단점
    - 단어의 의미를 완전히 이해하지 못하는 문제가 있습니다.
    - 중요한 의미를 가진 단어들이 더 많은 가중치를 받는 단어들로부터 영향을 받을 수 있습니다.
    - 다른 유사도 측정 방법과 비교하면 정확성이 상대적으로 낮을 수 있습니다.

    3. SequenceMatcher 유사도


    문자열의 서로 다른 부분 문자열(substring) 사이에서 최장 공통부분 문자열(longest common substring)을 찾아내는 원리

    "Hello, world!"와 "Hi, world!"를 비교해보면 다음과 같이 계산됩니다.

  1. 두 문자열의 길이를 비교하여 더 짧은 문자열인 "Hi, world!"를 기준으로 설정합니다.
  2. 기준 문자열인 "Hi, world!"의 모든 요소를 순차적으로 확인하면서, 다른 문자열인 "Hello, world!"에서 해당 요소와 가장 유사한 요소를 찾습니다.
  3. 가장 유사한 요소를 찾으면, 그 요소를 포함한 다음 부분 문자열을 또 다른 요소와 비교합니다.
  4. 이 과정을 반복하여 두 문자열 사이의 일치하는 부분 문자열들을 찾습니다.

    장점
    - 비교하고자 하는 두 문자열 간의 유사도를 정확하게 측정할 수 있습니다.
    - 문자열 내에서 단어의 순서와 위치를 고려합니다.
    - 서로 다른 길이의 문자열도 비교할 수 있습니다.
    - 정확성이 높은 편입니다.

    단점
    - 대규모 문자열에서는 실행 속도가 느려질 수 있습니다.
    - 텍스트가 아닌 데이터 (예: 숫자)의 유사도를 측정하는 데는 적합하지 않습니다.
#SequenceMatcher 이용 유사도 측정

df_similar = pd.DataFrame(index=range(2,20000), columns=['대상조직','비교대상조직','유사도'])#데이터프레임 만들기

total_count = 0
answer_count = -1
input_count = 0

for i in target_dataframe.index:
    answer_count = answer_count + 1
    input_count = 0
    print("answer_count=",answer_count)

    for z in target_dataframe.index:
              
        #유사도측정
        answer_bytes = bytes(target_dataframe.loc[answer_count,'코멘트(불용어제거)'], 'utf-8') #대상조직 코멘트
        input_bytes = bytes(target_dataframe.loc[input_count,'코멘트(불용어제거)'], 'utf-8') #비교대상조직 코멘트
        answer_bytes_list = list(answer_bytes)
        input_bytes_list = list(input_bytes)
      
        sm = difflib.SequenceMatcher(None, answer_bytes_list, input_bytes_list)
        similar = sm.ratio()
        
        #데이터프레임
        df_similar.iloc[total_count]['대상조직'] = target_dataframe.iloc[answer_count,0] #대상조직명
        df_similar.iloc[total_count]['비교대상조직'] = target_dataframe.iloc[input_count,0] #비교대상조직명
        df_similar.iloc[total_count]['유사도'] = similar #유사도  
        
        print("total_count=",total_count)
        print("input_count=",input_count)
        total_count = total_count + 1
        input_count = input_count +1
        
df_similar

조직별 Groupby된 자료[total_피평가자조직] 예시입니다.

대상조직 비교대상조직 유사도
개발1팀 사업1팀 0.03
개발1팀 사업2팀 0.3
개발1팀 AI팀 1
사업1팀 AI팀 0.5
사업2팀 데이터팀 0.1
사업2팀 인사팀 0.2
….
재무실 개발2팀 1

 


2.  ONA 시각화

시각화에 대한 코드 예시는 아래 html파일로 확인할 수 있습니다.
https://drive.google.com/file/d/17OW-dYF1m4qT8X9M4qX264_q-kdp4EzV/view?usp=sharing

2D 시각화
3D 시각화


3.  결과해석 및 활용

본 글에서는 동료평가에서 키워드간의 유사도를 분석하고 networkx를 사용하여 이들 간의 관계를 시각화하였습니다.
조직 네트워킹 분석을 통해 각 조직간 커뮤니케이션 패턴 및 협업에 필요한 다양한 인사이트를 확인할 수 있습니다.
아래는 여러 가지 활용 방안을 정리한 내용입니다.

  • 여러 조직과 높은 유사도를 많이 확보한 인플루언서 조직을 확인할 수 있습니다.
  • 다양한 조직과 높은 연결성을 가진 허브 조직을 확인할 수 있습니다.
  • 병목현상을 완화할 수 있는 조직 위치를 파악할 수 있습니다.
  • 조직 개편에 따른 영향도(혹은 임팩트)를 파악하여 조직을 재구성할 수 있습니다.

코멘트 유사도를 활용한 조직 네트워크 분석은 기존 ONA방법론(설문조사를 통한 정량화된 데이터 활용)과 다른 접근방식으로 진행되었습니다. 조직의 구성원들이 평가받은 코멘트 내용이 타 조직과 유사하면 해당 조직 간의 협업 잠재력이 높을 것이라는 가정이 있었으며, 구체적으로 여러 가지 영향도와 신뢰도를 측정해야하는 과제도 남아있습니다.


Reference

[NLP] 문서 군집화(Clustering)와 문서간 유사도(Similarity) 측정하기

 

[NLP] 문서 군집화(Clustering)와 문서간 유사도(Similarity) 측정하기

이번 포스팅에서는 여러가지의 문서들을 군집화시켜보고 특정 하나의 문서가 다른 문서들간의 유사도를 측정해보는 방법에 대해서 알아보려고 한다. 군집분석은 비지도 학습으로 비슷한 데이

techblog-history-younghunjo1.tistory.com

[Python] 머신러닝 완벽가이드 - 08. 텍스트 분석[문서 군집화]

 

[Python] 머신러닝 완벽가이드 - 08. 텍스트 분석[문서 군집화]

텍스트 분석의 종류 중 하나인 문서 군집화 실습

romg2.github.io

자연어 처리 - 문장의 유사도 측정

 

https://www.google.com/url?cd=&esrc=s&q=&rct=j&sa=t&source=web&url=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeE90hB%2FbtqFViUcfbu%2FJ544X6Jps0mltgOIKrsZO0%2FKoNLP%2520%2528%25EC%259E%2590%25EC%2597%25B0%25EC%2596%25B4%2520%25EC%25B2%2598%25EB%25A6%25AC%2529%25203%2520-%2520%25EB%25AC%25B8%25EC%259E%25A5%2520%25EC%259C%25A0%25EC%2582%25AC%25EB%258F%2584%2520%25EC%25B8%25A1%25EC%25A0%2595.html%3Fattach%3D1%26knm%3Dtfile.html&usg=AOvVaw0xIQPDk8cT8Ho_H3_I2jMQ&ved=2ahUKEwjnhpPl_Jj-AhX5hlYBHWn-CgsQFnoECAkQAQ

 

www.google.com

[python] Text 유사도를 측정하는 여러 방법 (velog.io)

 

[python] Text 유사도를 측정하는 여러 방법

text 유사도를 측정해보아요

velog.io

3D Network Graphs in Python/v3

 

3d

How

plotly.com

Comments