<jupyter_start><jupyter_text>출처: https://blog.breezymind.com/2018/03/02/sklearn-feature_extraction-text-2/<jupyter_code>import pandas as pd
import numpy as np
pd.options.mode.chained_assignment = None
np.random.seed(0)

from konlpy.tag import Mecab
mecab = Mecab()


from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.metrics.pairwise import linear_kernel, cosine_similarity

# tokenizer : 문장에서 색인어 추출을 위해 명사,동사,알파벳,숫자 정도의 단어만 뽑아서 normalization, stemming 처리하도록 함
def tokenizer(raw, pos=["NNG","NNP"], stopword=['수','퀄리티','도시','분','전문','스타','년','원',\
                       '월','화','수','목','금','시','앤','일','그램','문'] ):
    return [
        word for word, tag in mecab.pos(raw)
            if len(word) > 1 and tag in pos and word not in stopword
        ]

# 테스트 문장
df = pd.read_csv("word2vec_wrangling.csv")
df.head()
import re

def preprocessing(text):
    # 개행문자 제거
    text = re.sub('\\\\n', ' ', text)
    # 특수문자 제거
    # 특수문자나 이모티콘 등은 때로는 의미를 갖기도 하지만 여기에서는 제거했습니다.
    # text = re.sub('[?.,;:|\)*~`’!^\-_+<>@\#$%&-=#}※]', '', text)
    # 한글, 영문, 숫자만 남기고 모두 제거하도록 합니다.
    # text = re.sub('[^가-힣ㄱ-ㅎㅏ-ㅣa-zA-Z0-9]', ' ', text)
    # 한글, 영문만 남기고 모두 제거하도록 합니다.
    text = re.sub('[^가-힣ㄱ-ㅎㅏ-ㅣa-zA-Z]', ' ', text)
    return text
%time rawdata = df['Content_txt'].apply(preprocessing)
vectorize = CountVectorizer(
    tokenizer=tokenizer, 
    min_df=10    # 예제로 보기 좋게 1번 정도만 노출되는 단어들은 무시하기로 했다
                # min_df = 0.01 : 문서의 1% 미만으로 나타나는 단어 무시
                # min_df = 10 : 문서에 10개 미만으로 나타나는 단어 무시
                # max_df = 0.80 : 문서의 80% 이상에 나타나는 단어 무시
                # max_df = 10 : 10개 이상의 문서에 나타나는 단어 무시
)
 
# 문장에서 노출되는 feature(특징이 될만한 단어) 수를 합한 Document Term Matrix(이하 DTM) 을 리턴한다
X = vectorize.fit_transform(rawdata)
 
print(
    'fit_transform, (sentence {}, feature {})'.format(X.shape[0], X.shape[1])
)
# fit_transform, (sentence 5, feature 7)
 
print(type(X))
# <class 'scipy.sparse.csr.csr_matrix'>
 
print(X.toarray())

# [[0, 1, 2, 0, 0, 0, 1],
# [0, 1, 1, 0, 0, 0, 2],
# [1, 0, 0, 2, 1, 1, 0],
# [1, 0, 0, 1, 0, 0, 0],
# [0, 0, 0, 3, 1, 1, 0]]
 
# 문장에서 뽑아낸 feature 들의 배열
features = vectorize.get_feature_names()
# 박조은 튜토리얼 이어나가려고 함
vectorizer = vectorize
feature_vector = X
feature_vector.shape
vocab = vectorizer.get_feature_names()
print(len(vocab))
vocab[:10]
# 각 리뷰마다 등장하는 단어에 빈도수가 표현됩니다. 0 은 등장하지 않음을 의미합니다.
pd.DataFrame(feature_vector[:10].toarray(), columns=vocab).head()
# 위에서 구한 단어벡터를 더하면 단어가 전체에서 등장하는 횟수를 알 수 있습니다.
# 벡터화 된 피처를 확인해 봄
# Bag of words 에 몇 개의 단어가 들어있는지 확인
dist = np.sum(feature_vector, axis=0)
    
df_freq = pd.DataFrame(dist, columns=vocab)
df_freq
# 행과 열의 축을 T로 바꿔주고 빈도수로 정렬
df_too_much = df_freq.T.sort_values(by=0, ascending=False).head(50)
df_too_much
df_too_much.T
too_much_list = list(df_too_much.T.columns.values)
print(too_much_list)
# df_freq_T = df_freq.T.reset_index()
# df_freq_T.columns = ["course", "freq"]
# # 강의명을 토큰 3개로 중복제거하기 위해, 강좌명에서 지식공유자의 이름을 빈문자열로 변경
# df_freq_T["course_find"] = df_freq_T["course"].str.replace("홍정모의", "")
# df_freq_T["course_find"] = df_freq_T["course_find"].apply(lambda x : " ". join(x.split()[:4]))
# df_freq_T.sort_values(["course_find", "freq"], ascending=False).head(10)<jupyter_output><empty_output><jupyter_text>TF-IDF<jupyter_code>from sklearn.feature_extraction.text import TfidfTransformer
transformer = TfidfTransformer(smooth_idf=False)
transformer
%%time 
feature_tfidf = transformer.fit_transform(feature_vector)
feature_tfidf.shape
feature_tfidf
# 각 row에서 전체 단어가방에 있는 어휘에서 등장하는 단어에 대한 one-hot-vector에 TF-IDF 가중치 반영
tfidf_freq = pd.DataFrame(feature_tfidf.toarray(), columns=vocab)
tfidf_freq.head() 
df_tfidf = pd.DataFrame(tfidf_freq.sum())
df_tfidf_top = df_tfidf.sort_values(by=0, ascending=False)
df_tfidf_top.head(50)
df_tfidf_bottom = df_tfidf.sort_values(by=0, ascending=True)
df_tfidf_bottom.head(10)
# 중간에 생략되는 단어를 자세히 보고자 할 때
# 제일 쓸모 없는 단어들 뽑아내기

top_list = []
for t in df_tfidf_top.index[:50]:
    top_list.append(t)
print(top_list)

['요가','필라테스','다이어트','']
list_too_much1 = ['운동', '요가', '필라테스', '댄스', '다이어트', '헬스', '발레', '번지', '플라잉', '살사', '니스', '복싱', '수업', '여자', '패들', '아쿠아', '일상', '시간', '보드', '서핑', '수영', '피트', '강사', '바디', '자이로', '오늘', '피닝', '남자', '레슨', '취미', '점핑', '여행', '회원', '건강', '맛집', '라틴', '키즈', '교육', '가능', '크로스', '소통', '바이크', '감사', '기구', '부산', '토닉', '교정', '스포츠', '그룹', '후프', '진행', '시작', '검도', '볼링', '등산', '수련', '클라이밍', '클럽', '개인', '학원', '사진', '서프', '데일리', '트레이닝', '센터', '스튜디오', '상담', '수영장', '에어로빅', '무용', '드럼', '동요', '피티', '트램', '탕가', '조깅', '공연', '파운드', '야사', '폴린', '광주', '수중', '피지', '동호회', '사람', '킥복싱', '휘트', '대구', '카페', '지도자', '선수', '핫요가', '플라이', '타요', '기부', '하루', '행복', '일산', '사이클', '체형']
list_too_much_tf_idf = ['운동', '요가', '필라테스', '댄스', '번지', '다이어트', '복싱', '발레', '니스', '수업', '플라잉', '헬스', '살사', '여자', '피트', '시간', '강사', '일상', '점핑', '취미', '바디', '교육', '오늘', '레슨', '남자', '키즈', '회원', '보드', '맛집', '가능', '교정', '라틴', '여행', '건강', '피닝', '진행', '서핑', '그룹', '플라이', '잠실', '개인', '부산', '스튜디오', '시작', '기구', '자이로', '학원', '상담', '센터', '감사', '피지', '소통', '지도자', '과정', '수련', '무용', '대구', '자격증', '클럽', '수영', '홍대', '볼링', '일산', '트레이닝', '동요', '동호회', '토닉', '사진', '영상', '크로스', '오픈', '사람', '데일리', '방송', '광주', '선생', '자세', '마음', '체형', '문의', '행복', '사랑', '카페', '근력', '동작', '탕가', '클래스', '드럼', '친구', '카톡', '무료', '전화', '스포츠', '공연', '야사', '할인', '하루', '에어로빅', '등록', '준비']
list_too_much_200 = list_too_much1 + list_too_much_tf_idf
bulyongeo_list = list(set(list_too_much_200))
print(bulyongeo_list)<jupyter_output>['점핑', '동작', '광주', '가능', '사진', '데일리', '공연', '하루', '카페', '영상', '바디', '일산', '검도', '살사', '대구', '사람', '볼링', '동요', '조깅', '등산', '체형', '클럽', '피지', '휘트', '무료', '자이로', '드럼', '발레', '수업', '폴린', '자격증', '피트', '트램', '홍대', '등록', '준비', '수영장', '센터', '댄스', '패들', '토닉', '요가', '일상', '클라이밍', '필라테스', '회원', '잠실', '여행', '취미', '여자', '킥복싱', '번지', '후프', '학원', '교육', '니스', '사랑', '부산', '스튜디오', '피티', '선생', '플라이', '레슨', '남자', '선수', '강사', '친구', '자세', '서핑', '교정', '클래스', '무용', '행복', '그룹', '수련', '트레이닝', '방송', '플라잉', '바이크', '수영', '키즈', '동호회', '지도자', '오늘', '타요', '개인', '헬스', '할인', '에어로빅', '기부', '상담', '라틴', '시작', '맛집', '아쿠아', '다이어트', '파운드', '카톡', '건강', '오픈', '마음', '수중', '탕가', '감사', '진행', '운동', '복싱', '소통', '문의', '전화', '사이클', '서프', '야사', '크로스', '근력', '기구', '시간', '핫요가', '피닝', '과정', '스포츠', '보드']
{'fraction_non_alphanumeric': 0.2589429584273284, 'fraction_numerical': 0.01643570737995488, 'mean_word_length': 4.45910290237467, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 11, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '142906', 'license': 'MIT', 'n_tokens_mistral': 3873, 'n_tokens_neox': 4820, 'n_words': 718, 'path': '2.KoNLPy frequency check with Mecab Tokenizer-Joeun_Park_Tutorial.ipynb', 'repo_name': 'fitcuration/instagram_hashtag_analysis', 'size': '6206'}