video_recommender.py
3.78 KB
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
from gensim.models import Word2Vec
import numpy as np
from numpy import dot
from numpy.linalg import norm
def recommend_videos(tags, segments, tag_model_path, video_model_path, top_k):
# 이 함수에서 모든걸 다 함
# tags는 label val 로 묶인 문자열 리스트임
# tags의 길이는 segment의 길이
# 비디오 벡터를 생성한 뒤 각 segment의 벡터와 비교해 가장 유사도 높은 segment의 인덱스 추출
# 그 후 그 인덱스 전후 2개 총 크기 5의 커널을 생성
# 벡터공간에서 비교한 후 추천할만한 영상의 아이디만 반환
#segments는 클래스 확률 클래스 확률... 일케 저장되어 있음
tag_vectors = Word2Vec.load(tag_model_path).wv
video_vectors = Word2Vec().wv.load(video_model_path)
error_tags = []
maxSimilarSegment = 0
maxSimilarity = -1
kernel = [np.zeros(100) for i in range(0,3)]
#우선은 비교를 뜰 입력 영상의 단일 비디오벡터를 구함
video_vector = np.zeros(100)
print(tags)
for (tag, weight) in tags:
if tag in tag_vectors.vocab:
#float(weight)
video_vector = video_vector + (tag_vectors[tag] * float(weight))
else:
# Pass if tag is unknown
if tag not in error_tags:
error_tags.append(tag)
#각 세그먼트마다 비교를 떠서 인덱스를 저장
currentIndex = 0
for segment in segments:
segment_vector = np.zeros(100)
segTags = [segment[i] for i in range(0,len(segment),2)]
segProbs = [float(segment[i]) for i in range(1,len(segment),2)]
for (tag, weight) in zip(segTags,segProbs):
if tag in tag_vectors.vocab:
#float(weight)
segment_vector = segment_vector + (tag_vectors[tag] * float(weight))
else:
# Pass if tag is unknown
if tag not in error_tags:
error_tags.append(tag)
#비디오 벡터와 세그먼트 벡터 비교
similarity = cos_sim(video_vector, segment_vector)
if similarity > maxSimilarity:
maxSimilarSegment = currentIndex
maxSimilarity = similarity
if maxSimilarSegment == 0:
maxSimilarSegment = 1
elif maxSimilarSegment == len(segments) - 1:
maxSimilarSegment = len(segments) - 2
#세그먼트 인덱스 증가
currentIndex = currentIndex + 1
print("len=============================================")
print(len(kernel))
print(maxSimilarSegment)
#커널 생성
for k in range (0,3):
segment = segments[maxSimilarSegment -1 + k]
segment_vector = np.zeros(100)
segTags = [segment[i] for i in range(0,len(segment),2)]
print(segTags)
segProbs = [float(segment[i]) for i in range(1,len(segment),2)]
for (tag, weight) in zip(segTags,segProbs):
if tag in tag_vectors.vocab:
#float(weight)
segment_vector = segment_vector + (tag_vectors[tag] * float(weight))
else:
# Pass if tag is unknown
if tag not in error_tags:
error_tags.append(tag)
kernel[k] = segment_vector
#여기에서 유사한 벡터들을 뽑아냄
#현재는 비디오id로 영상을 얻을 수 없으므로 반환값으로 비디오 아이디와 태그들, 확률 사용
similar_ids = [x[0] for x in video_vectors.similar_by_vector(video_vector, top_k)]
return similar_ids
def cos_sim(A, B):
return dot(A, B)/(norm(A)*norm(B))
def shiftKernel(kernel, newValue):
for i in range(0, len(kernel) - 1):
kernel[i] = kernel[i+1]
kernel[len(kernel) - 1] = newValue