728x90
반응형
2023/0907
** 연관 분석
1. word2vec
1.1) CBOW(Continuous Bag of Words)
- 여러 개의 단어를 나열한 뒤 이와 관련된 단어를 추정하는 문제
- 문자에서 나오는 n개의 단어 열로부터 다음 단어를 예측하는 것
the quick brown fox jumped over the lazy dog 이라는 문장을 훈련
the quick brown을 제시하면 fox를 추천하는 형태
1.2) Skip-Gram
- 특정한 단어로부터 문맥을 구성할 수 있는 단어를 예측하는 방식으로 window size라는 매개변수를 이용해서 단어를 예측
위의 문장에서 window size를 1로 설정
quick를 배치하면 the 와 brown을 가져옵니다.
window size를 2로 늘리면 brown fox 가 옵니다.
1.3) word2vec
- CBOW 와 Skip-Gram 방식으 ㅣ단어 임베딩을 구현한 C++ 라이브러리
- python 에서는 gensim 패키지의 Word2Vec 이란 클래스를 이용해서 제공
문장들을 매개변수로 받아서 유사도 계산을 해주고 가장 유사한 문장을 리턴해주는 기능을 제공하며 positive 와 negative 인수를 사용해서 관계도 찾을 수 있습니다.
1.4) 네이버 지식인 데이터를 크롤링 해서 단어 추천하기
검색 : https://search.naver.com/search.naver?where=kin&sm=tab_jum&ie=utf8&query=검색어&start=인덱스
검색어 : 네이버 지식iN검색
'검색어'의 네이버 지식iN검색 결과입니다.
search.naver.com
- 데이터 가져오기
from bs4 import BeautifulSoup
import time
import requests
from tqdm import tqdm_notebook
present_candi_text = []
html = 'https://search.naver.com/search.naver?where=kin&sm=tab_jum&ie=utf8&query=손흥민&start='
for n in range(1, 1000, 10):
response = requests.get(html + str(n))
try :
#print(response) #문제 발생
soup = BeautifulSoup(response.text, "html.parser")
tmp = soup.select('div.question_area > div.question_group > a')
for line in tmp:
#print(line.text)
present_candi_text.append(line.text)
except :
print("예외 발생")
time.sleep(0.5)
print(present_candi_text)
- 형태소 분석
import nltk
from konlpy.tag import Twitter
twitter = Twitter()
present_text = ''
for each_line in present_candi_text[:10000]:
present_text = present_text + each_line + '\n'
tokens_ko = twitter.morphs(present_text)
print(tokens_ko)
- 크롤링 데이터 전처리 및 한글자 제거
stop_words = ['.','\n','에서','<','가','당','요','답변','적','을','구','에','질문','제','를','이','도',
'좋','1','는','로','임영웅','으로','볼','것','은','다',',','니다','대','들',
'데','..','의','때','겠','고','게','바랍니다','한','일','할','어떻게','전부',
'10','?','하는','06','주','려고','인데','거','좀','는데','~','vs','...',
'하나','이상','20','뭐','까','있는','잘','습니다','다면','했','주려','비교',
'지','있','못','후','중','줄','알려주세요','과','어떤','기본','도서','ㅠㅠ', '시청',
'단어','라고','중요한','이번','없는','수','곳','이','보이','네','넣을까요']
tokens_ko = [each_word for each_word in tokens_ko
if each_word not in stop_words
if len(each_word) > 1]
ko = nltk.Text(tokens_ko, name='손흥민')
ko.vocab().most_common(50)
- 시각화
plt.figure(figsize=(15,6))
ko.plot(50)
plt.show()
- 워드 클라우드
import pytagcloud
data = ko.vocab().most_common(101) #단어 개수
taglist = pytagcloud.make_tags(data, maxsize=200)
for i in taglist:
if i["tag"] == '손흥민':
taglist.remove(i)
#태그 클라우드 생성
pytagcloud.create_tag_image(taglist, 'wordcloud.png', size=(900, 600), fontname='Korean', rectangular=False)
import matplotlib.pyplot
import matplotlib.image
img = matplotlib.image.imread('wordcloud.png')
imgplot = matplotlib.pyplot.imshow(img)
matplotlib.pyplot.show()
1.5) 연관 규칙 분석
- 원본 데이터에서 대상들의 연관된 규칙을 찾는 무방향성 데이터 마이닝 기법
- 하나의 거래나 사건에 포함된 항목 간의 관련성을 찾아서 둘 이상의 항목들로 구성된 연관성 규칙을 도출하는 탐색적 기법
- 트랜잭션 대상으로 트랜잭션 내의 연관성을 분석해서 거래의 규칙이나 패턴을 찾아내는 분석 방법.
- 장점
조건 반응 표현식의 결과를 이해하기 쉬움
비목적성 분석이 용이
편리한 분석 데이터 형태
계산의 용이성
- 단점
계산 시간이 오래 걸림
적절한 품목의 결정이 어려움 - 거래량이 적은 품목과 거래량이 많은 품목에 대한 상대성 차이에 의해 결과가 다르게 나타날 수 있고 규칙을 발견하기가 어려움
- 규칙은 if A ---> B
특정 사건이 발생했을 때 함께 발생하는 또 다른 사건의 규칙을 의미
- 연관 규칙은 A를 산 사람이 B를 함께 살 확률이 어떻게 되는 가를 보는 것이고 순차 분석은 A를 산 후 B를 살 확률이 얼마나 되는가
연관 규칙은 순서와 상관이 없지만 순차 분석은 순서가 상관 있음
- 활용 분야
고객 대상 상품 추천 및 상품 정보 발송
염기 서열 분석(단백질 서열과 같은 DNA 패턴)과 질병의 관계
의료비 허위 청구 순서 패턴 분석
불량 유발 공정 및 장비 패턴 탐지
웹 사이트의 메뉴 별 클릭 순서
- 분석 절차
거래 내역 데이터를 대상으로 트랜잭션 객체 생성
품목과 트랜잭션 ID 확인
지지도, 신뢰도, 향상도를 이용한 연관 규칙 발견
연관 규칙에 대한 시각화 - 네트워크 시각화
연관 분석 결과를 해설 및 업무 적용
- 연관 규칙 평가 척도
Support(지지도)
: n(X ^ Y)/N
전체 거래 개수에서 X 와 Y 가 모두 포함된 건수의 비율
전체 품목에서 X와 Y가 모두 구매한 거래 확률임.
지지도가 낮다는 것은 거래가 자주 발생하지 않는다는 의미
X와 Y의 순서를 변경해도 값은 그대로
Confidence(신뢰도)
: n(X ^ Y) / n(X)
X를 구매한 거래 중에서 Y도 구매한 경우
지지도는 포함 비중이 낮으면 연관성을 파악하기가 어려움
Lift(향상도)
: c(X ->Y) / s(Y)
두 항목의 독립성 여부를 수치로 제공
이 값이 1이면 완전 독립
이 값이 1보다 작으면 음의 상관관계
이 값이 1보다 크면 양의 상관 관계로 같이 구매할 확률이 높아지는 것
- 파이썬에서는 apyori 패키지를 이용해서 제공
하나의 트랜잭션을 list로 만들고 이 들의 list를 가지고 rule을 생성
인스턴스를 만들 때 지지도, 향상도, 신뢰도를 설정할 수 있음.
- 손흥민 연관 분석 예시
df = pd.read_csv("./tweet_temp.csv")
df.head()
#한글 이외의 문자 제거
import re
# 텍스트 정제 함수 : 한글 이외의 문자는 전부 제거합니다.
def text_cleaning(text):
hangul = re.compile('[^ ㄱ-ㅣ가-힣]+') # 한글의 정규표현식을 나타냅니다.
result = hangul.sub('', text)
return result
# ‘tweet_text’ 피처에 이를 적용합니다.
df['ko_text'] = df['tweet_text'].apply(lambda x: text_cleaning(x))
df.head()
# ‘tweet_text’ 피처에 이를 적용합니다.
df['ko_text'] = df['tweet_text'].apply(lambda x: text_cleaning(x))
df.head()
- 한글 형태소 분석
from konlpy.tag import Okt
from collections import Counter
# 한국어 약식 불용어사전 예시 파일 - https://www.ranks.nl/stopwords/korean
korean_stopwords_path = "./korean_stopwords.txt"
with open(korean_stopwords_path, encoding='utf8') as f:
stopwords = f.readlines()
stopwords = [x.strip() for x in stopwords]
def get_nouns(x):
nouns_tagger = Okt()
nouns = nouns_tagger.nouns(x)
# 한글자 키워드를 제거합니다.
nouns = [noun for noun in nouns if len(noun) > 1]
# 불용어를 제거합니다.
nouns = [noun for noun in nouns if noun not in stopwords]
return nouns
# ‘ko_text’ 피처에 이를 적용합니다.
df['nouns'] = df['ko_text'].apply(lambda x: get_nouns(x))
print(df.shape)
df.head()
- 거래를 만들어 연관 규칙 분석
!pip install apyori
from apyori import apriori
# 장바구니 형태의 데이터(트랜잭션 데이터)를 생성
transactions = [
['손흥민', '시소코'],
['손흥민', '케인'],
['손흥민', '케인', '포체티노']
]
# 연관 분석을 수행
results = list(apriori(transactions))
for result in results:
print(result)
- 옵션 설정
# 지지도 0.5, 신뢰도 0.6, 향상도 1.0 이상이면서 (손흥민, 케인) 처럼 규칙의 크기가 2 이하인 규칙을 추출
list(apriori(transactions,
min_support=0.5,
min_confidence=0.6,
min_lift=1.0,
max_length=2))
# 트랜잭션 데이터를 추출합니다.
transactions = df['nouns'].tolist()
transactions = [transaction for transaction in transactions if transaction] # 공백 문자열을 방지합니다.
print(transactions)
# 연관 분석을 수행
results = list(apriori(transactions,
min_support=0.1,
min_confidence=0.2,
min_lift=5,
max_length=2))
print(results)
# 데이터 프레임 형태로 정리합니다.
columns = ['source', 'target', 'support']
network_df = pd.DataFrame(columns=columns)
# 규칙의 조건절을 source, 결과절을 target, 지지도를 support 라는 데이터 프레임의 피처로 변환합니다.
for result in results:
if len(result.items) == 2:
items = [x for x in result.items]
row = [items[0], items[1], result.support]
series = pd.Series(row, index=network_df.columns)
network_df = network_df.append(series, ignore_index=True)
network_df.head()
- 말뭉치 추출하여 키워드 빈도를 추출하기
# 말뭉치를 추출
tweet_corpus = "".join(df['ko_text'].tolist())
print(tweet_corpus)
from konlpy.tag import Okt
from collections import Counter
# 명사 키워드를 추출합니다.
nouns_tagger = Okt()
nouns = nouns_tagger.nouns(tweet_corpus)
count = Counter(nouns)
# 한글자 키워드를 제거합니다.
remove_char_counter = Counter({x : count[x] for x in count if len(x) > 1})
print(remove_char_counter)
# 키워드와 키워드 빈도 점수를 ‘node’, ‘nodesize’ 라는 데이터 프레임의 피처로 생성
node_df = pd.DataFrame(remove_char_counter.items(), columns=['node', 'nodesize'])
node_df = node_df[node_df['nodesize'] >= 50] # 시각화의 편의를 위해 ‘nodesize’ 50 이하는 제거합니다.
node_df.head()
##result
node nodesize
2 축구 140
4 손흥민 560
5 선수 140
7 모델 105
10 한국 105
- 네트워크 시각화
!pip install networkx
import networkx as nx
plt.figure(figsize=(25,25))
# networkx 그래프 객체를 생성합니다.
G = nx.Graph()
# node_df의 키워드 빈도수를 데이터로 하여, 네트워크 그래프의 ‘노드’ 역할을 하는 원을 생성합니다.
for index, row in node_df.iterrows():
G.add_node(row['node'], nodesize=row['nodesize'])
# network_df의 연관 분석 데이터를 기반으로, 네트워크 그래프의 ‘관계’ 역할을 하는 선을 생성합니다.
for index, row in network_df.iterrows():
G.add_weighted_edges_from([(row['source'], row['target'], row['support'])])
# 그래프 디자인과 관련된 파라미터를 설정합니다.
pos = nx.spring_layout(G, k=0.6, iterations=50)
sizes = [G.nodes[node]['nodesize']*25 for node in G]
nx.draw_networkx(G, pos=pos, node_size=sizes)
# Windows 사용자는 AppleGothic 대신,'Malgun Gothic'. 그 외 OS는 OS에서 한글을 지원하는 기본 폰트를 입력합니다.
nx.draw_networkx_labels(G, pos=pos, font_family='Malgun Gothic', font_size=25)
# 그래프를 출력합니다.
ax = plt.gca()
plt.show()
3. 추천 시스템
3.1) 개요
- 구현 방법
Contents Based Filtering(콘텐츠 기반 필터링)
사용자가 특정한 아이템을 선호하는 경우 그 아이템과 유사한 콘텐츠를 가진 다른 아이템을 추천하는 방식
A 라는 영화를 보고 평점을 8점이라고 매기고 B라는 영화를 보고 평점을 9 점이라고 매긴다면 추후에 B라는 영화의 감독, 배우, 장르와 유사한 영화를 추천
Collaborative Filtering(협업 기반 필터링)
Nearest Neighbor(최근접 이웃) 협업 필터링 Latent Factor(잠재 요인) 협업 필터링으로 나눔
사용자가 아이템에 매긴 평점 정보나 구매 이력 등을 기반으로 사용자 행동 양식만을 기반으로 만드는 방식
사용자와 아이템 평점 매트릭스가 있다면 사용자가 특정 아이템에 매긴 평점을 가지고 아직 사용자가 매기지 않은 아이템에 대해서 평점을 예측하는 방식 -> 이 방식은 희소 행렬을 이용합니다.
최근접 이웃 필터링 : 아이템에 매겨진 점수를 기반으로 거리 계산을 하여 추천
잠재 요인 협업 필터링 : 사용자를 행으로 놓고 각 아이템을 열(피처)에 배치
사용자는 거의 모든 피처에 None을 소유
주성분 분석과 같은 차원 축소를 해서 None이 거의 없을 것이고 이를 복원하게 되면 빈자리에 값이 채워지게 됩니다.
차원 축소를 할 때 행렬 분해를 사용
- 예전에는 콘텐츠 기반 필터링과 최근접 이웃이 많이 사용되었는데 넷플릭스 추천 대회에서 행렬 분해를 이용한 Latent Factor 가 우승하면서 최근에 많이 사용
- 최근에는 여기서도 앙상블 기법처럼 콘텐츠 기반 필터링과 협업 기반 필터링을 같이 사용하기도 합니다.
3.2) 콘텐츠 기반 필터링
데이터는 kaggle에서 tmdb 5000 movies 데이터를 가지고 왔습니다.
- 데이터 읽어오기
movies = pd.read_csv('./data/movielens/movies.csv')
ratings = pd.read_csv('./data/movielens/ratings.csv')
print(movies.shape)
print(ratings.shape)
- 데이터를 탐색하면서 사용할 만한 피처를 추출
상품 추천 실습 코드 입니다!!
11.AssociationAnalysis.ipynb
0.27MB
반응형
LIST
'LG 헬로비전 DX DATA SCHOOL > Python' 카테고리의 다른 글
Tensorflow를 이용한 회귀 와 분류 (0) | 2023.09.15 |
---|---|
TensorFlow (0) | 2023.09.15 |
NLP(Natural Language Processing) 자연어 처리 (0) | 2023.09.05 |
차원 축소 (DimensionalityReduction) (0) | 2023.09.04 |
군집 분석 2 (0) | 2023.09.04 |