数据采集是指识别数据源、收集原始数据并将其传输或存储到可以处理的地方的过程。它是整个数据价值链的起点。
数据分析是指对采集到的数据进行清理、转换、建模、探索和解释,以发现有用的信息、得出结论并支持决策的过程。它是将原始数据转化为洞察力的关键步骤。
“数据采集”和“数据分析”是现代数据驱动决策的核心环节,它们紧密相连,共同构成了从原始信息到有价值见解的完整链条。
下面我将通过实际代码示例,展示数据采集(API获取、网页抓取)和数据分析(数据清洗、探索性分析、可视化)的全流程操作。
环境准备
# 安装必要库
pip install requests beautifulsoup4 pandas numpy matplotlib seaborn scikit-learn
一、数据采集代码示例
1、通过API获取数据(以天气数据为例)
import requests
import pandas as pd
def get_weather_data(api_key, city="Beijing", days=7):
"""从WeatherAPI获取天气数据"""
url = f"http://api.weatherapi.com/v1/forecast.json?key={api_key}&q={city}&days={days}"
try:
response = requests.get(url)
response.raise_for_status() # 检查请求是否成功
data = response.json()
# 提取所需数据
weather_data = []
for day in data['forecast']['forecastday']:
date = day['date']
max_temp = day['day']['maxtemp_c']
min_temp = day['day']['mintemp_c']
avg_temp = day['day']['avgtemp_c']
condition = day['day']['condition']['text']
rain_chance = day['day']['daily_chance_of_rain']
weather_data.append({
'date': date,
'max_temp': max_temp,
'min_temp': min_temp,
'avg_temp': avg_temp,
'condition': condition,
'rain_chance': rain_chance
})
return pd.DataFrame(weather_data)
except requests.exceptions.RequestException as e:
print(f"请求错误: {e}")
return None
# 使用示例 (需替换为实际API密钥)
# api_key = "YOUR_API_KEY"
# weather_df = get_weather_data(api_key)
# weather_df.to_csv('weather_data.csv', index=False)
2、网页抓取示例(电影Top250)
from bs4 import BeautifulSoup
import requests
import pandas as pd
import re
import time
def scrape_douban_top250():
"""抓取豆瓣电影Top250数据"""
base_url = "https://movie.douban.com/top250?start="
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'
}
movies = []
for start in range(0, 250, 25):
url = base_url + str(start)
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
for item in soup.find_all('div', class_='item'):
title = item.find('span', class_='title').text
year = re.search(r'((\d{4}))', item.find('div', class_='bd').p.text).group(1)
rating = float(item.find('span', class_='rating_num').text)
votes = item.find('div', class_='star').find_all('span')[-1].text[:-3]
quote = item.find('span', class_='inq').text if item.find('span', class_='inq') else ""
movies.append({
'title': title,
'year': int(year),
'rating': rating,
'votes': int(votes),
'quote': quote
})
time.sleep(1) # 礼貌性延迟
return pd.DataFrame(movies)
# 执行抓取
# movie_df = scrape_douban_top250()
# movie_df.to_csv('douban_top250.csv', index=False)
二、数据分析代码示例
1、数据清洗与预处理
import pandas as pd
import numpy as np
# 加载数据
df = pd.read_csv('douban_top250.csv')
# 1. 处理缺失值
print("缺失值统计:")
print(df.isnull().sum())
# 对于quote列的缺失值,填充为"无"
df['quote'] = df['quote'].fillna('无')
# 2. 异常值处理
# 检查评分范围 (豆瓣评分范围0-10)
print("\n评分统计:")
print(df['rating'].describe())
# 3. 数据类型转换
df['year'] = df['year'].astype(int)
# 4. 创建新特征 - 年代分类
bins = [0, 1960, 1980, 1990, 2000, 2010, 2020, np.inf]
labels = ['1960前', '60-70年代', '80年代', '90年代', '00年代', '10年代', '20年代']
df['decade'] = pd.cut(df['year'], bins=bins, labels=labels)
# 5. 数据抽样展示
print("\n清洗后数据示例:")
print(df.sample(5))
2、探索性数据分析(EDA)
import matplotlib.pyplot as plt
import seaborn as sns
# 设置可视化风格
sns.set(style="whitegrid")
plt.figure(figsize=(12, 8))
# 1. 评分分布
plt.subplot(2, 2, 1)
sns.histplot(df['rating'], bins=15, kde=True, color='skyblue')
plt.title('电影评分分布')
plt.xlabel('评分')
# 2. 不同年代电影数量
plt.subplot(2, 2, 2)
decade_counts = df['decade'].value_counts().sort_index()
sns.barplot(x=decade_counts.index, y=decade_counts.values, palette="viridis")
plt.title('不同年代电影数量')
plt.xlabel('年代')
plt.ylabel('数量')
plt.xticks(rotation=45)
# 3. 评分与投票数关系
plt.subplot(2, 2, 3)
sns.scatterplot(data=df, x='rating', y='votes', hue='decade', palette='Set2', s=100)
plt.title('评分与投票数关系')
plt.xlabel('评分')
plt.ylabel('投票数')
# 4. 各年代平均评分
plt.subplot(2, 2, 4)
decade_rating = df.groupby('decade')['rating'].mean().sort_index()
sns.barplot(x=decade_rating.index, y=decade_rating.values, palette="rocket")
plt.title('各年代平均评分')
plt.xlabel('年代')
plt.ylabel('平均评分')
plt.xticks(rotation=45)
plt.tight_layout()
plt.savefig('eda_visualization.png', dpi=300)
plt.show()
3、高级分析:评分预测模型
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error, r2_score
# 特征工程
df['title_length'] = df['title'].apply(len)
df['has_quote'] = df['quote'].apply(lambda x: 1 if x != '无' else 0)
# 准备数据
X = df[['year', 'votes', 'title_length', 'has_quote']]
y = df['rating']
# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 创建并训练模型
model = RandomForestRegressor(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
# 预测与评估
y_pred = model.predict(X_test)
mae = mean_absolute_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"模型评估结果:")
print(f"平均绝对误差(MAE): {mae:.4f}")
print(f"R²分数: {r2:.4f}")
# 特征重要性分析
feature_importances = pd.Series(model.feature_importances_, index=X.columns)
plt.figure(figsize=(10, 6))
feature_importances.sort_values().plot(kind='barh', color='teal')
plt.title('特征重要性分析')
plt.xlabel('重要性分数')
plt.tight_layout()
plt.savefig('feature_importance.png', dpi=300)
plt.show()
# 实际值与预测值对比
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.6, color='purple')
plt.plot([y.min(), y.max()], [y.min(), y.max()], 'k--', lw=2)
plt.xlabel('实际评分')
plt.ylabel('预测评分')
plt.title('实际评分 vs 预测评分')
plt.grid(True)
plt.tight_layout()
plt.savefig('prediction_comparison.png', dpi=300)
plt.show()
4、文本分析(电影短评)
from wordcloud import WordCloud
from collections import Counter
import jieba
# 生成词云
text = ' '.join(df['quote'].tolist())
# 中文分词
word_list = jieba.cut(text)
word_count = Counter(word_list)
# 过滤停用词和单字
stopwords = ['的', '了', '是', '我', '你', '他', '这', '那', '就', '也', '在', '和', '与']
filtered_words = {word: count for word, count in word_count.items()
if len(word) > 1 and word not in stopwords and not word.isdigit()}
# 创建词云
wordcloud = WordCloud(
font_path='simhei.ttf', # 中文字体文件
width=800,
height=600,
background_color='white',
max_words=200
).generate_from_frequencies(filtered_words)
plt.figure(figsize=(12, 8))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.title('豆瓣Top250电影短评词云')
plt.savefig('wordcloud.png', dpi=300)
plt.show()
三、完整流程整合
# 完整的数据采集与分析流程
def full_data_pipeline():
# 1. 数据采集
print("开始数据采集...")
movie_df = scrape_douban_top250()
movie_df.to_csv('douban_top250.csv', index=False)
print(f"采集完成,共获取{movie_df.shape[0]}条数据")
# 2. 数据清洗
print("\n开始数据清洗...")
# 添加清洗步骤...
# 3. 数据分析
print("\n开始数据分析...")
# 添加分析步骤...
# 4. 可视化
print("\n生成可视化图表...")
# 添加可视化步骤...
print("\n全流程完成!结果已保存到本地")
# 执行完整流程
# full_data_pipeline()
这个完整的代码示例涵盖了从数据采集到分析的全流程,你可以根据实际需求调整各部分内容。对于大规模数据项目,可以考虑使用Scrapy(爬虫)、Apache Spark(大数据处理)和TensorFlow/PyTorch(深度学习)等更专业的工具。
理解这两个环节及其紧密联系,对于任何希望利用数据驱动发展的个人或组织都至关重要。数据采集为你铺好道路,数据分析则为你点亮明灯,共同引领你走向更明智的决策。
大家想了解数据采集或数据分析的某个具体方面吗?比如某种采集技术、某种分析方法、特定行业的应用案例,或者相关的工具推荐?可以留言讨论,有空的时候我可以出个教程。