from fastai.collab import * ## 추천시스템
from fastai.text.all import * ## 텍스트분석 02wk-1: Overview (3)
Overview
fastai를 이용한 분석 steps, 추천시스템 실습, 텍스트분석 실습
강의영상
https://youtube.com/playlist?list=PLQqh36zP38-zJbe5FztJPSqicA2ZLwDgh
imports
import pandas as pdfastai를 이용한 분석 steps
- 비교
| 이미지분석(CNN) | 추천시스템 | 텍스트분석 | GAN | |
|---|---|---|---|---|
| 1단계 | ImageDataLoaders | CollabDataLoaders | TextDataLoaders | DataBlock -> dls |
| 2단계 | cnn_learner() | collab_learner() | language_model_learner() | GANLearner.wgan() |
| 3단계 | lrnr.fine_tune(1) | lrnr.fit() | lrnr.fit() | lrnr.fit() |
| 4단계 | lrnr.predict(), lrnr.model(X) | lrnr.model(X) | lrnr.predict() |
추천시스템 실습
1단계
df_view = pd.read_csv('https://raw.githubusercontent.com/guebin/DL2022/main/posts/I.%20Overview/2022-09-08-rcmd_view.csv')
df_view| 커피1 | 커피2 | 커피3 | 커피4 | 커피5 | 커피6 | 커피7 | 커피8 | 커피9 | 커피10 | 홍차1 | 홍차2 | 홍차3 | 홍차4 | 홍차5 | 홍차6 | 홍차7 | 홍차8 | 홍차9 | 홍차10 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 4.149209 | NaN | NaN | 4.078139 | 4.033415 | 4.071871 | NaN | NaN | NaN | NaN | 1.142659 | 1.109452 | NaN | 0.603118 | 1.084308 | NaN | 0.906524 | NaN | NaN | 0.903826 |
| 1 | 4.031811 | NaN | NaN | 3.822704 | NaN | NaN | NaN | 4.071410 | 3.996206 | NaN | NaN | 0.839565 | 1.011315 | NaN | 1.120552 | 0.911340 | NaN | 0.860954 | 0.871482 | NaN |
| 2 | 4.082178 | 4.196436 | NaN | 3.956876 | NaN | NaN | NaN | 4.450931 | 3.972090 | NaN | NaN | NaN | NaN | 0.983838 | NaN | 0.918576 | 1.206796 | 0.913116 | NaN | 0.956194 |
| 3 | NaN | 4.000621 | 3.895570 | NaN | 3.838781 | 3.967183 | NaN | NaN | NaN | 4.105741 | 1.147554 | NaN | 1.346860 | NaN | 0.614099 | 1.297301 | NaN | NaN | NaN | 1.147545 |
| 4 | NaN | NaN | NaN | NaN | 3.888208 | NaN | 3.970330 | 3.979490 | NaN | 4.010982 | NaN | 0.920995 | 1.081111 | 0.999345 | NaN | 1.195183 | NaN | 0.818332 | 1.236331 | NaN |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 95 | 0.511905 | 1.066144 | NaN | 1.315430 | NaN | 1.285778 | NaN | 0.678400 | 1.023020 | 0.886803 | NaN | 4.055996 | NaN | NaN | 4.156489 | 4.127622 | NaN | NaN | NaN | NaN |
| 96 | NaN | 1.035022 | NaN | 1.085834 | NaN | 0.812558 | NaN | 1.074543 | NaN | 0.852806 | 3.894772 | NaN | 4.071385 | 3.935935 | NaN | NaN | 3.989815 | NaN | NaN | 4.267142 |
| 97 | NaN | 1.115511 | NaN | 1.101395 | 0.878614 | NaN | NaN | NaN | 1.329319 | NaN | 4.125190 | NaN | 4.354638 | 3.811209 | 4.144648 | NaN | NaN | 4.116915 | 3.887823 | NaN |
| 98 | NaN | 0.850794 | NaN | NaN | 0.927884 | 0.669895 | NaN | NaN | 0.665429 | 1.387329 | NaN | NaN | 4.329404 | 4.111706 | 3.960197 | NaN | NaN | NaN | 3.725288 | 4.122072 |
| 99 | NaN | NaN | 1.413968 | 0.838720 | NaN | NaN | 1.094826 | 0.987888 | NaN | 1.177387 | 3.957383 | 4.136731 | NaN | 4.026915 | NaN | NaN | 4.164773 | 4.104276 | NaN | NaN |
100 rows × 20 columns
- row0 - row49 에 해당하는 유저는 커피를 선호
- row50 - row99 에 해당하는 유저는 홍차를 선호
df = pd.read_csv('https://raw.githubusercontent.com/guebin/DL2022/main/posts/I.%20Overview/2022-09-08-rcmd_anal.csv')
df| user | item | rating | item_name | |
|---|---|---|---|---|
| 0 | 1 | 15 | 1.084308 | 홍차5 |
| 1 | 1 | 1 | 4.149209 | 커피1 |
| 2 | 1 | 11 | 1.142659 | 홍차1 |
| 3 | 1 | 5 | 4.033415 | 커피5 |
| 4 | 1 | 4 | 4.078139 | 커피4 |
| ... | ... | ... | ... | ... |
| 995 | 100 | 18 | 4.104276 | 홍차8 |
| 996 | 100 | 17 | 4.164773 | 홍차7 |
| 997 | 100 | 14 | 4.026915 | 홍차4 |
| 998 | 100 | 4 | 0.838720 | 커피4 |
| 999 | 100 | 7 | 1.094826 | 커피7 |
1000 rows × 4 columns
- 컴퓨터는 이러한 형태를 더 분석하기 좋아한다.
df.item.unique(),df.user.unique()
# 유저는 1~100 으로 아이템은 1~20으로 번호가 매겨져 있음 (array([15, 1, 11, 5, 4, 14, 6, 20, 12, 17, 8, 9, 13, 19, 18, 16, 2,
3, 10, 7]),
array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
92, 93, 94, 95, 96, 97, 98, 99, 100]))
dls=CollabDataLoaders.from_df(df)dls.show_batch()| user | item | rating | |
|---|---|---|---|
| 0 | 2 | 1 | 4.031811 |
| 1 | 40 | 19 | 1.015886 |
| 2 | 39 | 20 | 0.853394 |
| 3 | 58 | 8 | 0.854745 |
| 4 | 38 | 6 | 4.055263 |
| 5 | 45 | 17 | 0.608018 |
| 6 | 59 | 14 | 3.986921 |
| 7 | 6 | 12 | 0.833454 |
| 8 | 98 | 13 | 4.354638 |
| 9 | 74 | 12 | 4.199568 |
X,y= dls.one_batch()X[0],y[0](tensor([64, 15]), tensor([4.1146]))
- 64번 유저가 15번 아이템을 먹었을때 평점을 4.1146 주었음
2단계
lrnr = collab_learner(dls,y_range=(0,5)) # y_range는 평점의 범위3단계
lrnr.fit(10) # 총 30번 정도 해야 적합이 잘된다. | epoch | train_loss | valid_loss | time |
|---|---|---|---|
| 0 | 0.044790 | 0.064825 | 00:00 |
| 1 | 0.042065 | 0.059010 | 00:00 |
| 2 | 0.039907 | 0.055658 | 00:00 |
| 3 | 0.038412 | 0.053847 | 00:00 |
| 4 | 0.037186 | 0.052595 | 00:00 |
| 5 | 0.036020 | 0.052121 | 00:00 |
| 6 | 0.035041 | 0.051959 | 00:00 |
| 7 | 0.034370 | 0.051995 | 00:00 |
| 8 | 0.033759 | 0.052022 | 00:00 |
| 9 | 0.033237 | 0.052229 | 00:00 |
4단계
- 하나의 배치 전체를 예측
yhat=lrnr.model(X.to("cuda:0"))
yhattensor([4.0162, 0.9041, 4.0706, 0.9730, 0.9861, 1.1032, 4.0559, 4.0745, 3.9329,
4.0195, 3.9139, 4.0732, 3.8666, 3.9556, 0.9634, 1.0055, 0.9944, 3.9826,
4.0456, 0.9961, 0.9438, 0.9291, 4.0212, 1.0700, 4.0543, 4.0441, 4.0918,
0.9850, 1.0140, 4.1212, 4.0628, 3.9923, 4.0395, 0.9331, 3.9581, 3.9999,
1.1152, 3.9131, 4.0565, 3.9264, 3.9619, 0.9421, 1.1348, 4.0688, 0.8939,
0.9684, 1.0505, 1.1034, 1.1027, 3.9411, 1.0582, 3.9680, 4.0465, 3.9554,
4.0419, 1.0965, 1.0784, 0.9954, 4.0205, 0.9373, 3.9045, 1.0255, 3.8102,
1.0640], device='cuda:0', grad_fn=<AddBackward0>)
- lrnr.model()은 GPU메모리에 존재하고 X는 일반메모리에 존재하므로 X를 GPU메모리로 옮겨주어야 함
- X.to(“cuda:0”)을 통하여 X를 GPU메모리로 옮기는 작업을 수행할 수 있다.
- 하나의 유저가 하나의 아이템을 선택했다고 가정하고 예측 (주어진 자료중에서 예측)
X.shapetorch.Size([64, 2])
X[0:1]tensor([[18, 5]])
- 18번 유저가 5번 아이템(커피)를 먹는다면?
lrnr.model(X[0:1].to("cuda:0"))tensor([4.1128], device='cuda:0', grad_fn=<AddBackward0>)
- 평점은 4.1128정도 될것
- 하나의 유저가 하나의 아이템을 선택했다고 가정하고 예측 (주어지지 않은 자료중에서 예측)
X[0:1]tensor([[18, 5]])
Xnew = torch.tensor([[1, 2]])lrnr.model(Xnew.to("cuda:0"))tensor([3.9397], device='cuda:0', grad_fn=<AddBackward0>)
텍스트분석 실습
1단계
df = pd.DataFrame({'text':['h e l l o . h e l l o ! h e l l o ? h e l l o !! h e l l o ??']*20000})
df| text | |
|---|---|
| 0 | h e l l o . h e l l o ! h e l l o ? h e l l o !! h e l l o ?? |
| 1 | h e l l o . h e l l o ! h e l l o ? h e l l o !! h e l l o ?? |
| 2 | h e l l o . h e l l o ! h e l l o ? h e l l o !! h e l l o ?? |
| 3 | h e l l o . h e l l o ! h e l l o ? h e l l o !! h e l l o ?? |
| 4 | h e l l o . h e l l o ! h e l l o ? h e l l o !! h e l l o ?? |
| ... | ... |
| 19995 | h e l l o . h e l l o ! h e l l o ? h e l l o !! h e l l o ?? |
| 19996 | h e l l o . h e l l o ! h e l l o ? h e l l o !! h e l l o ?? |
| 19997 | h e l l o . h e l l o ! h e l l o ? h e l l o !! h e l l o ?? |
| 19998 | h e l l o . h e l l o ! h e l l o ? h e l l o !! h e l l o ?? |
| 19999 | h e l l o . h e l l o ! h e l l o ? h e l l o !! h e l l o ?? |
20000 rows × 1 columns
dls = TextDataLoaders.from_df(df,text_col='text',is_lm=True) dls.show_batch()| text | text_ | |
|---|---|---|
| 0 | xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o | h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . |
| 1 | ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l | xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o |
| 2 | ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l | ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l |
| 3 | o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e | ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l |
| 4 | l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h | o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e |
| 5 | l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos | l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h |
| 6 | e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? | l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos |
| 7 | h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? | e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? |
| 8 | ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o | h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? ? xxbos h e l l o . h e l l o ! h e l l o ? h e l l o ! ! h e l l o ? |
- is_lm: text의 생성에 관심이 있다면 True로 설정할 것
2단계
lrnr = language_model_learner(dls, AWD_LSTM)3단계
lrnr.fit(1)| epoch | train_loss | valid_loss | time |
|---|---|---|---|
| 0 | 0.575245 | 0.245803 | 00:11 |
4단계
lrnr.predict('h e',n_words=30)'h e l l l o . h e l l . e l l o ? ? h e l l o ! ! h e l l o !'