ExamPass Assistant
oitedu.online

← 返回首页

多元统计分析 · 大题练习 8题

目录

一、聚类分析

📊 第1题 · Dat9 美国各州犯罪率聚类14分

数据集记录了1973年美国50个州每10万居民中因袭击、谋杀和强奸而被捕的人数,以及各州城市人口百分比。

  1. 导入数据后,计算欧式距离(2分)
  2. 用系统聚类法中的离差平方和法对数据进行分类(2分)
  3. 对分类结果建立树图,根据树图应该分几类?(2分)
  4. 绘制碎石图,根据碎石图确定K-means聚类的K值(3分)
  5. 做K=3的K-means聚类分析(2分)
  6. 输出K=3和K=2的聚类结果,纽约与加州是一类吗?(3分)
📝 参考代码
import pandas as pd
import scipy.cluster.hierarchy as sch

dat9 = pd.read_clipboard()

# 1. 欧式距离
dat9_D = sch.distance.pdist(dat9)

# 2. 离差平方和法(ward)系统聚类
dat9_H = sch.linkage(dat9_D, method='ward')

# 3. 树图
import matplotlib.pyplot as plt
sch.dendrogram(dat9_H)
plt.show()
# 根据树图 → 分3类

# 4. 碎石图确定K
from sklearn.cluster import KMeans
k_list = [1,2,3,4,5]
sse_list = []
for k in k_list:
    km = KMeans(n_clusters=k, n_init=10).fit(dat9)
    sse_list.append(km.inertia_)
plt.plot(k_list, sse_list, '-o')
plt.xlabel('K'); plt.ylabel('SSE'); plt.show()
# 根据碎石图 → K=2或3

# 5. K=3 K-means
dat9_KM = KMeans(n_clusters=3, n_init=10).fit(dat9).predict(dat9)

# 6. 输出结果,检查纽约与加州
dat9_class = pd.DataFrame({'类别': dat9_KM+1}, index=dat9.index)
print(dat9_class[dat9_class.类别==1])  # 纽约与加州同在类别1
📊 第2题 · Dat35 城镇居民消费聚类14分

2016年我国31个地区城镇居民人均消费支出(8项指标),需对指标进行聚类。

  1. 导入数据后,计算欧式距离(2分)
  2. 用系统聚类法中的离差平方和法进行分类(2分)
  3. 对分类结果建立树图(2分)
  4. 绘制碎石图,确定合适的K值(3分)
  5. 做K=3的K-means聚类分析(2分)
  6. 输出K=3聚类结果,北京与哪些地区分为一类?(3分)
📝 参考代码
dat35 = pd.read_clipboard()

# 1. 欧式距离
dat35_D = sch.distance.pdist(dat35)

# 2. 离差平方和法系统聚类
dat35_H = sch.linkage(dat35_D, method='ward')

# 3. 树图
sch.dendrogram(dat35_H)
plt.title("Dat35 系统聚类树图"); plt.show()

# 4. 碎石图
k_list = [1,2,3,4,5]
sse_list = []
for k in k_list:
    km = KMeans(n_clusters=k, n_init=10).fit(dat35)
    sse_list.append(km.inertia_)
plt.plot(k_list, sse_list, '-o')
plt.xlabel("K"); plt.ylabel("SSE"); plt.show()

# 5. K=3 K-means
dat35_KM = KMeans(n_clusters=3, n_init=10).fit(dat35).predict(dat35)

# 6. 北京所在类别
dat35_class = pd.DataFrame({'类别': dat35_KM+1}, index=dat35.index)
bj_class = dat35_class.loc['北京', '类别']
print("与北京同类的地区:", dat35_class[dat35_class.类别==bj_class].index.tolist())

二、判别分析

🎯 第3题 · d93 公交出行方式判别10分

工薪族公交出行调查:y=1乘公交,y=0骑自行车。x1:年龄,x2:月收入,x3:性别(1=男)。

  1. Fisher线性判别(2分)
  2. 回判并计算判对率(2分)
  3. 非线性判别(二次判别)(2分)
  4. 回判并计算判对率(2分)
  5. Fisher vs 非线性,哪个更适合?为什么?(2分)
📝 参考代码
d93 = pd.read_clipboard()

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as lda
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis as qda

X = d93[['性别','年龄','月收入']]
Y = d93.y

# 1. Fisher线性判别
d93_lda = lda().fit(X, Y)

# 2. 回判
d93['ld_G'] = d93_lda.predict(X)
d93_ld_M = d93.pivot_table('序号','y','ld_G', aggfunc=len, margins=True)
print('混淆矩阵:\n', d93_ld_M)
print(f'Fisher正确率: {sum(d93.y==d93.ld_G)/len(d93):.4f}')  # 0.75

# 3. 非线性判别
d93_qda = qda().fit(X, Y)

# 4. 回判
d93['qd_G'] = d93_qda.predict(X)
d93_qd_M = d93.pivot_table('序号','y','qd_G', aggfunc=len, margins=True)
print(d93_qd_M)
print(f'非线性正确率: {sum(d93.y==d93.qd_G)/len(d93):.4f}')  # 0.8214

# 5. 结论:非线性判别更适合,正确率更高(82.14% > 75%)
🎯 第4题 · dat121 鸢尾花判别10分

费歇鸢尾花数据,150朵花,4个度量变量 + Species(1=Setosa, 2=Versicolor, 3=Virginica)。

  1. Fisher线性判别(2分)
  2. 回判,判对率是多少?(2分)
  3. 非线性判别(2分)
  4. 回判,判对率是多少?(2分)
  5. Fisher vs 非线性,哪个更适合?为什么?(2分)
📝 参考代码
dat121 = pd.read_clipboard()

X = dat121[['sepal.length','sepal.width','petal.length','petal.width']]
Y = dat121.Species

# 1. Fisher线性判别
dat121_lda = lda().fit(X, Y)

# 2. 回判
dat121['ld_G'] = dat121_lda.predict(X)
dat121_ld_M = dat121.pivot_table('Species','Species','ld_G', aggfunc=len, margins=True)
print('混淆矩阵:\n', dat121_ld_M)
correct = sum(dat121['Species'] == dat121['ld_G'])
print(f'Fisher正确率: {correct}/{len(dat121)} = {correct/len(dat121):.4f}')

# 3. 非线性判别
dat121_qda = qda().fit(X, Y)

# 4. 回判
dat121['qd_G'] = dat121_qda.predict(X)
dat121_qd_M = dat121.pivot_table('Species','Species','qd_G', aggfunc=len, margins=True)
print(dat121_qd_M)
correct_qda = sum(dat121['Species'] == dat121['qd_G'])
print(f'非线性正确率: {correct_qda}/{len(dat121)} = {correct_qda/len(dat121):.4f}')

# 5. 比较两个正确率,更高的更适合

三、主成分分析

📈 第5题 · d61 交通运输业投资效益评价14分

30家交通运输业上市公司8项财务指标。X1:基本每股收益 X2:每股净资产 X3:净资产收益率 X4:净利润率 X5:总资产报酬率 X6:存货周转率 X7:固定资产周转率 X8:总资产周转率。

  1. 以协方差矩阵为统计量,对所有8个变量进行主成分分析(2分)
  2. 根据累计方差占比超80%应选取几个主成分?(2分)
  3. 第2个主成分的方差贡献率是多少?(2分)
  4. 写出第二主成分的表达式(2分)
  5. 绘制前2个主成分的信息图,哪3个公司得分较高?(4分)
  6. 前2维信息图是否有足够说服力,为什么?(2分)
📝 参考代码
from sklearn.decomposition import PCA
import numpy as np

d61 = pd.read_clipboard()

# 主成分评价函数
def PCscores(X, m=2):
    Z = (X - X.mean()) / X.std()
    p = Z.shape[1]
    pca = PCA(n_components=p).fit(Z)
    Vi = pca.explained_variance_
    Wi = pca.explained_variance_ratio_
    Vars = pd.DataFrame({'Variances': Vi}, index=[f'Comp{i+1}' for i in range(p)])
    Vars['Explained'] = Wi * 100
    Vars['Cumulative'] = np.cumsum(Wi) * 100
    print("\n方差贡献:\n", round(Vars, 4))
    Compi = [f'Comp{i+1}' for i in range(m)]
    loadings = pd.DataFrame(pca.components_[:m].T, columns=Compi, index=X.columns)
    print("\n主成分负荷:\n", round(loadings, 4))
    scores = pd.DataFrame(pca.fit_transform(Z)).iloc[:, :m]
    scores.index = X.index; scores.columns = Compi
    scores['Comp'] = scores.dot(Wi[:m])
    scores['Rank'] = scores['Comp'].rank(ascending=False).astype(int)
    return scores

# 1. 主成分分析
d61_pcs = PCscores(d61)
print(d61_pcs)

# 2. Comp1 49.38% + Comp2 21.74% + Comp3 13.01% = 84.14% > 80% → 选3个

# 3. 第2主成分方差贡献率: 21.74%

# 4. 第二主成分表达式(见负荷表Comp2列)

# 5. 信息图
def Scoreplot(Scores):
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    plt.plot(Scores.iloc[:,0], Scores.iloc[:,1], '*')
    plt.xlabel(Scores.columns[0]); plt.ylabel(Scores.columns[1])
    plt.axhline(y=0, ls=':'); plt.axvline(x=0, ls=':')
    for i in range(len(Scores)):
        plt.text(Scores.iloc[i,0], Scores.iloc[i,1], Scores.index[i])

Scoreplot(d61_pcs); plt.show()
# 得分较高:长江投资、铁龙物流、交运股份

# 6. 前2维仅71.12%,不足80%,说服力不够充分
📈 第6题 · dat52 工业企业效益主成分评价14分

我国各地区规模以上工业企业8项经济效益指标,前7项单位亿元,最后一项万人。

  1. 以协方差矩阵为统计量,对所有8个变量进行主成分分析(2分)
  2. 根据累计方差占比超80%应选取几个主成分?(2分)
  3. 写出第二主成分的表达式(2分)
  4. 绘制前2个主成分的信息图,哪3个公司得分较高?(4分)
  5. 前2维信息图是否有足够说服力,为什么?(2分)
  6. 第2个主成分的方差贡献率是多少?(2分)
📝 参考代码
dat52 = pd.read_clipboard()

# 1. 主成分分析
dat52_pcs = PCscores(dat52)
print(dat52_pcs)

# 2. 观察 Cumulative 列,找到超过80%的最小主成分数

# 3. 第二主成分表达式(写Comp2负荷系数)

# 4. 信息图
Scoreplot(dat52_pcs); plt.show()

# 5. 前2维累计贡献率若不够80%,需要更多主成分

# 6. 查看方差贡献表中 Comp2 的 Explained 值

四、因子分析

🔬 第7题 · dat52 工业企业效益因子分析18分

我国各地区规模以上工业企业8项经济效益指标,使用因子分析方法评价。

  1. KMO检验和Bartlett检验,分析是否适合做因子分析(4分)
  2. 8因子最大似然法估计(不要旋转)(2分)
  3. 根据共同度,有没有被公共因子很好解释的变量?(2分)
  4. 根据方差贡献率,应该选几个因子?(2分)
  5. 2因子varimax旋转,回归法计算因子得分(2分)
  6. 根据旋转后载荷对2个因子做合理解释(2分)
  7. 计算因子得分,投资者应投哪家公司?(4分)
📝 参考代码
dat52 = pd.read_clipboard()

import factor_analyzer as fa
from factor_analyzer import FactorAnalyzer as FA

# 1. KMO和Bartlett检验
kmo = fa.calculate_kmo(dat52)
print(f'KMO: {kmo[1]:.4f}')  # 0.7499,接近1,适合
chisq = fa.calculate_bartlett_sphericity(dat52)
print(f'卡方值={chisq[0]:.4f}, p值={chisq[1]:.4f}')  # p=0.0000,变量关系显著
# → 适合做因子分析

# 2. 8因子最大似然法
Fm1 = FA(n_factors=8, method='ml', rotation=None).fit(dat52.values)

# 3. 共同度
communalities = 1 - Fm1.get_uniquenesses()
print('共同度:', communalities)
# x7共同度仅68.6%,未被很好解释

# 4. 方差贡献
def Factors(fa): return [f'F{i}' for i in range(1, fa.n_factors+1)]
Vars_names = ['方差','贡献率','累计贡献率']
Fm1_Vars = pd.DataFrame(Fm1.get_factor_variance(), Vars_names, Factors(Fm1))
print(Fm1_Vars)
# F1累计贡献率86.5%>80%,选1个因子即可

# 5. 2因子varimax旋转
Fp2 = FA(2, method='principal', rotation='varimax').fit(dat52.values)
Fp2_load = pd.DataFrame(Fp2.loadings_, dat52.columns, Factors(Fp2))
print('旋转后载荷:\n', Fp2_load)
# F1: X1-X6,X8(高载荷); F2: X7(高载荷)

# 6. 因子解释:F1代表综合经营效益,F2代表固定资产周转

# 因子得分函数
def FArank(Vars, Scores):
    Vi = Vars.values[0]
    Wi = Vi / sum(Vi)
    Fi = Scores.dot(Wi)
    Ri = Fi.rank(ascending=False).astype(int)
    return pd.DataFrame({'因子得分': Fi, '因子排名': Ri})

# 7. 因子得分
Fp2_scores = pd.DataFrame(Fp2.transform(dat52.values), dat52.index, Factors(Fp2))
Fp2_Vars = pd.DataFrame(Fp2.get_factor_variance(), Vars_names, Factors(Fp2))
print(FArank(Fp2_Vars, Fp2_scores))
# → 江苏排名最高,应投江苏
🔬 第8题 · d61 交通运输业因子分析18分

30家交通运输业上市公司8项财务指标,使用因子分析方法评价投资效益。

  1. KMO检验或Bartlett检验,分析是否适合做因子分析(4分)
  2. 4因子最大似然法估计(不要旋转)(2分)
  3. 根据共同度,有没有被公共因子很好解释的?(3分)
  4. 根据方差贡献率,应该选几个因子?(2分)
  5. 2因子varimax旋转,回归法计算因子得分(2分)
  6. 根据旋转后载荷对因子做合理解释(3分)
  7. 计算因子得分,投资者应该投哪家公司?(2分)
📝 参考代码
d61 = pd.read_clipboard()

import factor_analyzer as fa
from factor_analyzer import FactorAnalyzer as FA

# 1. KMO和Bartlett检验
kmo = fa.calculate_kmo(d61)
print(f'KMO: {kmo[1]:.4f}')
chisq = fa.calculate_bartlett_sphericity(d61)
print(f'卡方值={chisq[0]:.4f}, p值={chisq[1]:.4f}')
# KMO接近1且p<0.05 → 适合做因子分析

# 2. 4因子最大似然法
Fm4 = FA(n_factors=4, method='ml', rotation=None).fit(d61.values)

# 3. 共同度
communalities = 1 - Fm4.get_uniquenesses()
print('共同度:', communalities)

# 4. 方差贡献
Vars_df = pd.DataFrame(Fm4.get_factor_variance(),
    ['方差','贡献率','累计贡献率'],
    [f'F{i}' for i in range(1,5)])
print('\n方差贡献:\n', Vars_df)
# 选累计贡献率>80%的因子数

# 5. 2因子varimax旋转
F2 = FA(2, method='principal', rotation='varimax').fit(d61.values)
F2_load = pd.DataFrame(F2.loadings_, d61.columns, ['F1','F2'])
print('\n旋转后载荷:\n', F2_load)

# 6. 根据载荷解释因子含义

# 7. 因子得分
F2_scores = pd.DataFrame(F2.transform(d61.values), d61.index, ['F1','F2'])
F2_vars = pd.DataFrame(F2.get_factor_variance(), ['方差','贡献率','累计贡献率'], ['F1','F2'])
print('\n因子得分与排名:\n', FArank(F2_vars, F2_scores))
# 得分最高者推荐投资

← 返回首页