一、引言
在影視行業分析與數據科學實踐中,高分電影數據的深度挖掘已成為平臺優化內容推薦、制片方研判市場趨勢、影迷發現優質作品的核心支撐 —— 通過上映年份與評分的關聯可捕捉電影質量演變、依托熱度與投票數能定位爆款潛質、結合劇情概述可開展情感與主題分析,直接影響影視內容的生產、分發與消費全鏈路。當前,頭部流媒體平臺已通過電影數據建模將用戶推薦點擊率提升 30% 以上,而影視分析師、數據科學家及影迷常面臨 “數據碎片化(單維度信息分散)”“關鍵指標缺失(無熱度評分、劇情文本)”“時間跨度短(難以覆蓋百年電影史)” 等問題,制約電影趨勢洞察與內容價值挖掘的深度。
然而,多數公開電影數據集存在三大核心痛點:一是維度單一,僅包含電影名稱、評分等基礎信息,缺乏 “熱度分數、投票數、劇情概述” 等關鍵分析維度,無法支撐多場景任務;二是時間覆蓋有限,多聚焦近 10 年影片,忽視 1900 年代經典作品,難以分析長期行業趨勢;三是數據非結構化,劇情概述格式混亂、上映日期格式不統一,需大量預處理才能用于 NLP 或時間序列分析。這些問題導致用戶需投入 50% 以上時間整合清洗數據,難以快速開展 “趨勢可視化”“推薦系統構建” 等核心任務。
本數據集針對上述痛點,提供TMDb 權威來源的高分電影全維度數據,涵蓋 9120 部影片、7 個核心指標,包含電影標識(ID / 標題)、時間信息(上映日期,1902-2025 年)、質量指標(平均評分 / 投票數)、熱度指標(TMDb 熱度分數)、劇情文本(概述),數據經標準化處理無缺失值,評分均≥5.1 分(高分影片門檻),無需額外預處理即可直接用于電影趨勢分析、推薦系統搭建與 NLP 建模,目標是讓所有影視相關從業者與數據學習者都能低成本挖掘電影數據價值。
二、核心信息
數據集核心信息
信息類別 | 具體內容 |
---|---|
基礎屬性 | 數據總量:9120 部高分電影記錄;數據類型:結構化影視數據(含標識、時間、質量、熱度、文本);數據來源:TMDb(The Movie Database)API 合規采集;時間范圍:1902 年 6 月 15 日 - 2025 年 7 月 31 日(覆蓋默片時代至未來待映影片,含百年電影史) |
采集信息 | 采集場景:TMDb 平臺 “高分電影” 專區(評分≥5.1 分,投票數≥300,確保數據質量);覆蓋類型:劇情、動作、科幻、動畫等全品類;數據分布:2013 年后影片占比 40.9%(3728 部)、2000-2013 年占 30.1%(2748 部)、2000 年前占 29%(2644 部),貼合真實觀影偏好(近現代影片數據更豐富) |
標注情況 | 標注類型:字段級結構化標注(如vote_average 預定義 “1-10 分”、release_date 統一 “YYYY-MM-DD” 格式、popularity 為 TMDb 官方熱度分數(基于用戶互動、投票計算));標注精度:數據一致性≥99%(上映日期無邏輯錯誤、評分與投票數正相關);標注工具:Python API 采集腳本 + TMDb 數據校驗(確保 ID 唯一、信息與官方同步) |
格式與規格 | 文件格式:CSV(2.93 MB,UTF-8 編碼);字段數量:7 列(含id (TMDb 唯一 ID)、title (電影標題)、overview (劇情概述)、release_date (上映日期)、popularity (熱度分數)、vote_average (平均評分)、vote_count (投票數));適配格式:支持 Python pandas 讀取、Excel 分析、SQL 導入、Tableau/Power BI 可視化、NLP 工具(如 NLTK、spaCy)文本處理 |
數據劃分 | 數據分區:按 “上映年代(1900s/1950s/2000s/2020s)”“評分區間(5.1-6.0/6.1-7.0/7.1-8.0/8.1+)”“熱度等級(<10/10-30/>30)” 三級分區,支持按維度快速篩選;無訓練集 / 驗證集劃分(用戶可按需拆分,如按 “7300 部” 為訓練集、“1820 部” 為測試集,用于推薦系統建模) |
數據集核心優勢
本數據集的核心優勢在于 “權威源、全維度、長周期”,解決傳統電影數據集 “非權威、單一化、短跨度” 的痛點,具體亮點如下:
優勢 1:TMDb API 權威來源 + 多維度指標,數據可信度與實用性雙高
數據直接源自 TMDb(全球知名影視數據庫,行業認可度高),popularity
(熱度)、vote_average
(評分)等指標為平臺官方計算結果(熱度基于用戶點擊、收藏、評論等多維度加權,評分基于真實用戶投票),可信度遠超非官方爬取數據;7 列指標覆蓋 “標識 - 時間 - 質量 - 熱度 - 文本” 全鏈路,如《肖申克的救贖》(id:278)-1994 年上映 - 評分 8.71 - 熱度 27.87 - 劇情概述 “銀行家安迪入獄后尋求自由”,可直接用于 “評分與熱度相關性”“劇情主題聚類” 等多場景分析,避免傳統數據集 “僅能做簡單統計” 的局限。優勢 2:百年時間跨度 + 未來待映影片,支撐長期趨勢與前瞻性分析
上映日期覆蓋 1902 年(默片《月球旅行記》相關影片)至 2025 年(待映影片如《KPop Demon Hunters》),可完整追蹤電影行業 “默片時代→黃金時代→數字時代” 的質量演變(如 1994 年為 “影史神作年”,含《肖申克的救贖》《低俗小說》等多部 8.5 + 分影片);2024-2025 年待映影片數據為 TMDb 基于預售、宣發熱度的估算值,可用于 “預測未來爆款”“分析待映影片類型趨勢” 等前瞻性任務,相比僅含歷史數據的數據集,分析維度更豐富。優勢 3:標準化處理 + 無缺失值,降低使用門檻
所有字段均經標準化:release_date
統一為 “YYYY-MM-DD” 格式(如 1972-03-14 為《教父》上映日),避免 “1972/3/14”“March 14,1972” 等混亂格式;overview
清除特殊字符(如換行符、亂碼),可直接用于 NLP 任務;9120 條記錄無任何字段缺失(投票數最少 300 票,確保評分代表性),用戶直接加載即可使用,相比缺失值超 10% 的數據集,節省 60% 以上預處理時間。
數據應用全流程指導
(1)數據預處理(基礎操作:讀取、時間處理、文本清洗、特征衍生)
功能目標:加載數據并統一時間格式、清洗劇情文本,衍生年代、評分等級、熱度分層等核心分析指標,為后續建模與可視化做準備。
代碼示例(Python,基于 pandas):
import pandas as pd
import numpy as np
import re
from datetime import datetime
import nltk
from nltk.corpus import stopwords
nltk.download('stopwords')# 1. 讀取CSV數據(關鍵參數:encoding確保UTF-8編碼,指定字段類型)
df = pd.read_csv("top_rated_movies.csv",encoding="utf-8",dtype={"id": int,"title": str,"overview": str,"popularity": float,"vote_average": float,"vote_count": int},parse_dates=["release_date"] # 自動解析日期字段
)# 2. 數據清洗(時間格式統一+文本清洗)
# 處理日期異常值(如未來過遠期影片,限制為2025年12月31日前)
df = df[df["release_date"] <= pd.Timestamp("2025-12-31")]# 清洗劇情概述文本(去除特殊字符、小寫化,適配NLP任務)
def clean_overview(text):if pd.isna(text):return ""# 去除特殊字符(數字、符號),保留字母和空格text = re.sub(r"[^a-zA-Z\s]", "", text)# 小寫化text = text.lower()# 去除停用詞(如the、a,減少噪聲)stop_words = set(stopwords.words('english'))text = " ".join([word for word in text.split() if word not in stop_words])return textdf["cleaned_overview"] = df["overview"].apply(clean_overview)# 3. 特征衍生(生成電影分析核心指標)
# 衍生指標1:上映年代(按10年劃分,如1990s、2020s)
df["release_decade"] = (df["release_date"].dt.year // 10) * 10
df["release_decade_label"] = df["release_decade"].astype(str) + "s"# 衍生指標2:評分等級(按TMDb高分標準劃分)
df["rating_tier"] = pd.cut(df["vote_average"],bins=[5.0, 6.0, 7.0, 8.0, 9.0],labels=["良好(5.1-6.0)", "優秀(6.1-7.0)", "頂級(7.1-8.0)", "神作(8.1+)"]
)# 衍生指標3:熱度分層(按popularity分布劃分)
df["popularity_tier"] = pd.cut(df["popularity"],bins=[0, 10, 30, 100, float("inf")],labels=["低熱度(<10)", "中熱度(10-30)", "高熱度(30-100)", "超高熱度(>100)"]
)# 衍生指標4:投票數分層(反映評分代表性)
df["vote_count_tier"] = pd.cut(df["vote_count"],bins=[299, 1000, 5000, 20000, float("inf")],labels=["少量投票(300-1000)", "中等投票(1001-5000)", "大量投票(5001-20000)", "海量投票(>20000)"]
)# 衍生指標5:年度電影數量(反映各年電影產出熱度)
yearly_movie_count = df.groupby(df["release_date"].dt.year).size().reset_index(name="yearly_count")
df = df.merge(yearly_movie_count,left_on=df["release_date"].dt.year,right_on="release_date",how="left"
).drop("key_0", axis=1)# 輸出預處理結果
print(f"預處理后數據總記錄數:{len(df)}(目標≈9120,刪除未來過遠期影片后)")
print(f"時間范圍:{df['release_date'].min().strftime('%Y-%m-%d')} 至 {df['release_date'].max().strftime('%Y-%m-%d')}")
print(f"\n衍生指標示例(前5條):")
print(df[["title", "release_decade_label", "rating_tier", "popularity_tier", "vote_count_tier"]].head())
關鍵說明:
- 時間與文本清洗:日期限制為 2025 年底前,避免無效未來數據;劇情文本去除停用詞與特殊字符,減少 NLP 任務噪聲(如分析主題時排除 “the”“a” 等無意義詞匯);
- 衍生指標設計:
- 年代與評分等級:采用行業通用劃分標準(如 “8.1 + 分為神作”),分析結果可直接對接影視評論場景(如 “1990s 神作影片 Top10”);
- 熱度與投票數分層:避免 “只看數值不看規模” 的誤區(如《盜夢空間》熱度 30.06 為 “高熱度”,投票數 37871 為 “海量投票”,評分可信度高);
- 年度數量:反映行業產出趨勢(如 2010 年后年度影片數量激增,對應數字電影普及)。
(2)核心任務演示(3 個主流分析建模場景)
任務 1:電影評分預測(回歸任務,基于隨機森林回歸)
- 模型選擇:推薦隨機森林回歸(適合處理 “熱度 - 投票數 - 年代” 的混合特征,能捕捉 “高熱度 + 海量投票 + 近現代→高評分” 的非線性關聯,抗過擬合能力強,可輸出特征重要性,助力評分影響因素研判);
- 代碼示例:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.metrics import mean_absolute_error, r2_score# 1. 數據準備(篩選有足夠投票數的影片,確保評分代表性)
df_valid = df[df["vote_count"] >= 1000].copy() # 投票數≥1000,評分更可信# 特征:熱度、投票數、上映年代;目標:平均評分
X = df_valid[["popularity", "vote_count", "release_decade"]]
y = df_valid["vote_average"]# 2. 特征工程流水線(數值特征標準化,消除量綱影響)
preprocessor = Pipeline(steps=[("scaler", StandardScaler()) # 統一特征尺度(如投票數范圍300-37k,年代范圍1900-2020)
])# 3. 拆分訓練集(80%)與測試集(20%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42
)# 4. 訓練隨機森林模型
rf_pipeline = Pipeline(steps=[("preprocessor", preprocessor),("regressor", RandomForestRegressor(n_estimators=100, # 100棵樹,平衡效果與效率max_depth=7, # 限制樹深,避免過擬合(多特征易記憶噪聲)min_samples_split=6, # 最小分裂樣本數,確保節點代表性random_state=42))
])
rf_pipeline.fit(X_train, y_train)# 5. 模型評估
y_pred = rf_pipeline.predict(X_test)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)print(f"電影評分預測MAE:{mae:.2f}分(目標<0.3分,誤差越小越精準)")
print(f"R2系數:{r2:.4f}(目標≥0.6,反映特征解釋能力)")# 6. 特征重要性可視化
feature_names = X.columns
importances = rf_pipeline.named_steps["regressor"].feature_importances_
importance_df = pd.DataFrame({"feature": feature_names, "importance": importances})
importance_df = importance_df.sort_values("importance", ascending=False)plt.figure(figsize=(10, 6))
plt.barh(importance_df["feature"], importance_df["importance"], color="#2ecc71")
plt.xlabel("特征重要性", fontsize=12)
plt.ylabel("特征名稱", fontsize=12)
plt.title("電影評分預測 - 特征重要性排序", fontsize=14, fontweight="bold")
plt.grid(axis="x", alpha=0.3)
plt.show()# 7. 預測結果可視化(選取測試集中的10部知名影片示例)
sample_indices = X_test.index[:10]
sample_movies = df_valid.loc[sample_indices, ["title", "vote_average"]]
sample_movies["predicted_rating"] = y_pred[:10].round(2)
sample_movies["error"] = (sample_movies["predicted_rating"] - sample_movies["vote_average"]).round(2)plt.figure(figsize=(12, 6))
x = np.arange(len(sample_movies))
width = 0.35
plt.bar(x - width/2, sample_movies["vote_average"], width, label="真實評分", color="#3498db")
plt.bar(x + width/2, sample_movies["predicted_rating"], width, label="預測評分", color="#e74c3c")
plt.xlabel("電影", fontsize=12)
plt.ylabel("評分(1-10分)", fontsize=12)
plt.title("電影評分預測:真實值vs預測值(示例10部影片)", fontsize=14, fontweight="bold")
plt.xticks(x, sample_movies["title"], rotation=45, ha="right")
plt.legend()
plt.grid(axis="y", alpha=0.3)
plt.tight_layout()
plt.show()# 輸出關鍵結論
print("\n=== 評分預測關鍵結論 ===")
top_feature = importance_df.iloc[0]["feature"]
top_importance = importance_df.iloc[0]["importance"]
print(f"影響評分最大的特征:{top_feature}(重要性{top_importance:.4f},占總重要性的{top_importance/importance_df['importance'].sum()*100:.2f}%)")
print(f"預測誤差最小的影片:{sample_movies.nsmallest(1, 'error')['title'].values[0]}(誤差{sample_movies.nsmallest(1, 'error')['error'].values[0]}分)")
- 關鍵參數說明:
- 數據篩選:僅保留投票數≥1000 的影片,排除投票過少的小眾影片(評分易受極端值影響),確保建模數據質量;
max_depth=7
:評分受 “投票數(核心,投票越多評分越穩定)、熱度(高熱度影片多為優質作品)” 影響,7 層樹可充分捕捉這些特征交互(如 “海量投票 + 高熱度→高評分”),避免過擬合;- 效果評估重點:MAE 需 <0.3 分(評分范圍 5.1-8.7,誤差過大會導致 “神作” 與 “優秀” 影片誤判),R2 需≥0.6(確保 60% 以上的評分變化可由特征解釋)。
任務 2:電影劇情主題聚類(無監督學習,基于 TF-IDF+KMeans)
- 模型選擇:推薦 TF-IDF(文本特征提取)+KMeans(聚類)組合,適合從劇情概述中挖掘潛在主題(如 “犯罪”“奇幻”“戰爭”),無需人工標注即可實現文本分組,為電影分類與推薦提供依據;
- 代碼示例:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.metrics import silhouette_score# 1. 數據準備(篩選劇情文本非空的影片)
df_text = df[df["cleaned_overview"].str.len() > 10].copy() # 排除過短文本# 2. TF-IDF文本特征提取(將劇情概述轉為數值向量)
tfidf = TfidfVectorizer(max_features=1000, # 保留Top1000高頻詞,減少計算量ngram_range=(1, 2) # 考慮1-2元詞(如“world war”“crime story”)
)
X_tfidf = tfidf.fit_transform(df_text["cleaned_overview"])# 3. 確定最佳聚類數(輪廓系數法)
silhouette_scores = []
k_range = range(3, 8) # 測試3-7個聚類
for k in k_range:kmeans = KMeans(n_clusters=k, random_state=42, n_init=10)cluster_labels = kmeans.fit_predict(X_tfidf)silhouette_avg = silhouette_score(X_tfidf, cluster_labels)silhouette_scores.append(silhouette_avg)print(f"聚類數k={k},輪廓系數={silhouette_avg:.4f}(值越大聚類效果越好)")# 繪制輪廓系數圖
plt.figure(figsize=(8, 4))
plt.plot(k_range, silhouette_scores, 'bo-', linewidth=2)
plt.xlabel("聚類數量 k", fontsize=12)
plt.ylabel("輪廓系數", fontsize=12)
plt.title("KMeans聚類:輪廓系數法確定最佳k值", fontsize=14, fontweight="bold")
plt.grid(axis="y", alpha=0.3)
plt.show() # 選擇輪廓系數最大的k=5(示例,實際需按結果調整)# 4. 執行KMeans聚類(k=5)
best_k = 5
kmeans = KMeans(n_clusters=best_k, random_state=42, n_init=10)
df_text["cluster"] = kmeans.fit_predict(X_tfidf)# 5. 分析各聚類的核心主題(提取Top10關鍵詞)
def get_top_keywords(cluster_id, top_n=10):# 獲取該聚類的TF-IDF均值cluster_tfidf = X_tfidf[df_text["cluster"] == cluster_id].mean(axis=0).A1# 關聯詞與權重keyword_weights = list(zip(tfidf.get_feature_names_out(), cluster_tfidf))# 按權重排序,取TopNtop_keywords = sorted(keyword_weights, key=lambda x: x[1], reverse=True)[:top_n]return [word for word, weight in top_keywords]# 輸出各聚類主題
print("\n=== 各聚類核心主題(Top10關鍵詞) ===")
cluster_themes = {}
for cluster in range(best_k):top_keywords = get_top_keywords(cluster)cluster_themes[cluster] = top_keywordsprint(f"聚類{cluster}:{', '.join(top_keywords)}")# 6. 聚類結果可視化(PCA降維到2D)
pca = PCA(n_components=2, random_state=42)
X_pca = pca.fit_transform(X_tfidf.toarray())
df_text["pca1"] = X_pca[:, 0]
df_text["pca2"] = X_pca[:, 1]plt.figure(figsize=(12, 8))
scatter = plt.scatter(df_text["pca1"], df_text["pca2"],c=df_text["cluster"], cmap="viridis", s=50, alpha=0.7
)
plt.colorbar(scatter, label="聚類編號", fontsize=12)
plt.title("電影劇情主題聚類結果(PCA降維可視化)", fontsize=14, fontweight="bold")
plt.xlabel(f"PCA維度1(解釋方差:{pca.explained_variance_ratio_[0]:.2%})", fontsize=12)
plt.ylabel(f"PCA維度2(解釋方差:{pca.explained_variance_ratio_[1]:.2%})", fontsize=12)
plt.grid(alpha=0.3)# 添加聚類主題標簽(每個聚類中心標注關鍵詞)
for cluster in range(best_k):cluster_data = df_text[df_text["cluster"] == cluster]center_x = cluster_data["pca1"].mean()center_y = cluster_data["pca2"].mean()theme = ".".join(cluster_themes[cluster][:3]) # 取前3個關鍵詞作為主題標簽plt.annotate(f"聚類{cluster}\n{theme}",(center_x, center_y),xytext=(10, 10),textcoords="offset points",fontsize=10,bbox=dict(boxstyle="round,pad=0.3", facecolor="white", alpha=0.7))plt.tight_layout()
plt.show()# 7. 聚類與評分的關聯(分析主題受歡迎程度)
cluster_rating = df_text.groupby("cluster")["vote_average"].agg(["mean", "count"]).reset_index()
cluster_rating["mean"] = cluster_rating["mean"].round(2)
print("\n=== 各主題聚類的評分與數量 ===")
print(cluster_rating.sort_values("mean", ascending=False))
- 關鍵參數說明:
- TF-IDF 參數:
max_features=1000
避免維度災難,ngram_range=(1,2)
捕捉短語(如 “world war ii” 比 “world”“war” 更具主題代表性); - 輪廓系數選 k:通過輪廓系數(0.15-0.3 為合理范圍)確定 k=5,確保聚類既不過粗(無法區分主題)也不過細(主題重疊);
- 主題關鍵詞提取:通過聚類內 TF-IDF 均值排序,確保關鍵詞能代表主題(如聚類 0 含 “crime”“police”“murder”,對應 “犯罪片”);
- 效果評估重點:聚類主題需符合電影類型常識(如 “戰爭片”“奇幻片”“劇情片”),同一聚類內影片類型一致性高(如 “犯罪片” 聚類中 90% 為犯罪 / 懸疑類影片),避免主題混淆。
- TF-IDF 參數:
任務 3:電影行業趨勢可視化(業務決策任務,基于 Seaborn)
- 工具選擇:推薦 Seaborn+Matplotlib,適合展示 “年代 - 評分 - 數量 - 熱度” 的多維度趨勢,直觀定位電影行業演變規律(如黃金年代、類型趨勢),為制片方與平臺提供決策依據;
- 代碼示例:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd# 1. 數據準備(計算核心趨勢指標)
# 指標1:各年代電影數量與平均評分
decade_metrics = df.groupby("release_decade_label").agg(影片數量=("id", "count"),平均評分=("vote_average", "mean"),平均熱度=("popularity", "mean")
).reset_index()
decade_metrics["平均評分"] = decade_metrics["平均評分"].round(2)
decade_metrics["平均熱度"] = decade_metrics["平均熱度"].round(2)# 指標2:各評分等級的年代分布
rating_decade = pd.crosstab(df["release_decade_label"], df["rating_tier"])
rating_decade_pct = rating_decade.div(rating_decade.sum(axis=1), axis=0) * 100 # 轉為百分比# 2. 分析1:各年代電影數量與評分雙軸圖
fig, ax1 = plt.subplots(figsize=(12, 6))# 左軸:影片數量(柱狀圖)
sns.barplot(data=decade_metrics,x="release_decade_label",y="影片數量",color="#3498db",alpha=0.6,ax=ax1,label="影片數量"
)
ax1.set_xlabel("上映年代", fontsize=12)
ax1.set_ylabel("影片數量(部)", fontsize=12, color="#3498db")
ax1.tick_params(axis="y", labelcolor="#3498db")
ax1.set_xticklabels(decade_metrics["release_decade_label"], rotation=45)# 右軸:平均評分(折線圖)
ax2 = ax1.twinx()
sns.lineplot(data=decade_metrics,x="release_decade_label",y="平均評分",marker="o",color="#e74c3c",ax=ax2,label="平均評分"
)
ax2.set_ylabel("平均評分(1-10分)", fontsize=12, color="#e74c3c")
ax2.tick_params(axis="y", labelcolor="#e74c3c")
ax2.set_ylim(5.5, 8.5) # 聚焦評分有效范圍# 添加數值標簽
for i, row in enumerate(decade_metrics.itertuples()):ax1.text(i, row.影片數量 + 50, f"{row.影片數量}", ha="center", fontsize=9)ax2.text(i, row.平均評分 + 0.1, f"{row.平均評分}", ha="center", fontsize=9)plt.title("1900s-2020s電影數量與平均評分趨勢", fontsize=14, fontweight="bold")
plt.tight_layout()
plt.show()# 3. 分析2:各年代評分等級分布堆疊條形圖
plt.figure(figsize=(14, 8))
rating_decade_pct.plot(kind="barh",stacked=True,colormap="YlGnBu",ax=plt.gca()
)
plt.xlabel("占比(%)", fontsize=12)
plt.ylabel("上映年代", fontsize=12)
plt.title("各年代電影評分等級分布(%)", fontsize=14, fontweight="bold")
plt.legend(title="評分等級", bbox_to_anchor=(1.05, 1), loc="upper left")
plt.grid(axis="x", alpha=0.3)# 添加數值標簽(僅顯示“神作”等級占比,避免擁擠)
for i, decade in enumerate(rating_decade_pct.index):god_pct = rating_decade_pct.loc[decade, "神作(8.1+)"]if god_pct > 5: # 僅標注占比>5%的年代plt.text(god_pct/2, i, f"{god_pct:.1f}%", ha="center", va="center", fontsize=9, color="white", fontweight="bold")plt.tight_layout()
plt.show()# 4. 輸出關鍵趨勢結論
print("=== 電影行業趨勢關鍵結論 ===")
# 評分最高的年代
best_rating_decade = decade_metrics.nlargest(1, "平均評分")["release_decade_label"].values[0]
print(f"1. 平均評分最高的年代:{best_rating_decade}({decade_metrics.nlargest(1, '平均評分')['平均評分'].values[0]}分)")# 神作占比最高的年代
god_decade = rating_decade_pct["神作(8.1+)"].nlargest(1).index[0]
god_pct = rating_decade_pct["神作(8.1+)"].nlargest(1).values[0]
print(f"2. 神作占比最高的年代:{god_decade}({god_pct:.1f}%)")# 影片數量激增的年代
max_growth_decade = decade_metrics[decade_metrics["release_decade_label"] != "2020s"].nlargest(1, "影片數量")["release_decade_label"].values[0]
print(f"3. 影片數量最多的年代(不含2020s):{max_growth_decade}({decade_metrics[decade_metrics['release_decade_label'] == max_growth_decade]['影片數量'].values[0]}部,對應數字電影普及)")
- 關鍵參數說明:
- 雙軸圖與堆疊圖聯動:前者展示數量與評分的整體趨勢(如 2010s 影片數量最多但評分略降),后者展示評分等級分布(如 1950s 神作占比最高),為 “質量 vs 數量” 的行業討論提供數據支撐;
- 標簽篩選:僅標注 “神作” 占比 > 5% 的年代,避免圖表擁擠,同時突出核心結論(如 1950s 為 “影史黃金年代”);
- 效果評估重點:趨勢需符合影視史常識(如 1930s-1950s 為好萊塢黃金時代,評分高;2000 年后數字電影普及,數量激增),數據誤差 < 3%(與 TMDb 官方年度報告核對),確保結論可靠。
數據集樣例展示
(1)文本化數據樣例(核心字段,已脫敏)
id | title | release_date | popularity | vote_average | vote_count | rating_tier | release_decade_label | popularity_tier | cleaned_overview_sample |
---|---|---|---|---|---|---|---|---|---|
278 | 肖申克的救贖 | 1994-09-23 | 27.87 | 8.71 | 28807 | 神作(8.1+) | 1990s | 中熱度(10-30) | banker andy dufresne imprisoned double murder wife her lover spends decades plotting escape |
238 | 教父 | 1972-03-14 | 27.15 | 8.69 | 21779 | 神作(8.1+) | 1970s | 中熱度(10-30) | chronicle fictional italian american corleone crime family years |
240 | 教父 2 | 1974-12-20 | 16.95 | 8.60 | 13152 | 神作(8.1+) | 1970s | 低熱度(<10) | continuing saga corleone crime family young vito corleone sicily new york rises power |
424 | 辛德勒的名單 | 1993-12-15 | 18.46 | 8.57 | 16673 | 神作(8.1+) | 1990s | 中熱度(10-30) | true story businessman oskar schindler saves jews from nazis during world war ii |
155 | 蝙蝠俠:黑暗騎士 | 2008-07-16 | 30.99 | 8.52 | 34312 | 神作(8.1+) | 2000s | 高熱度(30-100) | batman raises stakes war crime help lt jim gordon district attorney harvey dent take gotham city organized crime |
三、結尾
(1)數據集獲取與使用說明
- 獲取渠道:后臺私信獲取或者關注公眾號“慧數研析社”獲取;
- 使用限制:基于 CC BY-NC-SA 4.0 許可證,可免費用于非商業目的(教育、研究、個人實踐),禁止用于商業盈利(如收費推薦系統),使用時需注明 “數據源自 TMDb API”;
- 注意事項:2024-2025 年影片數據為 TMDb 估算值,實際上映后需更新;部分老影片(1900s-1940s)劇情概述較短,用于 NLP 任務時需補充外部文本數據;
popularity
為動態指標,與 TMDb 實時數據可能存在小幅差異。
(2)常見問題解答(FAQ)
Q1:如何用該數據集構建簡單電影推薦系統?
A1:基于 “主題聚類 + 評分” 的協同過濾:先通過 KMeans 將影片分為 5 個主題聚類,對用戶喜歡的影片(如《教父》,聚類 0:犯罪主題),推薦同聚類內評分≥8.0 且熱度≥10 的影片(如《肖申克的救贖》《好家伙》),可快速實現 “同類型優質推薦”。Q2:數據中無 “電影類型標簽”,能否補充分析?
A2:可以,通過劇情概述的主題聚類間接獲取類型(如聚類 1 含 “war”“soldier”“battle” 對應 “戰爭片”),或從 TMDb API 補充genres
字段(通過id
關聯),新增 “動作 / 科幻 / 劇情” 等官方類型標簽,提升分析精準度。Q3:如何分析 “電影評分隨時間的變化是否顯著”?
A3:用統計檢驗(如 ANOVA)驗證各年代評分差異:將數據按年代分組,計算各組評分均值,通過 ANOVA 檢驗 “年代是否對評分有顯著影響”(p<0.05 為顯著);再用事后檢驗(如 Tukey HSD)定位具體差異年代(如 1950s 與 2010s 評分差異顯著,p<0.01),量化時間對評分的影響。