精华内容
下载资源
问答
  • 7000多字的论文,是对双因素在网站研究的很好应用。。。
  • 通过理论分析、实例验证以及UDEC数值计算方法验证了厚松散层水平煤层开采条件下岩层移动与地表沉降内、外“类曲线”模型。此外,还分析了内、外“类曲线”共轭形成条件、影响因素与整体运移规律。结果表明:在厚...
  • 将信用风险、利率期限结构引入到二叉树定价模型中,建立以股价...对比标的股价二叉树定价模型的计算结果,发现基于双因素的可转债定价模型的计算精确度较高,同时,计算得到的理论价值的走势跟市场价格的走势较为相似。
  • 1. 无交互作用的双因素方差分析模型 2. 有交互作用的双因素方差分析模型 7.3 一元线性回归分析 相关关系的类型 7.3.2 一元线性回归模型 1.回归参数的估计 2.回归模型、参数的显著性检验 7.3.3 一元线性回归分析应用 ...

    🚀【MOOC数学建模与实验---学习笔记---整理汇总表】🚀

    🌈【学习网址:MOOC---郑州轻工业大学---数学建模与实验】🌈

    目   录

    7.1 单因素方差分析

    7.1.1 方差分析概念

    7.1.2 单因素方差分析的数据结构

    例7.1.1  三种治疗方案对降血糖的疗效比较

    7.1.3 单因素方差分析模型

    定理7.1.1 总变异 = 组间变异 + 组内变异

    例7.1.1 Matlab求解

    7.2 双因素方差分析

    7.2.1 问题引入

    7.2.2 双因素方差分析的数据结构

    7.2.3 因素方差分析模型

    1. 无交互作用的双因素方差分析模型

    2. 有交互作用的双因素方差分析模型

    7.3 一元线性回归分析

    7.3.1 回归分析的概念

    相关关系的类型

    7.3.2 一元线性回归模型

    1.回归参数的估计

    2.回归模型的显著性检验

    3.回归参数的显著性检验

    7.3.3 一元线性回归分析应用

    7.4 多元线性回归分析

    7.4.1 多元线性回归模型

    多元线性回归分析内容

    7.4.2 回归参数的估计

    7.4.3 回归方程的拟合优度

    7.4.4 显著性检验

    1.模型的显著性检验

    2. 偏回归系数的显著性检验

    7.4.5 共线性诊断

    7.5 牙膏价格问题

    7.5.1 问题描述

    7.5.2 问题分析

    7.5.3 模型假设与符号

    7.5.4 模型建立与求解

    1.牙膏价格差对销售量影响模型

    2.广告费用对销售量影响模型

    3.牙膏价格差与广告费用对销售量影响模型

    4.模型改进

    7.5.5 结果分析

    7.6 方差分析与回归分析的SPSS实现

    7.6.1 SPSS软件概述

    1 SPSS版本与安装

    2 SPSS界面

    3 SPSS特点

    4 SPSS数据

    7.6.2 SPSS与方差分析

    1 单因素方差分析

    2 双因素方差分析

    7.6.3 SPSS与回归分析 

    SPSS回归分析过程

    牙膏价格问题的回归分析


    数学方法解决实际问题,应用数学方法、概念:应用 -> 理论 -> 研究


    常用数据分析统计方法:方差分析、回归分析、主成分分析、因子分析、聚类分析、判别分析...


    历年赛题方法(全国赛):

    • 2010B 上海世博会影响力的定量评估
    • 2012A 葡萄酒的评价(回归分析、关联性分析)
    • 2013A 车道被占用对城市道路通行能力的影响(回归分析)
    • 2017B “拍照赚钱”的任务定价(回归分析、聚类分析)

    主要内容:方差分析、回归分析

    1. 单因素方差分析
    2. 多因素方差分析
    3. 一元回归分析
    4. 多元回归分析

    7.1 单因素方差分析

    数据分析   统计模型:方差分析模型、回归分析模型、主成分分析模型、聚类分析模型、因子分析模型

    7.1.1 方差分析概念

    • 在工农业生产和科学研究中,经常遇到这样的问题:影响产品产量、质量的因素很多,我们需要了解在这众多的因素中,哪些因素对影响产品产量、质量有显著影响。为此,要先做试验,然后对测试的结果进行分析。方差分析(Analysis of Variance,简称ANOVA)就是分析测试结果的一种方法。                主要是多组实验数据比较所采用的方法
    • 方差分析是检验多组样本均值间的差异是否具有统计意义的一种方法。

    例如,医学界研究几种药物对某种疾病的疗效;农业研究土壤、肥料、日照时间等因素对某种农作物产量的影响;不同饲料对牲畜体重增长的效果等都可以使用方差分析方法去解决。

    7.1.2 单因素方差分析的数据结构

    • 若指标观测值X只受一个因素A的影响,检验A在取不同的状态或水平时,对指标值X的影响称为单因素试验
    • 观测值X称为因变量(响应变量),是连续型的数值变量。
    • 因素(Factor)A是影响因变量变化的客观条件。

    设因素A有r个水平,每个水平下重复观测n次(n:重复数),则观测数据为如下形式

       \overline{x_{i}}:第i行的平均值;\overline{x}:整个实验数据的算数平均值(总均值)

    例7.1.1  三种治疗方案对降血糖的疗效比较

    例7.1.1 某医生研究一种四类降糖新药的疗效,按完全随机设计方案治疗糖尿病患者,治疗一月后,记录下每名受试者血糖下降值,资料见下表,问三种治疗方案对降血糖的疗效是否相同?【No,第1组疗效显著高于另外两组!】

    每一组,18名受试验者。3个剂量水平,每个剂量水平 重复观测 18次(n=18)。比较均值!

    7.1.3 单因素方差分析模型

    • 方差分析是从总体上判断多组数据平均数(r≥3)之间的差异是否显著。
    • 方差分析将全部数据看成是一个整体,分析构成变量的变异原因,进而计算不同变异来源的总体方差的估值。然后进行F检验,判断各样本的总体平均数是否有显著差异。若差异显著,再对平均数进行两两之间的比较。

    假设检验:分析数据之间差异是否显著。

       i:代表水平;j:代表重复数

    x_{ij} = \mu _{i} + \varepsilon _{ij} : 观测值 = 治疗方案 + 随机因素

    \mu _{i} :反映第x种(x = 1\2\3)治疗方案的平均治疗水平。

     H0:原假设;各个水平下的均值相同

    H0:先假定不同水平下的均值是相等的;三种治疗方案之间是没有差异的。-> 利用 数据分析 进行检验(类似于 反证法)

    单因素方差分析法是将样本总偏差的平方和分解成两个平方和(因子平方和误差平方和),通过这两个平方和之间的比较,导出假设检验的统计量和拒绝域。

    总偏差平方和:所有数据的偏差平方和。(求和:每个观测值与总均值之间的差的平方。)

    因子平方和:比较各个水平(行)下,数据之间的差异。xi:第i个水平下的样本均值。每个水平下的均值与总均值的偏差平方和。

    误差平方和:各个组内的偏差平方和。每一行数据内部的偏差平方和。主要与 随机误差 有关。

    自由度:自由取值的变量个数。

    定理7.1.1 总变异 = 组间变异 + 组内变异

    ST:所有数据之间的差异(xij之间的差异越大,ST就越大)。

    x_{ij} = \mu _{i} + \varepsilon _{ij} :\mu _{i} (组间变异\不同治疗方案) + \varepsilon _{ij}(组内变异)

    H0:原假设(\mu _{1} = \mu _{2} = \mu _{3} = ... = \mu _{r}

    用“均方和”进行比较:消除自由度的影响。MSA、MSE进行比较:观察SA、SE哪个引起的误差偏大。

    如果,因子平方和 所占的比例较大:各个因子之间的差异较大;

    如果,误差平方和 所占的比例较大:数据之间的差异,主要由随机误差引起。

    数据量越多,随机因素多占的比例越大,ST越大,∴ 用均方和进行比较。

    F(f_{A}, f_{E}) :F分布(第一自由度, 第二自由度)

    第一自由度:(r-1)、(水平数-1)          第二自由度:(n-r)、(样本观测值的个数-水平数)

    H0不合理:SA占的比例越大,F越大,越拒绝原假设。

    一般,r ≥ 3   《概率论与数理统计》

    拒绝原假设(各个水平下的均值相等):各个水平下的均值 有 显著差异。P值越小(小于α)(α一般为0.05)

    例7.1.1 Matlab求解

    % 例7.1.1
    x = xlsread('C:\Users\lwx\Desktop\chapter7.xlsx','Sheet1','A1:C18') % 读取数据
    % 每个水平(列)下 观测值、重复数都是一样的 单因素误差分析:重复数一样的数据容易分析处理
    [p,table,stats] = anova1(x)

    图1:方差分析表        图2:均值盒形图    箱形图    红线:反映平均血糖下降值(第1个下降值最高)     

        

    n:[18 18 18]:样本量          s:残差均方           残差自由度:51       means:均值比较

    三列数据:三组治疗方案的治疗效果;18个测试者;行数:重复数。

    7.2 双因素方差分析

    7.2.1 问题引入

    在实际应用中,指标值(因变量)往往受多个不同因素的影响。不仅这些因素会影响指标值,而且这些因素的不同水平交叉也会影响指标值。统计学中把多个因素不同水平交叉对指标值的影响称为交互作用。在多因素方差分析中,交互作用作为一个新因素来处理。 这里介绍两个因素的方差分析,亦称为双因素方差分析

    7.2.2 双因素方差分析的数据结构

    • 假设在观测指标X的试验中,有两个变化因素A和B。因素A有r个水平,记作A1 ,A2 ,…,Ar;因素B有k个水平,记作B1 ,B2 ,…,Bk;则A 与B的不同水平组合A_{i}B_{j}(i=1,2,…,r;j=1,2,…,k)共有rk个,每个 水平组合称为一个处理,每个处理作m次试验(亦可1次试验),得rkm个观测值x_{ij},双因素的有重复(无重复)观测数据表7.2.2。

       交叉项:重复观测数

    A1、B1水平下,有m个观测值。

    7.2.3 因素方差分析模型

    1. 无交互作用的双因素方差分析模型

    在双因素方差分析中,若不考虑两因素的交互作用效应,数据可采用无重复观测

       类似于 单因素方差分析

    x11...xrk:交叉水平下的观测值。

    \overline{x_{i.}}:第i行的算数平均(代表因素A的各个水平下的样本平均值)

    \overline{x_{.j}}:第j列的算数平均(代表因素B的各个水平下的样本平均值,因素B的第j个水平下 数据的算数平均);

    \overline{x}:所有数据的算数平均(总算数平均值)。

     A_{i}:第i个水平下

    在无交互作用下,分析因素A,B的不同水平对试验结果是否有显著影响,即为检验如下假设是否成立:

     检验两组假设:假设因素A下,不同水平下的均值没有差异;假设因素B...

    类似单因素方差分析数据的处理,在上述定义下,无交互作用双因素方差分析模型中的平方和分解如下。

     m=1的情况。

    SA:不同行数据之间的差异,因素A的不同水平之间的差异;SB:不同列数据之间的差异。SE:随机误差平方和。

    检验两组假设:假设因素A下,不同水平下的均值没有差异;假设因素B...   -->   构造两个检验统计量。

     无交互作用的双因素方差分析

    在Matlab中进行双因素方差分析,采用命令

    [p, table, stats] = anova2(x,reps)

    reps:试验数据(每个交叉水平下)重复次数,缺省时为1。

    % 例7.2.1
    x = [365,350,343,340,323;345,368,363,330,333;
        358,232,353,343,308;288,280,298,260,298]'; % 不转置 也行
    [p,table,stats] = anova2(x)

      此图,表格数据有误。看matlab运行图,即可。

    P值越大,越不拒绝原假设。

    2. 有交互作用的双因素方差分析模型

    在数据分析种,不一定存在交互作用,但是可以通过数据处理来识别有没有交互作用。

    交叉水平下的重复数 m。l:交叉水平下的重复数。

    \overline{x_{i.}}:第i行的算数平均(代表因素A的各个水平下的样本平均值)

    \overline{x_{.j}}:第j列的算数平均(代表因素B的各个水平下的样本平均值,因素B的第j个水平下 数据的算数平均);

    \overline{x_{ij}}:因素A、B交叉水平下的平均值。

    存在交互作用的情况下,双因素方差分析需要检验如下假设

    原假设 H03:假设不存在交互作用。

    有交互作用的双因素方差分析

     重复观测、交互作用影响

    拒绝原假设(各个水平下的均值相等):各个水平下的均值 有 显著差异。P值越小(小于α)(α一般为0.05)

    P值大,不拒绝 原假设。

    % 例7.2.2
    x = [26,19;24,20;27,23;25,22;25,21;
        20,18;17,17;22,13;21,16;17,12];
    [p,table,stats] = anova2(x,5) % 5:每个交叉水平下的重复数

    7.3 一元线性回归分析

     在应用问题研究当中,如果涉及到变量与变量之间的分析,可以借助回归分析来进行研究。

    7.3.1 回归分析的概念

    研究变量间的关系常有两种。

    • 确定性关系函数关系

    如圆面积与圆半径的关系;价格一定时,商品销售额与销售量的关系等。

    • 相关关系

    如父亲与子女身高的关系;收入水平与受教育程度间的关系等。

    变量间的相关关系不能用完全确切的函数形式表示,但在平均意义下 有一定的定量关系表达式。研究总体(总体规律)

    相关关系的类型

       不相关:无明显相关关系

    回归分析(Regression Analysis)就是研究变量间的相关关系的统计方法,是英国生物学家兼统计学家高尔顿在研究父代与子代身高关系时得到的分析方法。

    通过对客观事物中变量的大量观察或试验获得的数据,寻找隐藏在数据背后的相关关系,并给出它们的表达形式——回归函数的估计。

    回归分析主要用于研究指标的估计和预测。

    通过数据分析,得到 回归表达式(回归函数),对变量进行估计、预测。

    设变量y与x(一维或多维)间有相关关系,称x为自变量(解释变量),y为因变量(被解释变量)。

    若x为一般变量,在获得x取值后,设y 的取值为一随机变量,可表示为

                                           y = f(x) + ε

    上式称为一般回归模型,其中ε称为随机误差项,一般假设 ε~N(0, \sigma ^{2})。正态分布

    7.3.2 一元线性回归模型

     r_{xy}:反映 x组数据与y组数据的线性相关程度。

    r_{xy} 越大,线性相关程度越强。            |r_{xy}| ≤ 1              

    一元线性回归分析内容

    (1)回归参数\beta _{0},\beta _{1},\sigma ^{2}的估计

    (2)回归模型的显著性检验

    (3)回归参数的显著性检验

    1.回归参数的估计

    yi:观测值          最小二乘法(参数估计、数据拟合)             \beta _{0}+\beta _{1}x_{i} :yi的回归值

     (7.3.3) 求导式

     \overline{x} , \overline{y}:x、y数据的样本均值

    2.回归模型的显著性检验

    在模型假定下,可以证明

    对模型(7.3.2)的显著性提出假设

          H0 : 回归方程不显著,H1 : 回归方程显著

    如果回归方程显著,意味着SSE应该比较小,F值应该比较大,所以在显著水平α下,当 F\geq F_{\alpha } (1,n-2)时,拒绝原假设,认为回归方程显著。

    3.回归参数的显著性检验

     t^2 = F

    MATLAB进行回归分析的命令为 regress,其调用方式为 [b,bint,r,rint,stats] = regress(y, x) ,其输出结果为

    • b :回归方程的系数
    • bint:回归方程系数的95%置信区间
    • r: 回归方程的残差
    • rint:残差的95%置信区间
    • stats: 可决系数R^{2}、模型检验F值、模型检验P值

    7.3.3 一元线性回归分析应用

    例7.3.1 为研究销售收入与广告费用支出之间的关系,某医药管理部门随机抽取20家药品生产企业,得到它们的年销售收入和广告费用支出(万元)的数据如下表。分析销售收入与广告费用之间的关系。

    分析 由表(1)可得模型检验F值为116.3958,P值非常小,即模型是显著的;由表(2)可得模型的决定系数R^{2} = 0.866067,接近于1,说明模型拟合效果较好;由表(3)可得回归方程的系数\beta _{0} = 274.5502,\beta _{1} = 5.1308,且参数\beta _{1}检验的P值较小,显著非零,则回归方程为

    根据得到的回归方程可进行因变量y的估计和预测。

    7.4 多元线性回归分析

    研究多个变量之间相关性的常用统计方法:多元线性回归分析。

    7.4.1 多元线性回归模型

    实际应用中影响因变量变化的因素往往有多个,例如产出受各种投入要素(资本、劳动力、技术等)的影响;销售额受价格和广告费投入等的影响。      研究 多个变量 影响 因变量的情况。

    回归模型中自变量(解释变量)个数为两个及两个以上时,即为多元回归模型

    多元线性回归模型的一般形式为

     (p=1:一元线性回归模型)

    • \beta _{1}\beta _{2},...,\beta _{p} 称为 偏回归系数              \beta _{0} :辅助作用,根据实际问题分析,选择是否保留。
    • β_{i}\beta _{i} 表示假定其他变量不变,当 xi 每变动一个单位时,y 的平均变动值。 

    多元线性回归分析内容

    1. 回归参数的估计
    2. 回归方程的拟合优度
    3. 显著性检验
    4. 共线性诊断

    7.4.2 回归参数的估计

    x_{np} :第p个自变量的观测值。

    yi的值 由 自变量xi的线性回归值、随机误差 \varepsilon_{i} 的值 所构成。

    Y:因变量构成的列向量;\beta:回归参数向量;\varepsilon:随机误差项构成的向量。

     偏导数 = 0

    7.4.3 回归方程的拟合优度

    7.4.4 显著性检验

    多元线性回归分析的显著性检验包括模型的显著性检验和各偏回归系数的显著性检验。

    1.模型的显著性检验

    2. 偏回归系数的显著性检验

    关于模型的显著性检验 不拒绝 原假设 时,模型是不显著的,此时 不必做 偏回归系数的显著性检验。

    7.4.5 共线性诊断

    多元线性回归分析中,要求回归模型(7.4.1)中自变量之间线性无关。若有两个或两个以上的自变量彼此相关,称模型存在多重共线性

    多重共线性产生的问题

    (1)可能会使回归的结果造成混乱,甚至会把分析引入歧途;

    (2)可能对参数估计值的正负号产生影响,特别是各回归系数的正负号有可能同预期的正负号相反 。

    检测多重共线性的最简单的一种办法是计算模型中各对自变量之间的相关系数,并对各相关系数进行显著性检验。若有一个或多个相关系数显著,就表示模型中所用的自变量之间相关,存在着多重共线性。

    如果出现下列情况,暗示存在多重共线性。(存在多重共线性,需要对模型进行修正)

    • 模型中各对自变量之间显著相关;
    • 当模型的线性关系检验(F检验)显著时,几乎所有回归系数的t检验却不显著;
    • 回归系数的正负号与预期的相反。

    7.5 牙膏价格问题

    7.5.1 问题描述

    某大型牙膏制造企业为了更好地拓展产品市场,有效地管理库存,公司董事会要求销售部门根据市场调查,找出公司生产的牙膏销 售量与销售价格、广告投入等因素之间的关系,从而预测出在不同价格和广告费用下的销售量。表7.5.1是30个销售周期(4周为1销售周期)中收集到的资料。试根据这些数据建立一个数学模型,分析牙膏的销售量与其它因素的关系,为制定价格策略和广告投入提供决策依据。

    7.5.2 问题分析

    1.牙膏价格与销售量

    由于牙膏是小件生活必需品,对大多数顾客来说,在购买同类产品的牙膏时更多地会在意不同品牌中间的价格差异,而不是他们的 价格本身。因此在研究各个因素对销售量的影响时,用价格差代替公司销售价格更为合适。

    通过分析其他厂家牙膏价格与本公司牙膏价格差对销售量的影响关系,建立价格差与销售量的相关模型。

    2.广告费用与销售量

    通过分析广告费用对销售量的影响关系,建立广告费用与销售 量的相关模型。

    7.5.3 模型假设与符号

    实际中,由于影响牙膏销售量的因素有很多,根据问题分析和相关数据,提出假设:

    (1)假设牙膏销售量主要受价格差和广告费用影响,即其它因素对销售量的影响归入随机误差。

    (2)令 y~本公司牙膏销售量;x_{1}~其它厂家牙膏价格与本公司牙膏价格差;x_{2}~本公司广告费用。x_{1}x_{2}对y的影响、建立模型。

    7.5.4 模型建立与求解

    1.牙膏价格差对销售量影响模型

     正相关的线性关系

    2.广告费用对销售量影响模型

       勉强接受:线性关系

    建立模型:多尝试,以合理性为前提,越简单越好。

    3.牙膏价格差与广告费用对销售量影响模型

    由(7.5.1)和(7.5.2),将常数项合并,随机误差项合并,且不考虑牙膏价格差与广告费用对销售量的交叉影响。可得牙膏价格差与广告 费用对销售量影响模型

                                     

    由数据进行回归分析,见表7.5.2

                                        

    4.模型改进

     只考虑 线性关系

    由表7.5.3回归结果可得,修正可决系数为0.874,模型显著性检验的p值为0,模型是显著的。并且各回归参数均显著非0,说明模型 有效,得到牙膏价格差与广告费用对销售量影响模型为

                                                         

    7.5.5 结果分析

                                                         

    由模型(7.5.5)可知,提高本公司牙膏价格,将会减少本公司牙膏销售量,例如,广告费不变时,本公司牙膏价格比其它厂家平均价格 提高1元,估计销售量将会减少约1.468百万支。

    另一方面,一定程度上,增加广告费用将会提高销售量,但过 度增加广告费用就会增加成本。

    根据模型(7.5.5),只要给定了x_{1}x_{2},代入就可以对销售量进行估计和预测,还可以进行一定的置信度下的区间预测。如当x_{1}=0.2,x_{2}=6.5时,可以计算得到销售量的预测值约为8.379(百万支),其95%的预测区间为[7.874, 8.863]。

    在公司管理中,这个预测上限可以用来作为公司的生产和库存数量;而这个预测下限可以用来较好地把握公司的现金流,因为到时至少有7.874百万支牙膏可以有把握的卖出去,可以回来相应的销售款。

    若考虑牙膏价格差与广告费用两个因素间可能会有交互作用,可以将二者的乘积x_{1}x_{2}来表示这个作用对销售量的影响,对原来的模型进行改进,

       

    同理,可对模型7.5.6进行回归分析,研究模型的有效性和显著性(略)。

    7.6 方差分析与回归分析的SPSS实现

    数据统计分析:Matlab、R、SPSS

    7.6.1 SPSS软件概述

    1 SPSS版本与安装

    SPSS的版本每年更新,当前最新为SPSS26.0,较新版本都有中文版,这里以2013年的SPSS22.0中文版为例介绍其安装及应用。

     数学建模【SPSS 下载、安装】

    2 SPSS界面

    SPSS的主要界面 有 数据编辑窗口 和 结果输出窗口。

    SPSS软件在其基本界面上集成了数据录入、转换、检索、统计分析、作图、制表及编辑等功能;采用类似EXCEL表格的方式输入与管理数据,数据接口较为通用,能方便的从其他数据库中读入数据。

    数据编辑窗口:标题栏、菜单栏、工具栏、状态栏、数据视图、变量视图

    控制菜单图标、窗口名称、窗口控制图标、窗口控制按钮

    变量视图

    3 SPSS特点

    • (1)囊括了各种成熟的统计方法与模型,为统计分析用户提供了全方位的统计学算法,为各种研究提供了相应的统计学方法。
    • (2)提供了各种数据准备与数据整理技术。
    • (3)自由灵活的表格功能。
    • (4)各种常用的统计学图形。

    SPSS最突出的特点就是操作界面极为友好,输出结果美观漂亮。SPSS是第一个采用人机交互界面的统计软件,非常容易学习和使用。

    SPSS软件基本操作可通过点击鼠标来完成,有一定统计基础且熟悉Windows一般操作的应用者参考它的帮助系统 基本上 可以自学使用;除了数据录入及部分命令程序等少数输入工作需要使用键盘键入外,对于常见的统计分析方法完全可以通过对“菜单”、“对话框”的操作完成,无需编程。

    4 SPSS数据

    SPSS能够与常用的数据文件格式互交。                  Excel文件

    SPSS数据文件中,变量有三种的基本类型:数值型、字符型和日期型。

    SPSS的文件类型:

    (1)数据文件:拓展名为.sav

    (2)结果文件:拓展名为.spv

    (3)图形文件:拓展名为.cht

    (4)语法文件:拓展名为.sps

    7.6.2 SPSS与方差分析

    【例7.1.1、例7.2.2 Excel文件:链接:https://pan.baidu.com/s/1PLXyYCelCfOGgMPbl7T2AA   提取码:zjxs】

    1 单因素方差分析

    生成数据:1、导入数据;2、手工录入

    54条数据:因变量(血糖下降值)记为A,分组变量(3个组别)记为g。Excel表中,第一行为变量名。

       

      数据视图
    变量视图

    单因素方差分析

      

       

    多重比较:将 各个水平下的均值 进行比较。Tukey:针对重复次数一样的多重比较。显著性水平 默认 0.05。

    左边:输出列表;右边:输出结果(概括性描述)。

    表2:方差极性检验(显著性-P值:0.871)   表3:方差分析表(因子平方和、误差平方和;总平方和)

     只要P值小于0.05,就认为 是有 显著差异的。

    根据多重比较的结果,进行分类得到的分类表。

      

    均值图                      1、2之间,有显著差异;2、3无显著差异。

    2 双因素方差分析

    【例7.1.1、例7.2.2 Excel文件:链接:https://pan.baidu.com/s/1PLXyYCelCfOGgMPbl7T2AA   提取码:zjxs】 

    双因素并且考虑交互作用的方差分析:将分析数据作为因变量指标;将时段、路段两个因素 建立 两个分组变量。

    将Excel表中的数据,导入SPSS。

       

    选择 “模型”:

        

       

    绘图

      -> 点击“添加”  ->   

    事后多重比较

    选项

        

      

        

        

    7.6.3 SPSS与回归分析 

    SPSS回归分析过程

    牙膏价格问题的回归分析

       

       

          

       

    表1:自变量、因变量、标准差...描述结果;表2:相关系数矩阵表---研究共线性;

    模型汇总统计量计算 Model Summary;ANOVA:回归分析的方差分析表;

    coefficients:回归系数估计

    不考虑x2(将x2从模型中去除!)

      

    展开全文
  • Java基础知识面试题(2020最新版)

    万次阅读 多人点赞 2020-02-19 12:11:27
    Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。 jdk1.5之后的三大版本 Java SE(J2SE,Java 2 Platform Standard Edition,标准版) Java SE ...

    Java面试总结(2021优化版)已发布在个人微信公众号【技术人成长之路】,优化版首先修正了读者反馈的部分答案存在的错误,同时根据最新面试总结,删除了低频问题,添加了一些常见面试题,对文章进行了精简优化,欢迎大家关注!😊😊

    【技术人成长之路】,助力技术人成长!更多精彩文章第一时间在公众号发布哦!

    文章目录

    Java面试总结汇总,整理了包括Java基础知识,集合容器,并发编程,JVM,常用开源框架Spring,MyBatis,数据库,中间件等,包含了作为一个Java工程师在面试中需要用到或者可能用到的绝大部分知识。欢迎大家阅读,本人见识有限,写的博客难免有错误或者疏忽的地方,还望各位大佬指点,在此表示感激不尽。文章持续更新中…

    序号内容链接地址
    1Java基础知识面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104390612
    2Java集合容器面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104588551
    3Java异常面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104390689
    4并发编程面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104863992
    5JVM面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104390752
    6Spring面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104397516
    7Spring MVC面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104397427
    8Spring Boot面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104397299
    9Spring Cloud面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104397367
    10MyBatis面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/101292950
    11Redis面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/103522351
    12MySQL数据库面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104778621
    13消息中间件MQ与RabbitMQ面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104588612
    14Dubbo面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104390006
    15Linux面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104588679
    16Tomcat面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104397665
    17ZooKeeper面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104397719
    18Netty面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/104391081
    19架构设计&分布式&数据结构与算法面试题(2020最新版)https://thinkwon.blog.csdn.net/article/details/105870730

    Java概述

    何为编程

    编程就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程。

    为了使计算机能够理解人的意图,人类就必须要将需解决的问题的思路、方法、和手段通过计算机能够理解的形式告诉计算机,使得计算机能够根据人的指令一步一步去工作,完成某种特定的任务。这种人和计算机之间交流的过程就是编程。

    什么是Java

    Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程 。

    jdk1.5之后的三大版本

    • Java SE(J2SE,Java 2 Platform Standard Edition,标准版)
      Java SE 以前称为 J2SE。它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的 Java 应用程序。Java SE 包含了支持 Java Web 服务开发的类,并为Java EE和Java ME提供基础。
    • Java EE(J2EE,Java 2 Platform Enterprise Edition,企业版)
      Java EE 以前称为 J2EE。企业版本帮助开发和部署可移植、健壮、可伸缩且安全的服务器端Java 应用程序。Java EE 是在 Java SE 的基础上构建的,它提供 Web 服务、组件模型、管理和通信 API,可以用来实现企业级的面向服务体系结构(service-oriented architecture,SOA)和 Web2.0应用程序。2018年2月,Eclipse 宣布正式将 JavaEE 更名为 JakartaEE
    • Java ME(J2ME,Java 2 Platform Micro Edition,微型版)
      Java ME 以前称为 J2ME。Java ME 为在移动设备和嵌入式设备(比如手机、PDA、电视机顶盒和打印机)上运行的应用程序提供一个健壮且灵活的环境。Java ME 包括灵活的用户界面、健壮的安全模型、许多内置的网络协议以及对可以动态下载的连网和离线应用程序的丰富支持。基于 Java ME 规范的应用程序只需编写一次,就可以用于许多设备,而且可以利用每个设备的本机功能。

    JVM、JRE和JDK的关系

    JVM
    Java Virtual Machine是Java虚拟机,Java程序需要运行在虚拟机上,不同的平台有自己的虚拟机,因此Java语言可以实现跨平台。

    JRE
    Java Runtime Environment包括Java虚拟机和Java程序所需的核心类库等。核心类库主要是java.lang包:包含了运行Java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省加载这个包

    如果想要运行一个开发好的Java程序,计算机中只需要安装JRE即可。

    JDK
    Java Development Kit是提供给Java开发人员使用的,其中包含了Java的开发工具,也包括了JRE。所以安装了JDK,就无需再单独安装JRE了。其中的开发工具:编译工具(javac.exe),打包工具(jar.exe)等

    JVM&JRE&JDK关系图

    什么是跨平台性?原理是什么

    所谓跨平台性,是指java语言编写的程序,一次编译后,可以在多个系统平台上运行。

    实现原理:Java程序是通过java虚拟机在系统平台上运行的,只要该系统可以安装相应的java虚拟机,该系统就可以运行java程序。

    Java语言有哪些特点

    简单易学(Java语言的语法与C语言和C++语言很接近)

    面向对象(封装,继承,多态)

    平台无关性(Java虚拟机实现平台无关性)

    支持网络编程并且很方便(Java语言诞生本身就是为简化网络编程设计的)

    支持多线程(多线程机制使应用程序在同一时间并行执行多项任)

    健壮性(Java语言的强类型机制、异常处理、垃圾的自动收集等)

    安全性

    什么是字节码?采用字节码的最大好处是什么

    字节码:Java源代码经过虚拟机编译器编译后产生的文件(即扩展为.class的文件),它不面向任何特定的处理器,只面向虚拟机。

    采用字节码的好处

    Java语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以Java程序运行时比较高效,而且,由于字节码并不专对一种特定的机器,因此,Java程序无须重新编译便可在多种不同的计算机上运行。

    先看下java中的编译器和解释器

    Java中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟机器。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。在Java中,这种供虚拟机理解的代码叫做字节码(即扩展为.class的文件),它不面向任何特定的处理器,只面向虚拟机。每一种平台的解释器是不同的,但是实现的虚拟机是相同的。Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行,这就是上面提到的Java的特点的编译与解释并存的解释。

    Java源代码---->编译器---->jvm可执行的Java字节码(即虚拟指令)---->jvm---->jvm中解释器----->机器可执行的二进制机器码---->程序运行。
    

    什么是Java程序的主类?应用程序和小程序的主类有何不同?

    一个程序中可以有多个类,但只能有一个类是主类。在Java应用程序中,这个主类是指包含main()方法的类。而在Java小程序中,这个主类是一个继承自系统类JApplet或Applet的子类。应用程序的主类不一定要求是public类,但小程序的主类要求必须是public类。主类是Java程序执行的入口点。

    Java应用程序与小程序之间有那些差别?

    简单说应用程序是从主线程启动(也就是main()方法)。applet小程序没有main方法,主要是嵌在浏览器页面上运行(调用init()线程或者run()来启动),嵌入浏览器这点跟flash的小游戏类似。

    Java和C++的区别

    我知道很多人没学过C++,但是面试官就是没事喜欢拿咱们Java和C++比呀!没办法!!!就算没学过C++,也要记下来!

    • 都是面向对象的语言,都支持封装、继承和多态
    • Java不提供指针来直接访问内存,程序内存更加安全
    • Java的类是单继承的,C++支持多重继承;虽然Java的类不可以多继承,但是接口可以多继承。
    • Java有自动内存管理机制,不需要程序员手动释放无用内存

    Oracle JDK 和 OpenJDK 的对比

    1. Oracle JDK版本将每三年发布一次,而OpenJDK版本每三个月发布一次;

    2. OpenJDK 是一个参考模型并且是完全开源的,而Oracle JDK是OpenJDK的一个实现,并不是完全开源的;

    3. Oracle JDK 比 OpenJDK 更稳定。OpenJDK和Oracle JDK的代码几乎相同,但Oracle JDK有更多的类和一些错误修复。因此,如果您想开发企业/商业软件,我建议您选择Oracle JDK,因为它经过了彻底的测试和稳定。某些情况下,有些人提到在使用OpenJDK 可能会遇到了许多应用程序崩溃的问题,但是,只需切换到Oracle JDK就可以解决问题;

    4. 在响应性和JVM性能方面,Oracle JDK与OpenJDK相比提供了更好的性能;

    5. Oracle JDK不会为即将发布的版本提供长期支持,用户每次都必须通过更新到最新版本获得支持来获取最新版本;

    6. Oracle JDK根据二进制代码许可协议获得许可,而OpenJDK根据GPL v2许可获得许可。

    基础语法

    数据类型

    Java有哪些数据类型

    定义:Java语言是强类型语言,对于每一种数据都定义了明确的具体的数据类型,在内存中分配了不同大小的内存空间。

    分类

    • 基本数据类型
      • 数值型
        • 整数类型(byte,short,int,long)
        • 浮点类型(float,double)
      • 字符型(char)
      • 布尔型(boolean)
    • 引用数据类型
      • 类(class)
      • 接口(interface)
      • 数组([])

    Java基本数据类型图

    switch 是否能作用在 byte 上,是否能作用在 long 上,是否能作用在 String 上

    在 Java 5 以前,switch(expr)中,expr 只能是 byte、short、char、int。从 Java5 开始,Java 中引入了枚举类型,expr 也可以是 enum 类型,从 Java 7 开始,expr 还可以是字符串(String),但是长整型(long)在目前所有的版本中都是不可以的。

    用最有效率的方法计算 2 乘以 8

    2 << 3(左移 3 位相当于乘以 2 的 3 次方,右移 3 位相当于除以 2 的 3 次方)。

    Math.round(11.5) 等于多少?Math.round(-11.5)等于多少

    Math.round(11.5)的返回值是 12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加 0.5 然后进行下取整。

    float f=3.4;是否正确

    不正确。3.4 是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成 float f =3.4F;。

    short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗

    对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int型,需要强制转换类型才能赋值给 short 型。

    而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short(s1 + 1);其中有隐含的强制类型转换。

    编码

    Java语言采用何种编码方案?有何特点?

    Java语言采用Unicode编码标准,Unicode(标准码),它为每个字符制订了一个唯一的数值,因此在任何的语言,平台,程序都可以放心的使用。

    注释

    什么Java注释

    定义:用于解释说明程序的文字

    分类

    • 单行注释
      格式: // 注释文字
    • 多行注释
      格式: /* 注释文字 */
    • 文档注释
      格式:/** 注释文字 */

    作用

    在程序中,尤其是复杂的程序中,适当地加入注释可以增加程序的可读性,有利于程序的修改、调试和交流。注释的内容在程序编译的时候会被忽视,不会产生目标代码,注释的部分不会对程序的执行结果产生任何影响。

    注意事项:多行和文档注释都不能嵌套使用。

    访问修饰符

    访问修饰符 public,private,protected,以及不写(默认)时的区别

    定义:Java中,可以使用访问修饰符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。

    分类

    private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
    default (即缺省,什么也不写,不使用任何关键字): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
    protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
    public : 对所有类可见。使用对象:类、接口、变量、方法

    访问修饰符图

    运算符

    &和&&的区别

    &运算符有两种用法:(1)按位与;(2)逻辑与。

    &&运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true 整个表达式的值才是 true。&&之所以称为短路运算,是因为如果&&左边的表达式的值是 false,右边的表达式会被直接短路掉,不会进行运算。

    注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。

    关键字

    Java 有没有 goto

    goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。

    final 有什么用?

    用于修饰类、属性和方法;

    • 被final修饰的类不可以被继承
    • 被final修饰的方法不可以被重写
    • 被final修饰的变量不可以被改变,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的

    final finally finalize区别

    • final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表
      示该变量是一个常量不能被重新赋值。
    • finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块
      中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
    • finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调
      用,当我们调用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的
      最后判断。

    this关键字的用法

    this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针。

    this的用法在java中大体可以分为3种:

    1.普通的直接引用,this相当于是指向当前对象本身。

    2.形参与成员名字重名,用this来区分:

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    

    3.引用本类的构造函数

    class Person{
        private String name;
        private int age;
        
        public Person() {
        }
     
        public Person(String name) {
            this.name = name;
        }
        public Person(String name, int age) {
            this(name);
            this.age = age;
        }
    }
    

    super关键字的用法

    super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类。

    super也有三种用法:

    1.普通的直接引用

    与this类似,super相当于是指向当前对象的父类的引用,这样就可以用super.xxx来引用父类的成员。

    2.子类中的成员变量或方法与父类中的成员变量或方法同名时,用super进行区分

    class Person{
        protected String name;
     
        public Person(String name) {
            this.name = name;
        }
     
    }
     
    class Student extends Person{
        private String name;
     
        public Student(String name, String name1) {
            super(name);
            this.name = name1;
        }
     
        public void getInfo(){
            System.out.println(this.name);      //Child
            System.out.println(super.name);     //Father
        }
     
    }
    
    public class Test {
        public static void main(String[] args) {
           Student s1 = new Student("Father","Child");
           s1.getInfo();
     
        }
    }
    

    3.引用父类构造函数

    3、引用父类构造函数

    • super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)。
    • this(参数):调用本类中另一种形式的构造函数(应该为构造函数中的第一条语句)。

    this与super的区别

    • super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名 super.成员函数据名(实参)
    • this:它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
    • super()和this()类似,区别是,super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。
    • super()和this()均需放在构造方法内第一行。
    • 尽管可以用this调用一个构造器,但却不能调用两个。
    • this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。
    • this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
    • 从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

    static存在的主要意义

    static的主要意义是在于创建独立于具体对象的域变量或者方法。以致于即使没有创建对象,也能使用属性和调用方法

    static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。

    为什么说static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次。因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。

    static的独特之处

    1、被static修饰的变量或者方法是独立于该类的任何对象,也就是说,这些变量和方法不属于任何一个实例对象,而是被类的实例对象所共享

    怎么理解 “被类的实例对象所共享” 这句话呢?就是说,一个类的静态成员,它是属于大伙的【大伙指的是这个类的多个对象实例,我们都知道一个类可以创建多个实例!】,所有的类对象共享的,不像成员变量是自个的【自个指的是这个类的单个实例对象】…我觉得我已经讲的很通俗了,你明白了咩?

    2、在该类被第一次加载的时候,就会去加载被static修饰的部分,而且只在类第一次使用时加载并进行初始化,注意这是第一次用就要初始化,后面根据需要是可以再次赋值的。

    3、static变量值在类加载的时候分配空间,以后创建类对象的时候不会重新分配。赋值的话,是可以任意赋值的!

    4、被static修饰的变量或者方法是优先于对象存在的,也就是说当一个类加载完毕之后,即便没有创建对象,也可以去访问。

    static应用场景

    因为static是被类的实例对象所共享,因此如果某个成员变量是被所有对象所共享的,那么这个成员变量就应该定义为静态变量

    因此比较常见的static应用场景有:

    1、修饰成员变量 2、修饰成员方法 3、静态代码块 4、修饰类【只能修饰内部类也就是静态内部类】 5、静态导包

    static注意事项

    1、静态只能访问静态。 2、非静态既可以访问非静态的,也可以访问静态的。

    流程控制语句

    break ,continue ,return 的区别及作用

    break 跳出总上一层循环,不再执行循环(结束当前的循环体)

    continue 跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)

    return 程序返回,不再执行下面的代码(结束当前的方法 直接返回)

    在 Java 中,如何跳出当前的多重嵌套循环

    在Java中,要想跳出多重循环,可以在外面的循环语句前定义一个标号,然后在里层循环体的代码中使用带有标号的break 语句,即可跳出外层循环。例如:

    public static void main(String[] args) {
        ok:
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                System.out.println("i=" + i + ",j=" + j);
                if (j == 5) {
                    break ok;
                }
    
            }
        }
    }
    

    面向对象

    面向对象概述

    面向对象和面向过程的区别

    面向过程

    优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。

    缺点:没有面向对象易维护、易复用、易扩展

    面向对象

    优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护

    缺点:性能比面向过程低

    面向过程是具体化的,流程化的,解决一个问题,你需要一步一步的分析,一步一步的实现。

    面向对象是模型化的,你只需抽象出一个类,这是一个封闭的盒子,在这里你拥有数据也拥有解决问题的方法。需要什么功能直接使用就可以了,不必去一步一步的实现,至于这个功能是如何实现的,管我们什么事?我们会用就可以了。

    面向对象的底层其实还是面向过程,把面向过程抽象成类,然后封装,方便我们使用的就是面向对象了。

    面向对象三大特性

    面向对象的特征有哪些方面

    面向对象的特征主要有以下几个方面

    抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。

    封装

    封装把一个对象的属性私有化,同时提供一些可以被外界访问的属性的方法,如果属性不想被外界访问,我们大可不必提供方法给外界访问。但是如果一个类没有提供给外界访问的方法,那么这个类也没有什么意义了。

    继承

    继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承我们能够非常方便地复用以前的代码。

    关于继承如下 3 点请记住:

    1. 子类拥有父类非 private 的属性和方法。

    2. 子类可以拥有自己属性和方法,即子类可以对父类进行扩展。

    3. 子类可以用自己的方式实现父类的方法。(以后介绍)。

    多态

    所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。

    在Java中有两种形式可以实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并覆盖接口中同一方法)。

    其中Java 面向对象编程三大特性:封装 继承 多态

    封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性。

    继承:继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。通过使用继承可以提高代码复用性。继承是多态的前提。

    关于继承如下 3 点请记住

    1. 子类拥有父类非 private 的属性和方法。

    2. 子类可以拥有自己属性和方法,即子类可以对父类进行扩展。

    3. 子类可以用自己的方式实现父类的方法。

    多态性:父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性。

    在Java中有两种形式可以实现多态:继承(多个子类对同一方法的重写)和接口(实现接口并覆盖接口中同一方法)。

    方法重载(overload)实现的是编译时的多态性(也称为前绑定),而方法重写(override)实现的是运行时的多态性(也称为后绑定)。

    一个引用变量到底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。运行时的多态是面向对象最精髓的东西,要实现多态需要做两件事:

    • 方法重写(子类继承父类并重写父类中已有的或抽象的方法);
    • 对象造型(用父类型引用子类型对象,这样同样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为)。

    什么是多态机制?Java语言是如何实现多态的?

    所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

    多态分为编译时多态和运行时多态。其中编辑时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的函数,通过编辑之后会变成两个不同的函数,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是我们所说的多态性。

    多态的实现

    Java实现多态有三个必要条件:继承、重写、向上转型。

    继承:在多态中必须存在有继承关系的子类和父类。

    重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

    向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。

    只有满足了上述三个条件,我们才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。

    对于Java而言,它多态的实现机制遵循一个原则:当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。

    面向对象五大基本原则是什么(可选)

    • 单一职责原则SRP(Single Responsibility Principle)
      类的功能要单一,不能包罗万象,跟杂货铺似的。
    • 开放封闭原则OCP(Open-Close Principle)
      一个模块对于拓展是开放的,对于修改是封闭的,想要增加功能热烈欢迎,想要修改,哼,一万个不乐意。
    • 里式替换原则LSP(the Liskov Substitution Principle LSP)
      子类可以替换父类出现在父类能够出现的任何地方。比如你能代表你爸去你姥姥家干活。哈哈~~
    • 依赖倒置原则DIP(the Dependency Inversion Principle DIP)
      高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象。就是你出国要说你是中国人,而不能说你是哪个村子的。比如说中国人是抽象的,下面有具体的xx省,xx市,xx县。你要依赖的抽象是中国人,而不是你是xx村的。
    • 接口分离原则ISP(the Interface Segregation Principle ISP)
      设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好。就比如一个手机拥有打电话,看视频,玩游戏等功能,把这几个功能拆分成不同的接口,比在一个接口里要好的多。

    类与接口

    抽象类和接口的对比

    抽象类是用来捕捉子类的通用特性的。接口是抽象方法的集合。

    从设计层面来说,抽象类是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。

    相同点

    • 接口和抽象类都不能实例化
    • 都位于继承的顶端,用于被其他实现或继承
    • 都包含抽象方法,其子类都必须覆写这些抽象方法

    不同点

    参数抽象类接口
    声明抽象类使用abstract关键字声明接口使用interface关键字声明
    实现子类使用extends关键字来继承抽象类。如果子类不是抽象类的话,它需要提供抽象类中所有声明的方法的实现子类使用implements关键字来实现接口。它需要提供接口中所有声明的方法的实现
    构造器抽象类可以有构造器接口不能有构造器
    访问修饰符抽象类中的方法可以是任意访问修饰符接口方法默认修饰符是public。并且不允许定义为 private 或者 protected
    多继承一个类最多只能继承一个抽象类一个类可以实现多个接口
    字段声明抽象类的字段声明可以是任意的接口的字段默认都是 static 和 final 的

    备注:Java8中接口中引入默认方法和静态方法,以此来减少抽象类和接口之间的差异。

    现在,我们可以为接口提供默认实现的方法了,并且不用强制子类来实现它。

    接口和抽象类各有优缺点,在接口和抽象类的选择上,必须遵守这样一个原则:

    • 行为模型应该总是通过接口而不是抽象类定义,所以通常是优先选用接口,尽量少用抽象类。
    • 选择抽象类的时候通常是如下情况:需要定义子类的行为,又要为子类提供通用的功能。

    普通类和抽象类有哪些区别?

    • 普通类不能包含抽象方法,抽象类可以包含抽象方法。
    • 抽象类不能直接实例化,普通类可以直接实例化。

    抽象类能使用 final 修饰吗?

    不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类

    创建一个对象用什么关键字?对象实例与对象引用有何不同?

    new关键字,new创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。一个对象引用可以指向0个或1个对象(一根绳子可以不系气球,也可以系一个气球);一个对象可以有n个引用指向它(可以用n条绳子系住一个气球)

    变量与方法

    成员变量与局部变量的区别有哪些

    变量:在程序执行的过程中,在某个范围内其值可以发生改变的量。从本质上讲,变量其实是内存中的一小块区域

    成员变量:方法外部,类内部定义的变量

    局部变量:类的方法中的变量。

    成员变量和局部变量的区别

    作用域

    成员变量:针对整个类有效。
    局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)

    存储位置

    成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。
    局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。当方法调用完,或者语句结束后,就自动释放。

    生命周期

    成员变量:随着对象的创建而存在,随着对象的消失而消失
    局部变量:当方法调用完,或者语句结束后,就自动释放。

    初始值

    成员变量:有默认初始值。

    局部变量:没有默认初始值,使用前必须赋值。

    使用原则

    在使用变量时需要遵循的原则为:就近原则
    首先在局部范围找,有就使用;接着在成员位置找。

    在Java中定义一个不做事且没有参数的构造方法的作用

    Java程序在执行子类的构造方法之前,如果没有用super()来调用父类特定的构造方法,则会调用父类中“没有参数的构造方法”。因此,如果父类中只定义了有参数的构造方法,而在子类的构造方法中又没有用super()来调用父类中特定的构造方法,则编译时将发生错误,因为Java程序在父类中找不到没有参数的构造方法可供执行。解决办法是在父类里加上一个不做事且没有参数的构造方法。

    在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是?

    帮助子类做初始化工作。

    一个类的构造方法的作用是什么?若一个类没有声明构造方法,改程序能正确执行吗?为什么?

    主要作用是完成对类对象的初始化工作。可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。

    构造方法有哪些特性?

    名字与类名相同;

    没有返回值,但不能用void声明构造函数;

    生成类的对象时自动执行,无需调用。

    静态变量和实例变量区别

    静态变量: 静态变量由于不属于任何实例对象,属于类的,所以在内存中只会有一份,在类的加载过程中,JVM只为静态变量分配一次内存空间。

    实例变量: 每次创建对象,都会为每个对象分配成员变量内存空间,实例变量是属于实例对象的,在内存中,创建几次对象,就有几份成员变量。

    静态变量与普通变量区别

    static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。

    还有一点就是static成员变量的初始化顺序按照定义的顺序进行初始化。

    静态方法和实例方法有何不同?

    静态方法和实例方法的区别主要体现在两个方面:

    1. 在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。
    2. 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制

    在一个静态方法内调用一个非静态成员为什么是非法的?

    由于静态方法可以不通过对象进行调用,因此在静态方法里,不能调用其他非静态变量,也不可以访问非静态变量成员。

    什么是方法的返回值?返回值的作用是什么?

    方法的返回值是指我们获取到的某个方法体中的代码执行后产生的结果!(前提是该方法可能产生结果)。返回值的作用:接收出结果,使得它可以用于其他的操作!

    内部类

    什么是内部类?

    在Java中,可以将一个类的定义放在另外一个类的定义内部,这就是内部类。内部类本身就是类的一个属性,与其他属性定义方式一致。

    内部类的分类有哪些

    内部类可以分为四种:成员内部类、局部内部类、匿名内部类和静态内部类

    静态内部类

    定义在类内部的静态类,就是静态内部类。

    public class Outer {
    
        private static int radius = 1;
    
        static class StaticInner {
            public void visit() {
                System.out.println("visit outer static  variable:" + radius);
            }
        }
    }
    

    静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量;静态内部类的创建方式,new 外部类.静态内部类(),如下:

    Outer.StaticInner inner = new Outer.StaticInner();
    inner.visit();
    
    成员内部类

    定义在类内部,成员位置上的非静态类,就是成员内部类。

    public class Outer {
    
        private static  int radius = 1;
        private int count =2;
        
         class Inner {
            public void visit() {
                System.out.println("visit outer static  variable:" + radius);
                System.out.println("visit outer   variable:" + count);
            }
        }
    }
    

    成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有。成员内部类依赖于外部类的实例,它的创建方式外部类实例.new 内部类(),如下:

    Outer outer = new Outer();
    Outer.Inner inner = outer.new Inner();
    inner.visit();
    
    局部内部类

    定义在方法中的内部类,就是局部内部类。

    public class Outer {
    
        private  int out_a = 1;
        private static int STATIC_b = 2;
    
        public void testFunctionClass(){
            int inner_c =3;
            class Inner {
                private void fun(){
                    System.out.println(out_a);
                    System.out.println(STATIC_b);
                    System.out.println(inner_c);
                }
            }
            Inner  inner = new Inner();
            inner.fun();
        }
        public static void testStaticFunctionClass(){
            int d =3;
            class Inner {
                private void fun(){
                    // System.out.println(out_a); 编译错误,定义在静态方法中的局部类不可以访问外部类的实例变量
                    System.out.println(STATIC_b);
                    System.out.println(d);
                }
            }
            Inner  inner = new Inner();
            inner.fun();
        }
    }
    

    定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。局部内部类的创建方式,在对应方法内,new 内部类(),如下:

     public static void testStaticFunctionClass(){
        class Inner {
        }
        Inner  inner = new Inner();
     }
    
    匿名内部类

    匿名内部类就是没有名字的内部类,日常开发中使用的比较多。

    public class Outer {
    
        private void test(final int i) {
            new Service() {
                public void method() {
                    for (int j = 0; j < i; j++) {
                        System.out.println("匿名内部类" );
                    }
                }
            }.method();
        }
     }
     //匿名内部类必须继承或实现一个已有的接口 
     interface Service{
        void method();
    }
    

    除了没有名字,匿名内部类还有以下特点:

    • 匿名内部类必须继承一个抽象类或者实现一个接口。
    • 匿名内部类不能定义任何静态成员和静态方法。
    • 当所在的方法的形参需要被匿名内部类使用时,必须声明为 final。
    • 匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

    匿名内部类创建方式:

    new/接口{ 
      //匿名内部类实现部分
    }
    

    内部类的优点

    我们为什么要使用内部类呢?因为它有以下优点:

    • 一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
    • 内部类不为同一包的其他类所见,具有很好的封装性;
    • 内部类有效实现了“多重继承”,优化 java 单继承的缺陷。
    • 匿名内部类可以很方便的定义回调。

    内部类有哪些应用场景

    1. 一些多算法场合
    2. 解决一些非面向对象的语句块。
    3. 适当使用内部类,使得代码更加灵活和富有扩展性。
    4. 当某个类除了它的外部类,不再被其他的类使用时。

    局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上final?

    局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上final呢?它内部原理是什么呢?

    先看这段代码:

    public class Outer {
    
        void outMethod(){
            final int a =10;
            class Inner {
                void innerMethod(){
                    System.out.println(a);
                }
    
            }
        }
    }
    

    以上例子,为什么要加final呢?是因为生命周期不一致, 局部变量直接存储在栈中,当方法执行结束后,非final的局部变量就被销毁。而局部内部类对局部变量的引用依然存在,如果局部内部类要调用局部变量时,就会出错。加了final,可以确保局部内部类使用的变量与外层的局部变量区分开,解决了这个问题。

    内部类相关,看程序说出运行结果

    public class Outer {
        private int age = 12;
    
        class Inner {
            private int age = 13;
            public void print() {
                int age = 14;
                System.out.println("局部变量:" + age);
                System.out.println("内部类变量:" + this.age);
                System.out.println("外部类变量:" + Outer.this.age);
            }
        }
    
        public static void main(String[] args) {
            Outer.Inner in = new Outer().new Inner();
            in.print();
        }
    
    }
    

    运行结果:

    局部变量:14
    内部类变量:13
    外部类变量:12
    

    重写与重载

    构造器(constructor)是否可被重写(override)

    构造器不能被继承,因此不能被重写,但可以被重载。

    重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?

    方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。

    重载:发生在同一个类中,方法名相同参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和访问修饰符无关,即重载的方法不能根据返回类型进行区分

    重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类(里氏代换原则);如果父类方法访问修饰符为private则子类中就不是重写。

    对象相等判断

    == 和 equals 的区别是什么

    == : 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数据类型 == 比较的是值,引用数据类型 == 比较的是内存地址)

    equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:

    情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。

    情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象的内容相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。

    举个例子:

    public class test1 {
        public static void main(String[] args) {
            String a = new String("ab"); // a 为一个引用
            String b = new String("ab"); // b为另一个引用,对象的内容一样
            String aa = "ab"; // 放在常量池中
            String bb = "ab"; // 从常量池中查找
            if (aa == bb) // true
                System.out.println("aa==bb");
            if (a == b) // false,非同一对象
                System.out.println("a==b");
            if (a.equals(b)) // true
                System.out.println("aEQb");
            if (42 == 42.0) { // true
                System.out.println("true");
            }
        }
    }
    

    说明:

    • String中的equals方法是被重写过的,因为object的equals方法是比较的对象的内存地址,而String的equals方法比较的是对象的值。
    • 当创建String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个String对象。

    hashCode 与 equals (重要)

    HashSet如何检查重复

    两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗?

    hashCode和equals方法的关系

    面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?”

    hashCode()介绍

    hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode()函数。

    散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利用到了散列码!(可以快速找到所需要的对象)

    为什么要有 hashCode

    我们以“HashSet 如何检查重复”为例子来说明为什么要有 hashCode

    当你把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相符的hashcode,HashSet会假设对象没有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。(摘自我的Java启蒙书《Head first java》第二版)。这样我们就大大减少了 equals 的次数,相应就大大提高了执行速度。

    hashCode()与equals()的相关规定

    如果两个对象相等,则hashcode一定也是相同的

    两个对象相等,对两个对象分别调用equals方法都返回true

    两个对象有相同的hashcode值,它们也不一定是相等的

    因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖

    hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)

    对象的相等与指向他们的引用相等,两者有什么不同?

    对象的相等 比的是内存中存放的内容是否相等而 引用相等 比较的是他们指向的内存地址是否相等。

    值传递

    当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递

    是值传递。Java 语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的

    为什么 Java 中只有值传递

    首先回顾一下在程序设计语言中有关将参数传递给方法(或函数)的一些专业术语。按值调用(call by value)表示方法接收的是调用者提供的值,而按引用调用(call by reference)表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。 它用来描述各种程序设计语言(不只是Java)中方法参数传递方式。

    Java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,也就是说,方法不能修改传递给它的任何参数变量的内容。

    下面通过 3 个例子来给大家说明

    example 1

    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 20;
    
        swap(num1, num2);
    
        System.out.println("num1 = " + num1);
        System.out.println("num2 = " + num2);
    }
    
    public static void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
    
        System.out.println("a = " + a);
        System.out.println("b = " + b);
    }
    

    结果

    a = 20
    b = 10
    num1 = 10
    num2 = 20
    

    解析

    img

    在swap方法中,a、b的值进行交换,并不会影响到 num1、num2。因为,a、b中的值,只是从 num1、num2 的复制过来的。也就是说,a、b相当于num1、num2 的副本,副本的内容无论怎么修改,都不会影响到原件本身。

    通过上面例子,我们已经知道了一个方法不能修改一个基本数据类型的参数,而对象引用作为参数就不一样,请看 example2.

    example 2

        public static void main(String[] args) {
            int[] arr = { 1, 2, 3, 4, 5 };
            System.out.println(arr[0]);
            change(arr);
            System.out.println(arr[0]);
        }
    
        public static void change(int[] array) {
            // 将数组的第一个元素变为0
            array[0] = 0;
        }
    

    结果

    1
    0
    

    解析

    img

    array 被初始化 arr 的拷贝也就是一个对象的引用,也就是说 array 和 arr 指向的时同一个数组对象。 因此,外部对引用对象的改变会反映到所对应的对象上。

    通过 example2 我们已经看到,实现一个改变对象参数状态的方法并不是一件难事。理由很简单,方法得到的是对象引用的拷贝,对象引用及其他的拷贝同时引用同一个对象。

    很多程序设计语言(特别是,C++和Pascal)提供了两种参数传递的方式:值调用和引用调用。有些程序员(甚至本书的作者)认为Java程序设计语言对对象采用的是引用调用,实际上,这种理解是不对的。由于这种误解具有一定的普遍性,所以下面给出一个反例来详细地阐述一下这个问题。

    example 3

    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Student s1 = new Student("小张");
            Student s2 = new Student("小李");
            Test.swap(s1, s2);
            System.out.println("s1:" + s1.getName());
            System.out.println("s2:" + s2.getName());
        }
    
        public static void swap(Student x, Student y) {
            Student temp = x;
            x = y;
            y = temp;
            System.out.println("x:" + x.getName());
            System.out.println("y:" + y.getName());
        }
    }
    

    结果

    x:小李
    y:小张
    s1:小张
    s2:小李
    

    解析

    交换之前:

    img

    交换之后:

    img

    通过上面两张图可以很清晰的看出: 方法并没有改变存储在变量 s1 和 s2 中的对象引用。swap方法的参数x和y被初始化为两个对象引用的拷贝,这个方法交换的是这两个拷贝

    总结

    Java程序设计语言对对象采用的不是引用调用,实际上,对象引用是按值传递的。

    下面再总结一下Java中方法参数的使用情况:

    • 一个方法不能修改一个基本数据类型的参数(即数值型或布尔型》
    • 一个方法可以改变一个对象参数的状态。
    • 一个方法不能让对象参数引用一个新的对象。

    值传递和引用传递有什么区别

    值传递:指的是在方法调用时,传递的参数是按值的拷贝传递,传递的是值的拷贝,也就是说传递后就互不相关了。

    引用传递:指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。

    Java包

    JDK 中常用的包有哪些

    • java.lang:这个是系统的基础类;
    • java.io:这里面是所有输入输出有关的类,比如文件操作等;
    • java.nio:为了完善 io 包中的功能,提高 io 包中性能而写的一个新包;
    • java.net:这里面是与网络有关的类;
    • java.util:这个是系统辅助类,特别是集合类;
    • java.sql:这个是数据库操作的类。

    import java和javax有什么区别

    刚开始的时候 JavaAPI 所必需的包是 java 开头的包,javax 当时只是扩展 API 包来说使用。然而随着时间的推移,javax 逐渐的扩展成为 Java API 的组成部分。但是,将扩展从 javax 包移动到 java 包将是太麻烦了,最终会破坏一堆现有的代码。因此,最终决定 javax 包将成为标准API的一部分。

    所以,实际上java和javax没有区别。这都是一个名字。

    IO流

    java 中 IO 流分为几种?

    • 按照流的流向分,可以分为输入流和输出流;
    • 按照操作单元划分,可以划分为字节流和字符流;
    • 按照流的角色划分为节点流和处理流。

    Java Io流共涉及40多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系, Java I0流的40多个类都是从如下4个抽象类基类中派生出来的。

    • InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
    • OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

    按操作方式分类结构图:

    IO-操作方式分类

    按操作对象分类结构图:

    IO-操作对象分类

    BIO,NIO,AIO 有什么区别?

    简答

    • BIO:Block IO 同步阻塞式 IO,就是我们平常使用的传统 IO,它的特点是模式简单使用方便,并发处理能力低。
    • NIO:Non IO 同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。
    • AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。

    详细回答

    • BIO (Blocking I/O): 同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的 I/O 并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。但是,当面对十万甚至百万级连接的时候,传统的 BIO 模型是无能为力的。因此,我们需要一种更高效的 I/O 处理模型来应对更高的并发量。
    • NIO (New I/O): NIO是一种同步非阻塞的I/O模型,在Java 1.4 中引入了NIO框架,对应 java.nio 包,提供了 Channel , Selector,Buffer等抽象。NIO中的N可以理解为Non-blocking,不单纯是New。它支持面向缓冲的,基于通道的I/O操作方法。 NIO提供了与传统BIO模型中的 SocketServerSocket 相对应的 SocketChannelServerSocketChannel 两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就像传统中的支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式正好与之相反。对于低负载、低并发的应用程序,可以使用同步阻塞I/O来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发
    • AIO (Asynchronous I/O): AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改进版 NIO 2,它是异步非阻塞的IO模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。AIO 是异步IO的缩写,虽然 NIO 在网络操作中,提供了非阻塞的方法,但是 NIO 的 IO 行为还是同步的。对于 NIO 来说,我们的业务线程是在 IO 操作准备好时,得到通知,接着就由这个线程自行进行 IO 操作,IO操作本身是同步的。查阅网上相关资料,我发现就目前来说 AIO 的应用还不是很广泛,Netty 之前也尝试使用过 AIO,不过又放弃了。

    Files的常用方法都有哪些?

    • Files. exists():检测文件路径是否存在。
    • Files. createFile():创建文件。
    • Files. createDirectory():创建文件夹。
    • Files. delete():删除一个文件或目录。
    • Files. copy():复制文件。
    • Files. move():移动文件。
    • Files. size():查看文件个数。
    • Files. read():读取文件。
    • Files. write():写入文件。

    反射

    什么是反射机制?

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    静态编译和动态编译

    • **静态编译:**在编译时确定类型,绑定对象
    • **动态编译:**运行时确定类型,绑定对象

    反射机制优缺点

    • 优点: 运行期类型的判断,动态加载类,提高代码灵活度。
    • 缺点: 性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的java代码要慢很多。

    反射机制的应用场景有哪些?

    反射是框架设计的灵魂。

    在我们平时的项目开发过程中,基本上很少会直接使用到反射机制,但这不能说明反射机制没有用,实际上有很多设计、开发都与反射机制有关,例如模块化的开发,通过反射去调用对应的字节码;动态代理设计模式也采用了反射机制,还有我们日常使用的 Spring/Hibernate 等框架也大量使用到了反射机制。

    举例:①我们在使用JDBC连接数据库时使用Class.forName()通过反射加载数据库的驱动程序;②Spring框架也用到很多反射机制,最经典的就是xml的配置模式。Spring 通过 XML 配置模式装载 Bean 的过程:1) 将程序内所有 XML 或 Properties 配置文件加载入内存中; 2)Java类里面解析xml或properties里面的内容,得到对应实体类的字节码字符串以及相关的属性信息; 3)使用反射机制,根据这个字符串获得某个类的Class实例; 4)动态配置实例的属性

    Java获取反射的三种方法

    1.通过new对象实现反射机制 2.通过路径实现反射机制 3.通过类名实现反射机制

    public class Student {
        private int id;
        String name;
        protected boolean sex;
        public float score;
    }
    
    public class Get {
        //获取反射机制三种方式
        public static void main(String[] args) throws ClassNotFoundException {
            //方式一(通过建立对象)
            Student stu = new Student();
            Class classobj1 = stu.getClass();
            System.out.println(classobj1.getName());
            //方式二(所在通过路径-相对路径)
            Class classobj2 = Class.forName("fanshe.Student");
            System.out.println(classobj2.getName());
            //方式三(通过类名)
            Class classobj3 = Student.class;
            System.out.println(classobj3.getName());
        }
    }
    

    网络编程

    网络编程的面试题可以查看我的这篇文章重学TCP/IP协议和三次握手四次挥手,内容不仅包括TCP/IP协议和三次握手四次挥手的知识,还包括计算机网络体系结构,HTTP协议,get请求和post请求区别,session和cookie的区别等,欢迎大家阅读。

    常用API

    String相关

    字符型常量和字符串常量的区别

    1. 形式上: 字符常量是单引号引起的一个字符 字符串常量是双引号引起的若干个字符
    2. 含义上: 字符常量相当于一个整形值(ASCII值),可以参加表达式运算 字符串常量代表一个地址值(该字符串在内存中存放位置)
    3. 占内存大小 字符常量只占两个字节 字符串常量占若干个字节(至少一个字符结束标志)

    什么是字符串常量池?

    字符串常量池位于堆内存中,专门用来存储字符串常量,可以提高内存的使用率,避免开辟多块空间存储相同的字符串,在创建字符串时 JVM 会首先检查字符串常量池,如果该字符串已经存在池中,则返回它的引用,如果不存在,则实例化一个字符串放到池中,并返回其引用。

    String 是最基本的数据类型吗

    不是。Java 中的基本数据类型只有 8 个 :byte、short、int、long、float、double、char、boolean;除了基本类型(primitive type),剩下的都是引用类型(referencetype),Java 5 以后引入的枚举类型也算是一种比较特殊的引用类型。

    这是很基础的东西,但是很多初学者却容易忽视,Java 的 8 种基本数据类型中不包括 String,基本数据类型中用来描述文本数据的是 char,但是它只能表示单个字符,比如 ‘a’,‘好’ 之类的,如果要描述一段文本,就需要用多个 char 类型的变量,也就是一个 char 类型数组,比如“你好” 就是长度为2的数组 char[] chars = {‘你’,‘好’};

    但是使用数组过于麻烦,所以就有了 String,String 底层就是一个 char 类型的数组,只是使用的时候开发者不需要直接操作底层数组,用更加简便的方式即可完成对字符串的使用。

    String有哪些特性

    • 不变性:String 是只读字符串,是一个典型的 immutable 对象,对它进行任何操作,其实都是创建一个新的对象,再把引用指向该对象。不变模式的主要作用在于当一个对象需要被多线程共享并频繁访问时,可以保证数据的一致性。

    • 常量池优化:String 对象创建之后,会在字符串常量池中进行缓存,如果下次创建同样的对象时,会直接返回缓存的引用。

    • final:使用 final 来定义 String 类,表示 String 类不能被继承,提高了系统的安全性。

    String为什么是不可变的吗?

    简单来说就是String类利用了final修饰的char类型数组存储字符,源码如下图所以:

    /** The value is used for character storage. */
    private final char value[];
    

    String真的是不可变的吗?

    我觉得如果别人问这个问题的话,回答不可变就可以了。 下面只是给大家看两个有代表性的例子:

    1) String不可变但不代表引用不可以变

    String str = "Hello";
    str = str + " World";
    System.out.println("str=" + str);
    

    结果:

    str=Hello World
    

    解析:

    实际上,原来String的内容是不变的,只是str由原来指向"Hello"的内存地址转为指向"Hello World"的内存地址而已,也就是说多开辟了一块内存区域给"Hello World"字符串。

    2) 通过反射是可以修改所谓的“不可变”对象

    // 创建字符串"Hello World", 并赋给引用s
    String s = "Hello World";
    
    System.out.println("s = " + s); // Hello World
    
    // 获取String类中的value字段
    Field valueFieldOfString = String.class.getDeclaredField("value");
    
    // 改变value属性的访问权限
    valueFieldOfString.setAccessible(true);
    
    // 获取s对象上的value属性的值
    char[] value = (char[]) valueFieldOfString.get(s);
    
    // 改变value所引用的数组中的第5个字符
    value[5] = '_';
    
    System.out.println("s = " + s); // Hello_World
    

    结果:

    s = Hello World
    s = Hello_World
    

    解析:

    用反射可以访问私有成员, 然后反射出String对象中的value属性, 进而改变通过获得的value引用改变数组的结构。但是一般我们不会这么做,这里只是简单提一下有这个东西。

    是否可以继承 String 类

    String 类是 final 类,不可以被继承。

    String str="i"与 String str=new String(“i”)一样吗?

    不一样,因为内存的分配方式不一样。String str="i"的方式,java 虚拟机会将其分配到常量池中;而 String str=new String(“i”) 则会被分到堆内存中。

    String s = new String(“xyz”);创建了几个字符串对象

    两个对象,一个是静态区的"xyz",一个是用new创建在堆上的对象。

    String str1 = "hello"; //str1指向静态区
    String str2 = new String("hello");  //str2指向堆上的对象
    String str3 = "hello";
    String str4 = new String("hello");
    System.out.println(str1.equals(str2)); //true
    System.out.println(str2.equals(str4)); //true
    System.out.println(str1 == str3); //true
    System.out.println(str1 == str2); //false
    System.out.println(str2 == str4); //false
    System.out.println(str2 == "hello"); //false
    str2 = str1;
    System.out.println(str2 == "hello"); //true
    

    如何将字符串反转?

    使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。

    示例代码:

    // StringBuffer reverse
    StringBuffer stringBuffer = new StringBuffer();
    stringBuffer. append("abcdefg");
    System. out. println(stringBuffer. reverse()); // gfedcba
    // StringBuilder reverse
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder. append("abcdefg");
    System. out. println(stringBuilder. reverse()); // gfedcba
    

    数组有没有 length()方法?String 有没有 length()方法

    数组没有 length()方法 ,有 length 的属性。String 有 length()方法。JavaScript中,获得字符串的长度是通过 length 属性得到的,这一点容易和 Java 混淆。

    String 类的常用方法都有那些?

    • indexOf():返回指定字符的索引。
    • charAt():返回指定索引处的字符。
    • replace():字符串替换。
    • trim():去除字符串两端空白。
    • split():分割字符串,返回一个分割后的字符串数组。
    • getBytes():返回字符串的 byte 类型数组。
    • length():返回字符串长度。
    • toLowerCase():将字符串转成小写字母。
    • toUpperCase():将字符串转成大写字符。
    • substring():截取字符串。
    • equals():字符串比较。

    在使用 HashMap 的时候,用 String 做 key 有什么好处?

    HashMap 内部实现是通过 key 的 hashcode 来确定 value 的存储位置,因为字符串是不可变的,所以当创建字符串时,它的 hashcode 被缓存下来,不需要再次计算,所以相比于其他对象更快。

    String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的

    可变性

    String类中使用字符数组保存字符串,private final char value[],所以string对象是不可变的。StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,char[] value,这两种对象都是可变的。

    线程安全性

    String中的对象是不可变的,也就可以理解为常量,线程安全。AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。

    性能

    每次对String 类型进行改变的时候,都会生成一个新的String对象,然后将指针指向新的String 对象。StringBuffer每次都会对StringBuffer对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下使用StirngBuilder 相比使用StringBuffer 仅能获得10%~15% 左右的性能提升,但却要冒多线程不安全的风险。

    对于三者使用的总结

    如果要操作少量的数据用 = String

    单线程操作字符串缓冲区 下操作大量数据 = StringBuilder

    多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

    Date相关

    包装类相关

    自动装箱与拆箱

    装箱:将基本类型用它们对应的引用类型包装起来;

    拆箱:将包装类型转换为基本数据类型;

    int 和 Integer 有什么区别

    Java 是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java 为每一个基本数据类型都引入了对应的包装类型(wrapper class),int 的包装类就是 Integer,从 Java 5 开始引入了自动装箱/拆箱机制,使得二者可以相互转换。

    Java 为每个原始类型提供了包装类型:

    原始类型: boolean,char,byte,short,int,long,float,double

    包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

    Integer a= 127 与 Integer b = 127相等吗

    对于对象引用类型:==比较的是对象的内存地址。
    对于基本数据类型:==比较的是值。

    如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用常量池中的Integer对象,超过范围 a1==b1的结果是false

    public static void main(String[] args) {
        Integer a = new Integer(3);
        Integer b = 3;  // 将3自动装箱成Integer类型
        int c = 3;
        System.out.println(a == b); // false 两个引用没有引用同一对象
        System.out.println(a == c); // true a自动拆箱成int类型再和c比较
        System.out.println(b == c); // true
    
        Integer a1 = 128;
        Integer b1 = 128;
        System.out.println(a1 == b1); // false
    
        Integer a2 = 127;
        Integer b2 = 127;
        System.out.println(a2 == b2); // true
    }
    

    常用工具类库

    单元测试

    日志

    展开全文
  • RT 的其他决定因素是在现有理论的基础上假设的,并进行了实证检验。 响应时间在很大程度上取决于双方玩家在前几轮中选择的行动以及由此产生的结果。 具体来说,在获得最大可能回报的上一轮获胜后,响应时间最短; ...
  • 地学计算方法/地统计学(第四章变异函数理论模型)

    千次阅读 多人点赞 2020-05-21 09:06:39
    4.1变异函数理论模型 4.1.1有基态值模型 球状模型 γ(h)={0h=0C0+C(3h2a−1h32a3)0<h≤aC0+Ch>a \gamma(h)=\left\{\begin{array}{lr} 0 & h=0 \\ C_{0}+C\left(\frac{3 h}{2 a}-\frac{1 h^{3}}{2 a^{3}}\...

    4变异函数结构分析

    4.1变异函数理论模型

    image-20200518092428204

    4.1.1有基态值模型

    球状模型
    γ ( h ) = { 0 h = 0 C 0 + C ( 3 h 2 a − 1 h 3 2 a 3 ) 0 < h ≤ a C 0 + C h > a \gamma(h)=\left\{\begin{array}{lr} 0 & h=0 \\ C_{0}+C\left(\frac{3 h}{2 a}-\frac{1 h^{3}}{2 a^{3}}\right) & 0<h \leq a \\ C_{0}+C & h>a \end{array}\right. γ(h)=0C0+C(2a3h2a31h3)C0+Ch=00<hah>a
    在这里插入图片描述
    C 0 , C 0 + C , C , a C_0,C_0+C,C,a C0,C0+C,C,a分别为块金常数、基台值、拱高、变程,其中球状模型是应用最广的模型,一般只用于一维,二维,和三维数据,最适合用在当空间相关性随步长增加而线性递减的情况(即曲线的斜率是线性递减的)。

    指数模型
    γ ( h ) = { 0 h = 0 C 0 + C ( 1 − e − h a ) h > 0 \gamma(h)=\left\{\begin{array}{ll} 0 & h=0 \\ C_{0}+C\left(1-e^{-\frac{h}{a}}\right) & h>0 \end{array}\right. γ(h)={0C0+C(1eah)h=0h>0
    image-20200518093425565
    C 0 , C 0 + C , C , a C_0,C_0+C,C,a C0,C0+C,C,a分别为块金常数、基台值、拱高、该模型在原点处的切线和基台值相交时的所对应的步长,其中 3 a 3a 3a约等于变程(对应于0.95*基台值)

    适合一维或多维数据,由于指数模型在较大步长时也不能等于先验方差(相关系数也不能等于0),因此其变程定义为当变异函数为0.95 σ 2 σ_2 σ2 σ 2 σ_2 σ2为先验方差)所对应的步长

    高斯模型
    γ ( h ) = { 0 h = 0 C 0 + C ( 1 − e − h 2 a 2 ) h > 0 \gamma(h)=\left\{\begin{array}{ll} 0 & h=0 \\ C_{0}+C\left(1-e^{-\frac{h^2}{a^2}}\right) & h>0 \end{array}\right. γ(h)={0C0+C(1ea2h2)h=0h>0
    image-20200518094319416
    C 0 , C 0 + C , C , 3 a C_0,C_0+C,C,\sqrt{3}a C0,C0+C,C,3 a分别为块金常数、基台值、拱高、约为变程,适合一维或多维数据,因此其变程定义为当变异函数为0.95 σ 2 σ_2 σ2 σ 2 σ_2 σ2为先验方差)所对应的步长一般适用于当数据在短距离内呈现高度连续性的情况

    三种常用模型比较

    在这里插入图片描述
    对于球状模型与指数模型来说,插值结果表面比较粗糙,而对于高斯模型来说,插值结果较为平滑,是因为高斯模型的空间相关性随步长先增加后降低,连续性较强。

    线性有基态值模型
    γ ( h ) = { 0 h = 0 C 0 + A h 0 < h < a C 0 + C h = a \gamma(h)=\left\{\begin{array}{lc} 0 & h=0 \\ C_{0}+A h & 0<h<a \\ C_{0}+C & h=a \end{array}\right. γ(h)=0C0+AhC0+Ch=00<h<ah=a
    在这里插入图片描述
    C 0 , C 0 + C , C , A C_0,C_0+C,C,A C0,C0+C,C,A分别为块金常数、基台值、拱高、斜率

    纯块金效应模型
    γ ( h ) = { 0 h = 0 C 0 h > 0 \gamma(h)=\left\{\begin{array}{ll} 0 & h=0 \\ C_{0} & h>0 \end{array}\right. γ(h)={0C0h=0h>0
    在这里插入图片描述

    4.1.2无基态值模型

    线性无基态值模型
    γ ( h ) = { 0 h = 0 C 0 + A h h > 0 \gamma(h)=\left\{\begin{array}{ll} 0 & h=0 \\ C_{0}+Ah & h>0 \end{array}\right. γ(h)={0C0+Ahh=0h>0
    在这里插入图片描述
    幂函数值模型
    γ ( h ) = A h θ   1 < θ < 2 \gamma(h)=Ah^{\theta} \ 1<\theta<2 γ(h)=Ahθ 1<θ<2
    在这里插入图片描述

    4.1.3孔穴效应模型

    变异函数在h大于一定距离后并非单调递增,而是以一定的周期b进行波动,此时变异函数曲线显示出一种”孔穴效应(hole effect)”.

    孔穴效应模型包括有基台值模型和无基台值模型

    有基台值

    孔穴效应模型一般用于当数据呈现出一定周期性的情况,孔穴效应模型的变程为:当变异函数的值等于先验方差时所对应的最短步长
    γ ( h ) = { 0 h = 0 C 0 + C ( 1 − s i n ( π h / r ) π h r ) h > 0 \gamma(h)=\left\{\begin{array}{ll} 0 & h=0 \\ C_0+C(1-\frac{sin(\pi h/r)}{\pi hr}) & h>0 \end{array}\right. γ(h)={0C0+C(1πhrsin(πh/r))h=0h>0
    在这里插入图片描述

    4.1.4时空变异模型

    在这里插入图片描述
    γ ( h H , h V ) = ( c 0 + c ) − c [ 1 + 1 w 2 ( h H + α h V ) 2 ] − v 2 e − 1 ξ ∣ h H + α h V ∣ \gamma\left(h_{H}, h_{V}\right)=\left(c_{0}+c\right)-c\left[1+\frac{1}{w^{2}}\left(h_{H}+\alpha h_{V}\right)^{2}\right]^{-\frac{v}{2}} e^{-\frac{1}{\xi}\left|h_{H}+\alpha h_{V}\right|} γ(hH,hV)=(c0+c)c[1+w21(hH+αhV)2]2veξ1hH+αhV
    三维情况下,理论模型比二维情况下要复杂, c 0 + c c_0+c c0+c基态值,当 h H , h V h_H,h_V hH,hV均为0,等于 c 0 + c − c = c 0 c_0+c-c=c_0 c0+cc=c0,d当二者趋近于无穷大, c 0 + c c_0+c c0+c,发现在随着距离的递增与时间递增,也是趋近于一个平面的,也有变程的概念,称为时空上的变程,时间上的变程在5-6d,空间上的变程在此例中还没出现,

    4.1.5影响变异函数的主要因素

    • 样点距离和支撑大小

    随着样点间距增大,样点差异性逐渐增大,某些小尺度下的结构特征将变得不明显,因此需确定采样最小尺度,从而保证精度且不过分增加采样强度。
    支撑大小,即取样尺寸、形状和方向。小支撑尺度采样,样本内的差异一般小于样本间的差异,而大支撑度采样则样本内变异增大,从而消除样本间的差异

    • 样本数量

    样本数量(此为样点对的数目)在小距离上比在大距离上多。一般,统计计算时样本的数量越多,结果越精确,但在实际工作中,一般要求在变程以内各距离上的点对数目不应小于20对

    • 特异值影响

    变程范围内的特异值(异常值)会导致块金常数增大,即变异函数的随机成分增加,自相关性减弱。但是变异函数模型块金效应越小越好(特异值会使方差变大使得总体的值提升,特异值在区域的中心会比区域的边上对计算结果影响更大,因为在区域中心,特异值在各种滞后距下,对更多的点进行配对,如果在区域边缘,进行配对的概率就小,参与到试验变异函数计算次数就少,因此特别是在短距离范围内情况下,特异质的影响会更大)

    • 比例效应影响

    比例效应会导致实验变异函数值产生畸变,使基台值和块金值增大,导致结构特征不明显,使克里金估计精度降低,可通过对原始数据取对数来消除比例效应影响(存在比例效应,数据是不符合正态分布的,数据有一定的趋势,不符合平稳假设)

    4.2变异函数的套合结构

    套合结构,就是把分别出现在不同距离h上或不同方向上同时起作用的变异性组合起来,对全部有效的结构信息,作定量化的概括,以表示区域化变量的主要特征

    套合结构可以表示为多个变异函数之和,每一个变异函数代表一个方向一种特定尺度上的变异性。

    单一方向上的套合

    套合结构中每一个变异函数代表同一方向上的一种特定尺度的变异,并可以用不同的变异函数理论模型来拟合,即单一方向的套合结构
    r ( h ) = r 0 ( h ) + r 1 ( h ) + . . . . . . + r n ( h ) = ∑ i = 0 n r i ( h ) r(h)=r_0(h)+r_1(h)+......+r_n(h)=\sum_{i=0}^nr_i(h) r(h)=r0(h)+r1(h)+......+rn(h)=i=0nri(h)
    r i ( h ) r_i(h) ri(h)可以是相同的或不同的理论模型

    举例

    土壤是一个不均匀、具有高度空间异质性的复合体,它与土壤母质、气候、水文、地形和生物等因素有关,分析土壤空间变异的因素,可将其变异分为系统变异(土壤形成因素相互作用造成)和随机变异(可以观测到的,但与土壤形成印务无关且不能直接分析的)两大类,

    由h分开的两个点 x x x x + h x+h x+h的土壤某一性质 Z ( x ) Z(x) Z(x) Z ( x + h ) Z(x+h) Z(x+h)。当h趋近于0时,可以认为两点间的差异完全是由取样和测定误差造成,当 h h h逐步增大,如 h = 10 m h=10m h=10m,差异可能还要加上诸如水分等因素,当 h = 100 m h=100m h=100m时,在新的变异要考虑地形的作用

    若设由取样和测定误差引起变异为 ϒ 0 ( h ) ϒ_0(h) ϒ0(h),由水分引起的变异为 ϒ 1 ( h ) ϒ_1(h) ϒ1(h),由地形引起的变异为 ϒ 2 ( h ) ϒ_2(h) ϒ2(h),则当两点相距100m时,实际上两点的土壤变异性质为

    ϒ ( h ) = ϒ 0 ( h ) + ϒ 1 ( h ) + ϒ 2 ( h ) ​ ϒ(h)=ϒ_0(h)+ϒ_1(h)+ϒ_2(h)​ ϒ(h)=ϒ0(h)+ϒ1(h)+ϒ2(h)
    ϒ 0 ( h ) ϒ_0(h) ϒ0(h)代表微观上的变异,变程 a 0 a_0 a0极小,可用纯块金效应模型模拟, ϒ 1 ( h ) ϒ_1(h) ϒ1(h)代表由水分引起的变异若用球状模型模拟且变程为 a 1 = 10 m a_1=10m a1=10m ϒ 2 ( h ) ϒ_2(h) ϒ2(h)代表由地形引起的变异若用球状模型模拟且变程为 a 2 = 100 m a_2=100m a2=100m

    最终得出的套合模型结果如下:
    r ( h ) = { c 0 h = 0 c 0 + c 1 { 3 2 h a 1 − 1 2 ( h a 1 ) 3 } + c 2 { 3 2 h a 2 − 1 2 ( h a 2 ) 3 } 0 < h ≤ a 1 c 0 + c 1 + c 2 { 3 2 h a 2 − 1 2 ( h a 2 ) 3 } a 1 < h ≤ a 2 c 0 + c 1 + c 2 h > a 2 r(h)=\left\{\begin{array}{ll} c_{0} & h=0 \\ c_{0}+c_{1}\left\{\frac{3}{2} \frac{h}{a_{1}}-\frac{1}{2}\left(\frac{h}{a_{1}}\right)^{3}\right\}+c_{2}\left\{\frac{3}{2} \frac{h}{a_{2}}-\frac{1}{2}\left(\frac{h}{a_{2}}\right)^{3}\right\} & 0<h \leq a_{1} \\ c_{0}+c_{1}+c_{2}\left\{\frac{3}{2} \frac{h}{a_{2}}-\frac{1}{2}\left(\frac{h}{a_{2}}\right)^{3}\right\} & a_{1}<h \leq a_{2} \\ c_{0}+c_{1}+c_{2} & h>a_{2} \end{array}\right. r(h)=c0c0+c1{23a1h21(a1h)3}+c2{23a2h21(a2h)3}c0+c1+c2{23a2h21(a2h)3}c0+c1+c2h=00<ha1a1<ha2h>a2

    4.3变异函数理论模型的最优拟合

    为了定量地描述整个区域的变量特征,需要根据实验变异函数值,选择合适的理论模型来拟合一条最优的理论变异函数曲线,用以更精确反映变量的变化规律

    变异函数理论模型的最优拟合主要包括步骤:

    4.3.1确定变异函数模型形态

    根据变异函数散点图判断,

    有基台值模型,无基台值模型,空穴效应模型?

    是否存在单一方向上不同尺度的套合情况?

    是否存在各向异性?
    在这里插入图片描述

    4.3.2模型参数的最优估计

    对于不同模型,待估参数有所不同

    参数估计通常有下列两种方法:

    4.3.2.1人工拟合

    在这里插入图片描述
    在这里插入图片描述

    4.3.2.2自动拟合

    自动拟合主要是根据步长 ( h ) (h) (h)和变异函数 r ( h ) r(h) r(h)之间的关系来确定变异函数模型参数

    普通最小二乘拟合

    利用最小二乘法估计变异函数模型参数的核心思想:
    min ⁡ ( r , s , a ) ∑ k = 1 k ˉ ( γ ^ k − γ ( h k ; r , s , a ) ) 2 \min _{(r, s, a)} \sum_{k=1}^{\bar{k}}\left(\hat{\gamma}_{k}-\gamma\left(h_{k} ; r, s, a\right)\right)^{2} (r,s,a)mink=1kˉ(γ^kγ(hk;r,s,a))2
    其中 γ k ^ \hat{\gamma_k} γk^代表根据实验数据所得到的变异函数值 γ ( h k ; r , s , a ) \gamma\left(h_{k} ; r, s, a\right) γ(hk;r,s,a)代表理论变异函数模型,其参数为 r , s , a r,s,a r,s,a变程,基台值,块金常数

    缺点:不应该把变异函数靠近原点附近的点与其他点平等对待,因为原点附近的点对于反映空间自相关性更加重要

    加权最小二乘拟合

    加权回归法的核心思想:以样点对的个数作为权重,因为距离小的样点对要比距离大的样点对多,因此小距离权重大,突显了原点附近点的重要性
    min ⁡ r , s , a ∑ k = 1 w k ( γ ^ k − γ ( h k ; r , s , a ) ) 2 \min _{r, s, a} \sum_{k=1} w_{k}\left(\hat{\gamma}_{k}-\gamma\left(h_{k} ; r, s, a\right)\right)^{2} r,s,amink=1wk(γ^kγ(hk;r,s,a))2
    权重: w k = ∣ N k ∣ γ ( h k ; r , s , a ) 2 , k = 1 , . . , k ˉ w_{k}=\frac{\left|N_{k}\right|}{\gamma\left(h_{k} ; r, s, a\right)^{2}} \quad, \quad k=1, . ., \bar{k} wk=γ(hk;r,s,a)2Nk,k=1,..,kˉ

    4.3.3模型拟合评价

    模型拟合评价包括
    1.最优曲线检验:对参数和方程本身进行显著性检验。
    2.模型比较:通过平均误差,决定系数(R2)等统计指标对不同的模型进行比较,从中选出最优拟合模型
    在这里插入图片描述
    线性有基台值模型的残差最小,决定系数最大,其次是球状模型,基台值基本相同,但线性有基台值模型的变程最小,其次是高斯模型和球状模型。块金值是指数模型的最小,其次是球状模型和线性有基台值模型。
    对这5个参数,显然最重要的是考虑决定系数R2的大小,其次是考虑残差RSS的大小,然后再考虑变程和块金值的大小,根据这个原则,选择球状模型作为本实例的变异函数理论模型是比较合适的,这个理论模型除了具有较高的拟合精度外,对变程内的模拟可以得到满意的结果

    4.4基于优化搜索算法的参数拟合

    对于结构复杂的变异函数理论模型,特别是套合结构模型,参数复杂,难以用一般的通用方法求解出模型中的参数。但一些智能优化算法,如遗传算法、模拟退火算法、蚁群算法能够使用统一的流程求解出接近最优的参数。
    以遗传算法为例,介绍该算法在求解套合结构模型时的流程

    在这里插入图片描述

    1.多尺度套合模型的规范表达

    在单一模型中均带有块金值 c 0 c_0 c0,为实现套合模型将块金值部分表达为纯块金模型,即 r ( h ) = c r(h)=c r(h)=c,单一模型就转变为块金模型与一个代表空间相关的函数 r i ( h ) r_i(h) ri(h),每个的函数可表达为 c f ( h , a ) cf(h,a) cf(h,a),当 h h h大于变程时, r ( h ) r(h) r(h)的值为前面若干模型系数 c c c的和,其结果也成为基台值,因此可将套合模型表示为若干个模型叠加,即
    r ( h ) = r 0 ( h ) + r 1 ( h ) + ⋯ + r n ( h ) = ∑ i = 0 n r i ( h ) = ∑ i = 0 n c i f i ( h , a i ) \begin{array}{c} r(h)=r_{0}(h)+r_{1}(h)+\cdots+r_{n}(h) =\sum_{i=0}^{n} r_{i}(h)=\sum_{i=0}^{n} c_{i} f_{i}\left(h, a_{i}\right) \end{array} r(h)=r0(h)+r1(h)++rn(h)=i=0nri(h)=i=0ncifi(h,ai)
    其中 a 0 = 0 , a i > a i − 1 , f i a_0=0,a_i>a_{i-1},f_i a0=0,ai>ai1,fi h h h取值范围为 [ 0 , + ∞ ] [0,+\infty] [0,+],对于每个 r i ( h ) r_i(h) ri(h) h > a i h>a_i h>ai时对于球状与线性模型 f i = 1 f_i=1 fi=1对于指数模型与高斯模型 f i = 0.95 f_i=0.95 fi=0.95因为指数与高斯模型中 h = a , r ( h ) = c 0 + c ( 1 − e − 3 ) = c 0 + 0.95 c h=a,r(h)=c_0+c(1-e^{-3})=c_0+0.95c h=a,r(h)=c0+c(1e3)=c0+0.95c,因此在计算时要考虑这个近似值,避免跳跃

    2.编码策略与初始化种群

    需要求解参数为 2 n + 1 2n+1 2n+1个(第一个模型总为纯块金)在实际计算中令 c i = ∑ j = 0 i c j c_i=\sum_{j=0}^{i}c_j ci=j=0icj,从经验半方差图识别 c i c_i ci取值区间,并有以下约束:
    c i > 0 , c i > c i − 1 , a i > 0 , a i > a i − 1 c_{i}>0, \quad c_{i}>c_{i-1}, \quad a_{i}>0, \quad a_{i}>a_{i-1} ci>0,ci>ci1,ai>0,ai>ai1
    假设需要顾及 m ( m < = 2 n + 1 ) m(m<=2n+1) m(m<=2n+1)个参数,每个参数的取值范围和估值精度分别是 U m i n , U m a x Umin,Umax Umin,Umax Q i Qi Qi,则将 m m m个参数分别以 L 1 , L 2 , … … , L m L1,L2,……,Lm L1,L2,,Lm为长度进行二进制编码,其中
    L i = ceil ⁡ ( log ⁡ 2 ( Umax ⁡ i − Umin ⁡ i Q i ) ) L_{i}=\operatorname{ceil}\left(\log _{2}\left(\frac{\operatorname{Umax}_{i}-\operatorname{Umin}_{i}}{Q_{i}}\right)\right) Li=ceil(log2(QiUmaxiUmini))
    则每条染色体长度为 ∑ i = 1 m L i \sum_{i=1}^{m}L_i i=1mLi染色体中每个参数编码对应的解码公式为:
    m i = U min ⁡ i + ( ∑ k = 1 L i b k 2 k − 1 ) × U max ⁡ i − U min ⁡ i 2 L i − 1 ​ m_{i}=U \min _{i}+\left(\sum_{k=1}^{L_{i}} b_{k} 2^{k-1}\right) \times \frac{U \max _{i}-U \min _{i}}{2^{L_{i}}-1}​ mi=Uimin+(k=1Libk2k1)×2Li1UmaxiUmini
    3.确定个体适应度评价函数

    根据统计学思想,对理论模型的最优拟合实质上就是让理论变异函数值和实际变异函数值之间的方差最小,然而在实际计算中,实际变异函数曲线上个点的重要性是不同的,往往滞后距小的点的重要性要大于滞后距大的点,因此采用以滞后距的倒数作为权系数参与适应度评价函数的构建,最终函数形式为( 函数值越大,个体适应度越高)
    f i = 1 ∑ i = 1 N ( h ) w i ∗ ( r ∗ ( h i ) − r ( h i ) ) 2 f_{i}=\frac{1}{\sum_{i=1}^{N(h)} w_{i} *\left(r^{*}\left(h_{i}\right)-r\left(h_{i}\right)\right)^{2}} fi=i=1N(h)wi(r(hi)r(hi))21
    其中 w i = ∑ i = 1 N ( h ) h i h i w_i=\frac{\sum_{i=1}^{N(h)}h_i}{h_i} wi=hii=1N(h)hi

    4.遗传操作

    遗传算法主要包括3个基本算子,即选择、交叉和变异,为此,需确定交叉概率 P c P_c Pc和变异概率 P m P_m Pm,3个过程执行以后,将产生新一代种群,并记录适应度最高的染色体。

    • 选择算子

    采用轮盘赌法,利用比例介于各个个体适应度的概率觉得其遗传下一代的可能性。若种群数位 T T T,个体适应度为 f i f_i fi,则每个个体被选取的概率为 P i = f i ∑ k = 1 T f k P_i=\frac{f_i}{\sum_{k=1}^{T}f_k} Pi=k=1Tfkfi,当个体选择的概率确定后,产生 [ 0 , 1 ] [0,1] [0,1]之间的均匀随机数来决定哪个可以遗传到下一代后续计算。

    • 交叉算子

    采用单点交叉,只有一个交叉点位置,按照交叉概率随机选择经过选择操作后种群个体交叉对象,两两配对,然后随机产生交叉位置,从而产生新个体。
    在这里插入图片描述
    采样多点交叉
    在这里插入图片描述

    • 变异算子

    实验基本位变异法,按照变异概率,随机选择需要变异的个体,再个体在随机选择变异位置,将0变1,1变为0,从而产生新个体。

    5.收敛条件判断

    收敛条件判断常常有两种,历代以来适应度值相差小于某个阈值,还有一种是设置最大迭代次数。

    课堂讨论题

    1.如何改进上述算法,在用户不能确定理论变异函数类型时,能自动匹配模型类型并进行参数估计

    对给定的 n n n个套合模型中,每个模型附加一个模型类型编码,模型类型编码长度由模型类型的个数决定,构建基本模型类型函数库,假如模型库中有4个常用模型(线性有基台值、球状、指数、高斯),那么模型类型编码长度就是两位,假定00,01,10,11可以分别代表上述四个模型。

    假定用 n n n模型进行套合,那么要求解的估计参数就有 3 n + 1 3n+1 3n+1个,其中有 [ c 0 , c 1 , . . . , c n ] [c_0,c_1,...,c_n] [c0,c1,...,cn]以及对应的变程 [ a 1 , a 2 , . . . , a n ] [a_1,a_2,...,a_n] [a1,a2,...,an]以及模型类型参数 t y p e 1 , t y p e 2 , . . . , t y p e n type_1,type_2,...,type_n type1,type2,...,typen,因此每个种群对应的解空间定义如下:
    S = [ c 0 , c 1 , … c n , a 1 , a 2 , … a n , t y p e 1 , t y p e 2 , … , t y p e n ] S=\left[c_{0}, c_{1}, \ldots c_{n}, a_{1}, a_{2}, \ldots a_{n}, t y p e_{1}, t y p e_{2}, \ldots, t y p e_{n}\right] S=[c0,c1,cn,a1,a2,an,type1,type2,,typen]
    在交叉和变异时,交叉对模型类型的染色体片段不进行交叉,在变异时大概率来进行模型类型的变异

    2 如何在程序设计或功能界面上提高此算法的运行效率,使算法能够尽快找到较好的解

    采用自适应双交叉点遗传算法

    根据适应度动态调节交叉概率和遗传概率大小

    交叉概率 P c P_{c} Pc 和变异概率 P m P_{m} Pm 对遗传算法性能有很大的影响,直接影响算法收敛性1。虽然 P c P_{c} Pc 较大的时候种群更容易产生新个体,但是当其变大时,优良个体在种群中保留率也降低。对 P m P_{m} Pm 来说,若其过大则本算法相当于普通的随机算法,失去了遗传算法的意义。直接给出Srinvivas提出的自适应遗传算法(Adaptive GA, AGA)方法

    对于适应值高于群体平均适应值的个体,对应于较低的交叉概率和变异概率,使该个体得以保护进入下一代;而低于平均适应值的个体,相对应于较高的交叉概率和变异概率,使该个体被淘汰掉。因此,自适应遗传算法能够提供相对某个解的最佳交叉概率和变异概率
    P c = { P c 1 − ( P c 1 − P c 2 ) ( f ′ − f a v g ) f m a x − f a v g , f ′ ≥ f a v g P c 1 , f ′ < f a v g P m = { P m 1 − ( P m 1 − P m 2 ) ( f m a x − f ) f m a x − f a v g , f ≥ f a v g P m 1 , f ′ < f a v g \begin{array}{l} P_{c}=\left\{\begin{array}{ll} P_{c 1}-\frac{\left(P_{c 1}-P_{c 2}\right)\left(f^{\prime}-f_{a v g}\right)}{f_{m a x}-f_{a v g}}, & f^{\prime} \geq f_{a v g} \\ P_{c 1}, & f^{\prime}<f_{a v g} \end{array}\right. \\ P_{m}=\left\{\begin{array}{ll} P_{m 1}-\frac{\left(P_{m 1}-P_{m 2}\right)\left(f_{m a x}-f\right)}{f_{m a x}-f_{a v g}}, & f \geq f_{a v g} \\ P_{m 1}, & f^{\prime}<f_{a v g} \end{array}\right. \end{array} Pc={Pc1fmaxfavg(Pc1Pc2)(ffavg),Pc1,ffavgf<favgPm={Pm1fmaxfavg(Pm1Pm2)(fmaxf),Pm1,ffavgf<favg
    f m a x fmax fmax——群体中最大的适应度值
    f a v g favg favg——每代群体的平均适应度值
    f ′ f^\prime f——要交叉的两个个体中较大的适应度值
    f f f——要变异的个体的适应度值
    P c 1 = 0.9 , P c 2 = 0.6 , P m 1 = 0.1 , P m 2 = 0.001 P_{c1}=0.9,P_{c2}=0.6,P_{m1}=0.1,P_{m2}=0.001 Pc1=0.9Pc2=0.6Pm1=0.1Pm2=0.001

    3.通过学习的内容,谈谈对参数拟合问题有何启发

    4.5结构分析步骤

    1.区域化变量选择

    • 根据具体研究目的而定,要有明确物理意义,最好能定量表示。
    • 支撑大小、形状与取样,测试方法应相同。

    2.数据获取与审议

    • 审议内容包括取样设计,样点间距离的大小,取样方法,数据的代表性,数据均匀性,时空一致性,原始数据的记录,是否存在系统误差等

    3.数据统计分析

    数据统计分析指对取样数据计算平均值、方差、变异系数、偏度、峰度等统计指标,并进行相关、正态、趋势、各向异性等特性分析,目的在于对数据特性进行初步了解,提出简单明晰的解释

    4.变异函数计算

    • 等间距规则网格数据
    • 非等间距的不规则网格数据

    5.变异函数结构分析

    结构分析的目的在于通过分析各种实验变异函数来分析所研究区域化现象的主要结构特征,包括各向同性,各向异性,块金效应,套合结构等

    6.变异函数最优拟合及检验

    为了研究区域化现象,需要根据实验变异函数散点图拟合理论变异函数模型。理论模型的优劣可通过统计指标来检验

    7.变异函数理论模型的专业分析

    展开全文
  • Stata: 空间面板数据模型及Stata实现

    万次阅读 多人点赞 2019-05-10 10:37:56
    由于面板数据模型所具有的众多优点 (刻画个体异质性,减弱模型共线性和增加自由度等),其被广泛应用于实证计量中。在 「 Stata: 面板数据模型-一文读懂」 文中,我们已对面板数据模型进行了介绍。 然而,当研究样本...

    作者:游万海 (福州大学)

    Stata 连享会: 知乎 | 简书 | 码云 | CSDN

    本文 PDF 版本 点击下载

    点击查看完整推文列表

    Stata连享会   计量专题 || 精品课程 || 简书推文 || 公众号合集

    连享会#金秋十月 @ 空间计量专题 (2019.10.24-27,成都)

    2019.10-杨海生-空间计量专题-连享会

    图片来源:Golgher 和 Voss (2016)

    图片来源:Golgher 和 Voss (2016)

    1. 背景介绍

    由于面板数据模型所具有的众多优点 (刻画个体异质性,减弱模型共线性和增加自由度等),其被广泛应用于实证计量中。在 「 Stata: 面板数据模型-一文读懂」 文中,我们已对面板数据模型进行了介绍。

    然而,当研究样本涉及到多个单元时 (如多个国家),研究单元间的空间相关性不可忽略。例如,在利用跨国样本研究环境污染 (如 C O 2 CO_{2} CO2 排放量) 的影响因素时,除考虑该国经济发展水平,人口总数,城市化水平和工业化水平等宏观变量之外,还应将其他研究单元的情况考虑在内,包括他国的环境污染程度 (后文纳入 W Y WY WY 的理论依据) 和宏观经济因素 (后文纳入 W X WX WX 的理论依据)。 理由如下:第一,由于污染的空间流动性,对于一些特定的污染物,本地区的污染水平会对其 “邻近” 地区的污染水平造成影响;第二,当某个地区的经济发展较快时,“邻近” 地区会模仿该地区的经济发展模式和产业布局,进而也会对其环境污染水平造成影响。

    正如地理学第一定律 ( Tobler’s First Law ) 所说:任何事物都是与其他事物相关的,只不过相近的事物关联更紧密。空间计量计量学的发展为这一理论研究提供了有力的工具。 本推文将对面板数据框架下的空间计量模型 (空间面板数据模型) 进行讨论。本文主要分四部分内容进行介绍:

    • 模型介绍: 空间面板模型简介
    • 空间权重矩阵构造
    • 模型解释
    • 模型实现

    2. 模型介绍: 空间面板模型简介

    2.1 双向固定效应模型:不考虑空间相关性

    在介绍空间面板模型之前,我们先简单回顾一下普通的面板数据模型。这里以双向固定效应模型为例进行说明,详情参见「 Stata: 面板数据模型-一文读懂」

    面板数据模型同时包含了截面和时间两个维度,后文用 i i i ( i = 1 , ⋯ &ThinSpace; , N i =1, \cdots, N i=1,,N) 表示截面 (个体), t t t ( t = 1 , ⋯ &ThinSpace; , T t=1, \cdots, T t=1,,T) 表示时间,设定如下面板数据模型:

    y i t = α i + λ t + x i t β + ϵ i t y_{it} = \alpha_{i} + \lambda_{t} + \mathbf{x_{it}}\beta + \epsilon_{it} yit=αi+λt+xitβ+ϵit

    其中,

    • y i t y_{it} yit N T × 1 NT\times 1 NT×1 因变量,
    • x i t \mathbf{x_{it}} xit N T × k NT\times k NT×k 自变量,
    • ϵ i t \epsilon_{it} ϵit 为模型误差项, β \beta β是待估计参数,表示 x i t \mathbf{x_{it}} xit y i t y_{it} yit 的边际影响。
    • α i \alpha_{i} αi 表示个体效应,表示那些不随时间改变的影响因素,如个人的消费习惯、企业文化和经营风格等;
    • λ t \lambda_{t} λt 表示时间效应,用于控制随时间改变因素的影响 (时间虚拟变量包括时间趋势项,时间趋势主要用于控制技术进步),如广告的投放 (往往通过电视或广播,我们可以认为在特定的年份所有个体所接受的广告投放量相同)。

    显然, α i \alpha_{i} αi λ t \lambda_{t} λt 在多数情况下都是无法直接观测或难以量化的,因此也就无法进入模型。在截面分析中往往会引起遗漏变量的问题。

    面板数据模型的主要用途之一就在于处理这些不可观测的个体效应或时间效应。当对所有的 i i i, α i \alpha_{i} αi 均相等时,模型退化为混合数据模型 ( Pooled OLS ),可直接用 reg y x 命令进行参数估计。

    2.2 空间面板数据模型

    上述模型中解释变量仅仅纳入自身的因素,未考虑其他地区的一些因素。例如,一个国家的 C O 2 CO_{2} CO2 排放水平不仅与其"邻近"地区的 C O 2 CO_{2} CO2 排放水平有关,还可能与其他地区的经济社会等因素存在关联。

    空间面板数据模型进一步加入了空间滞后被解释变量 W Y WY WY 和空间滞后误差项 W ϵ W\epsilon Wϵ。前者称为空间滞后模型,后者称为空间误差模型。两类模型的主要区别在于刻画空间相依方式的不同,前者主要描述空间相依性 ( Spatial dependence ),后者描述空间异质性 ( Spatial heterogeneity )。 进一步地,加入空间滞后解释变量 W X WX WX。考虑到模型的应用广泛性,本推文主要讨论同时纳入 W Y WY WY W X WX WX 的空间模型,该模型称为空间杜宾模型 ( Spatial Durbin model )。模型如下:

    y i , t = a i + λ t + ρ ∑ j = 1 N w i , j y i , t + x i , t β + ∑ j = 1 N w i , j x i , j , t θ + ε i t y_{i, t}=a_{i} + \lambda_{t}+\rho \sum_{j=1}^{N} w_{i, j} y_{i, t}+\boldsymbol{x}_{i, t} \boldsymbol{\beta}+\sum_{j=1}^{N} w_{i, j} \boldsymbol{x}_{i, j, t} \boldsymbol{\theta}+\varepsilon_{it} yi,t=ai+λt+ρj=1Nwi,jyi,t+xi,tβ+j=1Nwi,jxi,j,tθ+εit

    进一步,可将该模型写成向量形式:

    y t = ρ W y t + x t β + W x t θ + a + λ t ι n + ε t y_{t}=\rho W y_{t}+x_{t} \beta+W x_{t} \theta+a+\lambda_{t} \iota_{n}+\varepsilon_{t} yt=ρWyt+xtβ+Wxtθ+a+λtιn+εt

    其中, ε t ∼ N ( 0 , σ ε 2 I n ) \varepsilon_{t} \sim \mathcal{N}\left(0, \sigma_{\varepsilon}^{2} I_{n}\right) εtN(0,σε2In) ; a = [ a 1 , a 2 , … , a n ] a=\left[a_{1}, a_{2}, \ldots, a_{n}\right] a=[a1,a2,,an]; l n l_{n} ln ( n × 1 ) (n \times 1) (n×1) 的列向量,每个元素都为 1。

    y t = [ y 1 t y 2 t ⋮ y n t ] ,    x t = [ 1 x 21 t ⋯ x k 1 t 1 x 22 t ⋯ x k 2 t ⋮ ⋮ ⋱ ⋮ 1 x 2 n t ⋯ x k n t ] y_{t}=\left[ \begin{array}{c}{y_{1 t}} \\ {y_{2 t}} \\ {\vdots} \\ {y_{n t}}\end{array}\right], \ \ x_{t}=\left[ \begin{array}{cccc}{1} &amp; {x_{21 t}} &amp; {\cdots} &amp; {x_{k 1 t}} \\ {1} &amp; {x_{22 t}} &amp; {\cdots} &amp; {x_{k 2 t}} \\ {\vdots} &amp; {\vdots} &amp; {\ddots} &amp; {\vdots} \\ {1} &amp; {x_{2 n t}} &amp; {\cdots} &amp; {x_{k n t}}\end{array}\right] yt=y1ty2tynt,  xt=111x21tx22tx2ntxk1txk2txknt

    β = [ β 1 , β 2 ⋯ β k ] ′ \beta = \left[ \beta_1, \beta_{2} \cdots \beta_{k} \right]&#x27; β=[β1,β2βk] θ = [ θ 1 , θ 2 ⋯ θ k ] ′ \theta = \left[ \theta_1, \theta_{2} \cdots \theta_{k} \right]&#x27; θ=[θ1,θ2θk].

    W W W 为空间权重矩阵,其合理定义是应用空间计量模型的一个关键前提。前文我们不厌其烦地多次提到"邻近"地区, W W W 的一个作用就是用于某个地区的"邻近"地区包括哪些。此外,还可通过 W W W 定义邻近地区对本地区的影响方式和程度。

    连享会计量方法专题……

    3. 空间权重矩阵构造

    与普通面板数据模型相比,空间面板数据模型通过引入空间权重矩阵来定义研究单元之间的关联方式和关联程度。从现有文献来看,常用的空间权重矩阵可以归纳为两类。一类为基于地理位置构造的,如 RookQueenK-nearest 和 距离倒数次方权重矩阵;一类为基于社会经济因素的空间权重矩阵。前者的优点为直观且满足空间权重矩阵外生性假定,而后者的优点为有较强的经济含义且更符合实际应用背景。基于社会经济因素的空间权重矩阵,由于不同年份的社会经济指标值不同,其通常是随着时间变化而改变,但是此时模型通常较为复杂,实证中常取平均值构造空间权重矩阵 (此外,时变空间权重矩阵也被提出)。

    为了对模型进行正确识别,必须保证空间权重矩阵的外生性。基于经济社会因素构造的空间权重矩阵有时经济含义较为明显,但是通常都不满足外生性假设。因此,在实际应用中最常用的空间权重矩阵是基于地理信息或者地理位置的,如 RookQueen 以及距离权重矩阵。

    3.1 Rook 和 Queen 权重矩阵

    例如,在省域环境问题研究中,通常认为"邻近"省份的环境治理行为存在相似。这里的"邻近"可以认为从地理位置来看,两个省份存在地理接壤。若存在共同边界,元素设定为 1,否则设定为 0。假设我们有 5 个省份 (下文统称为 单元#),其地理分布如下图所示
    连享会-空间权重矩阵的构造
    Rook 空间权重矩阵是一个 5 行 5 列的方阵:

    W R o o k = ( 0 1 0 0 0 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 ) 5 × 5 W_{Rook} = \left( \begin{array}{ccc}{0} &amp; {1} &amp; {0} &amp; {0} &amp; {0} \\ {1} &amp; {0} &amp; {1} &amp; {1} &amp; {0} \\ {0} &amp; {1} &amp; {0} &amp; {0} &amp; {0} \\ {0} &amp; {1} &amp; {0} &amp; {0} &amp; {0} \\ {0} &amp; {0} &amp; {0} &amp; {0} &amp; {0} \end{array}\right)_{5\times 5} WRook=01000101100100001000000005×5

    具体解释如下:

    • W R o o k W_{Rook} WRook 矩阵的对角线元素均为 0。这很显然。否则的话,你怎么解释 “我自己和自己相邻” 呢?
    • W R o o k W_{Rook} WRook 矩阵的第一行表示 单元1 与各个单元之间的相邻关系。以第一行第二列为例, W R o o k [ 1 ,   2 ] = 1 W_{Rook}[1,\ 2] = 1 WRook[1, 2]=1,表示 单元1单元2 相邻。按此逻辑,我们很容易猜知 W R o o k [ 2 ,   1 ] = 1 W_{Rook}[2,\ 1] = 1 WRook[2, 1]=1
    • 细心的读者可以看出,在上例中,单元5 与其他单元都不存在共同边界,导致 W R o o k W_{Rook} WRook 矩阵的第 5 行元素的值全部为 0。例如,在我国省域单元研究中,海南省就是这样的情况。Rook 空间权重矩阵的设定不允许出现这种情况。因此,在实际分析中,若利用 Rook 空间权重矩阵,通常假设海南省与广东省存在相邻。

    对于这种 孤零零的单元,另一种处理办法是放宽假设,可以认为只要存在顶点相接,就认为两地区为"邻居"关系,这就是 Queen 空间权重矩阵。按照这一设定,空间权重矩阵可定义为

    W Q u e e n = ( 0 1 0 0 0 1 0 1 1 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 ) W_{Queen} = \left( \begin{array}{ccc}{0} &amp; {1} &amp; {0} &amp; {0} &amp; {0} \\ {1} &amp; {0} &amp; {1} &amp; {1} &amp; {0} \\ {0} &amp; {1} &amp; {0} &amp; {0} &amp; {0} \\ {0} &amp; {1} &amp; {0} &amp; {0} &amp; {1} \\ {0} &amp; {0} &amp; {0} &amp; {1} &amp; {0} \end{array}\right) WQueen=0100010110010000100100010

    3.2 距离权重矩阵

    前文已经提及,空间权重矩阵不仅可以定义 关联方式 (是否关联),而且可以定义 关联程度 (关联的紧密程度)。然而基于 RookQueen 的空间权重矩阵假定两个地区只要存在关联,其关联程度都是相同的 (等权重)。然而,这种假定往往有悖常理。例如,在环境污染研究中,一般认为距离近的地区,关联程度较高;又如,在国际贸易研究中,往来密切的地区之间关联程度较高。在这种情况下,基于空间距离的权重矩阵较为合适。基于距离的空间权重矩阵定义如下:

    w i j = 1 / d i j 2 d i j = arcos ⁡ [ ( sin ⁡ ϕ i × sin ⁡ ϕ j ) + ( cos ⁡ ϕ i × cos ⁡ ϕ j × cos ⁡ ( Δ τ ) ) ] × R \begin{array}{c}{w_{i j}=1 / d_{i j}^{2}} \\ {d_{i j}=\operatorname{arcos}\left[\left(\sin \phi_{i} \times \sin \phi_{j}\right)+\left(\cos \phi_{i} \times \cos \phi_{j} \times \cos (\Delta \tau)\right)\right] \times R}\end{array} wij=1/dij2dij=arcos[(sinϕi×sinϕj)+(cosϕi×cosϕj×cos(Δτ))]×R

    其中: ϕ i \phi_{i} ϕi ϕ j \phi_{j} ϕj分别表示某个国家 (如最大城市或首都) 的纬度和经度; Δ τ \Delta \tau Δτ为两个国家间经度之差; R R R为地球半径,等于 3958.761英里。在实际应用中,常对空间权重矩阵进行行标准化,空间权重矩阵的对角元素设为 0。

    3.3 经济权重矩阵

    与基于地理信息构造的空间权重矩阵相比,经济权重矩阵的实际应用背景较强,其没有统一的数学表达式。例如,研究经济增长影响因素时,研究样本为世界各国,一般认为两国间的贸易往来越多,它们之间的经济增长水平联系越紧密,此时可根据两国的贸易往来数据构造空间权重矩阵,空间权重矩阵定义如下:

    w i j = 1 2 T ∑ t ∈ T ( e x p o r t i j , t ∑ j e x p o r t i j , t + i m p o r t i j , t ∑ j i m p o r t i j , t ) w_{i j}=\frac{1}{2 T} \sum_{t \in T}\left(\frac{e x p o r t_{i j, t}}{\sum_{j} e x p o r t_{i j, t}}+\frac{i m p o r t_{i j, t}}{\sum_{j} i m p o r t_{i j, t}}\right) wij=2T1tT(jexportij,texportij,t+jimportij,timportij,t)

    其中: e x p o r t i j , t export_{ij,t} exportij,t表示在时刻 t t t国家 i i i向国家 j j j的出口总量, i m p o r t i j , t import_{ij,t} importij,t表示在时刻 t t t国家 i i i向国家 j j j的进口总量, T T T为时间长度。该式表示两国间的相似度为时间 T T T内双边贸易的平均。

    再如,基于 GDP 的空间权重可以定义为

    w i j = 1 − ∣ ( G D P j − G D P i ) / ( G D P j + G D P i ) ∣ w_{i j}=1-|\left(G D P_{j}-G D P_{i}\right) /\left(G D P_{j}+G D P_{i}\right)| wij=1(GDPjGDPi)/(GDPj+GDPi)

    其中, G D P i GDP_{i} GDPi G D P j GDP_{j} GDPj 分别表示研究时间内国家 i i i 和国家 j j j GDP 平均值, w i j w_{i j} wij 的取值范围为 0-1,可以看出,当两国的 GDP 较为接近时, w i j w_{i j} wij=1,当两国的 GDP 差异非常显著时, w i j = 0 w_{i j}=0 wij=0。值得注意的是,该空间权重矩阵并不随时间在改变。若针对不同时间 t t t,将 w i j , t ​ w_{ij,t}​ wij,t 值设定为不同的数值,此时的空间权重矩阵为时变的,对于该类模型的研究,详细可以参考 Lee and Yu (2012)。

    连享会计量方法专题……

    4. 模型解释

    4.1 非空间面板数据模型

    当假设研究单元不相依时 (independence),在时刻 t t t, 对所有的 i i i,有

    ∂ E ( y i ) / ∂ x i = β ∂ E ( y i ) / ∂ x j = 0 , i ≠ j \begin{array}{l}{\partial E\left(y_{i}\right) / \partial x_{i}=\beta} \\ {\partial E\left(y_{i}\right) / \partial x_{j}=0, i \neq j}\end{array} E(yi)/xi=βE(yi)/xj=0,i̸=j

    根据上述式子可知,模型系数和边际效应大小相同,解释变量 X 1 X_{1} X1 Y Y Y 的影响作用大小可以根据模型系数进行解释。

    4.2 空间面板数据模型

    空间计量模型因为包含 W y t W y_{t} Wyt W x t W x_{t} Wxt ,某个解释变量对被解释变量的总效应与其系数大小并不相等,此时总效应包括两部分:自身 (own-region) 的直接效应和其他单元引起的间接效应 (又称空间溢出效应, spatial spillover )。

    也就是说,某一单元 i i i 在时刻 t t t 的解释变量 x x x 的变动不仅会对该单元 (即 i i i ) 自身的被解释变量有直接影响,也会对其他单元 (即 单元 i i i 的 “邻居”) 的被解释变量有间接影响并最终会反过来影响单元 i i i (因为对于其他单元, i i i 也是其 “邻居”),这与非空间面板数据模型存在明显的不同。

    4.3 直接效应,间接效应和总效应

    为了解决空间计量模型系数难以解释问题,LeSage 和 Pace (2009) 提出直接效应 (direct effects, DE), 间接效应 (indirect effects, IE) 和 总效应 (total effects, TE)。对于空间 Durbin 模型,模型可以表示为

    y t = ( I − ρ W ) − 1 ( α + x t β + W x t θ + λ t ι n + ε t ) E ( y t ∣ x t ) = ( I − ρ W ) − 1 ( α + x t β + W x t θ + λ t ι n ) \begin{aligned} y_{t} &amp;=(I-\rho W)^{-1}\left(\alpha+x_{t} \beta+W x_{t} \theta+\lambda_{t} \iota_{n}+\varepsilon_{t}\right) \\ E\left(y_{t} | x_{t}\right) &amp;=(I-\rho W)^{-1}\left(\alpha+x_{t} \beta+W x_{t} \theta+\lambda_{t} \iota_{n}\right) \end{aligned} ytE(ytxt)=(IρW)1(α+xtβ+Wxtθ+λtιn+εt)=(IρW)1(α+xtβ+Wxtθ+λtιn)

    其中,在特定稳定条件下, ( I − ρ W ) − 1 = I + ρ W + ρ 2 W 2 + ρ 3 W 3 + … \left(\mathbf{I}-\rho \mathbf{W}\right)^{-1}=\mathbf{I}+\rho \mathbf{W}+\rho^{2} \mathbf{W}^{2}+\rho^{3} \mathbf{W}^{3}+\ldots (IρW)1=I+ρW+ρ2W2+ρ3W3+

    为了更为直观理解上述公式,以下用截面数据框架下 SAR 模型 (仅考虑 W Y WY WY) 为例,有

    E ( y ∣ X ) = ( I − ρ W ) − 1 X β E(\mathbf{y} | \mathbf{X})=(\mathbf{I}-\rho \mathbf{W})^{-1} \mathbf{X} \beta E(yX)=(IρW)1Xβ

    若研究样本为中国 34 个省级行政区域,经济发展水平为解释变量,记为 X 0 X_{0} X0,环境污染水平为被解释变量,记为 y y y。保持 X 0 X_{0} X0 的其他值不变,将福建省所对应的样本观察值修改为某个数值,将修改后变量记为 X 1 X_{1} X1, 则有

    E ( y ∣ X 1 ) − E ( y ∣ X 0 ) = ( I − ρ W ) − 1 X 1 β − ( I − ρ W ) − 1 X 0 β = ( I − ρ W ) − 1 Δ X β = ( I + ρ W + ρ 2 W 2 + ρ 3 W 3 + … ) Δ X β = Δ X β + ρ W Δ X β + ρ 2 W 2 Δ X β + ρ 3 W 3 Δ X β + … \begin{array}{l}{E\left(\mathbf{y} | \mathbf{X}_{1}\right)-E\left(\mathbf{y} | \mathbf{X}_{0}\right)} \\ {=(\mathbf{I}-\rho \mathbf{W})^{-1} \mathbf{X}_{1} \beta-(\mathbf{I}-\rho \mathbf{W})^{-1} \mathbf{X}_{0} \beta} \\ {=(\mathbf{I}-\rho \mathbf{W})^{-1} \Delta \mathbf{X} \beta}\\{=\left(\mathbf{I}+\rho \mathbf{W}+\rho^{2} \mathbf{W}^{2}+\rho^{3} \mathbf{W}^{3}+\ldots\right) \Delta \mathbf{X} \beta}\\{=\Delta \mathbf{X} \beta+\rho \mathbf{W} \Delta \mathbf{X} \beta+\rho^{2} \mathbf{W}^{2} \Delta \mathbf{X} \beta+\rho^{3} \mathbf{W}^{3} \Delta \mathbf{X} \beta+\ldots} \end{array} E(yX1)E(yX0)=(IρW)1X1β(IρW)1X0β=(IρW)1ΔXβ=(I+ρW+ρ2W2+ρ3W3+)ΔXβ=ΔXβ+ρWΔXβ+ρ2W2ΔXβ+ρ3W3ΔXβ+

    [ ∂ E ( y 1 ) ∂ x 1 ⋯ ∂ E ( y 1 ) ∂ x n ⋮ ⋱ ⋮ ∂ E ( y n ) ∂ x 1 ⋯ ∂ E ( y n ) ∂ x n ] = ( I − ρ W ) − 1 [ β k w 12 θ k ⋯ w 1 n θ k w 21 θ k β k ⋯ w 2 n θ k ⋮ ⋮ ⋱ ⋮ w n 1 θ k w n 2 θ k ⋯ β k ] \left[ \begin{array}{cccccc}{\frac{\partial E\left(y_{1}\right)}{\partial x_{1}}} &amp; {\cdots} &amp; {\frac{\partial E\left(y_{1}\right)}{\partial x_{n}}} \\ {\vdots} &amp; {\ddots} &amp; {\vdots} \\ {\frac{\partial E\left(y_{n}\right)}{\partial x_{1}}} &amp; {\cdots} &amp; {\frac{\partial E\left(y_{n}\right)}{\partial x_{n}}}\end{array}\right]=(\mathbf{I}-\rho \mathbf{W})^{-1} \left[ \begin{array}{cccc}{\beta_{k}} &amp; {w_{12} \theta_{k}} &amp; {\cdots} &amp; {w_{1 n} \theta_{k}} \\ {w_{21} \theta_{k}} &amp; {\beta_{k}} &amp; {\cdots} &amp; {w_{2 n} \theta_{k}} \\ {\vdots} &amp; {\vdots} &amp; {\ddots} &amp; {\vdots} \\ {w_{n 1} \theta_{k}} &amp; {w_{n 2} \theta_{k}} &amp; {\cdots} &amp; {\beta_{k}}\end{array}\right] x1E(y1)x1E(yn)xnE(y1)xnE(yn)=(IρW)1βkw21θkwn1θkw12θkβkwn2θkw1nθkw2nθkβk

    = { ( I − ρ W ) − 1 × ( β k I + θ k W ) } =\left\{(\mathbf{I}-\rho \mathbf{W})^{-1} \times\left(\beta_{k} \mathbf{I}+\theta_{k} \mathbf{W}\right)\right\} ={(IρW)1×(βkI+θkW)}

    4.3.1 直接效应

    直接效应为上述矩阵对角元素的平均值,若 A d ‾ A^{\overline{d}} Ad 表示对矩阵 A A A 的对角线元素求行平均,此时 DE 可以表示为:

    D E = { ( I − ρ W ) − 1 × ( β k I + θ k W ) } d ‾ DE = \left\{(\mathbf{I}-\rho \mathbf{W})^{-1} \times\left(\beta_{k} \mathbf{I}+\theta_{k} \mathbf{W}\right)\right\}^ {\overline{d}} DE={(IρW)1×(βkI+θkW)}d

    直接效应 表示的是某地区自变量对该因变量的影响大小,其包括反馈效应 (feedback effects, FE),即对其他地区的影响又会反过来影响该地区。从数值上来看,直接效应等于空间 Durbin 模型系数与反馈效应之和。具体地,反馈效应 指的是某个地区的解释变量 (如:技术创新) 会对其"邻近"地区的被解释变量 (如:可再生能源生产量),反过来又会影响该地区的被解释变量 (如:可再生能源生产量)。例如:某地区技术会被其"邻近"地区模仿与采用,用来生产可再生能源,这些地区又可将生产的再生能源出口到本地区,进而影响本地区的可再生能源量。
    空间计量-直接效应
    空间计量-间接效应

    4.3.2 间接效应

    间接效应 为矩阵非对角元素的行平均,若 A r s u m ‾ ​ A^{\overline{\mathrm{rsum}}}​ Arsum 表示对矩阵 A ​ A​ A 的非对角线元素求行平均,即 IE 可以表示为:
    I E = { ( I − ρ W ) − 1 × ( β k I + θ k W ) } r s u m ‾ IE = \left\{(\mathbf{I}-\rho \mathbf{W})^{-1} \times\left(\beta_{k} \mathbf{I}+\theta_{k} \mathbf{W}\right)\right\}^ {\overline{\mathrm{rsum}}} IE={(IρW)1×(βkI+θkW)}rsum

    间接效应,又称为空间溢出效应 (spatial spillover effects),用于度量“邻近”地区的某个解释变量(如:技术创新)对本地区的被解释变量的影响 (如:可再生能源生产)。值得注意的是,不能仅仅依靠空间自回归系数 ρ \rho ρ显著与否来判断空间效应的存在。

    4.3.3 总效应

    总效应为直接效应和间接效应之和,即 T E = D E + I E TE = DE + IE TE=DE+IE。其可以解释为某一地区的某个解释变量的变动对所有地区的被解释变量的平均影响。本部分主要讨论空间杜宾模型下的直接效应,间接效应(空间溢出效应)和总效应的计算,其他模型形式可以参考 LeSage和Pace(2009)。

    5. 模型实现

    5.1 命令语法介绍

    空间面板数据模型中包括了 W y Wy Wy,该变量为内生变量。相比静态面板数据模型,其估计更为复杂。当前常用的方法包括三种,包括:广义矩估计法 (GMM)、极大似然估计法 (ML) 和贝叶 斯 MCMC 估计法。GMM 估计的思路是将模型作为普通的动态面板数据模型进行估计,这时候 w y i , t wy_{i,t} wyi,t 存在内生性,应该设定相应的工具变量。具体地,可先利用 splagvar 或者 spgenerate 命令生成变量 w ∗ y i , t w*y_{i,t} wyi,t,进而利用 xtabond2 命令进行动态面板数据模型估计。在贝叶斯估计方法,更加详细可以参考 LeSage和Pace (2009)。本部分所介绍的 Stata 命令,主要是基于极大似然法进行参数估计。

    Stata 15 版增加相应的空间计量模型估计 (help spxtregress)和相关检验命令 (help spxtregress postestimation),在估计模型后可以通过 estat impact 计算直接效应,间接效应和总效应。详细的手册可以参考「 Stata: Stata 15 PDF 电子手册」 。目前,spxtregress 还不支持动态空间面板数据模型估计,这里主要介绍 Federico Belotti等人开发的 xsmle 命令,该命令同时支持空间动态面板数据模型的估计,该命令已发表在 Stata Journal,更为详细的可以参见
    「 Spatial panel-data models using Stata 」

    以空间杜宾模型为例, xsmle 语法如下:

     xsmle depvar [indepvars] [if] [in] [weight] ,  ///
           wmat(name) model(sdm) [SDM_options]
    

    为了方便说明,同时列出普通面板数据模型的命令语法,

      xtreg depvar [indepvars] [if] [in] [weight] , fe [FE_options]
    

    对比可以发现,xsmle 命令增加了 wmat()model() 这两个选项。model() 用于定义空间面板数据模型形式,包括空间杜宾模型 (SDM),空间滞后模型 (Spatial Autoregressive model, SAR),空间误差模型 (Spatial Error model, SEM),空间自相关模型 (Spatial Autocorrelation model, SAC),以及广义空间面板随机效应模型(Generalized Spatial Panel Random Effects model, GSRE)。

    连享会计量方法专题……

    5.2 空间权重矩阵生成

    前文已经介绍,利用空间计量模型的一个重要前提是空间权重矩阵的合理定义,wmat 选项就是用于空间权重矩阵,其可以为 Stata 中矩阵或者 spmat 目标(即利用 spmat 产生, help spmat )。下文基于地理位置信息构造空间权重矩阵进行说明。

    为了计算该类空间权重矩阵,首先需要获得研究单元的地理位置信息,如经度和维度。当研究样本为国家时,通常以国家的首都或者最大城市位置信息作为国家位置的代表。获取经度和维度有多种途径,比较方便的是下载到研究单元对象的 ESRI Shapefile (shapefile) 文件。中国的 shape 文件,包括省级,市级和县级的可以在国家基础信息中心申请下载 (各大论坛应该也有)。若研究的样本为世界各个国家,可以到 (http://www.diva-gis.org/gdata) 下载 。 例如,下载的 shape 文件包括:

    •   TM_WORLD_BORDERS_SIMPL-0.2.dbf
    •   TM_WORLD_BORDERS_SIMPL-0.2.shp
    •   TM_WORLD_BORDERS_SIMPL-0.2.shx
    •   TM_WORLD_BORDERS_SIMPL-0.2.prj

    首先,生成样本数据,这里假设研究样本为 10 个国家,时间为 1935 到 1954 年。

    clear
    input str16 countries
    "China"
    "United States"
    "Germany"
    "Japan"
    "India"
    "Brazil"
    "Russia"
    "South Africa"
    "United Kingdom"
    "Spain"
    end
    
    expand 20
    sort countries
    bys countries:gen year = _n + 1934
    egen company = group(countries)
    merge 1:1 company year using grunfeld
    keep if _merge==3
    drop _merge time
    
    save G:\sample_sp,replace
    

    若以 invest 为因变量,mvaluekstock 为自变量。若采用普通面板固定效应模型,在声明面板数据结构后,可利用如下命令进行估计:

    xtreg invest mvalue kstock,fe
    
    

    若采用空间面板数据模型进行建模,则还需要找出这些国家的经度和维度等地理信息。前文已经说明了如何下载 shapefile 文件,该文件中即包含了各个国家的地理信息。那么可以将研究单元数据和 shapefile 进行合并。这里需要用到 shp2dta 命令读取 shapefile 文件,该命令为外部命令,安装方式参考「 Stata: 外部命令的搜索、安装与使用」

    . cd "c:\"
    . shp2dta using "TM_WORLD_BORDERS_SIMPL-0.2.shp", ///
           database(data_db) coordinates(data_xy) ///
           genid(id) gencentroids(c) replace  
    
    . use "data_db", clear
    . rename NAME countries
    . list countries LAT LON in 1/10
    
         +-----------------------------------------+
         |           countries       LAT       LON |
         |-----------------------------------------|
      1. | Antigua and Barbuda    17.078   -61.783 |
      2. |             Algeria    28.163     2.632 |
      3. |          Azerbaijan     40.43    47.395 |
      4. |             Albania    41.143    20.068 |
      5. |             Armenia    40.534    44.563 |
         |-----------------------------------------|
      6. |              Angola   -12.296    17.544 |
      7. |      American Samoa   -14.318   -170.73 |
      8. |           Argentina   -35.377   -65.167 |
      9. |           Australia   -24.973   136.189 |
     10. |             Bahrain    26.019    50.562 |
         +-----------------------------------------+
    

    读取 shapefile 后,可以发现有 LATLON 两个变量,分别代表了对应国家的纬度和经度。

    接下来,利用该数据和样本数据 sample_sp.dta 根据 countries 这一变量进行合并,并将数据保存为 spatial_weight.dta。

    merge 1:m countries using "G:\sample_sp.dta"
    keep if _merge==3
    drop _merge
    keep countries year LAT LON invest mvalue kstock
    sort countries year
    by countries, sort: list, constant
    bys countries: keep if _n==1
    save G:\spatial_weight.dta,replace
    

    为了构造空间权重矩阵,利用上述生成的 spatial_weight.dta 数据中的纬度和经度信息进行计算。这里可以利用 spwmatrix生成空间权重矩阵。该命令可以构造多种形式的空间权重矩阵,包括基于地理位置信息的距离权重矩阵,基于经济社会变量的经济权重矩阵。此外,也可以导入 Geoda 生成的 gal 文件,或直接导入 txt 文件。

    例如,可利用上面代码产生距离倒数空间权重矩阵

    use "G:\spatial_weight.dta",clear
    spwmatrix gecon LAT LON, wn(example_w2)  ///
        wtype(inv) r(3958.761) alpha(1) ///
        xport(example_w2,txt) row replace
    spmat import example_w2 using example_w2.txt,replace
    spmat save example_w2 using example_w2m.spmat,replace
    spmat use WW using example_w2m.spmat,replace 
    

    我们来看 spwmatrix 命令的语法:

    spwmatrix gecon varlist [if] [in],  ///
           wname(wght_name) ///
           [wtype(bin|inv|econ|invecon) ///
           cart r(#) dband(numlist) ///
           alpha(#) knn(#) ///
           econvar(varname1) beta(#) Other_options] 
    

    wname() 填写生成的矩阵名称,wtype() 内填写生成矩阵类型,如 bin 表示 binary 二元权重矩阵,inv 表示生成逆距离矩阵,econ 为经济权重矩阵等。r() 内填写地球半径,单位可以是英里或者千米。alpha() 内填写数字,如 1 表示距离 1 次方倒数,2 表示距离平方的倒数。knn() 用于定义最邻近单元个数。row 表示对该矩阵进行行标准化。

    在运行 spwmatrix 后,在本地会生成 example_w2.txt 文件,可以将其导入到 Stata 中查看,

    insheet using "example_w2.txt", clear delimiter(" ") names
    drop v1
    rename (v#) (v#),renumber
    export excel using "spatial_weight.xls",replace 
    list in 1/10
    

    上述生成的 spatial_weight.xls文件就可以导入到 RMatlab 中运行。

    此外,也可以生成 k-nearest 空间权重矩阵,代码如下:

    use G:\spatial_weight.dta,clear
    spwmatrix gecon LAT LON, ///
         wn(knear_w) knn(5) ///
         xport(distant_nearest,txt) ///
         row replace /*这里定义最近的5个地区为邻居*/
    spmat import nearest_w using distant_nearest.txt,replace
    spmat save nearest_w using nearest_w.spmat,replace
    spmat use WW using nearest_w.spmat,replace  
    

    5.3 空间面板数据模型估计

    根据步骤 (2) ,我们已经生成了空间权重矩阵,接下来按照第 (1) 部分生成的 sample_sp.dta 数据进行实证建模

    cd "H:\"
    use spatial_weight.dta,clear
    spwmatrix gecon LAT LON, ///
          wn(example_w2) wtype(inv) ///
          r(3958.761) alpha(1) ///
          xport(example_w2,txt) row replace
    spmat import example_w2 using "example_w2.txt", replace
    spmat save example_w2 using "example_w2m.spmat", replace
    spmat use WW using "example_w2m.spmat", replace 
    
    use sample_sp.dta,clear
    rename company id
    
    xtset id year,y
    local xorg "invest mvalue kstock"
    foreach f of local xorg {
    gen ln`f' = log(`f')
    }
    
    est clear
    eststo: xtreg lninvest lnmvalue lnkstock, fe /*普通面板数据模型*/
    
    eststo:xsmle lninvest lnmvalue lnkstock, fe ///
           model(sar) wmat(WW) type(both) ///
           effects nolog /*空间面板数据模型:SAR model*/
    

    估计结果显示如下:

    convergence not achieved
    Computing marginal effects standard errors using MC simulation...
    
    SAR with spatial and time fixed-effects              Number of obs =       200
    
    Group variable: id                                Number of groups =        10
    Time variable: year                                   Panel length =        20
    
    R-sq:    within  = 0.4258
             between = 0.8555
             overall = 0.8165
    
    Mean of fixed-effects =  3.5886
    
    Log-likelihood =    31.1740
    ------------------------------------------------------------------------------
        lninvest |      Coef.   Std. Err.      z    P>|z|     [95% Conf. Interval]
    -------------+----------------------------------------------------------------
    Main         |
        lnmvalue |   .3087483   .0771167     4.00   0.000     .1576024    .4598942
        lnkstock |   .0788984   .0306623     2.57   0.010     .0188015    .1389953
    -------------+----------------------------------------------------------------
    Spatial      |
             rho |  -.4325611    .167113    -2.59   0.010    -.7600965   -.1050257
    -------------+----------------------------------------------------------------
    Variance     |
        sigma2_e |   .0415918   .0042036     9.89   0.000     .0333528    .0498308
    -------------+----------------------------------------------------------------
    LR_Direct    |
        lnmvalue |   .3189515   .0808705     3.94   0.000     .1604482    .4774549
        lnkstock |    .079349   .0306296     2.59   0.010      .019316    .1393819
    -------------+----------------------------------------------------------------
    LR_Indirect  |
        lnmvalue |  -.0952446   .0387047    -2.46   0.014    -.1711044   -.0193847
        lnkstock |  -.0239403   .0128027    -1.87   0.061    -.0490331    .0011526
    -------------+----------------------------------------------------------------
    LR_Total     |
        lnmvalue |    .223707    .064382     3.47   0.001     .0975205    .3498934
        lnkstock |   .0554087   .0221398     2.50   0.012     .0120155     .098802
    --------------------------------------------------------