문자열전처리 함수 모음

BABY CAT·2022년 8월 2일
0

data

목록 보기
1/6

DictVectorizer

from sklearn.feature_extraction import DictVectorizer # 백오브워드(빈도만고려) 인코딩 벡터 .벡터화장치
v = DictVectorizer(sparse=False)
D = [ {'A':1, 'B':2},{'B':3, 'C':1}]
X = v.fit_transform(D)
print(X) #피처는 단어 행은 문장
print(v.feature_names_)
d_l = { 'A':5, 'B':1, 'D':100 } # D로 피팅이되잇기 때문에 D:100 은 안뜨고 C자리엔 당연히0이들어감
print(v.transform(d_l)) 

CountVectorizer

from sklearn.feature_extraction.text import CountVectorizer #카운트기반으로보겟다
corpus = [
    'This is the first document.',
    'This is the second second document.',
    'And the third one.',
    'Is this the first document?',
    'The last document?'
]
v1 = CountVectorizer()
v1.fit(corpus) #corpus를 보캐불러리로 만들겟다
print(v1.vocabulary_) #보캐불러리의 단어마다 인덱스를 준 것  # : 숫자 는 인덱스다
print(v1.transform(['This is the second second document.']).toarray())  #숫자값을주는데  corpus로 핏햇으니까 이 기준 빈도수숫자를주는것 # second가 두개인데 위 숫자인덱에서 second는 6인덱스이기 때문에 6인덱자리에 2가들어간다 

# 트랜스폼, 보캐불러리, 디티엠
t_data = '나는 오늘은 습기가 높아서 슬퍼 강의는 잘 듣고 있니?'
from sklearn.feature_extraction.text import CountVectorizer
t_t = t_data.replace('?','')
bv = CountVectorizer()
bv.fit_transform([t_t]).toarray()
bv.vocabulary_ #보캐 : 단어별 인덱
문서 = [ '나는 강의는 어려워', '나는 날씨가 덥고 습기가 많아', '나는 오늘은 그냥 있니?' , '나는 수업은 듣고 있니?' ]
# DTM 행렬 / BOW빈도
bv.transform(문서).toarray()
bv2.vocabulary_
bv2 = CountVectorizer(stop_words=['나는']) #불용어=나는
bv2.fit_transform(문서).toarray()
bv2.vocabulary_ # '나는'이 없다

Tokenizer를 활용한 카운트, TFIDF

data1 = '나는 오늘 정말 피곤해 그래서 힘들어'    # [ eq.wqe.ewq ]한문장이 하나의 벡터 하나의 점-원점 선의 방향
data2 = '나는 오늘 정말 못해 그래서 힘들어' 
data3 = '나는 오늘 너무 즐거와 그래서 행복해' 

data = [data1,data2,data3]
from tensorflow.keras.preprocessing.text import Tokenizer
tk = Tokenizer()
tk.fit_on_texts(data)
tk.index_word

tk.texts_to_matrix(data, mode='count')
tk.texts_to_matrix(data, mode='tfidf')

TfidfVectorizer

### TF*IDF 라이브러리 활용

# TF IDF 벡터라이저 불러오기
from sklearn.feature_extraction.text import TfidfVectorizer # TF IDF 값을 정규화한 형태
t_data = [ 
    '공부 하고 싶다' ,
    '공부 하고 싫다' ,
    '공부 내일 할까' ,
    '공부 하고 놀기' ,
    '놀기 말고 놀자' ] 
tfidfv = TfidfVectorizer().fit(t_data)
tfidfv.vocabulary_ # 단어:인덱스 의 t_data 기준 보캐불러리 생성
a = tfidfv.transform(t_data).toarray() # TF IDF 어레이
pd.DataFrame(a, columns = ['공부','내일','놀기','놀자','말고','싫다','싶다','하고','할까']) # TF IDF 데이터프레임으로 # tfidfv.vocabulary_ 로 칼럼확인
# 변수3개를 핏_트랜스폼
data1 = '나는 오늘 정말 피곤해 그래서 힘들어' 
data2 = '나는 오늘 정말 못해 그래서 힘들어' 
data3 = '나는 오늘 너무 즐거와 그래서 행복해' 
t_v = TfidfVectorizer()
m_data = t_v.fit_transform( [data1,data2,data3] ) # 각각의 문장들로 점 3개가 만들어졌다.
m_data.toarray() # 각각의 문장들로 점 3개가 만들어졌다.
m_data.toarray().shape # (3,10) # 단어10개 피처10개 해당피처에 숫자값

TF IDF 원시적 방법

### TF*IDF 원시적 방법

# 불러오기
from math import log # idf연산에 필요한 로그
import pandas as pd 
t_data = [ 
    '공부 하고 싶다' ,
    '공부 하고 싫다' ,
    '공부 내일 할까' ,
    '공부 하고 놀기' ,
    '놀기 말고 놀자' ] 

# 단어 (보캐불러리셋집합만들기)
vos = list(set( 단어 for 문장 in t_data for 단어 in 문장.split())) # 중복방지를위한set # t_data에서 문장을 꺼내서 스플릿해서 단어를 꺼내서 리스트로 만든다.

# TF 특정문서에서 특정 단어의 등장 횟수 (DTM의 값)
# DT 특정 단어가 등장한 문장의 수
# IDF 디티에 반비례하는 수 (로그 1플러스 디티 분의 엔)
# TFIDF : TF 곱하기 IDF , DTM 데이터프레임에 각 밸류에 각각의 가중치를 곱한 것

# TF-IDF  공식 코드화

# TF 빈도
n=len(t_data) # 문장의 개수
def tf(t,d):       
    return d.count(t)    # d 문서에 t 단어가 몇번 나왔는지 count 

# IDF 가중치, 역빈도(문장안의 빈도가 적으면 오히려 주요단어일 가능성이 높아서 가중치가 높다)
def idf(t):
    df=0 
    for 문장 in t_data:
        df +=  t in 문장   # 문장안에 t 가 있다면 1이 df에 전달됨 > df 에 +1 씩 증가함 
    return log(n/(df+1))                   # idf 공식    idf(d,t) = log ( n / 1+df(t) )

# TFIDF
def tfidf(t,d):
    return tf(t,d)*idf(t)

# DTM = tf table
t_l = []
for i in range(n): # 문장개수
    t_l.append([]) # 이차원리스트를만들기위한 [ [],[],[] ] #인덱스넣을칸작업
    d = t_data[i] # 문서에서 문장을 하나 뽑기
    for j in range(len(vos)): #vos 보캐불러셋집합
        t = vos[j] # 보캐에서 단어 하나를 뽑고
        t_l[-1].append(tf(t,d))   # [ [] ] 에 단어의 빈도를 넣는다 
import pandas as pd
tf_ = pd.DataFrame(t_l, columns = vos)
tf_  # 싶다 - 1이 하나뿐 > 문장에서 주요의미 > 가중치 높게

# IDF 연산 후 데이터프레임으로 만들기
idf_l = []
for i in range(len(vos)):
    t = vos[i] # 보캐에서 단어 하나를 뽑음
    idf_l.append(idf(t)) # IDF(t)로 단어t의 가중치를 뽑아서 리스트에 넣음
idf_ = pd.DataFrame(idf_l , index=vos , columns=['IDF']) 
idf_ # 각 보캐단어별 idf  가중치를 보여준다  (단어마다 weight 곱셈 = 벡터화)

# TFIDF를 연산 후 데이터프레임으로 만들기
tf_idf_l = []
for i in range(n): # n: 문장 개수
    tf_idf_l.append([]) # [ [] ] 이차원리스트생성
    d = t_data[i]  # 데이터에서 문서하나를 뽑음
    for j in range(len(vos)):  # 보캐len만큼
        t = vos[j] # 보캐에서 단어 하나씩 뽑음
        tf_idf_l[-1].append(tfidf(t,d)) # 이차원빈리스트에 TFIDF 값을 넣음
tf_idf_ = pd.DataFrame(tf_idf_l, columns=vos )
tf_idf_  # 데이터테이블: tf 와 idf 곱   tf-idf

# 국소표현.이산표현  BOW DTM  TF-IDF  (임베딩도 일종의 국소표현 임베딩을 하면 된다 단 유사도검사시 TF IDF로)
# 분산표현.연속표현  Word2Vec, FastText

# TFIDF 전용 라이브러리가 있기 때문에 위 코드는 더 쓰진 않는다.

pad_sequences

# 패딩 컨트롤 (디폴트 권장: 앞쪽으로 0 채우고 맥스렌으로 앞쪽부터 지워진다), 보통은 미괄식이니까 디폴트로 앞에서 0을 채운다. 그리고 순환시퀀스 특성상 단기기억 문제로 앞이 지워지기 때문에
ck_t_x = pad_sequences(t_x) # 디폴트 : 0을 왼쪽에서 채우고 맥스렌으로 왼쪽부터 지운다. 
ck_t_x = pad_sequences(t_x, padding = 'post') # padding = 'post' : 0을 뒤쪽으로 채우는 패딩 (디폴트앞)
ck_t_x = pad_sequences (t_x, padding = 'post', maxlen=4)  # 맥스렌을 쓰면 앞쪽부터 지운다. 예외) 0 있을 경우 스캔방향과 상관없이 0부터 지운다
ck_t_x = pad_sequences (t_x, padding = 'post', maxlen=4, truncating='post', )  # truncating='post', 맥스렌으로 뒤쪽에서 지우기
ck_t_x = pad_sequences (t_x, padding = 'post', maxlen=4, truncating='post', value=3 )  # value = 3  : 0 대신 3으로 채워준다
ck_t_x = pad_sequences (t_x, padding = 'post', maxlen=4, truncating='post', value=v ) # v = len(tn.word_index)+1 : 0대신 v을 넣는다 : 0 대신 최댓값 넣기 : 최댓값이 갱신이 되더라도 자동으로 변경이된다

Okt

# Okt.pro(문장) 
# 문장을 받으면 '단어/형태소'로 쪼개주는 코드
! pip install konlpy
from konlpy.tag import Okt # 한국어 단어 토크나이저
from tqdm import tqdm # 무한루프에 걸렸는지 진행 중인지 확인하기 위한 # 작업의 진행사항을 알려주는 패키지  ~% 진행 표시
from nltk.util import ngrams # 엔그램 단어 묶기, 문맥
tk = Okt()
def tk_f(문장):
	tk_d=['/'.join(i) for i in tk.pos(문장)] #pos : [ ('단어','형태소') ] 여기서 i에  ( . )튜플들어가고 조인()에들어가면 단어,형태소 사이 쉼표를 /로 조인
	return tk_d
tk_f(긍정문장_data[0]) # ['흠/Noun', '.../Punctuation', '포스터/Noun' ]

# tk.tagset 
tk.tagset 출력 : {'Adjective': '형용사', 'Adverb': '부사'} 태그정보

# 문장처리 (각 단어 빈도), tk.morphs(입력문자) #쪼개기 
! pip install kss konlpy
import nltk, kss, konlpy
from konlpy.tag import Okt # 한국어 단어 토크나이저
t_data = '나는 오늘은 습기가 높아서 슬퍼 강의는 잘 듣고 있니?'
tk = Okt()
tk.morphs(t_data)
def 문장_처리(in_t):
    입력문자 = in_t.replace('?','') #물음표제거
    토큰_data= tk.morphs(입력문자) #쪼개기     
    단어집합 = {}    #보캐만들기
    단어빈도수 = []
    for 단어 in 토큰_data:
        if 단어 not in 단어집합 : #단어집합 딕셔너리에 없다면 # 딕셔너리에키값으로
            단어집합[단어] = len(단어집합)  # 키와밸류 추가 # len(단어집합)부터 연산하니까 0이 들어감 즉 0부터 순서값
            단어빈도수.insert(len(단어집합)-1 , 1) # insert    # 1:처음들어가니까  #  len(단어집합)-1인덱스의 값에 +1을 한다는 뜻 # 여기서는 하나들어갔으니까 1-1 >0인덱스에 +1
        else:
            단어인덱스 = 단어집합.get(단어)  # 단어의 인덱스 # get 밸류뽑아오는
            단어빈도수[단어인덱스] += 1 #횟수 기록
    return 단어집합, 단어빈도수 #튜플로 두개 리턴
문장_처리(t_data) # 는 > 1인덱스 > 두번째 리스트에서 1인덱스에 숫자2  는 이게 2번 나왔다는 뜻

ngrams

# 엔그램 : 단어를 n개씩 묶어서 문맥을 파악할 수 있다
ng= ngrams(data, 2, pad_left=True, pad_right=True, left_pad_symbol="SS", right_pad_symbol='SE') # 바이그램

0개의 댓글