SD.
Gallery
About
Blog
Contact
Hire Me
2026-5-01Data Science

中国高等院校教育资源区域分布分析研究

8 min

中国高等院校教育资源区域分布分析研究

基于教育部 2024 年全国普通高等学校名单,通过数据采集、清洗、统计分析、机器学习聚类和可视化展示,系统性研究中国大陆高等教育资源的区域分布特征与均衡性。

项目背景

高等教育资源的区域分布直接影响教育公平与社会发展。本项目通过数据科学方法,量化分析我国高校资源的省际差异、区域特征、城市群集聚等关键问题,为教育政策制定提供数据支撑。

研究范围与数据口径

  • 研究范围:中国大陆普通高等学校(不含港澳台)
  • 数据源:教育部 2024 年全国普通高等学校名单
  • 双一流:2022 年第二轮"双一流"建设高校名单
  • 985/211:历史固定名单
  • 人口数据:第七次全国人口普查(2020 年)
  • 城市群:京津冀、长三角、粤港澳大湾区、成渝城市群

技术架构

核心技术栈

  • Python 3.12 - 项目基础语言
  • Pandas - 数据处理与分析
  • Scikit-learn - 机器学习聚类
  • Matplotlib + Seaborn - 数据可视化
  • Openpyxl - Excel 文件处理

核心功能实现

1. 数据采集与爬取

实现教育部官网数据自动采集:

import requests
import pandas as pd
from openpyxl import load_workbook

class EducationDataCrawler:
    def __init__(self):
        self.base_url = "https://www.moe.gov.cn"
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)'
        }
    
    def download_official_list(self):
        response = requests.get(
            f"{self.base_url}/jyb_xxgk/xxgk_content.html",
            headers=self.headers
        )
        
        excel_url = self.extract_excel_url(response.text)
        excel_data = requests.get(excel_url)
        
        with open('data/raw/universities_raw.xlsx', 'wb') as f:
            f.write(excel_data.content)
    
    def parse_excel(self):
        wb = load_workbook('data/raw/universities_raw.xlsx')
        ws = wb.active
        
        data = []
        for row in ws.iter_rows(min_row=2, values_only=True):
            data.append({
                'name': row[0],
                'province': row[1],
                'city': row[2],
                'level': row[3],
                'authority': row[4],
                'remark': row[5],
            })
        
        df = pd.DataFrame(data)
        df.to_csv('data/raw/universities_raw.csv', index=False)
        return df

2. 数据清洗与标准化

实现省份标准化、城市标准化、办学层次统一:

class DataCleaner:
    def __init__(self):
        self.province_mapping = self.load_province_mapping()
        self.elite_universities = self.load_elite_list()
    
    def clean_data(self, df: pd.DataFrame) -> pd.DataFrame:
        df = df.copy()
        
        df['province'] = df['province'].map(self.standardize_province)
        df['city'] = df['city'].map(self.standardize_city)
        
        df = df[~df['province'].isin(['香港', '澳门', '台湾'])]
        
        df['level_standard'] = df['level'].apply(self.standardize_level)
        df['ownership'] = df['authority'].apply(self.identify_ownership)
        
        df['is_985'] = df['name'].isin(self.elite_universities['985'])
        df['is_211'] = df['name'].isin(self.elite_universities['211'])
        df['is_double_first_class'] = df['name'].isin(
            self.elite_universities['double_first_class']
        )
        
        return df
    
    def standardize_province(self, province: str) -> str:
        return self.province_mapping.get(province, province)
    
    def standardize_level(self, level: str) -> str:
        if '本科' in level:
            return '本科'
        elif '专科' in level or '高职' in level:
            return '高职专科'
        return '其他'
    
    def identify_ownership(self, authority: str) -> str:
        if '民办' in authority or '民营' in authority:
            return '民办'
        return '公办'

3. 统计分析模块

生成省级、区域、城市、城市群多维度汇总:

class StatisticsAnalyzer:
    def __init__(self, df: pd.DataFrame):
        self.df = df
        self.regions = self.load_region_mapping()
        self.city_clusters = self.load_city_clusters()
    
    def generate_province_summary(self) -> pd.DataFrame:
        summary = self.df.groupby('province').agg({
            'name': 'count',
            'level_standard': lambda x: (x == '本科').sum(),
            'ownership': lambda x: (x == '公办').sum(),
            'is_985': 'sum',
            'is_211': 'sum',
            'is_double_first_class': 'sum',
        }).rename(columns={
            'name': 'total_universities',
            'level_standard': 'undergraduate_count',
            'ownership': 'public_count',
            'is_985': '985_count',
            'is_211': '211_count',
            'is_double_first_class': 'double_first_class_count',
        })
        
        population = self.load_population_data()
        summary['population'] = summary.index.map(population)
        summary['per_million'] = (
            summary['total_universities'] / summary['population'] * 1000000
        )
        
        return summary
    
    def generate_region_summary(self) -> pd.DataFrame:
        self.df['region'] = self.df['province'].map(self.regions)
        
        return self.df.groupby('region').agg({
            'name': 'count',
            'level_standard': lambda x: (x == '本科').sum(),
            'is_double_first_class': 'sum',
        })

4. 均衡性指标计算

计算基尼系数、泰尔指数、HHI、变异系数:

import numpy as np

class InequalityMetrics:
    def calculate_gini(self, data: np.ndarray) -> float:
        sorted_data = np.sort(data)
        n = len(data)
        cumsum = np.cumsum(sorted_data)
        
        gini = (2 * np.sum((np.arange(1, n + 1)) * sorted_data)) / (n * cumsum[-1]) - (n + 1) / n
        return gini
    
    def calculate_theil(self, data: np.ndarray) -> float:
        mean_value = np.mean(data)
        theil = np.sum((data / mean_value) * np.log(data / mean_value)) / len(data)
        return theil
    
    def calculate_hhi(self, data: np.ndarray) -> float:
        shares = data / np.sum(data)
        hhi = np.sum(shares ** 2)
        return hhi
    
    def calculate_cv(self, data: np.ndarray) -> float:
        return np.std(data) / np.mean(data)
    
    def calculate_lorenz_curve(self, data: np.ndarray) -> tuple:
        sorted_data = np.sort(data)
        cumsum = np.cumsum(sorted_data)
        
        x = np.arange(1, len(data) + 1) / len(data)
        y = cumsum / cumsum[-1]
        
        return x, y

5. 机器学习聚类

KMeans 聚类 + PCA 降维可视化:

from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

class MachineLearningAnalyzer:
    def __init__(self, province_summary: pd.DataFrame):
        self.data = province_summary
        self.scaler = StandardScaler()
    
    def prepare_features(self) -> pd.DataFrame:
        features = self.data[[
            'total_universities',
            'undergraduate_count',
            'double_first_class_count',
            'per_million',
        ]]
        
        features_scaled = self.scaler.fit_transform(features)
        return pd.DataFrame(features_scaled, columns=features.columns)
    
    def kmeans_clustering(self, n_clusters: int = 4):
        features = self.prepare_features()
        
        kmeans = KMeans(n_clusters=n_clusters, random_state=42)
        clusters = kmeans.fit_predict(features)
        
        self.data['cluster'] = clusters
        return self.data
    
    def pca_visualization(self):
        features = self.prepare_features()
        
        pca = PCA(n_components=2)
        pca_result = pca.fit_transform(features)
        
        self.data['pca_1'] = pca_result[:, 0]
        self.data['pca_2'] = pca_result[:, 1]
        
        return self.data, pca.explained_variance_ratio_

6. 数据可视化

生成地图、柱状图、堆叠图、散点图、洛伦兹曲线:

import matplotlib.pyplot as plt
import seaborn as sns

class Visualizer:
    def __init__(self, output_dir: str):
        self.output_dir = output_dir
        plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
    
    def plot_province_distribution(self, summary: pd.DataFrame):
        fig, ax = plt.subplots(figsize=(14, 6))
        
        summary = summary.sort_values('total_universities', ascending=False).head(20)
        
        ax.bar(summary.index, summary['total_universities'])
        ax.set_xlabel('省份')
        ax.set_ylabel('高校数量')
        ax.set_title('各省高校数量分布(Top 20)')
        plt.xticks(rotation=45)
        plt.tight_layout()
        plt.savefig(f'{self.output_dir}/province_distribution.png', dpi=300)
    
    def plot_lorenz_curve(self, x: np.ndarray, y: np.ndarray, gini: float):
        fig, ax = plt.subplots(figsize=(8, 8))
        
        ax.plot([0, 1], [0, 1], 'k--', label='完全平等线')
        ax.plot(x, y, 'b-', label=f'洛伦兹曲线 (Gini={gini:.3f})')
        ax.fill_between(x, y, [0, 1], alpha=0.3)
        
        ax.set_xlabel('累计省份比例')
        ax.set_ylabel('累计高校数量比例')
        ax.set_title('高校资源分布洛伦兹曲线')
        ax.legend()
        plt.tight_layout()
        plt.savefig(f'{self.output_dir}/lorenz_curve.png', dpi=300)
    
    def plot_cluster_result(self, data: pd.DataFrame):
        fig, ax = plt.subplots(figsize=(10, 8))
        
        scatter = ax.scatter(
            data['pca_1'],
            data['pca_2'],
            c=data['cluster'],
            cmap='viridis',
            s=100,
            alpha=0.6
        )
        
        for idx, row in data.iterrows():
            ax.annotate(idx, (row['pca_1'], row['pca_2']))
        
        ax.set_xlabel('主成分 1')
        ax.set_ylabel('主成分 2')
        ax.set_title('省级高校资源聚类结果(PCA降维)')
        plt.colorbar(scatter, label='聚类')
        plt.tight_layout()
        plt.savefig(f'{self.output_dir}/cluster_pca.png', dpi=300)

研究发现

1. 高校数量省际分布

  • 头部集中:江苏、广东、山东位居前三
  • 地区差异:东部省份高校数量显著高于中西部
  • 人均差异:北京、上海人均高校资源最丰富

2. 优质资源分布

  • 双一流分布:北京、上海、江苏占据优势
  • 985/211 集中:头部城市集聚效应明显
  • 区域不均:东部地区优质资源占比超 60%

3. 均衡性指标

  • 基尼系数:0.42(中等不均衡)
  • 泰尔指数:显示区域内差异大于区域间差异
  • 城市群集聚:京津冀、长三角高校密度最高

4. 机器学习聚类

识别出四类省份:

  • 第一梯队:北京、江苏、上海(高校数量多 + 优质资源多)
  • 第二梯队:广东、山东、湖北(高校数量多,优质资源中等)
  • 第三梯队:河南、四川、湖南(高校数量中等)
  • 第四梯队:西部省份(高校数量少,优质资源少)

技术挑战与解决方案

挑战 1:数据标准化

解决方案:构建省份、城市、办学层次映射表

挑战 2:多维度汇总

解决方案:pandas groupby + agg 实现灵活聚合

项目成果

  • 完整的数据采集与清洗流程
  • 36 个统计指标与可视化图表
  • 机器学习聚类分析
  • 完整的研究报告

技术启示

  1. 数据口径统一很重要:标准化是分析的基础
  2. 多维度分析更全面:省级、区域、城市群多角度
  3. 机器学习提供新视角:聚类发现隐藏模式
  4. 可视化是研究的重要支撑:图表让结论更直观

通过本项目,我系统掌握了数据科学研究的完整流程,从数据采集、清洗、统计分析到机器学习、可视化,每个环节都体现了严谨性与工程化思维。

Portfolio

专注于创造高品质、简洁且富有情感的数字产品体验。

链接

关于作品博客

社交

GitHubTwitterLinkedIn

© 2026 Portfolio. All rights reserved.

隐私政策服务条款