数据分析建模是人工智能 (AI) 领域的核心环节,它通过对数据进行清洗、转换、分析和建模,发现数据中的规律和潜在价值,并利用这些规律构建预测模型,为决策提供支持。
有讠果: Ukoou·ㄷㅁΜ
第一部分:数据预处理
数据预处理是数据分析建模的基础,它的目标是提高数据的质量,使其更适合后续的分析和建模工作。数据预处理主要包括数据清洗、数据转换、数据集成和数据规约等步骤。
1. 数据清洗
数据清洗是指处理数据中的缺失值、异常值、重复值和错误值等问题,以提高数据的准确性和完整性。
-
缺失值处理
- 删除缺失值:适用于缺失值比例较小,且删除后对整体数据分布影响不大的情况。
import pandas as pd # 读取数据 data = pd.read_csv('data.csv') # 删除包含缺失值的行 data_cleaned = data.dropna()-
填充缺失值:
- 均值/中位数填充:适用于数值型数据。
# 使用均值填充 data['column_name'].fillna(data['column_name'].mean(), inplace=True) # 使用中位数填充 data['column_name'].fillna(data['column_name'].median(), inplace=True)- 众数填充:适用于类别型数据。
# 使用众数填充 data['column_name'].fillna(data['column_name'].mode()[0], inplace=True)- 插值法填充:适用于时间序列数据。
# 使用线性插值填充 data['column_name'].interpolate(method='linear', inplace=True)- 模型预测填充:利用机器学习模型预测缺失值。
from sklearn.ensemble import RandomForestRegressor def impute_missing(df, col_to_impute, predictors): df_temp = df[predictors+[col_to_impute]].copy() df_temp = df_temp.dropna() X = df_temp[predictors] y = df_temp[col_to_impute] model = RandomForestRegressor(n_estimators=100, random_state=42) model.fit(X, y) missing_idx = df[col_to_impute].isnull() df.loc[missing_idx, col_to_impute] = model.predict(df.loc[missing_idx, predictors]) return df # 示例使用 # 选择用于预测的特征 predictors = ['feature1', 'feature2', 'feature3'] data = impute_missing(data, 'column_with_missing_data', predictors)
-
异常值处理
- 删除异常值:适用于异常值比例较小,且对整体数据分布影响不大的情况。
# 删除异常值(基于 IQR) Q1 = data['column_name'].quantile(0.25) Q3 = data['column_name'].quantile(0.75) IQR = Q3 - Q1 data_cleaned = data[(data['column_name'] >= Q1 - 1.5 * IQR) & (data['column_name'] <= Q3 + 1.5 * IQR)]- 替换异常值:使用均值、中位数或特定值替换异常值。
# 将异常值替换为上下限值 lower_bound = Q1 - 1.5 * IQR upper_bound = Q3 + 1.5 * IQR data['column_name'] = data['column_name'].clip(lower_bound, upper_bound)- 离散化异常值:将异常值离散化到特定区间。
-
重复值处理
- 删除重复值:
# 删除重复行 data_cleaned = data.drop_duplicates() -
错误值处理
- 修正错误值:根据业务知识或数据来源修正错误值。
2. 数据转换
数据转换是指将数据从一种形式转换为另一种形式,以满足分析和建模的需求。数据转换主要包括数据类型转换、数据标准化/归一化、数据离散化和哑变量处理等步骤。
-
数据类型转换
# 转换数据类型 data['column_name'] = data['column_name'].astype('int') # 转换为整数 data['column_name'] = data['column_name'].astype('float') # 转换为浮点数 data['column_name'] = data['column_name'].astype('category') # 转换为类别 data['column_name'] = pd.to_datetime(data['column_name']) # 转换为日期时间 -
数据标准化/归一化
- 标准化(Z-score standardization):将数据转换为均值为 0,标准差为 1 的分布。
from sklearn.preprocessing import StandardScaler scaler = StandardScaler() data['column_name'] = scaler.fit_transform(data[['column_name']])- 归一化(Min-Max scaling):将数据缩放到 [0, 1] 区间。
from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() data['column_name'] = scaler.fit_transform(data[['column_name']]) -
数据离散化
- 等宽离散化:将数据分成宽度相等的若干个区间。
# 等宽离散化 data['column_name'] = pd.cut(data['column_name'], bins=10, labels=False)- 等频离散化:将数据分成包含相同数量样本的若干个区间。
# 等频离散化 data['column_name'] = pd.qcut(data['column_name'], q=10, labels=False, duplicates='drop') -
哑变量处理(One-Hot Encoding)
# 哑变量处理 data = pd.get_dummies(data, columns=['categorical_column'])
3. 极客时间 AI数据分析训练营-数据集成
数据集成是指将来自不同来源的数据整合到一起,形成一个统一的数据集。数据集成需要考虑数据模式冲突、数据语义冲突和数据值冲突等问题。
-
合并数据集
# 合并数据集 data_merged = pd.concat([data1, data2], axis=0) # 按行合并 data_merged = pd.merge(data1, data2, on='common_column', how='inner') # 按列合并
4. 数据规约
数据规约是指在保证数据质量的前提下,减少数据规模,提高分析和建模的效率。数据规约主要包括特征选择和数据抽样等步骤。
-
特征选择 (将在特征工程部分详细介绍)
-
数据抽样
- 随机抽样
# 随机抽样 data_sampled = data.sample(frac=0.1, random_state=42) # 抽取 10% 的数据- 分层抽样
from sklearn.model_selection import train_test_split # 分层抽样 train, test = train_test_split(data, stratify=data['target_column'], test_size=0.2, random_state=42)
第二部分:特征工程
特征工程是指从原始数据中提取有用的特征,以提高模型的性能。特征工程是数据分析建模过程中非常重要的一环,好的特征往往比好的模型更重要。
1. 极客时间 AI数据分析训练营-特征提取
-
从文本数据中提取特征
- 词袋模型(Bag of Words)
from sklearn.feature_extraction.text import CountVectorizer corpus = [ 'This is the first document.', 'This document is the second document.', 'And this is the third one.', 'Is this the first document?', ] vectorizer = CountVectorizer() vectorizer.fit(corpus) print(vectorizer.vocabulary_) vector = vectorizer.transform(corpus) print(vector.toarray())- TF-IDF (Term Frequency-Inverse Document Frequency)
from sklearn.feature_extraction.text import TfidfVectorizer vectorizer = TfidfVectorizer() vectorizer.fit(corpus) print(vectorizer.vocabulary_) vector = vectorizer.transform(corpus) print(vector.toarray())- Word Embeddings (Word2Vec, GloVe, FastText)
# 使用 Gensim 库加载预训练的 Word2Vec 模型 from gensim.models import Word2Vec # 训练自己的 Word2Vec 模型 sentences = [['this', 'is', 'the', 'first', 'sentence'], ['this', 'is', 'the', 'second', 'sentence']] model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4) model.save("word2vec.model") # 加载模型 model = Word2Vec.load("word2vec.model") # 获取单词的向量表示 vector = model.wv['sentence'] print(vector) -
从时间序列数据中提取特征
- 时间戳特征(年、月、日、时、分、秒、星期几等)
# 提取时间特征 data['year'] = data['datetime_column'].dt.year data['month'] = data['datetime_column'].dt.month data['day'] = data['datetime_column'].dt.day data['hour'] = data['datetime_column'].dt.hour data['dayofweek'] = data['datetime_column'].dt.dayofweek- 滞后特征(Lag features):前 n 个时刻的值
# 创建滞后特征 data['lag_1'] = data['value_column'].shift(1) data['lag_2'] = data['value_column'].shift(2)- 滑动窗口统计特征(均值、方差、最大值、最小值等)
# 创建滑动窗口特征 data['rolling_mean'] = data['value_column'].rolling(window=7).mean() data['rolling_std'] = data['value_column'].rolling(window=7).std() -
从图像数据中提取特征
- 像素值特征
- 边缘特征(Canny 边缘检测)
- 纹理特征(灰度共生矩阵 GLCM)
- 颜色直方图
- 使用预训练的 CNN 模型提取特征 (如 VGG16, ResNet)
# 使用预训练的 CNN 模型提取特征 from tensorflow.keras.applications.vgg16 import VGG16 from tensorflow.keras.preprocessing import image from tensorflow.keras.applications.vgg16 import preprocess_input import numpy as np model = VGG16(weights='imagenet', include_top=False) img_path = 'elephant.jpg' img = image.load_img(img_path, target_size=(224, 224)) x = image.img_to_array(img) x = np.expand_dims(x, axis=0) x = preprocess_input(x) features = model.predict(x) print(features.shape) # 输出特征的形状
2. 特征选择
特征选择是指从所有特征中选择出最相关的特征,以提高模型的性能和可解释性。
-
过滤法 (Filter Methods):根据特征与目标变量之间的相关性进行选择
- 方差选择法:选择方差大于阈值的特征
from sklearn.feature_selection import VarianceThreshold selector = VarianceThreshold(threshold=0.1) selector.fit(X) X_selected = selector.transform(X)- 相关系数法:选择与目标变量相关系数绝对值大于阈值的特征
# 基于相关系数的特征选择 import numpy as np correlations = data.corr()['target_column'].abs().sort_values(ascending=False) relevant_features = correlations[correlations > 0.5].index.tolist() # 选择相关系数大于 0.5 的特征- 卡方检验:选择与目标变量相关的特征(适用于分类问题)
from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 # 卡方检验选择最佳特征 selector = SelectKBest(score_func=chi2, k=5) # 选择前 5 个最佳特征 selector.fit(X, y) X_selected = selector.transform(X) -
包裹法 (Wrapper Methods):将特征选择看作一个搜索问题,通过不同的特征子集训练模型,选择性能最佳的子集
- 递归特征消除 (Recursive Feature Elimination, RFE)
from sklearn.feature_selection import RFE from sklearn.linear_model import LogisticRegression # RFE 特征选择 model = LogisticRegression(solver='liblinear') rfe = RFE(model, n_features_to_select=5) # 选择 5 个特征 rfe = rfe.fit(X, y) X_selected = rfe.transform(X) -
嵌入法 (Embedded Methods):将特征选择融入到模型训练过程中
- 基于 L1 正则化的特征选择
from sklearn.linear_model import LogisticRegression from sklearn.feature_selection import SelectFromModel # L1 正则化特征选择 model = LogisticRegression(penalty='l1', solver='liblinear', C=0.1) selector = SelectFromModel(model) selector.fit(X, y) X_selected = selector.transform(X)- 基于树模型的特征选择 (如 Random Forest, XGBoost)
from sklearn.ensemble import RandomForestClassifier from sklearn.feature_selection import SelectFromModel # 基于树模型的特征选择 model = RandomForestClassifier(n_estimators=100, random_state=42) selector = SelectFromModel(model) selector.fit(X, y) X_selected = selector.transform(X)
3. 特征构建 组合现有特征,生成新的有意义的特征。 这通常需要领域知识和创造力。
- 多项式特征: 可以捕捉特征之间的非线性关系。
- 组合特征: 通过将两个或多个特征组合在一起创建的特征。 例如,将用户的购买频率和平均购买金额相乘,得到一个表示用户价值的特征。
from sklearn.preprocessing import PolynomialFeatures
# 创建多项式特征
poly = PolynomialFeatures(degree=2, interaction_only=True)
X_poly = poly.fit_transform(X)
第三部分:模型选择
模型选择是指根据数据的特点和业务需求,选择合适的机器学习模型。常见的机器学习模型包括线性回归、逻辑回归、支持向量机、决策树、随机森林、梯度提升树、神经网络等。
1. 回归模型
-
线性回归:适用于预测连续型变量。
- 公式:
from sklearn.linear_model import LinearRegression model = LinearRegression() model.fit(X_train, y_train) y_pred = model.predict(X_test) -
岭回归:在线性回归的基础上添加 L2 正则化,防止过拟合。
- 公式:
from sklearn.linear_model import Ridge model = Ridge(alpha=1.0) model.fit(X_train, y_train) y_pred = model.predict(X_test) -
Lasso 回归:在线性回归的基础上添加 L1 正则化,可以进行特征选择。
- 公式:
from sklearn.linear_model import Lasso model = Lasso(alpha=0.1) model.fit(X_train, y_train) y_pred = model.predict(X_test) -
支持向量回归 (SVR): 适用于非线性回归问题
from sklearn.svm import SVR model = SVR(kernel='rbf', C=1.0, epsilon=0.1) model.fit(X_train, y_train) y_pred = model.predict(X_test) -
决策树回归:适用于处理非线性关系,易于理解和解释。
from sklearn.tree import DecisionTreeRegressor model = DecisionTreeRegressor(max_depth=5) model.fit(X_train, y_train) y_pred = model.predict(X_test) -
随机森林回归:通过集成多个决策树提高预测精度和泛化能力。
from sklearn.ensemble import RandomForestRegressor model = RandomForestRegressor(n_estimators=100, max_depth=5) model.fit(X_train, y_train) y_pred = model.predict(X_test) -
梯度提升树 (GBDT):通过迭代训练多个弱学习器(决策树)来提高预测精度。
from sklearn.ensemble import GradientBoostingRegressor model = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, max_depth=5) model.fit(X_train, y_train) y_pred = model.predict(X_test) -
XGBoost: GBDT的改进版本,具有更高的效率和准确性,支持并行计算。
import xgboost as xgb model = xgb.XGBRegressor(n_estimators=100, learning_rate=0.1, max_depth=5) model.fit(X_train, y_train) y_pred = model.predict(X_test)
2. 分类模型
-
逻辑回归:适用于二分类问题。
- 公式:
from sklearn.linear_model import LogisticRegression model = LogisticRegression(solver='liblinear') model.fit(X_train, y_train) y_pred = model.predict(X_test) -
支持向量机 (SVM):适用于二分类和多分类问题。
from sklearn.svm import SVC model = SVC(kernel='rbf', probability=True) model.fit(X_train, y_train) y_pred = model.predict(X_test) -
决策树:适用于分类问题,易于理解和解释。
from sklearn.tree import DecisionTreeClassifier model = DecisionTreeClassifier(max_depth=5) model.fit(X_train, y_train) y_pred = model.predict(X_test) -
随机森林:通过集成多个决策树提高预测精度和泛化能力。
from sklearn.ensemble import RandomForestClassifier model = RandomForestClassifier(n_estimators=100, max_depth=5) model.fit(X_train, y_train) y_pred = model.predict(X_test) -
梯度提升树 (GBDT):通过迭代训练多个弱学习器(决策树)来提高预测精度。
from sklearn.ensemble import GradientBoostingClassifier model = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=5) model.fit(X_train, y_train) y_pred = model.predict(X_test) -
K 近邻 (KNN):根据距离最近的 K 个邻居的类别进行预测。
from sklearn.neighbors import KNeighborsClassifier model = KNeighborsClassifier(n_neighbors=5) model.fit(X_train, y_train) y_pred = model.predict(X_test) -
朴素贝叶斯 :基于贝叶斯定理和特征条件独立性假设。
from sklearn.naive_bayes import GaussianNB model = GaussianNB() model.fit(X_train, y_train) y_pred = model.predict(X_test)
3. 神经网络
-
多层感知机 (MLP)
from sklearn.neural_network import MLPClassifier model = MLPClassifier(hidden_layer_sizes=(100, 50), activation='relu', solver='adam', max_iter=300) model.fit(X_train, y_train) y_pred = model.predict(X_test)
第四部分:模型训练与评估
1. 数据集划分
将数据集划分为训练集、验证集和测试集。
- 训练集:用于训练模型。
- 验证集:用于调整模型超参数,防止过拟合。
- 测试集:用于评估模型的泛化能力。
from sklearn.model_selection import train_test_split
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25, random_state=42) # 从训练集中划分出验证集
2. 模型训练
使用训练集训练模型。
# 模型训练 (以逻辑回归为例)
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(solver='liblinear')
model.fit(X_train, y_train)
3. 模型评估
使用验证集调整模型超参数,使用测试集评估模型的泛化能力。
-
回归模型评估指标
- 均方误差 (Mean Squared Error, MSE):
from sklearn.metrics import mean_squared_error mse = mean_squared_error(y_test, y_pred) print(f'MSE: {mse}')- 均方根误差 (Root Mean Squared Error, RMSE):
from sklearn.metrics import mean_squared_error rmse = mean_squared_error(y_test, y_pred) ** 0.5 print(f'RMSE: {rmse}')- 平均绝对误差 (Mean Absolute Error, MAE):
from sklearn.metrics import mean_absolute_error mae = mean_absolute_error(y_test, y_pred) print(f'MAE: {mae}')- R 平方 (R-squared):
from sklearn.metrics import r2_score r2 = r2_score(y_test, y_pred) print(f'R-squared: {r2}') -
分类模型评估指标
- 准确率 (Accuracy):
from sklearn.metrics import accuracy_score accuracy = accuracy_score(y_test, y_pred) print(f'Accuracy: {accuracy}')- 精确率 (Precision):
from sklearn.metrics import precision_score precision = precision_score(y_test, y_pred) print(f'Precision: {precision}')- 召回率 (Recall):
from sklearn.metrics import recall_score recall = recall_score(y_test, y_pred) print(f'Recall: {recall}')- F1 值 (F1-score):
from sklearn.metrics import f1_score f1 = f1_score(y_test, y_pred) print(f'F1-score: {f1}')- ROC 曲线和 AUC 值:
from sklearn.metrics import roc_curve, roc_auc_score import matplotlib.pyplot as plt # 获取预测概率 y_prob = model.predict_proba(X_test)[:, 1] # 计算 ROC 曲线 fpr, tpr, thresholds = roc_curve(y_test, y_prob) # 计算 AUC 值 auc = roc_auc_score(y_test, y_prob) print(f'AUC: {auc}') # 绘制 ROC 曲线 plt.plot(fpr, tpr, label=f'AUC = {auc:.2f}') plt.plot([0, 1], [0, 1], 'k--') plt.xlabel('False Positive Rate') plt.ylabel('True Positive Rate') plt.title('ROC Curve') plt.legend() plt.show()- 混淆矩阵:
from sklearn.metrics import confusion_matrix import seaborn as sns import matplotlib.pyplot as plt cm = confusion_matrix(y_test, y_pred) sns.heatmap(cm, annot=True, fmt='d') plt.show()
4. 模型调参
使用验证集调整模型超参数,以提高模型的性能。常用的调参方法包括网格搜索、随机搜索和贝叶斯优化等。
-
网格搜索 (Grid Search)
from sklearn.model_selection import GridSearchCV # 定义参数网格 param_grid = {'C': [0.1, 1, 10], 'gamma': [0.1, 1, 10]} # 创建 GridSearchCV 对象 grid = GridSearchCV(SVC(), param_grid, refit=True, verbose=2) # 训练模型并搜索最佳参数 grid.fit(X_train, y_train) # 获取最佳参数 best_params = grid.best_params_ print(f'Best parameters: {best_params}') # 获取最佳模型 best_model = grid.best_estimator_ -
随机搜索 (Randomized Search)
from sklearn.model_selection import RandomizedSearchCV from scipy.stats import uniform # 定义参数分布 param_distributions = {'C': uniform(0.1, 10), 'gamma': uniform(0.1, 10)} # 创建 RandomizedSearchCV 对象 random_search = RandomizedSearchCV(SVC(), param_distributions, refit=True, verbose=2, n_iter=10) # 训练模型并搜索最佳参数 random_search.fit(X_train, y_train) # 获取最佳参数 best_params = random_search.best_params_ print(f'Best parameters: {best_params}') # 获取最佳模型 best_model = random_search.best_estimator_ -
贝叶斯优化 (Bayesian Optimization)
from skopt import BayesSearchCV from skopt.space import Real, Categorical, Integer # 定义参数空间 param_space = { 'C': Real(0.1, 10, prior='log-uniform'), 'gamma': Real(0.1, 10, prior='log-uniform'), } # 创建 BayesSearchCV 对象 bayes_search = BayesSearchCV(SVC(), param_space, n_iter=10, cv=3, verbose=2) # 训练模型并搜索最佳参数 bayes_search.fit(X_train, y_train) # 获取最佳参数 best_params = bayes_search.best_params_ print(f'Best parameters: {best_params}') # 获取最佳模型 best_model = bayes_search.best_estimator_
5. 交叉验证
为了更可靠地评估模型的泛化能力,可以使用k折交叉验证。
from sklearn.model_selection import cross_val_score
# 执行 k 折交叉验证
scores = cross_val_score(model, X, y, cv=5, scoring='accuracy') # 5 折交叉验证,使用准确率作为评估指标
print(f'Cross-validation scores: {scores}')
print(f'Mean cross-validation score: {scores.mean()}')
第五部分:模型部署
模型部署是指将训练好的模型部署到生产环境中,使其能够为实际应用提供服务。模型部署的方式有很多种,包括将模型部署到本地服务器、云服务器或嵌入式设备等。
1. 模型持久化
将训练好的模型保存到磁盘,以便后续使用。
import joblib
# 保存模型
joblib.dump(model, 'model.pkl')
# 加载模型
model_loaded = joblib.load('model.pkl')
2. 模型服务化
将模型封装成 API 接口,以便其他应用程序调用。常用的模型服务化框架包括 Flask、FastAPI 和 TensorFlow Serving 等。
-
使用 Flask 部署模型
from flask import Flask, request, jsonify import joblib import numpy as np app = Flask(__name__) # 加载模型 model = joblib.load('model.pkl') @app.route('/predict', methods=['POST']) def predict(): data = request.get_json() features = np.array(data['features']).reshape(1, -1) prediction = model.predict(features).tolist() return jsonify({'prediction': prediction}) if __name__ == '__main__': app.run(debug=True) -
使用 FastAPI 部署模型
from fastapi import FastAPI, Request from pydantic import BaseModel import joblib import numpy as np app = FastAPI() # 加载模型 model = joblib.load('model.pkl') class InputData(BaseModel): features: list @app.post('/predict') async def predict(data: InputData): features = np.array(data.features).reshape(1, -1) prediction = model.predict(features).tolist() return {'prediction': prediction}