Python ๊ฐ์ ๋ถ์
ํ
์คํธ๋ก ๋ถํฐ ์ด๋ ํ ์ฃผ๊ด์ ์ธ ์๊ฒฌ์ ๋ฝ์๋ด๋ ๊ฒ์ด ๊ฐ์ ๋ถ์์ด๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก train data๋ก ๋ถํฐ ๋ฐ์ดํฐ ๋ถ์์ ํ๊ณ test data์ ๋ฐ์์ ํ๋ค.
์ฃผ๋ก ๊ธ์ /๋ถ์ ํ์์ 2์ง ๋ต๋ณ์ ๋ฐํํ์ฌ 1/0 ๋๋ 1/-1์ ๊ฐ์ผ๋ก ๊ธ์ ๋ถ์ ์ ํ๋จํ๋ค.
๊ฐ ์ธ์ด๋ณ๋ก ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ์ด ์กฐ๊ธ์ฉ ๋ค๋ฅด๋ค.
์์ด ๋ฐ์ดํฐ ์ ๊ตฌํ๊ธฐ
๋ฐ์ดํฐ ์
์ ๊ตฌํ๊ธฐ ์ํด ์ฐธ์กฐํ๊ธฐ ์ข์ ์ฌ์ดํธ์ ๋ํ ๊ธ์ด๋ค.
์ด๋ฒ ๊ธ์์๋ ์บ๊ธ์์ ํธ์ํฐ ๊ฐ์ ๋ถ์์ ์ํ ๋ฐ์ดํฐ ์
์ ๋ค์ด๋ฐ์ ์ ์ฒ๋ฆฌ๋ฅผ ํด๋ณผ๊ฑฐ๋ค.
ํด๋น ์ฌ์ดํธ์์ sentiment๋ฅผ ๊ฒ์ํ๋ฉด ๊ฐ์ข ๊ฐ์ ๋ถ์์ ์ํ ๋ฐ์ดํฐ์ ์ ์ ๊ณตํด์ค๋ค.
ํธ์ํฐ ๊ธ์ ๋ํ test์ train ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ค.
์์ด ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ
๋ฐ์ดํฐ ๋ถ๋ฌ์ค๊ธฐ
header=0 : ํ์ผ ์ฒซ๋ฒ์งธ ํ์ ์ด ์ด๋ฆ์ด ์๋ค๋ ๊ฒ์ ์ธ์ง
delimiter : ๊ตฌ๋ถ์
quoting=3 : ์๋ฐ์ดํ๋ฅผ ๋ฌด์ํ๋๋ก ํ๋ค.
import pandas as pd
train = pd.read_csv(
'/Users/Jamong/Desktop/data/twitter_sentiment/train.tsv',
header=0,
delimiter='\t',
quoting=3
)
test = pd.read_csv(
'/Users/Jamong/Desktop/data/twitter_sentiment/test.tsv',
header=0,
delimiter='\t',
quoting=3
)
์๋ฏธ์๋ ์์ด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๊ธฐ ์ํด์ 4~5๋จ๊ณ์ ๋ฐ์ดํฐ ๊ฐ๊ณต์ฒ๋ฆฌ๊ฐ ํ์ํ๋ค.
์๋๋ train data ์๋ํ raw data์ ์ผ๋ถ์ด๋ค.
1. HTML ์ ๊ฑฐ(์๋ ๊ฒฝ์ฐ์๋ง)
ํด๋น ๋ฐ์ดํฐ์์๋ htmlํ๊ทธ๊ฐ ์๋ค.
HTML์ ๊ฑฐ ์์
์ด ํ์ ์์ง๋ง, ํ์ํ ๋ฐ์ดํฐ์ ๊ฒฝ์ฐ BeautifulSoup๋ฅผ ์ด์ฉํด์ ์ ๊ฑฐ์์
์ ํด์ฃผ๋ฉด ๋๋ค.
from bs4 import BeautifulSoup
raw_tweet = BeautifulSoup(raw_tweet, 'html.parser').get_text()
2. ์์ด๊ฐ ์๋ ๋ฌธ์๋ฅผ ๊ณต๋ฐฑ์ผ๋ก ๋์ฒด
์์ด๊ฐ ์๋ ๋ฌธ์๋ ์ ๊ฑฐํ์ฌ ๋จ์ดํ ๋จ๊ธฐ๋๋ก ํ๋ค.
์ด๋ ์ ๊ทํํ์์ ์ฌ์ฉํ์ฌ ์ ๊ฑฐํด์ค๋ค.
import re
# ์๋ฌธ์ ์ด์ธ ๋ฌธ์๋ ๊ณต๋ฐฑ์ผ๋ก ๋ณํ
only_english = re.sub('[^a-zA-Z]', ' ', data)
3. ๋๋ฌธ์๋ ์๋ฌธ์๋ก ๋ณํ
์์ด์ ๊ฒฝ์ฐ ๋ฌธ์ฅ์ ์์์ด๋ ๊ณ ์ ๋ช ์ฌ๋ ๋๋ฌธ์๋ก ์์ํ์ฌ ๋ถ์ํ ๋ "Apple"๊ณผ "apple"์ ๋ค๋ฅธ ๋จ์ด ์ทจ๊ธํ๊ฒ๋๋ค.
๋ชจ๋ ๋จ์ด๋ฅผ ์๋ฌธ์๋ก ๋ณํํ๋ค.
# ์๋ฌธ์ ๋ณํ
no_capitals = only_english.lower().split()
4. ๋ถ์ฉ์ด ์ ๊ฑฐ
ํ์ต ๋ชจ๋ธ์์ ์์ธก์ด๋ ํ์ต์ ์ค์ ๋ก ๊ธฐ์ฌํ์ง ์๋ ํ
์คํธ๋ฅผ ๋ถ์ฉ์ด๋ผ๊ณ ํ๋ค.
I, that, is, the, a ๋ฑ๊ณผ ๊ฐ์ด ์์ฃผ ๋ฑ์ฅํ๋ ๋จ์ด์ด์ง๋ง ์ค์ ๋ก ์๋ฏธ๋ฅผ ์ฐพ๋๋ฐ ๊ธฐ์ฌํ์ง ์๋ ๋จ์ด๋ค์ ์ ๊ฑฐํ๋ ์์
์ด ํ์ํ๋ค.
from nltk.corpus import stopwords
# ๋ถ์ฉ์ด ์ ๊ฑฐ
stops = set(stopwords.words('english'))
no_stops = [word for word in no_capitals if not word in stops]
nltk stopwords๊ด๋ จ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค๋ฉด nltk download ์์
์ ์ฝ๋์์ผ๋ก ํด์ค๋ค.
nltk.download('stopwords')
5. ์ด๊ฐ ์ถ์ถ
see, saw, seen
run, running, ran
์ ์์์ฒ๋ผ ์ดํ์ด ๊ณผ๊ฑฐํ์ด๋ ๋ฏธ๋ํ์ด๋ ํ๋์ ๋จ์ด๋ก ์ทจ๊ธํ๊ธฐ ์ํ ์ฒ๋ฆฌ์์ ์ด๋ค.
nltk์์ ์ ๊ณตํ๋ ํํ์ ๋ถ์๊ธฐ๋ฅผ ์ฌ์ฉํ๋๋ฐ ์ฌ๋ฌ๊ฐ์ง ์ด๊ฐ์ถ์ถ ์๊ณ ๋ฆฌ์ฆ(Porter, Lancaster, Snowball ๋ฑ๋ฑ)์ด ์กด์ฌํ๋ค.
import nltk
# ์ด๊ฐ ์ถ์ถ
stemmer = nltk.stem.SnowballStemmer('english')
stemmer_words = [stemmer.stem(word) for word in no_stops]
์ ์ฒ๋ฆฌ ์ ์ฒด ์์
def data_text_cleaning(data):
# ์๋ฌธ์ ์ด์ธ ๋ฌธ์๋ ๊ณต๋ฐฑ์ผ๋ก ๋ณํ
only_english = re.sub('[^a-zA-Z]', ' ', data)
# ์๋ฌธ์ ๋ณํ
no_capitals = only_english.lower().split()
# ๋ถ์ฉ์ด ์ ๊ฑฐ
stops = set(stopwords.words('english'))
no_stops = [word for word in no_capitals if not word in stops]
# ์ด๊ฐ ์ถ์ถ
stemmer = nltk.stem.SnowballStemmer('english')
stemmer_words = [stemmer.stem(word) for word in no_stops]
# ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถ๋ ๋ฌธ์์ด๋ก ๊ฒฐํฉํ์ฌ ๊ฒฐ๊ณผ ๋ฐํ
return ' '.join(stemmer_words)
๋ฉํฐํ๋ก์ธ์ฑ ์์
ํด๋น ๋ฐ์ดํฐ๋ ์ ์ฒ๋ฆฌ ์์
ํ๋๋ฐ ์ค๋ ๊ฑธ๋ฆฌ์ง ์๋๋ค.
๋ฐ์ดํฐ ์, ๋ฐ์ดํฐ ๊ธธ์ด๊ฐ ๋์ด๋ ์๋ก PC์ฌ์์ ๋ฐ๋ผ ์ ์ฒ๋ฆฌ ์์
์๊ฐ ์ฐจ์ด๊ฐ ๋ง์๋๋ค.
์ ์ฒ๋ฆฌ ์์
๋ง ์งํํ๋๋ฐ ๋ช๋ถ์ฉ ๊ฑธ๋ฆด ์ ์๋ค.
์ด๋ฌํ ์์
์ ๋น ๋ฅด๊ฒ ์งํํด์ฃผ๊ธฐ ์ํด์ ๋ฉํฐํ๋ก์ธ์ฑ์ผ๋ก ์์
์ ์งํํ๋ค.
from multiprocessing import Pool
def use_multiprocess(func, iter, workers):
pool = Pool(processes=workers)
result = pool.map(func, iter)
pool.close()
return result
import time
if __name__ == '__main__':
start_time = time.time()
train = pd.read_csv('/Users/Jamong/Desktop/data/twitter_sentiment/train.tsv',
header=0, delimiter='\t', quoting=3)
test = pd.read_csv('/Users/Jamong/Desktop/data/twitter_sentiment/test.tsv',
header=0, delimiter='\t', quoting=3)
clean_processed_tweet = use_multiprocess(data_text_cleaning, train['tweet'], 3)
print('์คํ ์๊ฐ :', (time.time() - start_time))โ
Tweet ๋จ์ด ์ ํ์ธ
seaborn์ ์ฌ์ฉํด์ tweet๋ณ ๋จ์ด์ ์ ๊ณ ์ ๋จ์ด ์๋ฅผ ์๊ฐํํด์ ํ์ธํด๋ณผ๊ฑฐ๋ค.
import matplotlib.pyplot as plt
from matplotlib import rc
import seaborn as sns
def show_tweet_word_count_stat(data):
num_word = []
num_unique_words = []
for item in data:
num_word.append(len(str(item).split()))
num_unique_words.append(len(set(str(item).split())))
# ์ผ๋ฐ
train['num_words'] = pd.Series(num_word)
# ์ค๋ณต ์ ๊ฑฐ
train['num_unique_words'] = pd.Series(num_unique_words)
x = data[0]
x = str(x).split()
print(len(x))
rc('font', family='AppleGothic')
fig, axes = plt.subplots(ncols=2)
fig.set_size_inches(18, 6)
print('Tweet ๋จ์ด ํ๊ท ๊ฐ : ', train['num_words'].mean())
print('Tweet ๋จ์ด ์ค๊ฐ ๊ฐ', train['num_words'].median())
sns.distplot(train['num_words'], bins=100, ax=axes[0])
axes[0].axvline(train['num_words'].median(), linestyle='dashed')
axes[0].set_title('Tweet ๋จ์ด ์ ๋ถํฌ')
print('Tweet ๊ณ ์ ๋จ์ด ํ๊ท ๊ฐ : ', train['num_unique_words'].mean())
print('Tweet ๊ณ ์ ๋จ์ด ์ค๊ฐ ๊ฐ', train['num_unique_words'].median())
sns.distplot(train['num_unique_words'], bins=100, color='g', ax=axes[1])
axes[1].axvline(train['num_unique_words'].median(), linestyle='dashed')
axes[1].set_title('Tweet ๊ณ ์ ํ ๋จ์ด ์ ๋ถํฌ')
plt.show()
show_tweet_word_count_stat(clean_processed_tweet)
๊ฒฐ๊ณผ
๊ฐ Tweet๋ณ ๋จ์ด ์ต๋ ์ต์ ์์ ์ค๊ฐ, ํ๊ท ๊ฐ์ ์๊ฐํํ์ฌ ํ์ธ
์ ์ฒด ์คํ ์ฝ๋
from multiprocessing import Pool
import pandas as pd
import re
import time
import nltk
from nltk.corpus import stopwords
import matplotlib.pyplot as plt
from matplotlib import rc
import seaborn as sns
def use_multiprocess(func, iter, workers):
pool = Pool(processes=workers)
result = pool.map(func, iter)
pool.close()
return result
def check_basic_info():
print("-----train-----")
print(train.head())
print(train.info())
print(train['tweet'][0:10])
print("\n\n-----test-----")
print(test.head())
print(test.info())
def data_text_cleaning(data):
# ์๋ฌธ์ ์ด์ธ ๋ฌธ์๋ ๊ณต๋ฐฑ์ผ๋ก ๋ณํ
only_english = re.sub('[^a-zA-Z]', ' ', data)
# ์๋ฌธ์ ๋ณํ
no_capitals = only_english.lower().split()
# ๋ถ์ฉ์ด ์ ๊ฑฐ
stops = set(stopwords.words('english'))
no_stops = [word for word in no_capitals if not word in stops]
# ์ด๊ฐ ์ถ์ถ
stemmer = nltk.stem.SnowballStemmer('english')
stemmer_words = [stemmer.stem(word) for word in no_stops]
# ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถ๋ ๋ฌธ์์ด๋ก ๊ฒฐํฉํ์ฌ ๊ฒฐ๊ณผ ๋ฐํ
return ' '.join(stemmer_words)
def show_tweet_word_count_stat(data):
num_word = []
num_unique_words = []
for item in data:
num_word.append(len(str(item).split()))
num_unique_words.append(len(set(str(item).split())))
# ์ผ๋ฐ
train['num_words'] = pd.Series(num_word)
# ์ค๋ณต ์ ๊ฑฐ
train['num_unique_words'] = pd.Series(num_unique_words)
x = data[0]
x = str(x).split()
print(len(x))
rc('font', family='AppleGothic')
fig, axes = plt.subplots(ncols=2)
fig.set_size_inches(18, 6)
print('Tweet ๋จ์ด ํ๊ท ๊ฐ : ', train['num_words'].mean())
print('Tweet ๋จ์ด ์ค๊ฐ ๊ฐ', train['num_words'].median())
sns.distplot(train['num_words'], bins=100, ax=axes[0])
axes[0].axvline(train['num_words'].median(), linestyle='dashed')
axes[0].set_title('Tweet ๋จ์ด ์ ๋ถํฌ')
print('Tweet ๊ณ ์ ๋จ์ด ํ๊ท ๊ฐ : ', train['num_unique_words'].mean())
print('Tweet ๊ณ ์ ๋จ์ด ์ค๊ฐ ๊ฐ', train['num_unique_words'].median())
sns.distplot(train['num_unique_words'], bins=100, color='g', ax=axes[1])
axes[1].axvline(train['num_unique_words'].median(), linestyle='dashed')
axes[1].set_title('Tweet ๊ณ ์ ํ ๋จ์ด ์ ๋ถํฌ')
plt.show()
if __name__ == '__main__':
start_time = time.time()
train = pd.read_csv('/Users/Jamong/Desktop/data/twitter_sentiment/train.tsv',
header=0, delimiter='\t', quoting=3)
test = pd.read_csv('/Users/Jamong/Desktop/data/twitter_sentiment/test.tsv',
header=0, delimiter='\t', quoting=3)
check_basic_info()
clean_processed_tweet = use_multiprocess(data_text_cleaning, train['tweet'], 3)
print('์คํ ์๊ฐ :', (time.time() - start_time))
show_tweet_word_count_stat(clean_processed_tweet)โ
๋๊ธ