python爬虫预测豆瓣电影/人工智能运用
基于豆瓣电影数据的类型预测模型开发
一、项目思路与数据准备
要预测豆瓣电影的类型,需要通过爬虫获取电影的特征数据(如导演、演员、剧情简介等),然后利用机器学习模型训练分类器。以下是完整实现方案:
二、数据爬取:获取豆瓣电影特征与类型
import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
import random
import re
# 配置请求头模拟浏览器访问
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
def crawl_douban_movies():
"""爬取豆瓣电影数据,包括标题、导演、演员、剧情简介和类型"""
all_movies = []
# 遍历豆瓣电影分类页(以剧情片、喜剧片、动作片为例)
categories = ['剧情', '喜剧', '动作'] # 可扩展更多类型
for category in categories:
for start in range(0, 200, 20): # 每类爬取200部电影
url = f'https://movie.douban.com/tag/#/sort/score/type/{category}?start={start}&limit=20'
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status() # 检查请求是否成功
soup = BeautifulSoup(response.text, 'lxml')
# 提取电影列表
movie_items = soup.find_all('div', class_='item-root')
for item in movie_items:
try:
# 提取标题
title = item.find('span', class_='title').text.strip()
# 提取导演和演员
info = item.find('div', class_='abstract_2').text.strip()
director = re.search(r'导演: (.*?) ', info).group(1) if re.search(r'导演: (.*?) ', info) else ''
actors = re.search(r'主演: (.*)', info).group(1) if re.search(r'主演: (.*)', info) else ''
# 提取剧情简介
intro = item.find('div', class_='abstract_3').text.strip() if item.find('div', class_='abstract_3') else ''
# 记录类型
movie_type = category
all_movies.append({
'title': title,
'director': director,
'actors': actors,
'intro': intro,
'type': movie_type
})
print(f"成功爬取: {title} - {movie_type}")
except Exception as e:
print(f"解析电影信息失败: {e}")
# 随机延时避免反爬
time.sleep(random.uniform(1, 3))
except Exception as e:
print(f"请求出错: {e}")
# 保存为DataFrame
df = pd.DataFrame(all_movies)
df.to_csv('douban_movies.csv', index=False, encoding='utf-8-sig')
return df
# 执行爬取(首次运行时取消注释)
# df = crawl_douban_movies()
# 直接加载已爬取数据(后续运行时使用)
df = pd.read_csv('douban_movies.csv')
print(f"已加载{len(df)}部电影数据")
三、数据预处理:特征提取与清洗
import nltk
import re
from nltk.corpus import stopwords
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
# 下载英文停用词(中文停用词需自定义)
nltk.download('stopwords')
english_stopwords = set(stopwords.words('english'))
# 自定义中文停用词
chinese_stopwords = {'的', '了', '在', '是', '我', '有', '和', '就', '不', '人', '都', '一', '一个', '上', '也', '很', '到', '说', '要', '去', '你', '会', '着', '没有', '看', '好', '自己', '这'}
def preprocess_text(text):
"""文本预处理:清洗、分词、去停用词"""
if not isinstance(text, str):
return ''
# 去除特殊字符和数字
text = re.sub(r'[^\u4e00-\u9fa5a-zA-Z]', ' ', text)
# 转换为小写
text = text.lower()
# 分词(简化处理,中文可使用jieba分词)
words = re.findall(r'\w+', text)
# 去除停用词
filtered_words = [word for word in words if word not in english_stopwords and word not in chinese_stopwords]
return ' '.join(filtered_words)
# 合并导演、演员和剧情简介作为特征文本
df['combined_features'] = df['director'] + ' ' + df['actors'] + ' ' + df['intro']
# 应用文本预处理
df['processed_features'] = df['combined_features'].apply(preprocess_text)
# 划分训练集和测试集
X = df['processed_features']
y = df['type']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 使用TF-IDF提取特征
vectorizer = TfidfVectorizer(max_features=1000, stop_words=chinese_stopwords.union(english_stopwords))
X_train_tfidf = vectorizer.fit_transform(X_train)
X_test_tfidf = vectorizer.transform(X_test)
print(f"TF-IDF特征维度: {X_train_tfidf.shape[1]}")
四、模型训练:多分类算法对比
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt
# 定义模型列表
models = {
'随机森林': RandomForestClassifier(n_estimators=100, random_state=42),
'支持向量机': SVC(probability=True, random_state=42),
'逻辑回归': LogisticRegression(multi_class='multinomial', solver='lbfgs', random_state=42)
}
# 训练并评估模型
results = {}
for name, model in models.items():
print(f"\n训练{name}模型...")
model.fit(X_train_tfidf, y_train)
y_pred = model.predict(X_test_tfidf)
accuracy = accuracy_score(y_test, y_pred)
results[name] = accuracy
print(f"{name}准确率: {accuracy:.4f}")
print("分类报告:")
print(classification_report(y_test, y_pred))
# 绘制混淆矩阵
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(10, 8))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
xticklabels=sorted(df['type'].unique()),
yticklabels=sorted(df['type'].unique()))
plt.xlabel('预测类型')
plt.ylabel('真实类型')
plt.title(f'{name}混淆矩阵')
plt.tight_layout()
plt.savefig(f'{name}_confusion_matrix.png')
# 比较模型性能
plt.figure(figsize=(10, 6))
plt.bar(results.keys(), results.values())
plt.xlabel('模型')
plt.ylabel('准确率')
plt.title('不同模型的电影类型预测准确率')
plt.tight_layout()
plt.savefig('model_comparison.png')
plt.show()
# 选择最佳模型(以随机森林为例)
best_model = RandomForestClassifier(n_estimators=100, random_state=42)
best_model.fit(X_train_tfidf, y_train)
五、模型应用:预测新电影类型
def predict_movie_type(movie_info):
"""预测新电影的类型"""
# 预处理输入文本
processed_info = preprocess_text(movie_info)
# 转换为TF-IDF特征
tfidf_features = vectorizer.transform([processed_info])
# 预测类型
predicted_type = best_model.predict(tfidf_features)[0]
# 获取预测概率
proba = best_model.predict_proba(tfidf_features)[0]
proba_dict = {label: prob for label, prob in zip(best_model.classes_, proba)}
# 按概率排序
sorted_proba = sorted(proba_dict.items(), key=lambda x: x[1], reverse=True)
print(f"\n===== 电影类型预测结果 =====")
print(f"输入信息: {movie_info[:50]}...")
print(f"预测类型: {predicted_type}")
print("\n各类别概率:")
for label, prob in sorted_proba:
print(f"{label}: {prob:.4f}")
return predicted_type, sorted_proba
# 示例:预测新电影类型
test_movie = "由诺兰导演,基里安·墨菲主演,讲述科学家通过梦境窃取机密的科幻故事,充满悬疑和烧脑情节。"
predict_movie_type(test_movie)
# 保存模型以便后续使用
import joblib
joblib.dump(best_model, 'movie_type_classifier.pkl')
joblib.dump(vectorizer, 'tfidf_vectorizer.pkl')
六、优化方向与注意事项
1. 数据增强:
◦ 爬取更多电影类型(如科幻、悬疑、爱情等)和样本数量(建议每类至少500部)
◦ 增加更多特征(如上映年份、国家/地区、评分等)
2. 文本处理优化:
◦ 中文文本使用jieba等专业分词工具
◦ 尝试Word2Vec、FastText等词向量模型替代TF-IDF
3. 模型升级:
◦ 尝试深度学习模型(如LSTM、BERT)处理文本序列
◦ 使用XGBoost、LightGBM等提升树模型提高分类精度
4. 合规与反爬:
◦ 爬取时控制频率(如添加随机延时),避免封禁IP
◦ 仅爬取公开数据,不涉及用户隐私信息
通过上述方案,可实现一个基于豆瓣电影数据的类型预测模型,该模型能根据电影的导演、演员和剧情简介等信息,智能判断其所属类型,准确率通常可达70%~85%(取决于数据质量和模型复杂度)。
更多推荐


所有评论(0)