Kapex13 commited on
Commit
080b8e9
·
verified ·
1 Parent(s): e10e9b9

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +17 -21
src/streamlit_app.py CHANGED
@@ -39,7 +39,6 @@ def list_str_to_text(x):
39
 
40
  def clean_actors_string(val):
41
  v = str(val).strip().lower()
42
- # если фраза мусорная или вообще нет букв — заменяем на "Неизвестно"
43
  if any(bad in v for bad in BAD_ACTORS) or not re.search(r'[a-zа-яё]', v):
44
  return "Неизвестно"
45
  return val
@@ -58,26 +57,27 @@ def extract_intro_paragraph(text, max_sentences=4):
58
  def clean_tvshows_data(path):
59
  df = pd.read_csv(path)
60
 
61
- # actors: списки в строки + чистка мусора
62
  df["actors"] = df["actors"].apply(list_str_to_text)
63
  df["actors"] = df["actors"].apply(clean_actors_string)
64
 
65
- # genres: списки в строки
66
  df["genres"] = df["genres"].apply(list_str_to_text)
67
 
 
68
  df["year"] = pd.to_numeric(df["year"], errors="coerce").fillna(0).astype(int)
69
  df["num_seasons"] = pd.to_numeric(df["num_seasons"], errors="coerce").fillna(0).astype(int)
70
  df["tvshow_title"] = df["tvshow_title"].fillna("Неизвестно")
71
  df["description"] = df["description"].fillna("Нет описания").astype(str).str.strip()
72
 
73
- # Удаляем короткие описания (<15 слов)
74
  df = df[df["description"].apply(lambda x: len(str(x).split())) >= 15]
75
 
76
- # Удаляем часто повторяющиеся описания (>=3)
77
  to_drop_exact = df["description"].value_counts()[lambda x: x >= 3].index
78
  df = df[~df["description"].isin(to_drop_exact)]
79
 
80
- # Мусорные шаблоны
81
  garbage_patterns = [
82
  r"(всё в порядке[.!?~ ,]*){3,}",
83
  r"(я не знаю[^.!?]*){2,}",
@@ -90,14 +90,14 @@ def clean_tvshows_data(path):
90
  return any(re.search(p, text) for p in garbage_patterns)
91
  df = df[~df["description"].apply(matches_garbage)]
92
 
93
- # Мусорные подстроки
94
  bad_phrase_parts = [
95
  "однадцатая секретаря", "тридцать третья", "оу, оу-у-у",
96
  "всё в порядке?", "я не знаю, что делать"
97
  ]
98
  df = df[~df["description"].str.lower().apply(lambda t: any(p in t for p in bad_phrase_parts))]
99
 
100
- # Бинарные one-hot-колонки
101
  genre_onehots = [
102
  c for c in df.columns
103
  if c not in ['tvshow_title','year','genres','actors','rating','description',
@@ -106,13 +106,13 @@ def clean_tvshows_data(path):
106
  ]
107
  df = df.drop(columns=genre_onehots, errors="ignore")
108
 
109
- # Нормализуем жанры
110
  df["basic_genres"] = df["genres"].apply(filter_to_basic_genres)
111
 
112
- # Колонка type (Фильм/Сериал)
113
  df["type"] = df["num_seasons"].apply(lambda x: "Сериал" if pd.notna(x) and int(x) > 1 else "Фильм")
114
 
115
- # Гарантия колонок
116
  for col in ["image_url", "url", "rating", "language", "country"]:
117
  if col not in df.columns:
118
  df[col] = None
@@ -151,17 +151,11 @@ def semantic_search(query, embedder, index, df, genre=None, year=None, country=N
151
 
152
  @st.cache_resource(ttl=3600)
153
  def init_groq_llm():
154
- # 1. Пробуем вытащить из переменных окружения (HF Spaces)
155
- key = os.environ.get("GROQ_API_KEY") \
156
- or (st.secrets.get("GROQ_API_KEY") if hasattr(st, "secrets") else None) \
157
- or st.text_input("Введите API-ключ Groq:", type="password")
158
-
159
  if not key:
160
  st.warning("Введите ваш Groq API ключ для генерации ответов.")
161
  return None
162
-
163
  os.environ["GROQ_API_KEY"] = key
164
-
165
  try:
166
  return ChatGroq(model="deepseek-r1-distill-llama-70b", temperature=0, max_tokens=2000)
167
  except Exception as e:
@@ -191,7 +185,6 @@ def main():
191
 
192
  df = load_data()
193
 
194
- # Гарантия колонки type
195
  if "type" not in df.columns:
196
  df["type"] = df["num_seasons"].apply(lambda x: "Сериал" if pd.notna(x) and int(x) > 1 else "Фильм")
197
 
@@ -200,6 +193,7 @@ def main():
200
  llm = init_groq_llm()
201
 
202
  colf1, colf2, colf3, colf4 = st.columns(4)
 
203
  with colf1:
204
  genres = ["Все"] + sorted(set(sum([g.split(", ") for g in df["basic_genres"].unique()], [])))
205
  genre_filter = st.selectbox("Жанр", genres)
@@ -259,8 +253,10 @@ def main():
259
  f" | {row['type']} | {row['num_seasons']} сез."
260
  )
261
  st.write(extract_intro_paragraph(row["description"]))
262
- if row["actors"]: st.caption(f"Актёры: {row['actors']}")
263
- if row["url"]: st.markdown(f"[Подробнее]({row['url']})")
 
 
264
  st.divider()
265
 
266
  if st.button("AI: почему эти подходят и что ещё посмотреть"):
 
39
 
40
  def clean_actors_string(val):
41
  v = str(val).strip().lower()
 
42
  if any(bad in v for bad in BAD_ACTORS) or not re.search(r'[a-zа-яё]', v):
43
  return "Неизвестно"
44
  return val
 
57
  def clean_tvshows_data(path):
58
  df = pd.read_csv(path)
59
 
60
+ # Преобразуем actors в строки и чистим мусор
61
  df["actors"] = df["actors"].apply(list_str_to_text)
62
  df["actors"] = df["actors"].apply(clean_actors_string)
63
 
64
+ # Преобразуем genres в строки
65
  df["genres"] = df["genres"].apply(list_str_to_text)
66
 
67
+ # Обработка числовых колонок
68
  df["year"] = pd.to_numeric(df["year"], errors="coerce").fillna(0).astype(int)
69
  df["num_seasons"] = pd.to_numeric(df["num_seasons"], errors="coerce").fillna(0).astype(int)
70
  df["tvshow_title"] = df["tvshow_title"].fillna("Неизвестно")
71
  df["description"] = df["description"].fillna("Нет описания").astype(str).str.strip()
72
 
73
+ # Фильтрация описаний короче 15 слов
74
  df = df[df["description"].apply(lambda x: len(str(x).split())) >= 15]
75
 
76
+ # Удаление часто повторяющихся описаний (3 и более)
77
  to_drop_exact = df["description"].value_counts()[lambda x: x >= 3].index
78
  df = df[~df["description"].isin(to_drop_exact)]
79
 
80
+ # Удаление мусорных шаблонов
81
  garbage_patterns = [
82
  r"(всё в порядке[.!?~ ,]*){3,}",
83
  r"(я не знаю[^.!?]*){2,}",
 
90
  return any(re.search(p, text) for p in garbage_patterns)
91
  df = df[~df["description"].apply(matches_garbage)]
92
 
93
+ # Удаление строк с известными мусорными подстроками
94
  bad_phrase_parts = [
95
  "однадцатая секретаря", "тридцать третья", "оу, оу-у-у",
96
  "всё в порядке?", "я не знаю, что делать"
97
  ]
98
  df = df[~df["description"].str.lower().apply(lambda t: any(p in t for p in bad_phrase_parts))]
99
 
100
+ # Удаление бинарных one-hot колонок жанров
101
  genre_onehots = [
102
  c for c in df.columns
103
  if c not in ['tvshow_title','year','genres','actors','rating','description',
 
106
  ]
107
  df = df.drop(columns=genre_onehots, errors="ignore")
108
 
109
+ # Нормализация жанров
110
  df["basic_genres"] = df["genres"].apply(filter_to_basic_genres)
111
 
112
+ # Колонка type (Фильм/Сериал) по кол-ву сезонов
113
  df["type"] = df["num_seasons"].apply(lambda x: "Сериал" if pd.notna(x) and int(x) > 1 else "Фильм")
114
 
115
+ # Гарантия существования нужных колонок
116
  for col in ["image_url", "url", "rating", "language", "country"]:
117
  if col not in df.columns:
118
  df[col] = None
 
151
 
152
  @st.cache_resource(ttl=3600)
153
  def init_groq_llm():
154
+ key = os.environ.get("GROQ_API_KEY") or (st.secrets.get("GROQ_API_KEY") if hasattr(st, "secrets") else None) or st.text_input("Введите API-ключ Groq:", type="password")
 
 
 
 
155
  if not key:
156
  st.warning("Введите ваш Groq API ключ для генерации ответов.")
157
  return None
 
158
  os.environ["GROQ_API_KEY"] = key
 
159
  try:
160
  return ChatGroq(model="deepseek-r1-distill-llama-70b", temperature=0, max_tokens=2000)
161
  except Exception as e:
 
185
 
186
  df = load_data()
187
 
 
188
  if "type" not in df.columns:
189
  df["type"] = df["num_seasons"].apply(lambda x: "Сериал" if pd.notna(x) and int(x) > 1 else "Фильм")
190
 
 
193
  llm = init_groq_llm()
194
 
195
  colf1, colf2, colf3, colf4 = st.columns(4)
196
+
197
  with colf1:
198
  genres = ["Все"] + sorted(set(sum([g.split(", ") for g in df["basic_genres"].unique()], [])))
199
  genre_filter = st.selectbox("Жанр", genres)
 
253
  f" | {row['type']} | {row['num_seasons']} сез."
254
  )
255
  st.write(extract_intro_paragraph(row["description"]))
256
+ if row["actors"]:
257
+ st.caption(f"Актёры: {row['actors']}")
258
+ if row["url"]:
259
+ st.markdown(f"[Подробнее]({row['url']})")
260
  st.divider()
261
 
262
  if st.button("AI: почему эти подходят и что ещё посмотреть"):