数据分析相关面试题-Python部分

数据分析相关面试题汇总

目录

Pandas

Pandas作用?

[如何读取 csv、excel?如何指定编码、索引?](#如何读取 csv、excel?如何指定编码、索引?)

[拿到一个 DataFrame,你第一步会看什么?](#拿到一个 DataFrame,你第一步会看什么?)

如何按条件筛选行?如何选取列?

如何查看重复行、删除重复?

如何把字符串转时间?转整数?

按专业分组,统计分数的均值、最大值、人数

[多表合并用什么?和 SQL 的 JOIN 对应什么?](#多表合并用什么?和 SQL 的 JOIN 对应什么?)

[用 Pandas 做 Excel 透视表](#用 Pandas 做 Excel 透视表)

[根据分数新增等级列(优秀 / 良好 / 及格)](#根据分数新增等级列(优秀 / 良好 / 及格))

如何提取年、月、日?如何按月求和?

如何识别并剔除异常值?

[行转列、列转行(melt /pivot)](#行转列、列转行(melt /pivot))

[apply/map/applymap 区别](#apply/map/applymap 区别)

为什么会出现SettingWithCopyWarning这个警告?怎么解决?

[如何实现 SQL 的 group by having?](#如何实现 SQL 的 group by having?)

[导出 Excel / CSV](#导出 Excel / CSV)

NumPy

NumPy作用?

[NumPy 数组(ndarray)和 Python 列表 list 的区别?](#NumPy 数组(ndarray)和 Python 列表 list 的区别?)

创建数组的常用方式有哪些?

查看数组属性

数组索引与切片

什么是广播(broadcasting)?为什么重要?

[数据归一化 / 标准化](#数据归一化 / 标准化)

[用 NumPy 实现 3σ 异常值筛选](#用 NumPy 实现 3σ 异常值筛选)

数组形状修改

[np.where 用法](#np.where 用法)

空值(NaN)相关问题

[为什么要设置 dtype?](#为什么要设置 dtype?)

随机数生成

[Matplotlib + Seaborn](#Matplotlib + Seaborn)

[Matplotlib 是什么?Seaborn 是什么?关系?](#Matplotlib 是什么?Seaborn 是什么?关系?)

数据分析常用哪些图表?分别用于什么场景?

[Matplotlib 两张图:figure /axes 是什么?](#Matplotlib 两张图:figure /axes 是什么?)

Matplotlib-绘制最简单的折线图

Matplotlib-画柱状图

Matplotlib-画直方图(看分布)

Matplotlib-画散点图(看相关性)

Matplotlib-画子图(多图并排)

Matplotlib-如何保存图片?

Matplotlib-中文乱码怎么解决?

[Seaborn-绘制柱状图(带误差棒 / 分组)](#Seaborn-绘制柱状图(带误差棒 / 分组))

Seaborn-箱线图(识别异常值)

[Matplotlib vs Seaborn 区别?](#Matplotlib vs Seaborn 区别?)

箱线图、直方图、散点图分别用来干什么?

什么时候用热力图?

如何让图表更专业、更适合汇报?

做数据分析时可视化流程是什么?

SciPy

[SciPy 是什么,在数据分析里用来干什么?](#SciPy 是什么,在数据分析里用来干什么?)

[什么是 p 值?](#什么是 p 值?)

常见统计检验怎么选?

导入scipy

正态性检验,如何检验一组数据是否符合正态分布?

[独立样本 t 检验](#独立样本 t 检验)

[配对样本 t 检验](#配对样本 t 检验)

[单样本 t 检验](#单样本 t 检验)

[方差分析 ANOVA(多组比较)](#方差分析 ANOVA(多组比较))

卡方检验(分类变量关联性)

皮尔逊相关系数(线性相关)

斯皮尔曼等级相关(非参数,不要求正态)

[秩和检验(非参数替代 t 检验)](#秩和检验(非参数替代 t 检验))

[t 检验和方差分析的区别?](#t 检验和方差分析的区别?)

什么时候用非参数检验?

[相关系数 ≠ 因果关系?](#相关系数 ≠ 因果关系?)

[p 值很小代表什么?](#p 值很小代表什么?)

数据分析完整统计检验流程?

Statsmodels

[Statsmodels 是什么?和 Sklearn 有什么区别?](#Statsmodels 是什么?和 Sklearn 有什么区别?)

线性回归用来干什么?

最小二乘线性回归代码

[如何看回归结果 summary?](#如何看回归结果 summary?)

逻辑回归(分类问题)

线性回归有哪些基本假设?

多重共线性怎么判断、怎么处理?

[异常值 / 强影响点怎么检测?](#异常值 / 强影响点怎么检测?)

[Statsmodels 时间序列能干什么?](#Statsmodels 时间序列能干什么?)

[ADF 平稳性检验](#ADF 平稳性检验)

[什么时候用 Statsmodels,什么时候用 Sklearn?](#什么时候用 Statsmodels,什么时候用 Sklearn?)

回归系数(coef)代表什么?

[p < 0.05 代表什么?](#p < 0.05 代表什么?)

[R² 是什么意思?太低怎么办?](#R² 是什么意思?太低怎么办?)

[用 Statsmodels 做过什么业务分析?](#用 Statsmodels 做过什么业务分析?)

Scikit-learn(sklearn)

[Scikit-learn 是什么,在数据分析里用来干什么?](#Scikit-learn 是什么,在数据分析里用来干什么?)

机器学习四大类

模型构建标准流程

分类特征编码:OneHot、LabelEncoder

[数值特征归一化 / 标准化](#数值特征归一化 / 标准化)

[缺失值处理 SimpleImputer](#缺失值处理 SimpleImputer)

数据集划分

线性回归(预测连续值,如分数)

逻辑回归(二分类,如是否升学、是否就业)

[决策树 / 随机森林(最常用、最强业务解释性)](#决策树 / 随机森林(最常用、最强业务解释性))

[K-Means 聚类(用户分层、生源分层)](#K-Means 聚类(用户分层、生源分层))

[PCA 降维](#PCA 降维)

分类模型指标有哪些?

回归模型指标有哪些?

聚类评估有哪些?

过拟合是什么?怎么解决?

欠拟合是什么?怎么解决?

什么是交叉验证?

为什么要用交叉验证?

[网格搜索 GridSearchCV](#网格搜索 GridSearchCV)

特征重要性怎么看?

分类模型评估指标

标准化和归一化区别?

类别特征用什么编码?

[用 sklearn 做过什么实际分析?](#用 sklearn 做过什么实际分析?)

类别不平衡(比如很少人违约、很少人辍学)怎么办?

[逻辑回归 / 决策树 / 随机森林怎么选?](#逻辑回归 / 决策树 / 随机森林怎么选?)

K-Means

[K-Means 是什么?](#K-Means 是什么?)

[K-Means 的执行过程?](#K-Means 的执行过程?)

[K 怎么确定?](#K 怎么确定?)

[K-Means 优缺点?](#K-Means 优缺点?)

[K-Means 为什么要标准化 / 归一化?](#K-Means 为什么要标准化 / 归一化?)

[K-Means 遇到异常值怎么办?](#K-Means 遇到异常值怎么办?)

[用 K-Means 做过什么?](#用 K-Means 做过什么?)


Pandas

Pandas作用?

主要用 Pandas 做数据读取、清洗、分组聚合、多表关联和特征工程,是日常最核心的库。

如何读取 csv、excel?如何指定编码、索引?

注释:编码常用 utf-8 / gbk,中文乱码常用 encoding='gbk' 或 encoding='gb2312'。

读取 CSV

python 复制代码
import pandas as pd

df = pd.read_csv("data.csv", encoding="utf-8")

读取 Excel

python 复制代码
import pandas as pd

df = pd.read_excel("data.xlsx", sheet_name="Sheet1")

读取时指定索引列

python 复制代码
import pandas as pd

df = pd.read_csv("data.csv", index_col="id")

拿到一个 DataFrame,你第一步会看什么?

先看结构、类型、空值、重复、异常值。

前5行,看数据结构

python 复制代码
df.head()

字段类型、是否有空值、占用内存

python 复制代码
df.info()

数值列统计(均值、分位数、最大最小)

python 复制代码
df.describe()

行数, 列数

python 复制代码
df.shape

每列空值数量(最重要)

python 复制代码
df.isnull().sum()

如何按条件筛选行?如何选取列?

  1. 条件筛选(最常用)
python 复制代码
df[df["age"] > 18]
  1. 多条件 & 且 | 或

& | 两边必须加括号,否则报错。

python 复制代码
df[(df["score"] >= 60) & (df["province"] == "河南")]
  1. loc:按标签(行名+列名)
python 复制代码
df.loc[df["score"] > 90, ["name", "score"]]
  1. iloc:按位置(第0行到第5行,前2列)
python 复制代码
df.iloc[0:5, 0:2]

如何查看、处理缺失值?

  • 数值列:均值 / 中位数 / 分位数
  • 分类列:众数
  • 空值很少:直接删
  • 空值有规律:前向填充 ffill / 后向填充 bfill

查看空值

python 复制代码
df.isnull().sum()

删除含空值的行

python 复制代码
df = df.dropna()

填充 0

python 复制代码
df = df.fillna(0)

连续数值用均值填充

python 复制代码
df["score"] = df["score"].fillna(df["score"].mean())

分类字段用众数填充

python 复制代码
df["province"] = df["province"].fillna(df["province"].mode()[0])

如何查看重复行、删除重复?

查看重复行数

python 复制代码
df.duplicated().sum()

删除全部重复行

python 复制代码
df = df.drop_duplicates()

按某一列去重(如按id去重,保留第一条)

python 复制代码
df = df.drop_duplicates(subset=["id"], keep="first")

如何把字符串转时间?转整数?

转时间类型(非常常用)

python 复制代码
df["date"] = pd.to_datetime(df["date"])

转整型

python 复制代码
df["age"] = df["age"].astype(int)

查看类型

python 复制代码
df.dtypes

按专业分组,统计分数的均值、最大值、人数

单指标

python 复制代码
df.groupby("major")["score"].mean()

多分组 + 多聚合函数

reset_index() 非常常用,否则分组字段是索引,不方便后续处理。

python 复制代码
df.groupby(["college", "major"])["score"].agg(
    mean_score="mean",
    max_score="max",
    count="count"
).reset_index()  # 把索引变回列

多表合并用什么?和 SQL 的 JOIN 对应什么?

  • 按共同字段关联 → merge
  • 上下堆叠数据 → concat
  • 按行号 / 索引合并 → join
  1. merge:按列关联(对应 SQL JOIN)
python 复制代码
df3 = pd.merge(df1, df2, on="id", how="left")  # left join
  1. concat:上下拼接(追加数据)
python 复制代码
 df_all = pd.concat([df1, df2], axis=0)
  1. join:按索引合并
python 复制代码
 df1.join(df2)

用 Pandas 做 Excel 透视表

python 复制代码
pd.pivot_table(
    data=df,
    index="college",      # 行
    columns="major",     # 列
    values="score",      # 值
    aggfunc="mean"       # 聚合方式
)

根据分数新增等级列(优秀 / 良好 / 及格)

方法1:np.where(简单二分类)

python 复制代码
import numpy as np

df["is_pass"] = np.where(df["score"] >= 60, 1, 0)

方法2:apply(多分类)

python 复制代码
df["level"] = df["score"].apply(lambda x:
    "优秀" if x >= 90 else
    "良好" if x >= 70 else
    "及格" if x >= 60 else "不及格"
)

方法3:pd.cut(分桶,最规范)

python 复制代码
df["level"] = pd.cut(
    df["score"],
    bins=[0, 60, 70, 90, 100],
    labels=["不及格", "及格", "良好", "优秀"]
)

如何提取年、月、日?如何按月求和?

python 复制代码
df["date"] = pd.to_datetime(df["date"])

df["year"] = df["date"].dt.year
df["month"] = df["date"].dt.month
df["day"] = df["date"].dt.day

按月重采样统计

python 复制代码
df.resample("M", on="date")["amount"].sum()

如何识别并剔除异常值?

超出 ±3σ 视为异常,是数据分析标准做法。

python 复制代码
mean = df["score"].mean()
std = df["score"].std()

upper = mean + 3 * std
lower = mean - 3 * std

df = df[(df["score"] >= lower) & (df["score"] <= upper)]

行转列、列转行(melt /pivot)

宽表 → 长表

python 复制代码
df_long = df.melt(id_vars="id", var_name="type", value_name="value")

长表 → 宽表

python 复制代码
df_wide = df_long.pivot(index="id", columns="type", values="value")

apply/map/applymap 区别

  • map:只用于 Series,元素映射
  • apply:可用于 Series / DataFrame,支持复杂函数
  • applymap:对 DataFrame 每个单元格 操作(现已逐渐被 map 替代)

为什么会出现SettingWithCopyWarning这个警告?怎么解决?

对切片 DataFrame 直接修改,Pandas 不确定你改原表还是副本。

解决 :加上 .copy() 即可。

python 复制代码
df = df[df["score"]>60].copy()

如何实现 SQL 的 group by having?

例子:筛选平均分 > 60 的专业

python 复制代码
df.groupby("major").filter(lambda x: x["score"].mean() > 60)

导出 Excel / CSV

python 复制代码
df.to_csv("out.csv", index=False, encoding="utf-8-sig")
df.to_excel("out.xlsx", index=False, sheet_name="结果")

NumPy

NumPy作用?

用 NumPy 做数值计算、异常值判断、数据归一化,配合 Pandas 做向量化操作。

NumPy 数组(ndarray)和 Python 列表 list 的区别?

  1. 数组元素类型必须统一,列表可以混放任意类型。
  2. 数组支持矢量化运算,不用循环,速度极快。
  3. 数组支持多维结构(矩阵),更适合数值计算。
  4. 数组占用内存更小,底层连续存储。
  5. 提供大量数学 / 统计函数,适合数据分析、建模。

创建数组的常用方式有哪些?

python 复制代码
import numpy as np

从列表创建

python 复制代码
arr = np.array([1,2,3,4])

全0/全1数组

python 复制代码
arr = np.zeros((3,4))
arr = np.ones((2,2))

固定值

python 复制代码
arr = np.full((2,3), 5)

等差序列

python 复制代码
arr = np.arange(0, 10, 2)    # 0,2,4,6,8
arr = np.linspace(0,10,5)    # 均分5个点

单位矩阵

python 复制代码
arr = np.eye(3)

查看数组属性

python 复制代码
arr = np.array([[1,2],[3,4]])

形状 (行数,列数)

python 复制代码
arr.shape

维度数

python 复制代码
arr.ndim

总元素个数

python 复制代码
arr.size

数据类型

python 复制代码
arr.dtype

转置

python 复制代码
arr.T

数组索引与切片

python 复制代码
arr = np.array([[1,2,3],
                [4,5,6],
                [7,8,9]])

取某行

python 复制代码
arr[0]

取某行某列

python 复制代码
arr[0, 1]

切片:所有行,前2列

python 复制代码
arr[:, :2]

布尔索引 arr[arr > 5]

python 复制代码
arr[arr > 5]

什么是广播(broadcasting)?为什么重要?

  • 不同形状的数组在运算时,NumPy 会自动扩展维度对齐,不需要手动循环。
  • 优点:代码简洁、速度极快、内存高效。
  • 是 Pandas、Matplotlib、机器学习库高效的基础。

示例:

python 复制代码
a = np.array([[1,2],[3,4]])
b = np.array([10, 20])
# b 自动广播成 [[10,20],[10,20]]
print(a + b)

常用数学 / 统计函数

python 复制代码
arr = np.array([1,2,3,4,5])

求和

python 复制代码
np.sum(arr)

均值

python 复制代码
np.mean(arr)

标准差

python 复制代码
np.std(arr)

方差

python 复制代码
np.var(arr)

最大值

python 复制代码
np.max(arr)

最小值

python 复制代码
np.min(arr)

中位数

python 复制代码
np.median(arr)

最大值下标

python 复制代码
np.argmax(arr)

最小值下标

python 复制代码
np.argmin(arr)

累计求和

python 复制代码
np.cumsum(arr)

数据归一化 / 标准化

题目:把数组缩放到 [0,1] 之间

python 复制代码
arr = np.array([1,2,3,4,5])
arr_min = arr.min()
arr_max = arr.max()

# 最小-最大归一化
arr_norm = (arr - arr_min) / (arr_max - arr_min)

题目:Z-score 标准化(均值 0,方差 1)

python 复制代码
arr_std = (arr - np.mean(arr)) / np.std(arr)

用 NumPy 实现 3σ 异常值筛选

python 复制代码
arr = np.array([1,2,3,4,100])

mean = arr.mean()
std = arr.std()

upper = mean + 3 * std
lower = mean - 3 * std

# 保留正常范围内数据
arr_clean = arr[(arr >= lower) & (arr <= upper)]

数组形状修改

python 复制代码
arr = np.arange(12)

改为3行4列

python 复制代码
arr.reshape(3,4)

展平成一维

python 复制代码
arr.flatten()

转置

python 复制代码
arr.reshape(3,4).T

拼接与分割

python 复制代码
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])

垂直拼接(上下)

python 复制代码
np.vstack([a, b])

水平拼接(左右)

python 复制代码
np.hstack([a, b])

均等分割

python 复制代码
np.vsplit(a, 2)
np.hsplit(a, 2)

np.where 用法

python 复制代码
arr = np.array([1,2,3,4,5])

满足条件返回x,否则y

python 复制代码
new_arr = np.where(arr > 3, 100, 0)

只返回满足条件的下标

python 复制代码
idx = np.where(arr > 3)

去重、唯一值

python 复制代码
arr = np.array([1,2,2,3,3,3])

去重

python 复制代码
np.unique(arr)

去重 + 计数

python 复制代码
vals, counts = np.unique(arr, return_counts=True)

空值(NaN)相关问题

python 复制代码
arr = np.array([1, 2, np.nan, 4])

判断是否 NaN

python 复制代码
np.isnan(arr)

注意:np.nan == np.nan 是 False,正确删除 NaN

python 复制代码
arr[~np.isnan(arr)]

算时自动跳过 NaN

python 复制代码
np.nanmean(arr)
np.nansum(arr)
np.nanstd(arr)

为什么要设置 dtype?

  • 控制内存占用(int8/int32/float64)
  • 避免溢出、计算错误
  • 提升运算速度
python 复制代码
arr = np.array([1,2,3], dtype=np.float32)

随机数生成

0~1 均匀分布

python 复制代码
np.random.rand(3,3)

标准正态分布

python 复制代码
np.random.randn(3,3)

整数随机

python 复制代码
np.random.randint(0,10, size=(2,2))

打乱顺序

python 复制代码
np.random.shuffle(arr)

设置随机种子,保证可复现

python 复制代码
np.random.seed(42)

Matplotlib + Seaborn

Matplotlib 是什么?Seaborn 是什么?关系?

  • Matplotlib:Python 最基础的绘图库,可以画几乎所有静态图表,自由度极高。
  • Seaborn:基于 Matplotlib 封装的统计可视化库,语法更简洁、图更美观,专门用于数据分析。
  • 关系:Seaborn 底层是 Matplotlib,可以互相配合使用。

数据分析常用哪些图表?分别用于什么场景?

  • 折线图:看趋势、时间变化
  • 柱状图 / 条形图:类别对比
  • 直方图 / 核密度图:看数据分布
  • 箱线图:看异常值、分位数、分布范围
  • 散点图:看变量相关性
  • 热力图:看相关系数矩阵
  • 饼图:看占比

Matplotlib 两张图:figure /axes 是什么?

  • figure:画布,整张图的容器
  • axes:子图,真正画图的区域
  • 现在推荐用 OO 风格fig, ax = plt.subplots()

Matplotlib-绘制最简单的折线图

python 复制代码
import matplotlib.pyplot as plt
import numpy as np

x = [1,2,3,4,5]
y = [2,4,6,8,10]

# 创建画布
fig, ax = plt.subplots(figsize=(8,4))
# 画折线
ax.plot(x, y, color='red', linewidth=2, marker='o', label='y=2x')
# 标题、标签
ax.set_title('折线图示例', fontsize=14)
ax.set_xlabel('X轴')
ax.set_ylabel('Y轴')
# 图例
ax.legend()
# 网格
ax.grid(True, alpha=0.3)
plt.show()

Matplotlib-画柱状图

python 复制代码
x = ['A','B','C','D']
y = [10,25,18,32]

fig, ax = plt.subplots()
ax.bar(x, y, color='steelblue')
ax.set_title('柱状图')
plt.show()

Matplotlib-画直方图(看分布)

python 复制代码
data = np.random.randn(1000)
fig, ax = plt.subplots()
ax.hist(data, bins=30, alpha=0.7)
ax.set_title('数据分布')
plt.show()

Matplotlib-画散点图(看相关性)

python 复制代码
x = np.random.randn(100)
y = x * 2 + np.random.randn(100)

fig, ax = plt.subplots()
ax.scatter(x, y, s=20, alpha=0.6)
ax.set_title('散点图')
plt.show()

Matplotlib-画子图(多图并排)

python 复制代码
fig, (ax1, ax2) = plt.subplots(1,2, figsize=(10,4))
ax1.plot([1,2,3],[4,5,6])
ax2.bar(['a','b'],[10,20])
plt.tight_layout()  # 自动调整间距
plt.show()

Matplotlib-如何保存图片?

  • dpi=300 高清
  • bbox_inches='tight' 防止标题被截断
python 复制代码
plt.savefig('test.png', dpi=300, bbox_inches='tight')

Matplotlib-中文乱码怎么解决?

python 复制代码
plt.rcParams['font.sans-serif'] = ['SimHei']  # 黑体
plt.rcParams['axes.unicode_minus'] = False     # 负号正常显示

Seaborn-绘制柱状图(带误差棒 / 分组)

python 复制代码
import seaborn as sns
import pandas as pd

df = pd.DataFrame({
    'major':['工','工','理','理'],
    'score':[80,85,75,78]
})

sns.barplot(data=df, x='major', y='score', palette='viridis')
plt.title('各专业平均分')
plt.show()

Seaborn-箱线图(识别异常值)

python 复制代码
# 单变量箱线图
sns.boxplot(y=df['score'])

# 分组箱线图
sns.boxplot(data=df, x='major', y='score')
plt.show()

Seaborn-热力图(相关系数矩阵)

用途 :看变量之间相关性,常用于生源、分数、深造率分析。

python 复制代码
# 构造相关矩阵
corr = df.corr()
# 画热力图
sns.heatmap(corr, annot=True, cmap='coolwarm', fmt='.2f')
plt.title('相关性热力图')
plt.show()

Seaborn-散点图 + 拟合线(看线性关系)

python 复制代码
sns.regplot(data=df, x='score', y='advance_rate')
plt.title('分数与深造率关系')
plt.show()

Seaborn-核密度图 / 分布对比

python 复制代码
sns.kdeplot(df['score'], fill=True)
plt.title('分数分布')
plt.show()

Seaborn-分面图 FacetGrid(按类别分别画图)

python 复制代码
g = sns.FacetGrid(df, col='major')
g.map(plt.hist, 'score')
plt.show()

Matplotlib vs Seaborn 区别?

  • Matplotlib:底层、灵活、代码多、适合自定义
  • Seaborn:高层、简洁、美观、适合统计分析、快速出图
  • 数据分析日常:Seaborn 快速画图 + Matplotlib 微调细节

箱线图、直方图、散点图分别用来干什么?

  • 箱线图:异常值 + 分位数 + 分组对比
  • 直方图:数据分布(是否正态、偏态)
  • 散点图:两个变量相关性、趋势

什么时候用热力图?

  • 展示相关系数矩阵
  • 展示交叉表、频次表
  • 常用于多维度指标相关性分析(如生源分数、毕业率、深造率)

如何让图表更专业、更适合汇报?

python 复制代码
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(10,5))
sns.barplot(...)
plt.title('...', fontsize=14)
plt.xlabel(...)
plt.ylabel(...)
plt.tight_layout()
plt.savefig('xxx.png', dpi=300)

做数据分析时可视化流程是什么?

  1. 先看数据整体:直方图 / 核密度图看分布
  2. 看异常值:箱线图
  3. 看对比:柱状图 / 条形图
  4. 看趋势:折线图
  5. 看相关性:散点图 + 热力图
  6. 最后用 Matplotlib 统一调整字体、标题、尺寸,导出高清图用于报告。

SciPy

SciPy 是什么,在数据分析里用来干什么?

SciPy 是基于 NumPy 的科学计算库,最常用在统计检验

数据分析中主要用于:A/B 测试、差异显著性检验、相关性分析

常见场景:

  • 不同专业深造率是否有显著差异
  • 不同生源分数是否存在真实差别
  • 政策 / 干预前后效果是否显著
  • 两个变量是否相关

什么是 p 值?

p 值是假设检验成立的概率

常用显著性水平 α = 0.05

  • p < 0.05:差异显著,拒绝原假设
  • p > 0.05:差异不显著,不能认为有真实差别

常见统计检验怎么选?

  • 两组连续数据比较 → t 检验
  • 多组连续数据比较 → 方差分析 ANOVA
  • 两个分类变量关系 → 卡方检验
  • 两个连续变量相关性 → 皮尔逊 / 斯皮尔曼相关
  • 非正态分布数据 → 秩和检验(Mann-Whitney U)

导入scipy

python 复制代码
from scipy import stats
import numpy as np

正态性检验,如何检验一组数据是否符合正态分布?

t 检验前提是数据正态,否则要用秩和检验。

python 复制代码
# 生成测试数据
data = np.random.normal(0, 1, 1000)

# Shapiro-Wilk 检验(小样本)
stat, p = stats.shapiro(data)

# Kolmogorov-Smirnov 检验
stat, p = stats.kstest(data, 'norm', args=(np.mean(data), np.std(data)))

print(f'p值={p:.3f}')
# p>0.05 → 符合正态
# p<0.05 → 非正态

独立样本 t 检验

比较 A/B 两组均值是否有显著差异

python 复制代码
group1 = np.array([80,82,85,87,81])
group2 = np.array([75,77,72,76,74])

# 独立样本 t 检验
stat, p = stats.ttest_ind(group1, group2)

print(f't统计量={stat:.3f}, p值={p:.3f}')

# 判断
if p < 0.05:
    print("差异显著")
else:
    print("差异不显著")

配对样本 t 检验

同一批学生干预前 vs 干预后成绩是否显著提高

用途:政策效果、教学干预、活动效果评估。

python 复制代码
before = [70,72,75,68,73]
after  = [76,78,82,74,79]

stat, p = stats.ttest_rel(before, after)

单样本 t 检验

样本均值是否显著不等于某个理论值

例如:本校平均分是否显著高于全省平均分

python 复制代码
data = [82,81,85,83,80]
pop_mean = 75  # 全省均值

stat, p = stats.ttest_1samp(data, pop_mean)

方差分析 ANOVA(多组比较)

3 个及以上专业的分数是否存在显著差异

python 复制代码
g1 = [80,82,85]
g2 = [75,77,79]
g3 = [70,72,71]

stat, p = stats.f_oneway(g1, g2, g3)

# p<0.05 → 至少一组有差异

卡方检验(分类变量关联性)

高频场景

  • 性别 vs 升学
  • 生源地 vs 毕业情况
  • 专业 vs 就业类型

输入是列联表(交叉表)

python 复制代码
# 列联表:行=性别,列=是否深造
table = [[50, 100],
         [30, 120]]

chi2, p, dof, expected = stats.chi2_contingency(table)

# p<0.05 → 两个分类变量显著相关

皮尔逊相关系数(线性相关)

  • corr 接近 1 → 强正相关
  • corr 接近 -1 → 强负相关
  • p<0.05 → 相关显著
python 复制代码
x = [1,2,3,4,5]
y = [2,4,5,7,8]

corr, p = stats.pearsonr(x, y)

斯皮尔曼等级相关(非参数,不要求正态)

数据不符合正态时用斯皮尔曼。

python 复制代码
corr, p = stats.spearmanr(x, y)

秩和检验(非参数替代 t 检验)

数据非正态时,不能用 t 检验,用 Mann-Whitney U

python 复制代码
stat, p = stats.mannwhitneyu(group1, group2)

t 检验和方差分析的区别?

  • t 检验:两组比较
  • ANOVA:三组及以上

什么时候用非参数检验?

  • 样本量小
  • 数据明显不符合正态分布
  • 存在极端异常值

相关系数 ≠ 因果关系?

相关只能说明一起变化,不能判断谁影响谁,也可能是第三方因素导致。

p 值很小代表什么?

代表两组差异极不可能是随机误差造成的,可以认为存在真实差异。

数据分析完整统计检验流程?

  1. 看数据分布 → 正态检验
  2. 正态 → t 检验 / ANOVA
  3. 非正态 → 秩和检验
  4. 分类变量 → 卡方检验
  5. 看相关性 → 皮尔逊 / 斯皮尔曼
  6. 看 p 值判断是否显著

Statsmodels

Statsmodels 是什么?和 Sklearn 有什么区别?

Statsmodels 是 Python 用于统计建模、统计推断 的库,侧重假设检验、p 值、置信区间、R²、残差分析等统计结果。

Sklearn 侧重预测、机器学习,不重视统计指标。

数据分析常用场景:

  • 线性回归 / 逻辑回归
  • 时间序列(ARIMA)
  • 方差分析
  • 拟合后看影响因素是否显著

总结

  • 解释因素影响、看显著性 → Statsmodels
  • 预测结果、准确率 → Sklearn

线性回归用来干什么?

分析哪些变量对目标有显著影响

量化影响大小(回归系数)

控制其他变量后,看某个因素的净影响

常用于:

  • 分数 / 深造率受哪些因素影响
  • 生源、性别、专业对毕业的影响
  • 政策效果评估

最小二乘线性回归代码

python 复制代码
import statsmodels.api as sm
import pandas as pd
import numpy as np

# 构造数据
df = pd.DataFrame({
    'score':      [80,85,77,79,82,83],  # 因变量 Y
    'study_hour': [5,  7,  4,  5, 6, 5], # 自变量 X1
    'age':        [19,20,19,18,20,19]    # X2
})

# 1. 自变量 X 必须加常数项(截距)
X = df[['study_hour', 'age']]
X = sm.add_constant(X)  # 必须加!
y = df['score']

# 2. 拟合模型
model = sm.OLS(y, X).fit()

# 3. 输出完整统计结果
print(model.summary())

注释

  • add_constant 不加会没有截距,结果错误
  • .summary() 是面试亮点:能看懂统计报表

如何看回归结果 summary?

1. R-squared(R²)

模型解释力,越接近 1 越好。

2. coef(系数)

变量每增加 1,y 变化多少。正 = 正向影响,负 = 负向影响。

3. P>|t|(p 值)

  • p < 0.05 :变量显著
  • p > 0.05:不显著,可剔除

4. std err / t

系数的统计显著性。

5. 残差诊断(JB、Prob (JB))

看残差是否正态,模型是否合理。

总结

先看 R² 判断解释力度,再看每个变量的 coef 方向与大小,最后看 p 值判断是否显著,同时观察残差是否满足正态假设。

逻辑回归(分类问题)

用于二分类问题:是否毕业、是否深造、是否就业、是否报到等。

python 复制代码
# 因变量是 0/1
y = np.array([1,1,0,1,0,1])

# 建模
model = sm.Logit(y, X).fit()
print(model.summary())

输出看

  • coef:影响方向
  • P>|z|:是否显著
  • 预测概率:model.predict(X)

线性回归有哪些基本假设?

  1. 线性:X 与 Y 线性关系
  2. 独立:样本相互独立
  3. 正态:残差近似正态分布
  4. 同方差:残差方差恒定
  5. 无多重共线性:自变量之间不高度相关

多重共线性怎么判断、怎么处理?

判断

  • 看系数符号反常、p 值不显著
  • 计算VIF(方差膨胀因子)
python 复制代码
from statsmodels.stats.outliers_influence import variance_inflation_factor

vif = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]

判断标准

  • VIF > 10:严重共线性
  • VIF > 5:轻度共线性

处理

  • 删除其中一个变量
  • 合并变量
  • 正则化(ridge/lasso)

异常值 / 强影响点怎么检测?

python 复制代码
# Cook 距离
infl = model.get_influence()
cook = infl.cooks_distance[0]

Cook 距离大 → 强影响点,需要检查。

Statsmodels 时间序列能干什么?

  • ARIMA / SARIMA 预测
  • 平稳性检验(ADF)
  • 白噪声检验
  • 趋势、季节性分析

ADF 平稳性检验

python 复制代码
from statsmodels.tsa.stattools import adfuller

stat, p, _, _, _, _ = adfuller(ts)
# p < 0.05 → 序列平稳

什么时候用 Statsmodels,什么时候用 Sklearn?

  • 统计推断、看显著性、解释影响因素、写分析报告 → Statsmodels
  • 预测、分类、模型准确率 → Sklearn

回归系数(coef)代表什么?

控制其他变量不变的情况下,该变量每增加 1,因变量平均变化多少。

p < 0.05 代表什么?

该变量对 Y 有显著影响,不是随机误差造成的。

R² 是什么意思?太低怎么办?

R² 表示模型能解释 Y 的方差比例。

太低说明:

  • 缺失重要变量
  • 关系不是线性
  • 噪声太大

用 Statsmodels 做过什么业务分析?

用 Statsmodels 做过影响因素分析 ,比如分析生源分数、学习时长、专业等变量对深造率 / 毕业率的影响,通过回归系数和 p 值判断哪些因素显著,最终给出可解释的分析结论,而不只是预测

Scikit-learn(sklearn)

Scikit-learn 是什么,在数据分析里用来干什么?

Python 里最通用的机器学习库,封装了几乎所有经典算法。

数据分析里主要用于:

  • 分类 / 预测(是否升学、是否报到、是否流失)
  • 特征重要性分析
  • 聚类(用户分群、生源分群)
  • 数据预处理(归一化、编码、降维)

和 Statsmodels 区别:

  • sklearn:重预测、重准确率
  • Statsmodels:重统计推断、重显著性、重解释

机器学习四大类

  • 分类:预测类别(0/1,是否深造)
  • 回归:预测连续值(分数、收入、升学概率)
  • 聚类:无标签分组(用户分层、生源分层)
  • 降维:PCA 等,简化特征、可视化

模型构建标准流程

  1. 数据读取与探索
  2. 特征工程(缺失值、编码、归一化)
  3. 划分训练集/测试集 train_test_split
  4. 模型初始化
  5. 训练 model.fit(X_train, y_train)
  6. 预测 model.predict(X_test)
  7. 评估指标(准确率、MAE、AUC 等)
  8. 模型优化与特征重要性

分类特征编码:OneHot、LabelEncoder

性别、专业等离散特征 → OneHotEncoder

有序类别(低/中/高)→ LabelEncoder

python 复制代码
from sklearn.preprocessing import OneHotEncoder, LabelEncoder

数值特征归一化 / 标准化

标准化(均值0方差1)→ 大多数模型首选

归一化(0~1)→ 神经网络、距离模型

python 复制代码
from sklearn.preprocessing import StandardScaler, MinMaxScaler

scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

缺失值处理 SimpleImputer

均值/中位数/众数填充

python 复制代码
from sklearn.impute import SimpleImputer

imputer = SimpleImputer(strategy='median')

数据集划分

python 复制代码
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
)

线性回归(预测连续值,如分数)

python 复制代码
from sklearn.linear_model import LinearRegression

model = LinearRegression()
model.fit(X_train, y_train)
pred = model.predict(X_test)

逻辑回归(二分类,如是否升学、是否就业)

python 复制代码
from sklearn.linear_model import LogisticRegression

model = LogisticRegression()
model.fit(X_train, y_train)
pred = model.predict(X_test)
pred_prob = model.predict_proba(X_test)[:,1]

决策树 / 随机森林(最常用、最强业务解释性)

  • 能输出特征重要性 feature_importances_
  • 不需要强特征标准化
  • 擅长非线性关系
python 复制代码
from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(n_estimators=100)
rf.fit(X_train, y_train)

K-Means 聚类(用户分层、生源分层)

用途:

  • 把学生分成:高分稳定型、潜力型、待关注型
  • 做精细化运营 / 培养策略
python 复制代码
from sklearn.cluster import KMeans

km = KMeans(n_clusters=3, random_state=42)
labels = km.fit_predict(X_scaled)

PCA 降维

python 复制代码
from sklearn.decomposition import PCA

pca = PCA(n_components=2)
X_pca = pca.fit_transform(X_scaled)

分类模型指标有哪些?

  • 准确率 Accuracy:总体预测对的比例
  • 精确率 Precision:预测为 1 的里面真的是 1
  • 召回率 Recall:真实 1 里被预测出来的比例
  • F1:精确率与召回率平衡
  • AUC / ROC:二分类最常用、最靠谱
python 复制代码
from sklearn.metrics import accuracy_score, precision_score, recall_score, roc_auc_score

回归模型指标有哪些?

  • MAE 平均绝对误差
  • MSE/RMSE 均方误差 / 平方根误差
  • 解释程度(越接近 1 越好)
python 复制代码
from sklearn.metrics import mean_absolute_error, r2_score

聚类评估有哪些?

  • 轮廓系数
  • Calinski-Harabasz 指数

过拟合是什么?怎么解决?

模型在训练集上表现特别好,但在测试集 / 新数据上表现很差。

原因:模型把噪声、偶然规律也学会了,没有学到真正通用的模式。

表现:

  • 训练集准确率 / 误差很优秀
  • 测试集准确率骤降、误差飙升
  • 模型太复杂,泛化能力差

解决方案:

1. 增加数据

  • 数据越多,噪声影响越小,模型越容易学到真实规律。

2. 降低模型复杂度

  • 线性模型:减少特征
  • 决策树:减小深度、减少叶子节点
  • 少用复杂模型(如深度树、复杂神经网络)

3. 正则化(最常用)

  • L1 正则:让部分特征系数变为 0,自动做特征选择
  • L2 正则:压缩系数大小,防止极端权重
  • 逻辑回归、线性回归常用:LogisticRegression(C=0.1) C 越小,正则越强

4. 剪枝(树模型专用)

  • 限制树深度 max_depth
  • 限制叶子节点最小样本数 min_samples_leaf
  • 提前停止生长

5. 特征选择 / 降维

  • 删除无关、冗余、噪声特征
  • 使用 PCA、方差筛选、相关性筛选

6. 早停 Early Stopping

  • 训练时监控验证集误差,不再提升就停止,防止过度学习。

7. 集成模型(简单有效)

  • 随机森林、XGBoost 自带抗过拟合能力,比单棵树稳得多。

总结

过拟合就是模型在训练集表现很好,但泛化能力差,在新数据上表现差。

解决方法主要有:增加数据、降低模型复杂度、使用正则化、特征选择、剪枝,以及用随机森林这类集成模型

欠拟合是什么?怎么解决?

模型在训练集上表现就很差,测试集也很差

原因:模型太简单、学习能力不足,连数据里的基本规律都没学会

表现:

  • 训练集误差大、准确率低
  • 测试集同样差
  • 模型偏差(Bias)过高

解决方案:

1. 增加更有用的特征

  • 手工构造特征(组合特征、交叉特征、时间特征等)
  • 引入更多维度信息

2. 提高模型复杂度

  • 换成更复杂的模型:线性 → 树模型 / 集成模型
  • 加深树深度、增加叶子节点

3. 减少正则化

  • 减小正则化强度
  • 线性模型调大 C
  • 树模型减少剪枝

4. 去掉不必要的降维、特征筛选

  • 别把有用信息过滤掉了

5. 训练更充分

  • 增加迭代次数
  • 调整学习率
欠拟合 Underfitting 过拟合 Overfitting
训练集效果 很好
测试集效果 很差
模型复杂度 太简单 太复杂
核心问题 高偏差,没学会规律 高方差,学了噪声
解决思路 加特征、加复杂度 降复杂度、正则、剪枝、加数据

总结

欠拟合是模型太简单,在训练集上都学不好,偏差过高。

解决方法主要是:增加有效特征、提高模型复杂度、减少正则化

而过拟合是模型太复杂,学了噪声,泛化差,需要降复杂度、正则化、剪枝、增加数据等方式解决。

什么是交叉验证?

交叉验证(Cross Validation)就是:把数据集分成多份,轮流用其中一部分当验证集,多次训练评估,最后取平均结果,让模型评估更可靠。

为什么要用交叉验证?

  • 只分一次 train/test,结果容易碰巧好 / 碰巧差,不稳定。
  • 交叉验证能避免运气成分,更真实地反映模型泛化能力。
  • 防止你因为单次划分运气好,高估或低估模型效果。

最常用的:K 折交叉验证(K-Fold)

流程(以 5 折 为例):

  1. 把数据平均分成 5 份
  2. 第 1 次:用 1,2,3,4 份训练,第 5 份验证
  3. 第 2 次:用 1,2,3,5 份训练,第 4 份验证
  4. ...... 依次轮换
  5. 最后得到 5 个分数,取平均值 作为最终评估结果
python 复制代码
from sklearn.model_selection import cross_val_score

# cv=5 就是 5 折交叉验证
scores = cross_val_score(model, X, y, cv=5)

# 平均分数
print(scores.mean())

总结

交叉验证是把数据集分成若干份,轮流作为验证集来多次评估模型,最后取平均结果。目的是让模型评估更稳定、可靠,避免单次划分带来的偶然性,更准确地反映模型的泛化能力。

扩展

  • K 一般取多少? 常用 5 折 或 10 折
  • **什么时候用留一法(LOOCV)?**数据特别少的时候
  • 交叉验证的作用?
    1. 评估模型效果
    2. 调参(网格搜索)
    3. 对比不同模型

网格搜索 GridSearchCV

GridSearchCV = 穷举所有参数组合 + 交叉验证(CV)自动选出最好的参数。

  • 模型里有很多超参数:比如随机森林的 max_depthn_estimators逻辑回归的 C(正则强度)
  • 人工一个个试太慢、不准
  • GridSearchCV 自动遍历所有参数组合,用交叉验证打分,选出最优一组

基本流程

  1. 定义一个参数网格(字典):要试哪些值都列出来
  2. 遍历每一种参数组合
  3. 每组参数都做 K 折交叉验证
  4. 记录平均分数
  5. 最终输出:最优参数 + 最优分数
python 复制代码
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV

# 模型
rf = RandomForestClassifier()

# 定义要搜索的参数网格
param_grid = {
    'max_depth': [3, 5, 7],       # 树深度
    'n_estimators': [50, 100, 200] # 树数量
}

# 网格搜索 + 5折交叉验证
grid = GridSearchCV(
    estimator=rf,
    param_grid=param_grid,
    cv=5,          # 5折交叉验证
    scoring='roc_auc'
)

grid.fit(X_train, y_train)

# 结果
print("最优参数:", grid.best_params_)
print("最优分数:", grid.best_score_)

# 用最优模型预测
best_model = grid.best_estimator_
  • 优点:结果客观、自动、可靠
  • 缺点 :参数多的时候非常慢(暴力穷举)
  • 更快的替代RandomizedSearchCV(随机搜索,不遍历全部)

总结

GridSearchCV 是一种自动调参方法 ,它会穷举我们指定的所有参数组合,并通过交叉验证 评估每组参数的效果,最终自动选出泛化能力最好的参数组合,让模型效果更稳定、避免人工调参的主观性。

特征重要性怎么看?

特征重要性 = 这个特征对模型预测贡献有多大,值越大,说明这个特征越关键。

1. 树模型(最常用)

  • 随机森林 Random Forest
  • 决策树
  • GBDT / XGBoost / LightGBM

2. 线性模型

  • 线性回归
  • 逻辑回归(看系数绝对值大小,但要先标准化)

3. 不推荐

KNN、SVM、神经网络 → 很难直接看重要性

树模型代码

python 复制代码
from sklearn.ensemble import RandomForestRegressor

model = RandomForestRegressor()
model.fit(X_train, y_train)

# 查看特征重要性
importances = model.feature_importances_

# 转成DataFrame方便看
import pandas as pd
fi = pd.DataFrame({
    'feature': X_train.columns,
    'importance': importances
}).sort_values('importance', ascending=False)

print(fi)

原理

  • 树在分裂时,用这个特征减少了多少误差(基尼系数 / 方差)
  • 减少越多 → 越重要

线性模型代码

  • 必须先标准化,否则量纲不同不能比
  • 系数绝对值越大 → 越重要
  • 正负代表影响方向
python 复制代码
from sklearn.linear_model import LinearRegression

model = LinearRegression()
model.fit(X_train_scaled, y_train)  # 必须先标准化!

coef = pd.DataFrame({
    'feature': X_train.columns,
    'coef': model.coef_
}).sort_values('coef', key=abs, ascending=False)

总结

树模型(如随机森林)可以直接通过 feature_importances_ 查看特征重要性,值越大表示该特征对预测贡献越大。线性模型需要先做标准化,再看系数的绝对值大小。在分析中常用它来识别关键影响因素。

注意

  • 特征重要性高 ≠ 因果关系,只是相关性
  • 多重共线性会让重要性失真
  • 树模型容易偏好高基数特征(如 ID、类别多的特征)
  • 数据分析里最常用:随机森林看特征重要性 ,用来做因素分析

分类模型评估指标

4 个基础指标

  • TP(真正例):真 1,预测 1
  • FN(假反例):真 1,预测 0
  • FP(假正例):真 0,预测 1
  • TN(真反例):真 0,预测 0

5 大核心指标

1. 准确率 Accuracy

公式:(TP + TN) / 全部

  • 所有样本里预测对的比例
  • 缺点:类别不平衡时完全没用(比如 99% 是 0,瞎猜都能 99% 准确率)

2. 精确率 Precision(查准率)

预测为 1 的里面,有多少是真 1

  • TP / (TP + FP)
  • 场景:宁可少抓,不能抓错例如:垃圾邮件识别、推荐系统

3. 召回率 Recall(查全率)

真实为 1 的里面,有多少被找出来

  • TP / (TP + FN)
  • 场景:宁可错抓,不能漏掉例如:金融欺诈、疾病检测、风险识别

4. F1 分数

精确率与召回率的调和平均

  • 2 * (Precision * Recall) / (Precision + Recall)
  • 两者都要兼顾时用

5. AUC(最常用、最重要)

  • 衡量模型整体区分能力
  • 范围 0.5 ~ 1
    • 0.5 = 瞎猜
    • 0.7~0.8 = 可用
    • 0.8~0.9 = 很好
    • 0.9+ = 极强
  • 优点:不受类别不平衡影响
  • 数据分析面试必说 AUC

总结

分类模型常用的评估指标有:准确率、精确率、召回率、F1 和 AUC 。准确率在不平衡数据下不可靠,所以我一般优先看 AUC。业务需要少误判时看精确率,需要不漏掉目标时看召回率,两者兼顾用 F1。

标准化和归一化区别?

归一化 MinMaxScaler 标准化 StandardScaler
范围 0~1 均值 0,方差 1
受异常值影响 很大 较小
数据分布要求 近似正态更稳
适用场景 固定范围、距离模型 大多数机器学习模型
  • StandardScaler:均值 0 方差 1 → 通用
  • MinMaxScaler:0~1 → 距离类模型(KNN、KMeans、神经网络)

用 归一化 的场景:

  • KNN、K-Means、SVM 等距离 - based 模型
  • 神经网络
  • 需要把值限定在 0~1 之间

用 标准化 的场景:

  • 线性回归、逻辑回归
  • 随机森林、树模型也可以用(不强制)
  • 数据存在异常值时更稳
  • 日常建模默认优先用标准化

树模型不需要标准化?树模型按大小排序分裂,和数值绝对大小无关。

总结

归一化是把数据缩放到 0~1 ,标准化是把数据变成 均值 0 方差 1 。归一化受异常值影响大,适合距离类模型;标准化更稳健,日常建模一般优先用标准化

类别特征用什么编码?

一、无序分类特征(性别、专业、城市、省份)

1. One-Hot 编码(独热编码)

最常用、默认首选

  • 一列变多列,只有 0/1
  • 不引入大小关系
  • 类别不多时用

适用:性别、专业、省份、学历等

二、有序分类特征(低 / 中 / 高、小 / 大、差 / 良 / 优)

2. 标签编码 / 有序编码 LabelEncoder / OrdinalEncoder

  • 按顺序映射成 0,1,2...
  • 保留大小关系

适用:成绩等级、风险等级、教育阶段

三、高基数类别(用户 ID、手机号、学校编号、超多省份)

3. 频率编码(计数编码)

用出现次数代替类别

4. 目标编码(均值编码)

用该类别对应的目标均值编码(比如:某专业深造率 = 编码)

适用:类别特别多、one-hot 会爆炸的场景

四、树模型 vs 线性模型怎么选?

树模型(随机森林、XGBoost)

  • 可以直接用标签编码
  • 也可以用 目标编码
  • 一般不用 one-hot(会影响效果)

线性模型 / 逻辑回归 / KNN / 神经网络

  • 必须用 One-Hot
  • 不能直接用标签编码(会引入虚假大小关系)

总结

类别不多的无序特征用 One-Hot 编码 ;有序特征用 标签编码或有序编码 ;类别特别多的高基数特征用 频率编码或目标编码;线性模型必须用 One-Hot,树模型可以直接用标签编码或目标编码。

用 sklearn 做过什么实际分析?

用 sklearn 做过学生升学概率预测模型,用随机森林看特征重要性,识别出影响深造的关键因素,并用聚类做学生分层,辅助制定针对性培养策略。

类别不平衡(比如很少人违约、很少人辍学)怎么办?

1. 更换评估指标(最简单、第一步必做)

  • 不用 Accuracy 准确率(会骗人)
  • 改用:
    • AUC
    • F1 分数
    • Recall 召回率

2. 调整样本(最常用)

(1)过采样 Oversampling

  • 少数类重复采样、生成样本
  • 优点:用足少量信息
  • 缺点:容易过拟合

(2)欠采样 Undersampling

  • 多数类随机删掉一些
  • 优点:快、简单
  • 缺点:丢信息

(3)SMOTE 算法

  • 在少数类样本之间插值生成新样本
  • 比简单过采样更不容易过拟合
  • 最常用、最推荐

3. 类别权重 Class Weight

直接在模型里给少数类更高的权重,惩罚错分。

代码示例:

python 复制代码
# 逻辑回归
LogisticRegression(class_weight='balanced')

# 随机森林
RandomForestClassifier(class_weight='balanced')

不用改数据,效果往往很好。

4. 阈值移动 Threshold Moving

模型默认阈值 0.5,我们调低阈值(如 0.2、0.3),让模型更容易预测为少数类,提高召回率

5. 集成方法

  • 对多数类多次欠采样
  • 训练多个模型
  • 最后投票不容易过拟合,效果稳定。

总结

类别不平衡时,首先不使用准确率 ,改用 AUC、F1、召回率。然后可以用SMOTE 过采样欠采样 平衡数据。最简单有效的是直接设置 class_weight='balanced' 调整类别权重。也可以通过降低阈值提高少数类的识别率。

逻辑回归 / 决策树 / 随机森林怎么选?

  • 逻辑回归 :线性模型,可解释性极强,速度快
  • 决策树 :非线性,可解释,但容易过拟合
  • 随机森林 :多棵树集成,效果最好、最稳,泛化能力强

1. 逻辑回归 Logistic Regression

  • 类型:线性模型
  • 优点
    • 速度极快
    • 可解释性最强(能看系数、显著性、概率)
    • 不容易过拟合
    • 输出是概率,方便业务理解
  • 缺点
    • 只能学线性关系
    • 无法处理复杂交互
  • 适合场景
    • 需要清晰解释因素影响(如:哪些因素影响升学 / 违约)
    • 数据量很大、要求快
    • 线上简单预测

2. 决策树 Decision Tree

  • 类型:非线性、规则模型
  • 优点
    • 可解释(能画树、能读规则)
    • 不用标准化
    • 能处理非线性、特征交互
  • 缺点
    • 非常容易过拟合
    • 不稳定,数据一变树就大变
  • 适合场景
    • 小数据、需要白盒规则
    • 做初步探索分析
    • 一般不直接用于最终建模

3. 随机森林 Random Forest

  • 类型:集成模型(多棵决策树投票)
  • 优点
    • 效果通常最好
    • 抗过拟合、稳定性强
    • 能处理非线性、异常值、多重共线性
    • 能输出特征重要性(数据分析神器)
  • 缺点
    • 比逻辑回归慢一点
    • 可解释性比逻辑回归差(黑盒)
  • 适合场景
    • 通用首选模型
    • 效果优先、不知道用啥时就用它
    • 找关键影响因素(特征重要性)
    • 分类 / 回归都强

怎么选?

1. 优先选 逻辑回归

  • 需要强可解释性
  • 要报告系数、显著性、影响方向
  • 数据大、要求速度

2. 优先选 随机森林

  • 追求预测效果
  • 存在非线性、特征交互
  • 想看特征重要性
  • 不知道用啥模型时的默认首选

3. 一般不单独用决策树

  • 容易过拟合、不稳定
  • 要用也用剪枝,或直接升级成随机森林

总结

逻辑回归线性、可解释性最强 ,适合需要清晰说明因素影响的场景;决策树能处理非线性,但容易过拟合;随机森林是集成模型,效果最稳定、泛化能力最强 ,还能输出特征重要性,是我做数据分析时的通用首选模型

K-Means

K-Means 是什么?

K-means 属于 Scikit-learn,是无监督聚类算法,把相似的样本自动分成 K 个簇。不需要标签 y,只需要特征 X。

python 复制代码
from sklearn.cluster import KMeans

K-Means 的执行过程?

  1. 随机选 K 个点作为初始质心
  2. 每个样本计算到质心距离,归到最近的簇
  3. 重新计算每个簇的新质心(均值)
  4. 重复 2、3,直到质心不再变化

归类 → 求中心 → 再归类

K 怎么确定?

  • **手肘法(Elbow Method)**看簇内误差平方和 SSE 下降趋势,拐弯点就是 K
  • **轮廓系数(Silhouette Score)**越大聚类效果越好
  • 结合业务:比如分 3 类:高价值 / 中等 / 普通

K-Means 优缺点?

优点

  • 简单、快、好用
  • 大数据集也能跑
  • 客户分群、用户分层神器

缺点

  • 需要手动指定 K
  • 异常值极敏感
  • 量纲敏感(必须标准化)
  • 只能发现凸、球形簇,不规则形状不行
  • 初始质心影响结果(要设 random_state)

K-Means 为什么要标准化 / 归一化?

因为 K-Means 基于距离(欧氏距离)。如果特征量纲不一样(比如年龄 0-100,收入 0-100 万),收入会直接主导距离,结果失真。

必须用 StandardScaler 或 MinMaxScaler。

K-Means 遇到异常值怎么办?

  • 先删异常值
  • 或用 K-Medians(更稳,但 sklearn 没有)
  • 或用 DBSCAN 密度聚类替代

用 K-Means 做过什么?

做用户 / 学生分层,比如根据成绩、活跃度、消费等特征聚类,分成高潜力、普通、待关注群体,用于精细化运营和策略分析。

相关推荐
未知鱼2 小时前
Python安全开发之简易Xss检测工具(详细注释)
python·安全·xss
yaoxin5211232 小时前
368. Java IO API - 基本文件属性
java·开发语言·python
Ujimatsu2 小时前
数据分析相关面试题-A/B 测试 & 统计学部分
算法·机器学习·数据分析
程序媛徐师姐2 小时前
Python基于机器学习的就业岗位推荐系统【附源码、文档说明】
python·机器学习·python机器学习·就业岗位推荐系统·python就业岗位推荐系统·python机器学习就业推荐·就业岗位推荐
Omics Pro2 小时前
空间组学下一代机器学习与深度学习
大数据·人工智能·深度学习·算法·机器学习·语言模型·自然语言处理
建军啊2 小时前
java审计进阶
java·开发语言·python
码界筑梦坊2 小时前
329-基于Python的交通流量数据可视化分析系统
开发语言·python·信息可视化·数据分析·django·vue·毕业设计
北京软秦科技有限公司2 小时前
AI报告文档审核深度赋能化工行业质量管理:IACheck驱动报告质量跃升与合规风险精准管控新范式
大数据·人工智能
TDengine (老段)3 小时前
TDengine IDMP 工业数据建模 —— 数据情景化
大数据·数据库·人工智能·时序数据库·iot·tdengine·涛思数据