-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsistem_rekomendasi.py
541 lines (384 loc) · 654 KB
/
sistem_rekomendasi.py
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
# -*- coding: utf-8 -*-
"""Sistem_Rekomendasi.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1TM0_nG04RzRf0AnuCeY4vF6K05iOWHet
<h1>Sistem Rekomendasi: Rekomendasi Film untuk Pengguna di Netflix Movies and TV Shows<h1>
---
Proyek Submission 2 - Machine Learning Terapan Dicoding
Dibuat oleh: [Kurnivan Noer Yusvianto](https://www.dicoding.com/users/kurnivan_ny)
<p align="center">
<img width="500" height="250" src="https://user-images.githubusercontent.com/72246401/137863762-394d381d-7312-4ece-806a-cdf8565baddf.png">
</p>
# Pendahuluan
Pada proyek Machine Learning Terapan dari Dicoding, topik yang dibahas adalah sistem rekomendasi di Netflix Movies and TV Shows menggunakan _content based filtering_ karena tidak membutuhkan data rating dari pengguna.
#1. Mengimpor pustaka/modul python yang dibutuhkan
"""
# update modul python terbaru
!pip install -U scikit-learn
!pip install -q kaggle
!pip install rake_nltk
!pip install --upgrade tensorflow_hub
# untuk mengunggah file ke google colab
from google.colab import files
# untuk pengolahan data
import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import CountVectorizer
from rake_nltk import Rake
import nltk
nltk.download('stopwords')
nltk.download('punkt')
import warnings
warnings.filterwarnings("ignore")
# untuk visualisasi data
import matplotlib.pyplot as plt
import plotly.express as px
from wordcloud import WordCloud
# Untuk pembuatan sistem rekomendasi
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
# Untuk evaluasi sistem rekomendasi
from sklearn.metrics.pairwise import cosine_similarity
"""#2. Mempersiapkan Dataset

Informasi Data:
| Jenis | Keterangan |
| :--- | :--- |
| Sumber | Kaggle Dataset : [Netflix Movies and TV Shows](https://www.kaggle.com/shivamb/netflix-shows)|
| Lisensi | CC0: Public Domain |
| Kategori | movies and tv shows |
| Rating Penggunaan | 10.0 (Gold) |
| Jenis dan Ukuran Berkas | CSV (3.4 MB) |
## 2.1 Menyiapkan kredensial akun Kaggle
"""
# unggah file ke google
files.upload()
# Membuat folder .kaggle di dalam folder root
!rm -rf ~/.kaggle && mkdir ~/.kaggle/
# Menyalin berkas kaggle.json pada direktori aktif saat ini ke folder .kaggle
!mv kaggle.json ~/.kaggle/kaggle.json
!chmod 600 ~/.kaggle/kaggle.json
"""## 2.1 Mengunggah dan Menyiapkan Dataset"""
# Mengunduh dataset menggunakan Kaggle CLI
!kaggle datasets download -d shivamb/netflix-shows
# Mengekstrak berkas zip
!unzip /content/netflix-shows.zip
"""# 3. Pemahaman Data *(Data Understanding)*
Pemahaman Data *(Data Understanding)* berupa memahami lebih jauh tentang data yang dikumpulkan sebelumnya dan memeriksa jenis masing-masing data dan mempelajari lebih lanjut tentang atribut(feature) dan namanya.
## 3.1 *Data Loading*
Proses loading data menggunakan library pandas untuk membaca file datanya (file csv).
"""
# Memuat data pada sebuah DataFrame menggunakan pandas
netflix_df = pd.read_csv("/content/netflix_titles.csv")
netflix_df
"""Terdapat 8.807 baris (records atau jumlah pengamatan) dan 12 kolom dalam dataset.
## 3.2 *Explanatory Data Analysis*
*Explanatory Data Analysis* (EDA) merupakan proses investigasi awal pada data untuk menganalisis karakteristik, menemukan pola, anomali, dan memeriksa asumsi pada data. Teknik ini biasanya menggunakan bantuan statistik dan representasi grafis atau visualisasi.
[Dicoding - Exploratory Data Analysis - Deskripsi Variabel](https://www.dicoding.com/academies/319/tutorials/17008?from=17006)
### 3.2.1 Deskripsi Variabel
Berdasarkan informasi dari [Kaggle](https://www.kaggle.com/shivamb/netflix-shows), variabel pada Netflix Movies and TV Shows sebagai berikut.
| Variabel | Deskripsi |
| :--- | :--- |
| show_id | id unik dari setiap pertunjukan |
| type | Kategori acara, bisa berupa Film atau Acara TV |
| title | Judul Film / Acara TV |
| director | Nama sutradara |
| cast | Nama aktor yang terlibat dalam film / pertunjukan |
| country | Negara tempat film / acara itu diproduksi |
| date_added | Tanggal saat acara ditambahkan di Netflix |
| release_year | Tahun rilis pertunjukan |
| rating | Tampilkan peringkat di Netflix |
| duration | Durasi waktu pertunjukan dalam menit |
| listed_in | Genre acaranya |
| description | Deskripsi ringkasan |
Mengubah data numerik menjadi data kategori agar mudah di analisis dan visualisasi
Untuk memahami deskripsi variabel pada data, dapat mengecek pada dataset dengan fungsi berikut.
"""
# Fungsi yang memuat informasi pada DataFrame
def report(df):
col = []
d_type = []
uniques = []
n_uniques = []
for i in df.columns:
col.append(i) # Nama Column
d_type.append(df[i].dtypes) # Tipe Data
uniques.append(df[i].unique()[:5]) # Elemen pada variabel
n_uniques.append(df[i].nunique()) # Jumlah elemen pada variabel
return pd.DataFrame({'Column': col, 'd_type':d_type, 'unique_sample':uniques, 'n_unique_sample':n_uniques})
report(netflix_df)
"""Untuk mengecek jumlah data kosong (*missing value*) yang biasanya berisi NaN dapat menggunakan isna() atau isnull()"""
# Menghitung jumlah data kosong (NaN) pada setiap kolom
netflix_df.isna().sum()
"""Untuk duplikasi data dapat menggunakan duplicated()"""
# Menghitung jumlah data yang duplikat
netflix_df.duplicated().sum()
"""### 3.2.2 *Univariate Analysis*
*Univariate Analysis* adalah metode yang digunakan untuk menganalisis dan mengeskplorasi data yang berisikan satu variabel dari suatu kumpulan data.
#### 3.2.2.1 Variabel type
"""
# Membuat dataframe jumlah elemen pada variabel type
type_df = pd.DataFrame(netflix_df['type'].value_counts().reset_index())
# Visualisasi variabel type menggunakan pie
fig = px.pie(type_df, 'index', 'type',title ='Movies vs TV Shows')
fig.update_traces(
marker = dict(colors = ['#213970','#1ee3e0'], line = dict(color = 'white', width = 4)))
fig.show()
"""#### 3.2.2.2 Variabel country"""
# Membuat dataframe 20 elemen teratas pada variabel country
country_count = netflix_df['country'].value_counts().sort_values(ascending=False).reset_index()
country_count = pd.DataFrame(country_count)
country_count = country_count.rename(columns={'index':'country', 'country':'count'})
topcountries = country_count[0:20]
topcountries
# Visualisasi 20 top countries
fig = px.funnel(topcountries, x='count', y='country', title='Top 20 Countries')
fig.update_layout(yaxis_title_text='Country')
fig.show()
"""#### 3.2.2.3 Variabel Relase Year"""
# Visualisasi variabel Relase Year
fig = px.histogram(netflix_df, x='release_year', title='Release Year', color='type')
fig.show()
"""#### 3.2.2.4 Variabel Rating"""
# Membuat dataframe 5 elemen teratas pada variabel rating
rating_count = netflix_df['rating'].value_counts().sort_values(ascending=False).reset_index()
rating_count = pd.DataFrame(rating_count)
rating_count = rating_count.rename(columns={'index':'rating', 'rating':'count'})
toprating = rating_count[0:5]
toprating
# Visualisasi 5 top rating
fig = px.funnel(toprating, x='count', y='rating', title='Top 5 Rating')
fig.update_layout(yaxis_title_text='rating')
fig.show()
"""#### 3.2.2.5 Variabel duration
Movies
"""
# Membuat dataframe variabel duration berdasarkan movies
types = netflix_df.groupby('type')
movie = types.get_group('Movie')
movie['duration'].dropna(inplace=True)
new = movie['duration'].str.split(" ", n = 1, expand = True)
movie.drop(columns =["duration"], inplace = True)
movie['duration']= new[0]
# Visualisasi variabel duration berdasarkan movies
fig = px.histogram(movie, x='duration', title='Duration in Movies')
fig.update_layout(xaxis_title_text='duration (minutes)')
fig.show()
"""TV Shows"""
# Membuat dataframe variabel duration berdasarkan tv show
types = netflix_df.groupby('type')
tv_show = types.get_group('TV Show')
tv_show['duration'].dropna(inplace=True)
new = tv_show['duration'].str.split(" ", n = 1, expand = True)
tv_show.drop(columns =["duration"], inplace = True)
tv_show['duration']= new[0]
# Visualisasi variabel duration berdasarkan tv show
fig = px.histogram(tv_show, x='duration', title='Duration in TV Shows')
fig.update_layout(xaxis_title_text='duration (season)')
fig.show()
"""#### 3.2.2.6 Variabel listed_in"""
# Membuat dataframe 10 elemen teratas pada variabel listed_in
listed_in = netflix_df['listed_in'].value_counts().sort_values(ascending=False).reset_index()
listed_in = pd.DataFrame(listed_in)
listed_in = listed_in.rename(columns={'index':'genre', 'listed_in':'count'})
listed_in = listed_in[0:10]
listed_in
# Visualisasi 10 genre
fig = px.funnel(listed_in, x='count', y='genre', title='Top 10 Genres')
fig.update_layout(yaxis_title_text='genre')
fig.show()
"""### 3.2.3 WordCloud
_Word Cloud_ merupakan salah satu metode untuk menampilkan data teks secara visual. Grafik ini populer dalam _text mining_ karena mudah dipahami. Dengan menggunakan _word cloud_, gambaran frekuensi kata-kata dapat ditampilkan dalam bentuk yang menarik namun tetap informatif. Semakin sering satu kata digunakan, maka semakin besar pula ukuran kata tersebut ditampilkan dalam _word cloud_.
#### 3.2.3.1 Variabel Title
"""
text = ' '.join(netflix_df.title.dropna().values)
wordcloud = WordCloud(background_color = 'black').generate(text)
plt.figure(figsize=(15, 6))
plt.imshow(wordcloud)
plt.axis('off')
plt.show()
"""#### 3.2.3.2 Variabel Director"""
text = ''.join(netflix_df.director.dropna().values)
wordcloud = WordCloud(background_color = 'black').generate(text)
plt.figure(figsize=(15, 6))
plt.imshow(wordcloud)
plt.axis('off')
plt.show()
"""#### 3.2.3.3 Variabel cast"""
text = ','.join(netflix_df.cast.dropna().values)
wordcloud = WordCloud(background_color = 'black').generate(text)
plt.figure(figsize=(15, 6))
plt.imshow(wordcloud)
plt.axis('off')
plt.show()
"""#### 3.2.3.4 Variabel Description"""
text = ' '.join(netflix_df.description.dropna().values)
wordcloud = WordCloud(background_color = 'black').generate(text)
plt.figure(figsize=(15, 6))
plt.imshow(wordcloud)
plt.axis('off')
plt.show()
"""#4. Persiapan Data *(Data Preparation)*
Persiapan Data *(Data Preparation)* adalah proses mengubah atau mentransformasi fitur-fitur data ke dalam bentuk yang mudah diinterpretasikan dan diproses oleh model *machine learning*.
## 4.1 Features List
Kami akan membuat daftar fitur yang akan kami gunakan. Kami hanya akan menggunakan fitur yang paling relevan bagi kami, mengingat masalah yang kami hadapi. Oleh karena itu, fitur yang kami pilih adalah title, type, director, cast, country, listed_in, description, dan rating.
Selain itu, kami mengubah tipe data menjadi string dan melakukan sedikit preprocessing data dan mengganti setiap baris yang memiliki nilai NaN dengan spasi/string kosong, sehingga tidak menghasilkan kesalahan saat menjalankan kode.
"""
# Memilih fitur yang akan dipilih
content_cols = ['title','type','director','cast','country','listed_in','description','rating']
data = netflix_df[content_cols]
# Mengubah tipe data ke string
data = data.astype(str)
# Mengisi NaN dengan spasi/string kosong
data = data.fillna(" ")
data
"""## 4.2 _Data Cleaning_
Kami menggunakan RAKE-NLTK. RAKE (Rapid Automatic Keyword Extraction) adalah algoritma ekstraksi kata kunci independen domain yang mencoba menentukan frasa kunci dalam tubuh teks dengan menganalisis frekuensi kemunculan kata dan kemunculannya bersama dengan kata lain dalam teks.
Kemudian digabungkan fitur berupa type, director, cast, country, listed_in, description, dan rating menjadi satu yaitu key_notes dan title tetap menjadi fitur sendiri.
Setelah itu, kami mengubah tipe data menjadi string dan membuang tanda baca seperti , & - . Dan menjadikan semua string menjadi huruf kecil dengan lower.
"""
# Inisialisasi awal rake
rake = Rake()
# Membuat fitur baru key_notes
data['key_notes'] = ''
# Data Cleaning
for index,row in data.iterrows():
plot = row['description']
rake.extract_keywords_from_text(plot)
keyword_score = rake.get_word_degrees()
types = ' '.join(row['type'].replace(' ','').split(',')).lower()
genre = ''.join(row['listed_in'].split(',')).lower()
director = ''.join(row['director'].replace(' ','').split(',')).lower()
cast = ' '.join(row['cast'].replace(' ','').split(',')).lower()
country = ''.join(row['country'].replace(' ','').split(',')).lower()
rating = ' '.join(row['rating'].replace(' ','').split(',')).lower()
keyword_score = ' '.join(list(keyword_score.keys()))
row['key_notes'] = types + ' ' + genre + ' ' + director + ' ' + cast + ' ' + keyword_score + ' ' + country + ' ' + rating
# Hanya menggunakan fitur title dan key_notes
recommend = data[['title','key_notes']]
recommend.head()
"""# 5. Pembuatan Model *(Modeling)*
Pada tahap ini, kita menggunakan _Content Based Filtering_ dengan CountVectorizer dan TF-IDF Vectorizer.
### 5.1 CountVectorizer
Count Vectorizer adalah cara untuk mengubah serangkaian string tertentu menjadi representasi frekuensi. Count Vectorizer dapat membantu dalam memahami jenis teks dengan frekuensi kata-kata di dalamnya. Namun mempunyai kelemahan berupa:
1. Ketidakmampuan dalam mengidentifikasi kata-kata yang lebih penting dan kurang penting untuk dianalisis.
2. Hanya mempertimbangkan kata-kata yang berlimpah di corpus sebagai kata yang paling signifikan secara statistik.
3. Tidak mengindentifikasi hubungan antar kata seperti kesamaan linguistik antar kata.
#### 5.1.1 Pembuatan CountVectorizer
Di definisikan variabel vectorizer sebagai CountVectorizer(), dengan stop_words=’english’ berfungsi untuk menghilangkan kata semacam: i, you, the, a, this, is dan sejenisnya.
"""
# Inisialisasi CountVectorizer
cv= CountVectorizer(analyzer='word',ngram_range=(1, 2),min_df=0, stop_words='english')
# Melakukan perhitungan idf pada data
cv.fit(recommend['title'])
# Melakukan fit lalu ditransformasikan ke bentuk matrix
cvidf_matrix = cv.fit_transform(recommend['key_notes'])
# Melihat ukuran matrix cv-idf
cvidf_matrix.shape
"""### 5.2 TF-IDF Vectorizer
TF-IDF Vectorizer (Term Frequency - Inverse Document Frequency) adalah statistik yang didasarkan pada frekuensi kata dalam korpus tetapi juga memberikan representasi numerik tentang betapa pentingnya sebuah kata untuk analisis statistik.
TF-IDF lebih baik daripada Count Vectorizers karena tidak hanya berfokus pada frekuensi kata yang ada dalam korpus tetapi juga memberikan pentingnya kata tersebut. Kami kemudian dapat menghapus kata-kata yang kurang penting untuk analisis, sehingga membuat model bangunan kurang kompleks dengan mengurangi dimensi input.
TF-IDF didasarkan pada logika bahwa kata-kata yang terlalu banyak dalam korpus dan kata-kata yang terlalu jarang keduanya tidak penting secara statistik untuk menemukan suatu pola. Faktor logaritma dalam TF-IDF secara matematis menghukum kata-kata yang terlalu banyak atau terlalu jarang dalam korpus dengan memberikan nilai TF-IDF yang rendah.
#### 5.2.1 Pembuatan TF-IDF Vectorizer
Di definisikan variabel vectorizer sebagai TfidfVectorizer(), dengan stop_words=’english’ berfungsi untuk menghilangkan kata semacam: i, you, the, a, this, is dan sejenisnya.
"""
# Inisialisasi TfidfVectorizer
tf = TfidfVectorizer(analyzer='word',ngram_range=(1, 2),min_df=0, stop_words='english')
# Melakukan perhitungan idf pada data
tf.fit(recommend['title'])
# Melakukan fit lalu ditransformasikan ke bentuk matrix
tfidf_matrix = tf.fit_transform(recommend['key_notes'])
# Melihat ukuran matrix tf-idf
tfidf_matrix.shape
"""# 6. Evaluasi Model
## 6.1 Evalusasi Model dengan Cosine Similarity CountVectorizer
Cosine similarity mengukur kesamaan antara dua vektor dan menentukan apakah kedua vektor tersebut menunjuk ke arah yang sama. Ia menghitung sudut cosinus antara dua vektor. Semakin kecil sudut cosinus, semakin besar nilai cosine similarity.

Cosine similarity dirumuskan sebagai berikut.

"""
# Menghitung cosine similarity pada matrix cv-idf
cosine_sim = cosine_similarity(cvidf_matrix, cvidf_matrix)
cosine_sim
# Membuat dataframe dari variabel cosine_sim dengan baris dan kolom berupa title
cosine_sim_df = pd.DataFrame(cosine_sim, index=recommend['title'], columns=recommend['title'])
print('Shape:', cosine_sim_df.shape)
# Melihat similarity matrix pada setiap title
cosine_sim_df.sample(5, axis=1).sample(10, axis=0)
"""## 6.2 Melakukan Rekomendasi dan Metrik Precision"""
titles = recommend['title']
indices = pd.Series(recommend.index, index=recommend['title'])
def recomendation(title:str):
idx = indices[title]
sim_scores = list(enumerate(cosine_sim[idx]))
sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)
sim_scores = sim_scores[1:26]
movie_indices = [i[0] for i in sim_scores]
sim_values = [i[1]for i in sim_scores]
print(f'Movie atau TV Show yang anda sukai {title}\n{len(sim_scores)} Movie atau TV Show berikut ini mungkin anda sukai:\n')
return pd.DataFrame(data = {"Nama Movie atau TV Show" : titles.iloc[movie_indices], "Cosine Similarity" : sim_values}).sort_values(by='Cosine Similarity',ascending=False).reset_index(drop=True), sim_values
def precision(gr,sv):
result = []
gr = len(gr)
sv = sv[:gr]
for x in sv:
if x>0.05:
result.append(x)
results = len(result)
precision = results/gr
print("Jumlah Rekomendasi Film yang sesuai: ", len(result))
print("Banyaknya Rekomendasi Film: ", gr)
return print('Precision adalah',round(precision,2))
gr,sv = recomendation("Story of Kale: When Someone's in Love")
gr
"""Metrik Precision"""
precision(gr,sv)
"""## 6.3 Evaluasi Model dengan Cosine Similarity TF-IDF Vectorizer
Cosine similarity mengukur kesamaan antara dua vektor dan menentukan apakah kedua vektor tersebut menunjuk ke arah yang sama. Ia menghitung sudut cosinus antara dua vektor. Semakin kecil sudut cosinus, semakin besar nilai cosine similarity.

Cosine similarity dirumuskan sebagai berikut.

"""
# Menghitung cosine similarity pada matrix tf-idf
cosine_sim = cosine_similarity(tfidf_matrix, tfidf_matrix)
cosine_sim
# Membuat dataframe dari variabel cosine_sim dengan baris dan kolom berupa title
cosine_sim_df = pd.DataFrame(cosine_sim, index=recommend['title'], columns=recommend['title'])
print('Shape:', cosine_sim_df.shape)
# Melihat similarity matrix pada setiap title
cosine_sim_df.sample(5, axis=1).sample(10, axis=0)
"""## 6.4 Melakukan Rekomendasi dan Metrik Precision"""
titles = recommend['title']
indices = pd.Series(recommend.index, index=recommend['title'])
def recomendation(title:str):
idx = indices[title]
sim_scores = list(enumerate(cosine_sim[idx]))
sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)
sim_scores = sim_scores[1:26]
movie_indices = [i[0] for i in sim_scores]
sim_values = [i[1]for i in sim_scores]
print(f'Movie atau TV Show yang anda sukai {title}\n{len(sim_scores)} Movie atau TV Show berikut ini mungkin anda sukai:\n')
return pd.DataFrame(data = {"Nama Movie atau TV Show" : titles.iloc[movie_indices], "Cosine Similarity" : sim_values}).sort_values(by='Cosine Similarity',ascending=False).reset_index(drop=True), sim_values
def precision(gr,sv):
result = []
gr = len(gr)
sv = sv[:gr]
for x in sv:
if x>0.05:
result.append(x)
results = len(result)
precision = results/gr
print("Jumlah Rekomendasi Film yang sesuai: ", len(result))
print("Banyaknya Rekomendasi Film: ", gr)
return print('Precision adalah',round(precision,2))
gr,sv = recomendation("Story of Kale: When Someone's in Love")
gr
"""Metrik Precision"""
precision(gr,sv)
"""# Penutup
Dari precision yang dilihat bahwa precision pada CountVectorizer lebih baik daripada TF-IDF Vectorizer. Precision pada CountVectorizer 1.0 artinya 100% sedangkan precision pada TF-IDF Vectorizer 0.6 atau 60%.
**Referensi**
* Dokumentasi Scikit-Learn: https://scikit-learn.org/stable/modules/classes.html
* Dataset: https://www.kaggle.com/shivamb/netflix-shows
"""