-> p432 k-평균의 단점 1.
-> 많아짐
->make_blobs(),make_circles() p437 p471
-> n_target ,p433
비전형 텍스트에서 의미 있는 정보를 추출하는 것
. 머신러닝, 언어 이해, 통계 등을 활용해 모델을 수립하고 정보를 추출해 BI(비즈니스 인텔리전스)나 예측 분석 등의 분석 작업을 주로 수행텍스트 분석은 비정형 데이터인 텍스트를 분석하는 것이다.
지금까지 머신러닝 모델은 주어진 정형 데이터 기반에서 모델을 수립하고 예측을 수행하였는데, 텍스트를 머신러닝에 적용하기 위해서는 머신러닝 알고리즘이 숫자형의 피처 기반 데이터만 입력받을 수 있기 때문에 word 기반의 다수의 피처로 추출하고 이 피처에 단어 빈도수와 같은 숫자 값을 부여한 벡터 값으로 표현하는 텍스트 변환 방법인 (피처 벡터화), ( 피처 추출 )를 거쳐야 한다.
대표적인 방법으로 BOW ( Bag of Words )와 Word2Vec
방법이 있다.
BOW는 대표적으로 Count 기반과 TF-IDF 기반 벡터화가 있다.
클렌징
: 불필요한 문자, 기호 등을 사전에 제거 (ex. html, xml tag)토큰화
: 문장/단어 토큰화, n-gram, 쉼표기준으로 조각조각 내줌.Stemming
: 원형 단어로 변환 시, 일반적인 방법 또는 더 단순화된 방법을 적용해서 원래 단어에서 일부 철자가 훼손된 어근 단어를 추출하는 경향이 있음Lemmatization
: 품사와 같은 문법적인 요소와 더 의미적인 부분을 감안해 정확한 철자로 된 어근 단어를 찾아줌
copus : 말뭉치,코퍼스
stem : 어간
stemming : 어간추출
:plays -> playLemmatization : 표제어 추출
:is -> be 품사.
텍스트에서 분석에 방해가 되는 불필요한 문자, 기호 등을 사전에 제거하는 작업 ( ex. HTML, XML 태그나 특정 기호 등을 사전에 제거 )
문장/단어 토큰화, n-gram, 쉼표기준으로 조각조각 내줌.
# 각각의 문장으로 구성된 list 객체 반환
from nltk import sent_tokenize
import nltk
nltk.download('punkt')
text_sample = 'The Matrix is everywhere its all around us, here even in this room. \
You can see it out your window or on your television. \
You feel it when you go to work, or go to church or pay your taxes.'
sentences = sent_tokenize(text=text_sample)
print(type(sentences),len(sentences))
print(sentences)
-> oup put
[nltk_data] Downloading package punkt to /root/nltk_data...
[nltk_data] Unzipping tokenizers/punkt.zip.
<class 'list'> 3
['The Matrix is everywhere its all around us, here even in this room.', 'You can see it out your window or on your television.', 'You feel it when you go to work, or go to church or pay your taxes.']
from nltk import word_tokenize
sentence = "The Matrix is everywhere its all around us, here even in this room."
words = word_tokenize(sentence)
print(type(words), len(words))
print(words)
-> out put
<class 'list'> 15
['The', 'Matrix', 'is', 'everywhere', 'its', 'all', 'around', 'us', ',', 'here', 'even', 'in', 'this', 'room', '.']
from nltk import word_tokenize, sent_tokenize
#여러개의 문장으로 된 입력 데이터를 문장별로 단어 토큰화 만드는 함수 생성
def tokenize_text(text):
# 문장별로 분리 토큰
sentences = sent_tokenize(text)
# 분리된 문장별 단어 토큰화
word_tokens = [word_tokenize(sentence) for sentence in sentences]
return word_tokens
#여러 문장들에 대해 문장별 단어 토큰화 수행.
word_tokens = tokenize_text(text_sample)
print(type(word_tokens),len(word_tokens))
print(word_tokens)
문장을 개별 단어 별로 하나씩 토큰화하면 문맥적인 의미가 무시됨. 이러한 문제를 해결하려고 도입한 것이 n-gram
1-gram : uni-gram
2-gram : bi-gram
3-gram : tri-gram
n-gram :
스톱 워드 ( Stop Word )는 분석에 큰 의미가 없는 단어
를 지칭한다.
print('영어 stop words 갯수:',len(nltk.corpus.stopwords.words('english')))
print(nltk.corpus.stopwords.words('english')[:20])
import nltk
nltk.download('stopwords')
stopwords = nltk.corpus.stopwords.words('english')
all_tokens = []
# 위 예제의 3개의 문장별로 얻은 word_tokens list 에 대해 stop word 제거 Loop
for sentence in word_tokens:
filtered_words=[]
# 개별 문장별로 tokenize된 sentence list에 대해 stop word 제거 Loop
for word in sentence:
#소문자로 모두 변환합니다.
word = word.lower()
# tokenize 된 개별 word가 stop words 들의 단어에 포함되지 않으면 word_tokens에 추가
if word not in stopwords:
filtered_words.append(word)
all_tokens.append(filtered_words)
print(all_tokens)
문법적으로 또는 의미적으로 변화하는 단어의 원형을 찾는 것.
Stemming
( 어간 추출 ) : 원형 단어로 변환 시 일반적인 방법을 적용하거나 더 단순화된 방법을 적용해 원래 단어에서 일부 철자가 훼손된
어근 단어를 추출하는 경향이 있다. (stemmer 제공), ( Porter, Lancaster, Snowball Stemmer )
Lemmatization
( 표제어 추출 ) : 품사와 같은 문법적인 요소와 더 의미적인 부분을 감안해 정확한
철자로 된 어근 단어를 찾아준다. 변환에 오랜 시간 필요함. ( WordNetLemmatizer 제공 )
from nltk.stem import PorterStemmer
stemmer = PorterStemmer()
print(stemmer.stem('working'),stemmer.stem('works'),stemmer.stem('worked'))
print(stemmer.stem('amusing'),stemmer.stem('amuses'),stemmer.stem('amused'))
print(stemmer.stem('happier'),stemmer.stem('happiest'))
print(stemmer.stem('fancier'),stemmer.stem('fanciest'))
print(stemmer.stem('was'), stemmer.stem('were'))
-> out put
work work work
amus amus amus
happier happiest
fancier fanciest
wa were
from nltk.stem import LancasterStemmer
stemmer = LancasterStemmer()
print(stemmer.stem('working'),stemmer.stem('works'),stemmer.stem('worked'))
print(stemmer.stem('amusing'),stemmer.stem('amuses'),stemmer.stem('amused'))
print(stemmer.stem('happier'),stemmer.stem('happiest'))
print(stemmer.stem('fancier'),stemmer.stem('fanciest'))
-> out put
work work work
amus amus amus
happy happiest
fant fanciest
from nltk.stem import WordNetLemmatizer
import nltk
nltk.download('omw-1.4')
lemma = WordNetLemmatizer()
print(lemma.lemmatize('amusing','v'),lemma.lemmatize('amuses','v'),lemma.lemmatize('amused','v'))
print(lemma.lemmatize('happier','a'),lemma.lemmatize('happiest','a'))
print(lemma.lemmatize('fancier','a'),lemma.lemmatize('fanciest','a'))
-> out put
[nltk_data] Downloading package omw-1.4 to /root/nltk_data...
amuse amuse amuse
happy happy
fancy fancy
Bag of Words 모델은 문서가 가지는 모든 단어를 문맥이나 순서를 무시하고 일괄적으로 단어에 대해 빈도 값
을 부여해 피처 값
을 추출하는 모델이다.
문서 내 모든 단어를 한꺼번에 봉투 안에 넣은 뒤에 흔들어서 섞는다는 의미로 Bag of Words
모델이라고 한다.
BOW 모델의 장점
은 쉽고 빠르게 구축할 수 있다는 것
이고 단순히 단어의 발생 횟수에 기반하고 잇지만, 예상보다 문서의 특징을 잘 나타낼 수 있는 모델이다.
하지만 BOW 기반의 NLP 연구는 여러 가지 제약을 지니는데 우선은 문맥의 의미를 반영하지 못한다
는 단점
을 지닌다.
문맥적인 의미가 무시
된다.희소 행렬 문제
이다.많은 문서에서 단어를 추출하면 문서마다 서로 다른 단어로 구성되어 매우 많은 단어가 칼럼으로 만들어지기 때문이다.
머신러닝 알고리즘은 일반적으로 숫자형 피처
를 데이터로 입력받아 동작하기 때문에 텍스트 자체를 바로 피처로 머신러닝 알고리즘에 입력할 수가 없다.
따라서 텍스트를 특정 의미를 가지는 숫자형 값인 벡터 값으로 변환해야 하는데, 이러환 변환을 피처 벡터화
라고 한다.
BOW 모델에서 피처 벡터화는 모든 문서에서 모든 단어를 칼럼 형태로 나열
하고 각 문서에서 해당 단어의 횟수나 정규화된 빈도를 값으로 부여하는 데이터 세트 모델로 변경하는 것이다.
(1) 카운트 기반 벡터화
: 단어 피처에 값을 부여할 때 각 문서에서 해당 단어가 나타나는 횟수에 Count를
부여하는 경우를 카운트 벡터화라고 한다. 카운트 값이 높을수록
중요한 단어로 인식되며, 이에 그 문서의 특징을 나타내는 단어가 아닌 언어의 특성상 문장에서 자주 사용될 수 밖에 없는 단어까지 높은 값을 부여하게 된다.
(2) TF-IDF
( Term Frequency - Inverse Document Frequency ) 기반 벡터화 : 위와 같은 카운트 기반 벡터화의 문제를 보완하기 위해 개별 문서에서 자주 나오는 단어
에 높은 가중치를 주되, 모든 문서에서 전반적으로 자주 나타나는 단어에 대해서는 페널티
를 주는 방식으로 값을 부여한다.
TF-IDF
방식을 사용하는것이 더 좋다.< CountVectorizer, TfidVectorizer의 파라미터 >
높은 빈도수
를 가지는 단어 피처를 제외, 정수 값을 가지면 전체 문서에 걸쳐 n개 이하로 나타나는 단어만 피처로 추출하고 부동 소수점 값을 가지면 전체 문서에 걸쳐 빈도수% 까지의 단어만 피처로 추출한다.낮은 빈도수
를 가지는 단어 피처를 제외높은 빈도를 가지는 단어 순으로 몇 개를 추출
할 건지 입력english
로 지정하면 여어의 스톱 워드로 지정된 단어는 추출에서 제외한다.n_gram 범위를 설정
한다. 튜플 형태로 (범위 최솟값, 범위 최댓값)을 지정단위를 지정
한다. default = 'word'토큰화
를 수행하는 정규 표현식 패턴을 지정합니다. default = '\b\w\w+\b'토큰화
를 별도의 커스텀 함수로 이용시 적용한다.< CountVectorizer 클래스를 이용한 피처 벡터화 방법 >
BOW 벡터화를 수행할 경우 불필요한 0값이 메모리 공간에 할당되어 메모리 공간이 많이 필요하다.
따라서 적은 메모리 공간을 차지할 수 있도록 변환이 필요하다.
대표적인 방법으로 COO 형식
과 CSR 형식
이 있다.
일반적으로 큰 희소 행렬을 저장하고 계산을 수행하는 능력이 CSR 형식이 더 뛰어나기 때문에 CSR 형식을 많이 사용한다.
COO(Coordinate : 좌표) 형식은 0이 아닌 데이터만 별도의 데이터 배열에 저장하고
, 그 데이터가 가리키는 행과 열의 위치를 별도의 배열로 저장하는 방식이다.
주로 scipy(사이파이)이용함. sparse.coo_matrix
CSR(Compressed Sparse Row) 형식은 COO 형식이 행과 열의 위치를 나타내기 위해서 반복적인 위치 데이터를 사용해야 하는 문제점을 해결한 방식이다.
COO 형식의 행 위치 배열을 자세히 살펴보면 순차적인 같은 값이 반복적으로 나타나는 것을 확인할 수 있다.
행 위치 배열이 0부터 순차적으로 증가하는 값으로 이루어졌다는 특성을 고려하면 행 위치 배열의 고유한 값의 시작 위치만 표기하는 방법으로 이러한 반복을 제거할 수 있다.
주로 scipy(사이파이)이용함. sparse.csr_matrix
from scipy import sparse
dense2 = np.array([[0,0,1,0,0,5],
[1,4,0,3,2,5],
[0,6,0,3,0,0],
[2,0,0,0,0,0],
[0,0,0,7,0,8],
[1,0,0,0,0,0]])
# 0 이 아닌 데이터 추출
data2 = np.array([1, 5, 1, 4, 3, 2, 5, 6, 3, 2, 7, 8, 1]) # 데이터 값 배열
# 행 위치와 열 위치를 각각 array로 생성
row_pos = np.array([0, 0, 1, 1, 1, 1, 1, 2, 2, 3, 4, 4, 5]) # 행 위치 배열
col_pos = np.array([2, 5, 0, 1, 3, 4, 5, 1, 3, 0, 3, 5, 0]) # 열 위치 배열
# COO 형식으로 변환
sparse_coo = sparse.coo_matrix((data2, (row_pos,col_pos)))
# 행 위치 배열의 고유한 값들의 시작 위치 인덱스를 배열로 생성
row_pos_ind = np.array([0, 2, 7, 9, 10, 12, 13]) # 마지막에 총 항목 개수 배열을 추가로 넣어준다
# CSR 형식으로 변환
sparse_csr = sparse.csr_matrix((data2, col_pos, row_pos_ind))
print('COO 변환된 데이터가 제대로 되었는지 다시 Dense로 출력 확인')
print(sparse_coo.toarray())
print('CSR 변환된 데이터가 제대로 되었는지 다시 Dense로 출력 확인')
print(sparse_csr.toarray())
-> out put
COO 변환된 데이터가 제대로 되었는지 다시 Dense로 출력 확인
[[0 0 1 0 0 5]
[1 4 0 3 2 5]
[0 6 0 3 0 0]
[2 0 0 0 0 0]
[0 0 0 7 0 8]
[1 0 0 0 0 0]]
CSR 변환된 데이터가 제대로 되었는지 다시 Dense로 출력 확인
[[0 0 1 0 0 5]
[1 4 0 3 2 5]
[0 6 0 3 0 0]
[2 0 0 0 0 0]
[0 0 0 7 0 8]
[1 0 0 0 0 0]]
from sklearn.datasets import fetch_20newsgroups
news_data = fetch_20newsgroups(subset='all',random_state=156)
print(news_data.keys())
import pandas as pd
print('target 클래스의 값과 분포도 \n',pd.Series(news_data.target).value_counts().sort_index())
print('target 클래스의 이름들 \n',news_data.target_names)
print(news_data.data[0])
from sklearn.datasets import fetch_20newsgroups
# subset='train'으로 학습용(Train) 데이터만 추출, remove=('headers', 'footers', 'quotes')로 내용만 추출
train_news= fetch_20newsgroups(subset='train', remove=('headers', 'footers', 'quotes'), random_state=156)
X_train = train_news.data
y_train = train_news.target
print(type(X_train))
# subset='test'으로 테스트(Test) 데이터만 추출, remove=('headers', 'footers', 'quotes')로 내용만 추출
test_news= fetch_20newsgroups(subset='test',remove=('headers', 'footers','quotes'),random_state=156)
X_test = test_news.data
y_test = test_news.target
print('학습 데이터 크기 {0} , 테스트 데이터 크기 {1}'.format(len(train_news.data) , len(test_news.data)))
-> out put
<class 'list'>
학습 데이터 크기 11314 , 테스트 데이터 크기 7532
from sklearn.feature_extraction.text import CountVectorizer
# Count Vectorization으로 feature extraction 변환 수행.
cnt_vect = CountVectorizer()
cnt_vect.fit(X_train)
X_train_cnt_vect = cnt_vect.transform(X_train)
# 학습 데이터로 fit( )된 CountVectorizer를 이용하여 테스트 데이터를 feature extraction 변환 수행.
X_test_cnt_vect = cnt_vect.transform(X_test)
print('학습 데이터 Text의 CountVectorizer Shape:',X_train_cnt_vect.shape)
->
학습 데이터 Text의 CountVectorizer Shape: (11314, 101631)
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# LogisticRegression을 이용하여 학습/예측/평가 수행.
lr_clf = LogisticRegression(max_iter=500)
lr_clf.fit(X_train_cnt_vect , y_train)
pred = lr_clf.predict(X_test_cnt_vect)
print('CountVectorized Logistic Regression 의 예측 정확도는 {0:.3f}'.format(accuracy_score(y_test,pred)))
-> out put
CountVectorized Logistic Regression 의 예측 정확도는 0.597
from sklearn.feature_extraction.text import TfidfVectorizer
# TF-IDF Vectorization 적용하여 학습 데이터셋과 테스트 데이터 셋 변환.
tfidf_vect = TfidfVectorizer()
tfidf_vect.fit(X_train)
X_train_tfidf_vect = tfidf_vect.transform(X_train)
X_test_tfidf_vect = tfidf_vect.transform(X_test)
# LogisticRegression을 이용하여 학습/예측/평가 수행.
lr_clf = LogisticRegression()
lr_clf.fit(X_train_tfidf_vect , y_train)
pred = lr_clf.predict(X_test_tfidf_vect)
print('TF-IDF Logistic Regression 의 예측 정확도는 {0:.3f}'.format(accuracy_score(y_test ,pred)))
-> out put
TF-IDF Logistic Regression 의 예측 정확도는 0.674
# stop words 필터링을 추가하고 ngram을 기본(1,1)에서 (1,2)로 변경하여 Feature Vectorization 적용.
tfidf_vect = TfidfVectorizer(stop_words='english', ngram_range=(1,2), max_df=300 )
tfidf_vect.fit(X_train)
X_train_tfidf_vect = tfidf_vect.transform(X_train)
X_test_tfidf_vect = tfidf_vect.transform(X_test)
lr_clf = LogisticRegression(max_iter=500)
lr_clf.fit(X_train_tfidf_vect , y_train)
pred = lr_clf.predict(X_test_tfidf_vect)
print('TF-IDF Vectorized Logistic Regression 의 예측 정확도는 {0:.3f}'.format(accuracy_score(y_test ,pred)))
-> out put
TF-IDF Vectorized Logistic Regression 의 예측 정확도는 0.692
from sklearn.model_selection import GridSearchCV
# 최적 C 값 도출 튜닝 수행. CV는 3 Fold셋으로 설정.
params = { 'C':[0.01, 0.1, 1, 5, 10]}
grid_cv_lr = GridSearchCV(lr_clf ,param_grid=params , cv=3 , scoring='accuracy' , verbose=1 )
grid_cv_lr.fit(X_train_tfidf_vect , y_train)
print('Logistic Regression best C parameter :',grid_cv_lr.best_params_ )
# 최적 C 값으로 학습된 grid_cv로 예측 수행하고 정확도 평가.
pred = grid_cv_lr.predict(X_test_tfidf_vect)
print('TF-IDF Vectorized Logistic Regression 의 예측 정확도는 {0:.3f}'.format(accuracy_score(y_test ,pred)))
-> out put
오래걸림 -__-
Fitting 3 folds for each of 5 candidates, totalling 15 fits
Logistic Regression best C parameter : {'C': 10}
TF-IDF Vectorized Logistic Regression 의 예측 정확도는 0.701
피처 벡터화와 ML 알고리즘 학습 / 예측을 위한 코드 작성을 한 번에 진행할 수 있다. 사이킷런은 GridSearchCV 클래스의 생성 파라미터로 Pipeline을 입력해 Pipeline 기반에서도 하이퍼 파라미터 튜닝을 GridSearchCV 방식으로 진행할 수 있게 지원한다.
이 때 Estimator가 아닌 Pipeline을 GridSearchCV에 입력할 경우에는 딕셔너리 형태의 key를 입력할 때 하이퍼 파라미터명이 객체 변수명과 결합되어 제공되기 때문에 객체 변수명에 언더바(\'_\') 2개를 연달아 붙인 뒤 파라미터 명을 붙여 Key 값으로 할당한다.
from sklearn.pipeline import Pipeline
# TfidfVectorizer 객체를 tfidf_vect 객체명으로, LogisticRegression객체를 lr_clf 객체명으로 생성하는 Pipeline생성
pipeline = Pipeline([
('tfidf_vect', TfidfVectorizer(stop_words='english', ngram_range=(1,2), max_df=300)),
('lr_clf', LogisticRegression(max_iter=500, C=10))
])
# 별도의 TfidfVectorizer객체의 fit_transform( )과 LogisticRegression의 fit(), predict( )가 필요 없음.
# pipeline의 fit( ) 과 predict( ) 만으로 한꺼번에 Feature Vectorization과 ML 학습/예측이 가능.
pipeline.fit(X_train, y_train)
pred = pipeline.predict(X_test)
print('Pipeline을 통한 Logistic Regression 의 예측 정확도는 {0:.3f}'.format(accuracy_score(y_test ,pred)))
-> out put
겁나 오래걸림 -__-
Pipeline을 통한 Logistic Regression 의 예측 정확도는 0.701
# Grid Search 시간이 오래 걸려 실행은 생략
from sklearn.pipeline import Pipeline
pipeline = Pipeline([
('tfidf_vect', TfidfVectorizer(stop_words='english')),
('lr_clf', LogisticRegression(max_iter = 500))
])
# Pipeline에 기술된 각각의 객체 변수에 언더바(_)2개를 연달아 붙여 GridSearchCV에 사용될
# 파라미터/하이퍼 파라미터 이름과 값을 설정. .
params = { 'tfidf_vect__ngram_range': [(1,1), (1,2), (1,3)],
'tfidf_vect__max_df': [100, 300, 700],
'lr_clf__C': [1,5,10]
}
# GridSearchCV의 생성자에 Estimator가 아닌 Pipeline 객체 입력
grid_cv_pipe = GridSearchCV(pipeline, param_grid=params, cv=3 , scoring='accuracy',verbose=1)
grid_cv_pipe.fit(X_train , y_train)
print(grid_cv_pipe.best_params_ , grid_cv_pipe.best_score_)
pred = grid_cv_pipe.predict(X_test)
print('Pipeline을 통한 Logistic Regression 의 예측 정확도는 {0:.3f}'.format(accuracy_score(y_test ,pred)))
-> out put
모르겠음... 기다려도 안나와
감성 분석(Sentiment Analysis)은 문서의 주관적인 감성/의견/감정/기분 등을 파악하기 위한 방법으로 소셜 미디어, 여론조사, 온라인 리뷰, 피드백 등 다양한 분야에서 활용되고 있다.
감성 분석은 문서 내 텍스트가 나타내는 여러 가지 주관적인 단어와 문맥을 기반으로 감성 수치
를 계산하는 방법을 이용한다.
이러한 감성 지수
는 긍정 감성
지수와 부정 감성
지수로 구성되며 이들 지수를 합산
해 긍정 감성 또는 부정 감성을 결정한다.
감성 분석은 머신러닝 관점에서 지도학습
과 비지도학습
방식으로 나눌 수 있는데,
우선 지도학습
은 학습 데이터와 타깃 레이블 값을 기반으로 감성 분석 학습을 수행한 뒤 이를 기반으로 다른 데이터의 감성 분석을 예측하는 방법으로 일반적인 텍스트 기반의 분류와 거의 동일하다.
비지도학습
의 경우에는 'Lexicon'이라는 일종의 감성 어휘 사전을 이용하는데, Lexicon은 감성 분석을 위한 용어와 문맥에 대한 다양한 정보를 가지고 있으며, 이를 이용해 긍정적, 부정적 감성 여부를 판단한다.
import pandas as pd
review_df = pd.read_csv("/content/drive/MyDrive/book/labeledTrainData.tsv", header = 0, sep = "\t", quoting = 3)
review_df.head(3)
# 텍스트가 어떻게 구성되어 있는지 확인
print(review_df['review'][0])
...
import re
# <br> html 태그는 replace 함수로 공백으로 변환
review_df['review'] = review_df['review'].str.replace('<br />', ' ')
# 파이썬의 re 모듈을 이용해 영어 문자열이 아닌 문자는 모두 공백으로 변환
review_df['review'] = review_df['review'].apply(lambda x : re.sub("[^a-zA-Z]", " ", x))
# [^a-zA-Z] 는 영어 대/소문자가 아닌 모든 문자를 찾는 정규 표현식
# 결정 값 클래스인 sentiment 칼럼을 별도로 추출
from sklearn.model_selection import train_test_split
class_df = review_df['sentiment']
feature_df = review_df.drop(['id','sentiment'], axis=1, inplace=False)
X_train, X_test, y_train, y_test= train_test_split(feature_df, class_df, test_size=0.3, random_state=156)
X_train.shape, X_test.shape
-> out put
((17500, 1), (7500, 1))
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, roc_auc_score
# 스톱 워드는 English, filtering, ngram은 (1,2)로 설정해 CountVectorization수행.
# LogisticRegression의 C는 10으로 설정.
pipeline = Pipeline([
('cnt_vect', CountVectorizer(stop_words='english', ngram_range=(1,2) )),
('lr_clf', LogisticRegression(C=10, max_iter = 500))]) # C 값이 작으면 훈련을 덜 복잡 ( 강한 규제)
# Pipeline 객체를 이용하여 fit(), predict()로 학습/예측 수행. predict_proba()는 roc_auc때문에 수행.
pipeline.fit(X_train['review'], y_train)
pred = pipeline.predict(X_test['review'])
pred_probs = pipeline.predict_proba(X_test['review'])[:,1]
print('예측 정확도는 {0:.4f}, ROC-AUC는 {1:.4f}'.format(accuracy_score(y_test ,pred),
roc_auc_score(y_test, pred_probs)))
-> out put
예측 정확도는 0.8860, ROC-AUC는 0.9503
# 스톱 워드는 english, filtering, ngram은 (1,2)로 설정해 TF-IDF 벡터화 수행.
# LogisticRegression의 C는 10으로 설정.
pipeline = Pipeline([
('tfidf_vect', TfidfVectorizer(stop_words='english', ngram_range=(1,2) )),
('lr_clf', LogisticRegression(C=10, max_iter = 500))])
pipeline.fit(X_train['review'], y_train)
pred = pipeline.predict(X_test['review'])
pred_probs = pipeline.predict_proba(X_test['review'])[:,1]
print('예측 정확도는 {0:.4f}, ROC-AUC는 {1:.4f}'.format(accuracy_score(y_test ,pred),
roc_auc_score(y_test, pred_probs)))
-> out put
예측 정확도는 0.8936, ROC-AUC는 0.9598
출처: