dxzmpk

endless hard working

0%

概括

这篇博客将对java中的本地方法进行介绍,主要从为什么需要本地方法,以及本地方法是如何运行的两个方面进行。

为什么需要本地方法

java的跨平台特性是其一大优点,我们通过一次编译得到字节码,就能在任何可以运行jvm(Java Virtual Machine)的系统上执行。然而,在有些情况下,我们可能需要一些纯java代码无法实现的功能,这时我们需要一些在本地编译好,只能在特定环境下执行的代码,也就是本地方法,本地方法常常由C/C++语言编写。

需要使用本地方法的情况主要有以下三种:

  1. 需要和硬件进行交互
  2. 对于有些方法,使用C/C++可以加快执行的速度,因为C/C++的编译是依赖于操作系统的,对于程序性能有要求的可以考虑使用本地方法。
  3. 有些库已经用其他语言写好,我们想使用但是不想重新再写一遍的话,就可以使用本地方法。

java代码是在 jvm中运行的, 本地方法是在本地环境中运行的,为了在java程序中调用本地方法,就需要一个桥梁将本地方法和jvm连接起来,这个桥梁就是JNI(java native interface)。

本地方法是如何运行的

java关键字native 表明某个接口是由本地代码实现的。

java调用C/C++代码的时候,使用的是动态链接库的方式(shared libs),因为我们不能把字节码和本地编译好的代码放在同一个二进制文件中(jvm无法执行本地代码)。因此,最终编译好的java代码只声明对本地代码的引用, 而不是直接把代码复制过来。所以引用的库中会包含so/.dll/.dylib等文件,操作系统不同,文件的格式也不同。

本地方法也是一种抽象方法, 我们只是声明方法头, 具体的实现则交给本地代码。

1
private native void aNativeMethod();

要实现本地方法的运行,主要需要以下组件:

  • Java Code – our classes. They will include at least one native method.
  • Native Code – the actual logic of our native methods, usually coded in C or C++.
  • JNI header file – this header file for C/C++ (include/jni.h into the JDK directory) includes all definitions of JNI elements that we may use into our native programs.
  • C/C++ Compiler – we can choose between GCC, Clang, Visual Studio, or any other we like as far as it’s able to generate a native shared library for our platform.

本地方法代码编写步骤

创建java类,其中声明本地方法

利用Java编译器(javac)的-h选项创建方法的引用,.h文件

创建.cpp文件,实现本地代码

编译并链接

编译C++代码:

Ubuntu version:

1
g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux com_baeldung_jni_HelloWorldJNI.cpp -o com_baeldung_jni_HelloWorldJNI.o

Windows version:

1
g++ -c -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 com_baeldung_jni_HelloWorldJNI.cpp -o com_baeldung_jni_HelloWorldJNI.o

MacOS version;

1
g++ -c -fPIC -I${JAVA_HOME}/include -I${JAVA_HOME}/include/darwin com_baeldung_jni_HelloWorldJNI.cpp -o com_baeldung_jni_HelloWorldJNI.o

和java共享库建立链接:

1
g++ -shared -fPIC -o libnative.so com_baeldung_jni_HelloWorldJNI.o -lc

Windows version:

1
g++ -shared -o native.dll com_baeldung_jni_HelloWorldJNI.o -Wl,--add-stdcall-alias

MacOS version:

1
g++ -dynamiclib -o libnative.dylib com_baeldung_jni_HelloWorldJNI.o -lc

在命令行中执行

1
java -cp . -Djava.library.path=/NATIVE_SHARED_LIB_FOLDER com.baeldung.jni.HelloWorldJNI

除此之外,java与本地方法之间还可以传递参数,参数类型是通过JNIEnv进行映射的,映射表的链接

参考文献

https://www.baeldung.com/jni

介绍

动机

我是一名NBA球迷,上大学后时间都由自己支配了,因此将更多的时间花在追星这件事上。而对于篮球迷来说,虎扑则是大家一起交流娱乐的乐园。在大多数无聊的时候,我会打开虎扑网页或者APP版,查看有关詹姆斯的信息。而且我只关注他一个人,别人的消息我都直接划过,甚至对我来说是浪费时间,因此萌生了 使用爬虫过滤信息的方法。

爬虫+EXCEL阅读

image-20201129210419725

image-20201129210601902

实现的唯一功能是爬取湿乎乎的话题这一板块的所有数据,然后过滤得到标题中包含詹姆斯的结果,最终将链接也一并返回。

需求大致是实现了,一开始用的也很起劲。但是,每次阅读之前我都需要打开Pycharm, 等爬取结束之后再打开EXCEL,这中间的步骤太多,以致大多数情况下,我都不愿意,也可能不记得使用这个工具。久而久之,写好的代码就被我闲置了。最近开始学习安卓开发,就萌生了将这个功能部署在云服务器,然后写一个APP来展示数据的想法,写这个应用的初衷是节约时间,故名曰:TIMESAVER。

版本迭代

v1.0

首页:

image-20201129221653452

点击获取之后,会进入等待状态,同时会向云服务器发送请求,云服务器实时爬取之后将结果返回到客户端。

image-20201129221805801

返回的数据直接放入TextView进行展示,展示效果如图:

image-20201129221944630

v2.0

最近新学习了ListView, 通过ListView可以自定义每一项的显示,相对来说自由度比较高,可以获得更加美观的结果。除此之外, ListView还自带滚动效果,省去了调整ScrollView的困难(在v1.0的实现中需要使用ScrollView, 其宽度和长度的属性设置曾产生了难以解释的结果,导致我最后只能通过硬编码的方式解决布局问题)。

通过菜单栏切换到列表模式:

image-20201129222756210

还是相同的操作,点击获取,等待……最终得到结果:

image-20201129222848423

肉眼可见的两点改进:

  • 不同新闻之间可以添加分割线,更加明确区分的界限。
  • 可以在标题前添加序号,方便计数与识别。

介绍

创建者模式

单例模式
工厂模式
工厂中的具体实例化

结构型模式

外观模式
尽管解决方案很大,但是客户端仍然希望使用简化的界面与子系统进行交互。
外观不会增加更多功能,而外观只是充当子系统的入口点。

image-20201126144147502

适配器模式
一个系统的输出可能与另一系统的预期输入不一致。

image-20201126144207333组成模式
多态性

image-20201126144226796

代理模式
能够完成相同的任务,但是将请求委派给原始对象以实现它们。
推迟创建资源密集型对象,直到需要
远程系统的本地表示
保证安全性

image-20201126144235090装饰者模式
行为组合->新类,类的数目可能会过于多
一对一聚合。
堆栈聚合,顺序很重要!
使用时,我们需要继承抽象装饰器并使用具体装饰器类实现组件接口

image-20201126144258511

行为模式

模板方法模式

模板方法模式定义了一个操作中算法的执行结构,而将一些子类之间不同的行为延迟到子类中定义。

image-20201126144309874

职责链模式

将问题的解决者对象连接在一起。将request 传递下去。

但是,如果其中的一个解决者没有传递对象的话,就会产生问题。这里需要使用模板方法模式规定行为的发生顺序,至于每个解决者如何解决问题,延迟到子类中进行实现。

image-20201126144321678

状态模式

当系统处于不同的状态,对不同的行为需要做出不同的反应时,我们往往需要使用很多的if-else条件分支。而使用状态模式,通过维持当前上下文的一个状态,由状态对发生的行为进行处理,而具体的实现在状态子类的对应方法中。通过这种方式就可以简化代码。

image-20201126144350572

指令模式

指令模式将对象对另一个对象的方法调用封装为一个Command对象,这样就可以将方法的调用保存到队列中之后再规划执行。

中介者模式

通过中介者,将相互有联系的对象的交互逻辑限制在中介者中,从而让代码更加集中,减少对象之间的耦合,但是同样地,会降低内聚性,因此需要在二者之间做好平衡。

观察者模式

主要包含一个域、三个方法,方法分别为添加订阅者,删除订阅者,通知全部订阅者,通知是通过调用所有Observer的update方法实现的,因此所有的Observer类都要实现相同的接口。

MVC and Good/Bad Design

image-20201126144408610

Code smell:

  • Comments
  • long methods
  • not just getter and setter
  • long parameter is bad, introduce parameter objects
  • global variables which is also bad

Part2: code smells when you make changes to the code

  • 如果一开始没有做到seperation of concerns, 会导致最终的divergent change.
  • change to be localized
  • 如果两个类总是频繁地进行交流,他们可能本就属于一处。
  • message chains: makes code harder to test independly
  • Switch Statements:
  • Speculative Generality
  • Refused Bequest: 拒绝馈赠

问题篇

不同表之间交叉在一起,很难进行之后微服务的划分

历史篇

  1. 本来考虑用promotion表来存储用户推广的记录,但是后来业务要求确认为只有收到推广的人下单了才算推广成功,并添加到用户的推广酬金中。因此删除了推广表,在订单中添加了推广码字段。减少了信息的冗余,适应了业务。

  2. TimeQuery, 在很多查询中都用到了时间作为查询的条件。为了保证时间的有效性,每次都需要进行一系列操作:

    • 时间为空值的话,需要设定为边界值
    • 如果开始时间大于结束时间,返回错误。
    • 因为时间精确到天,天默认是0:00,也就是对于结束时间,查询得到的结果是当天之前的,这可能导致用户查询不到想要的信息,因此结束的天数要加1。

    为了方便,直接抽象出一个TimeQuery类,任何需要时间的查询都继承这个类,并实现checkTime方法,返回HttpResponse,减少了重复代码。

  3. 之前生成订单的流程是

    1. 根据请求的id查询课程
    2. 检查课程库存是否为0,如果为0直接拒绝请求
    3. 将订单信息存入表中
    4. 课程库存减1,销量加1

    可能存在的问题是如果库存中有一个课程,那么两个用户同时请求生成订单,两个用户都能申请成功,导致课程变为数量变成-1。

    解决思路:

    • 当检查课程库存不为0时,先对课程库存进行操作,否则无法生成订单。

https://miro.medium.com/max/2079/0*K8kz2wcJ84fEme5s

Introduction— SIMPLICITY—> RIGHT —> EXPLAIN

评价软件架构设计好坏的标准:

  1. 对于代码很小的修改是不是会对其他地方有较大的影响 — flexible
  2. 代码重用是不是很困难 — reusable
  3. 软件是不是很难维护 — maintainable

Design — Architecture

Use Object to represent things; Modular,

用户故事的重要性

三种对象

  1. 实体对象

    对应于现实生活中的一些实体。

    知道自身的一些属性,同时可以对自己进行编辑。

    在分析时,通常是最先出现的。

  2. 边界对象

    边界对象位于系统的交界处,例如和网络进行通信的对象。

  3. 控制对象

    控制对象的主要作用是协调。当把一个大对象拆分成小对象之后,让一个对象控制其他对象是非常有用的。

    一个很好的例子就是设计模式之中的Mediator, 其作用是通过协调使得不同的对象之间达到松耦合的效果。

    flexible, reusable, and maintainable~

Non functional Requirements

CRC cards:

Class Responsibility Collaborator

Record Organize Refine

image-20201114124451028

Object-Oriented Modeling

1
abstraction, encapsulation, decomposition, and generalization

Degisn Pricinples — Abstraction

抽象将概念的简要表示提取出来,并忽略一些不重要的细节,从而让我们更好地理解概念。

Relevent Attributes and Behavior IN THIS CONTEXT

Encapsulation

封装既包括把属性值和行为包含在一个对象里,还包括暴露特定的数据和函数,同时还有将对某些数据和方法的访问限制在同一个对象内。

封装的思想之一是将对某些数据和功能的访问限制为仅在一个对象内.

这就提供了以下几点有用的性能:

  1. 自身的属性限制—-Integrity and Security
  2. 对外界数据和方法的保禄—-Changeable Implementation
  3. 内部的实现外部无法看到—-Black box, abstraction barrier , increase reusability

Decomposition

分解:把一个大的问题拆分成容易理解和解决的小问题

整体中的每一个不同的部分都可以单独开一个类,这样我们就能更好地组织、封装不同的部分。

整体和部分的关系

  1. 整体会包含多个部分,部分的数目可能是固定的,也可能是可变的,这取决于具体的问题。
  2. 整体和部分都有自己特定的生存周期,二者的生存周期可能是相同的,也可能是不同步的,同样需要具体问题具体分析。
  3. 整体之间也可以分享自己的部分

三种分解关系

  1. Association

    不依赖于彼此,但是可能会相互交互,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Association can be represented in Java code as well.  

    public class Student {
    //Any number of sports can be played by a student and any number of students can play a sport.
    public void play( Sport sport ){
    execute.play( sport );
    }

    }
  2. Aggregation

    整体拥有部分,但这种拥有权是比较弱的,部分也可以单独存在。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Aggregation can be represented in Java code as well. 

    public class Airliner {
    private ArrayList<CrewMember> crew;

    public Airliner() {
    crew = new ArrayList<CrewMember>();
    }

    public void add( CrewMember crewMember ) {

    }
    }
  3. Composition

    合成关系整体对于部分的排他性包含。换句话说,没有部分就不能存在一个整体,如果整体被破坏了,那么这些部分也将被破坏。在这中关系中,我们只能通过整体来访问部分。例如房屋和房间的关系。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    Composition can be represented using Java code as well.  

    public class House {
    private Room room;

    public House(){
    room = new Room();
    }
    }

Generalization

泛化体现在以下方面:

methods: 同一个方法可以用于不同的输入数据,因此我们不需要为每一个数据都建立方法,减少了代码的冗余。

inheritance: 通过继承可以省略重复的代码。

继承的优点:对于不同子类方法的修改只需要一次性在父类中修改即可。可以轻松添加子类,而不用重新添加相同的属性和方法,软件扩展起来更加容易。

1
2
3
4
5
6
Java中受保护的属性只能由以下人员访问:
• 封装的类本身
• 所有子类
• 同一包内的所有类

关键字abstract表示无法实例化该类。换句话说,不能创建该对象。

继承的不同种类

Java能够支持几种不同类型的继承。本课程中的以上示例是实现继承。

  1. 实现继承

    ​ 只能继承一个父类,提供了方法的实现细节。表示“是”关系。对于狮子来说,它既有动物的属性,又有狮子特有的属性,因此狮子是动物和狮子。

  2. 接口继承

    可以实现多个接口,同时不会继承方法细节。

这是因为从两个或多个超类继承会引起数据歧义 - 如果子类从两个或多个具有相同名称的属性或具有相同方法签名的行为的超类继承,则无法区分它们。由于Java无法确定引用了哪个对象,因此它不允许多重继承以防止数据歧义。而在接口继承中,具有多个接口的重叠方法签名只有单一实现,这是可以接受的。

在实现继承中,超类类型和子类类型之间具有一致性。子类对象可在程序中要处理超类类型的任何地方使用。类似地,在接口继承中,接口类型与实现类类型之间具有一致性。

使用接口的好处:

在面向对象的语言中,多态是指两个类对行为的描述相同,但是该行为的实现可能不同。

  1. 接口可以继承其他接口
  2. 允许多重继承

使用接口的时机

不应该将所有behavioural contracts都归纳为接口。创建接口需要满足特定要求:为相关类提供一种一致工作的方式。

设计的步骤

和顾客沟通时,主要使用的技术是CRC卡片,而在技术设计中,UML类表是更合适的选择。

image-20201114163502253

DESIGN PRINCIPLES

Evaluating Design Complexity

模块:指代组成程序的多个单元,包括其中的类和方法。这也是Design complexity关注的粒度。

良好的设计:模块可以重复使用,并且很方便地连接其他模块。这种特性主要由Cohesion和Couping两种指标来衡量。

耦合: ease to use -> loose couplng, 如果一个模块可以很容易地通过定义明确的接口连接其他模块,则是松耦合的。模块的耦合主要通过三个指标来度量:

  1. Degree 模块和其他模块连接的数目。
  2. Ease 模块之间建立连接的容易程度。
  3. Flexibility 模块之间是否很容易地进行调换, for something better in the future.

高耦合的特征:

  1. 一个模块需要通过大量的接口和参数来和其他模块建立连接。
  2. 一个模块相连的其他模块很难找到。
  3. 模块只能和其他几个特定的模块相连,而难以替换。

内聚: 目标要单一、明确,如果一个模块包含多个目标,则应该对其进行分隔。

需要平衡二者的关系。Complexity要合理地分布在模块之间和模块内。

Separation of Concerns 关注点分离

关注点:任何和问题的解决方法相关的事情。不同的关注点要放在软件的不同位置。

微信支付接口_后端篇

微信支付系统

微信支付系统是指完成微信支付流程中涉及的API接口、后台业务处理系统、账务系统、回调通知等系统的总称。

签名

商户后台微信支付后台根据相同的密钥和算法生成一个结果,用于校验双方身份合法性。签名的算法由微信支付制定并公开,常用的签名方式有:MD5、SHA1、SHA256、HMAC等。

支付账户

商户在微信公众平台或开放平台提交微信支付申请,微信支付工作人员审核资料无误后开通相应的微信支付权限。微信支付申请审核通过后,商户在申请资料填写的邮箱中收取到由微信支付小助手发送的邮件,此邮件包含开发时需要使用的支付账户信息,见图3.1所示。

微信审核通过邮件模板

微信审核通过邮件模板

邮件中的账户参数与接口API参数对应关系见表格:

邮件中参数 API参数名 详细说明
APPID appid appid是微信公众账号或开放平台APP的唯一标识,在公众平台申请公众账号或者在开放平台申请APP账号后,微信会自动分配对应的appid,用于标识该应用。可在微信公众平台—>开发—>基本配置里面查看,商户的微信支付审核通过邮件中也会包含该字段值。
微信支付商户号 mch_id 商户申请微信支付后,由微信支付分配的商户收款账号
API密钥 key 交易过程生成签名的密钥,仅保留在商户系统和微信支付后台,不会在网络中传播。商户妥善保管该Key,切勿在网络中传输,不能在其他客户端中存储,保证key不会被泄漏。商户可根据邮件提示登录微信商户平台进行设置。也可按以下路径设置:微信商户平台(pay.weixin.qq.com)—>账户中心—>账户设置—>API安全—>密钥设置
Appsecret secret AppSecret是APPID对应的接口密码,用于获取接口调用凭证access_token时使用。在微信支付中,先通过OAuth2.0接口获取用户openid,此openid用于微信内网页支付模式下单接口使用。可登录公众平台—>微信支付,获取AppSecret(需成为开发者且帐号没有异常状态)。

账户参数说明

协议规则

商户接入微信支付,调用API必须遵循以下规则:

传输方式 为保证交易安全性,采用HTTPS传输
提交方式 采用POST方法提交
数据格式 提交和返回数据都为XML格式,根节点名为xml
字符编码 统一采用UTF-8字符编码
签名算法 MD5/HMAC-SHA256
签名要求 请求和接收数据均需要校验签名,详细方法请参考安全规范-签名算法
证书要求 调用申请退款、撤销订单、红包接口等需要商户api证书,各api接口文档均有说明。
判断逻辑 先判断协议字段返回,再判断业务返回,最后判断交易状态

特别提示:

必须严格按照API的说明进行一单一支付,一单一红包,一单一付款,在未得到支付系统明确的回复之前不要换单,防止重复支付或者重复付款

交易类型

JSAPI—JSAPI支付(或小程序支付)、NATIVE—Native支付、APP—app支付,MWEB—H5支付,不同trade_type决定了调起支付的方式,请根据支付产品正确上传

时间

标准北京时间,时区为东八区;如果商户的系统时间为非标准北京时间。参数值必须根据商户系统所在时区先换算成标准北京时间, 例如商户所在地为0时区的伦敦,当地时间为2014年11月11日0时0分0秒,换算成北京时间为2014年11月11日8时0分0秒。

时间戳

标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数。注意:部分系统取到的值为毫秒级,需要转换成秒(10位数字)。

商户订单号

商户支付的订单号由商户自定义生成,仅支持使用字母、数字、中划线-、下划线_、竖线|、星号这些英文半角字符的组合,请勿使用汉字或全角等特殊字符。微信支付要求商户订单号保持唯一性(建议根据当前系统时间加随机序列来生成订单号)。重新发起一笔支付要使用原订单号,避免重复支付;*已支付过或已调用关单、撤销(请见后文的API列表)的订单号不能重新发起支付。

支付

交互细节:

以下是支付场景的交互细节,请认真阅读,设计商户页面的逻辑:

(1)用户打开商户网页选购商品,发起支付,在网页通过JavaScript调用getBrandWCPayRequest接口,发起微信支付请求,用户进入支付流程。

(2)用户成功支付点击完成按钮后,商户的前端会收到JavaScript的返回值。商户可直接跳转到支付成功的静态页面进行展示。

(3)商户后台收到来自微信开放平台的支付成功回调通知,标志该笔订单支付成功。

注:(2)和(3)的触发不保证遵循严格的时序。JS API返回值作为触发商户网页跳转的标志,但商户后台应该只在收到微信后台的支付成功回调通知后,才做真正的支付成功的处理。

微信内网页支付时序图

商户系统和微信支付系统主要交互:

1、商户server调用统一下单接口请求订单,api参见公共api【统一下单API

2、商户server接收支付通知,api参见公共api【支付结果通知API

3、商户server查询支付结果,api参见公共api【查询订单API

data: https://www.kaggle.com/c/competitive-data-science-predict-future-sales/data

notebook: https://www.kaggle.com/jagangupta/time-series-basics-exploring-traditional-ts

难点

提供的是每天的销量,但要求计算出每个月的销量

特征提取

月销量

首先对”date_block_num”,”shop_id”,”item_id”三个量进行聚合,这样能得出某月某个商店每个产品的月销量。然后对值进行累计运算,其中月份取最大最小值,价格取平均值,销量取总和。

每个类别的产品数量

取前10名进行可视化操作,得到

img

模型

单时间序列预测

目标要求我们以商店与商品的组合层次来预测下个月的销量。这里面有商店、商品、月份三个量。

在深入讨论所有组合之前,首先让我们了解如何预测单个的序列。

我选择预测整个公司每月的销量。

首先,让我们计算每月的总收入并取代该数据。

sales.groupby([“date_block_num”])[“item_cnt_day”].sum()

对[“date_block_num”])[“item_cnt_day”]两个量进行聚合,然后求和,得出每个月的总销量。

img

观察得出,销量存在一定的季节性,在一年中的某个时段,销量会剧增。

然后利用大小为12的窗口求窗口的均值和方差,绘制图像。

img

假设序列是加法模型

yt=St+Tt+Et

where yt is the data at period t, St is the seasonal component季节组件 at period t, Tt is the trend-cycle循环组件 component at period t and Et is the remainder (or irregular or error) component补充组件 at period t
Similarly for Multiplicative model,

yt=St x Tt x Et

稳定性检测:

q

Stationarity refers to time-invariance of a series. (ie) Two points in a time series are related to each other by only how far apart they are, and not by the direction(forward/backward)

When a time series is stationary, it can be easier to model. Statistical modeling methods assume or require the time series to be stationary.

There are multiple tests that can be used to check stationarity.

  • ADF( Augmented Dicky Fuller Test)
  • KPSS
  • PP (Phillips-Perron test)

Let’s just perform the ADF which is the most commonly used one.

Note: Step by step guide to perform dicky fuller test in Excel

Another Useful guide

good reference%20STA.ipynb)

实践

使用ADF(Augmented Dicky Fuller Test)进行稳定性检测。

1
2
3
4
5
6
7
8
9
Results of Dickey-Fuller Test:
Test Statistic -2.395704
p-value 0.142953
#Lags Used 0.000000
Number of Observations Used 33.000000
Critical Value (1%) -3.646135
Critical Value (5%) -2.954127
Critical Value (10%) -2.615968
dtype: float64

P值并没有显著小于关键值

接下来通过两步变换,首先一阶差去掉趋势性,然后跨度为12去掉季节性,得到新的时间序列。

1
2
3
4
5
6
7
8
9
Results of Dickey-Fuller Test:
Test Statistic -3.270101
p-value 0.016269
#Lags Used 0.000000
Number of Observations Used 21.000000
Critical Value (1%) -3.788386
Critical Value (5%) -3.013098
Critical Value (10%) -2.646397
dtype: float64

Now after the transformations, our p-value for the DF test is well within 5 %. Hence we can assume Stationarity of the series

We can easily get back the original series using the inverse transform function that we have defined above.

Now let’s dive into making the forecasts!

AR, MA and ARMA models:

TL: DR version of the models:

MA - Next value in the series is a function of the average of the previous n number of values AR - The errors(difference in mean) of the next value is a function of the errors in the previous n number of values ARMA - a mixture of both.

Now, How do we find out, if our time-series in AR process or MA process?

Let’s find out!

Stochastic proess

infinite number of random variables

A time series

Mean function:

随机过程由多个随机变量

当每个变量都取一定值的时候,随机过程就拥有了一个实现,成为时间序列。通过时间序列可以估计随机过程的某些特性。例如,若时间序列中的某一段或者某一点向后移动一段距离,得到的分布和之前的一致,则可以认为随机过程是有强稳定性的。

白噪声分析

constant variance

当时间间隔为0时,autocovariance是方差,否则为0。所以白噪声是稳定的。

白噪声的方差是常数,且独立于时间

autocorrelation自相关系数,不论lag有多少,都是0

当建立线性回归模型或者时间序列模型时,可以测试残差是不是白噪声,也就是错误。因为线性回归的假设之一就是错误是独立的,如果可以使用一个测试来检测残差是不是白噪声,就可以据此得知线性回归模型拟合得好不好。

random walk分析

平均值随着时间增长,极少情况下可能为0。

方差也不是常量。所以random work不是稳定过程。

moving average Process

Q=9 邻居间将增加更远的依赖,同时整体曲线将更加平缓。

Ljung-Box Test

  1. 测试时间序列中的序列自方差系数
  2. 测试预测模型的残差中是否还有需要建模的结构

卡方分布:k个独立的标准正态分布之和遵循的分布。

data: https://www.kaggle.com/c/house-prices-advanced-regression-techniques/data

notebooks: https://www.kaggle.com/pmarcelino/comprehensive-data-exploration-with-python

  1. Understand the problem. We’ll look at each variable and do a philosophical analysis about their meaning and importance for this problem.
  2. Univariable study. We’ll just focus on the dependent variable (‘SalePrice’) and try to know a little bit more about it.
  3. Multivariate study. We’ll try to understand how the dependent variable and independent variables relate.
  4. Basic cleaning. We’ll clean the dataset and handle the missing data, outliers and categorical variables.
  5. Test assumptions. We’ll check if our data meets the assumptions required by most multivariate techniques.

对缺失值的处理

对于缺失值来说不只是有进行默认填充、填充中位数等方式,还可以根据特征是否重要进行相应的删除,但这需要以事实来支撑。

Let’s analyse this to understand how to handle the missing data.

We’ll consider that when more than 15% of the data is missing, we should delete the corresponding variable and pretend it never existed. This means that we will not try any trick to fill the missing data in these cases. According to this, there is a set of variables (e.g. ‘PoolQC’, ‘MiscFeature’, ‘Alley’, etc.) that we should delete. The point is: will we miss this data? I don’t think so. None of these variables seem to be very important, since most of them are not aspects in which we think about when buying a house (maybe that’s the reason why data is missing?). Moreover, looking closer at the variables, we could say that variables like ‘PoolQC’, ‘MiscFeature’ and ‘FireplaceQu’ are strong candidates for outliers, so we’ll be happy to delete them.

In what concerns the remaining cases, we can see that ‘GarageX‘ variables have the same number of missing data. I bet missing data refers to the same set of observations (although I will not check it; it’s just 5% and we should not spend 20𝑖𝑛5in5 problems). Since the most important information regarding garages is expressed by ‘GarageCars’ and considering that we are just talking about 5% of missing data, I’ll delete the mentioned ‘GarageX‘ variables. The same logic applies to ‘BsmtX‘ variables.

Regarding ‘MasVnrArea’ and ‘MasVnrType’, we can consider that these variables are not essential. Furthermore, they have a strong correlation with ‘YearBuilt’ and ‘OverallQual’ which are already considered. Thus, we will not lose information if we delete ‘MasVnrArea’ and ‘MasVnrType’.

Finally, we have one missing observation in ‘Electrical’. Since it is just one observation, we’ll delete this observation and keep the variable.

In summary, to handle missing data, we’ll delete all the variables with missing data, except the variable ‘Electrical’. In ‘Electrical’ we’ll just delete the observation with missing data.

对异常值的处理

使用散点图绘制,观察其中的异常点,对于特别明显的异常点,进行删除。但是对于可能成为特殊案例的要予以保留。

对数据分布的验证

  • Normality - When we talk about normality what we mean is that the data should look like a normal distribution. This is important because several statistic tests rely on this (e.g. t-statistics). In this exercise we’ll just check univariate normality for ‘SalePrice’ (which is a limited approach). Remember that univariate normality doesn’t ensure multivariate normality (which is what we would like to have), but it helps. Another detail to take into account is that in big samples (>200 observations) normality is not such an issue. However, if we solve normality, we avoid a lot of other problems (e.g. heteroscedacity) so that’s the main reason why we are doing this analysis.

  • Homoscedasticity - I just hope I wrote it right. Homoscedasticity refers to the ‘assumption that dependent variable(s) exhibit equal levels of variance across the range of predictor variable(s)’ (Hair et al., 2013). Homoscedasticity is desirable because we want the error term to be the same across all values of the independent variables.

  • Linearity- The most common way to assess linearity is to examine scatter plots and search for linear patterns. If patterns are not linear, it would be worthwhile to explore data transformations. However, we’ll not get into this because most of the scatter plots we’ve seen appear to have linear relationships.

  • Absence of correlated errors - Correlated errors, like the definition suggests, happen when one error is correlated to another. For instance, if one positive error makes a negative error systematically, it means that there’s a relationship between these variables. This occurs often in time series, where some patterns are time related. We’ll also not get into this. However, if you detect something, try to add a variable that can explain the effect you’re getting. That’s the most common solution for correlated errors.

What do you think Elvis would say about this long explanation? ‘A little less conversation, a little more action please’? Probably… By the way, do you know what was Elvis’s last great hit?

特征工程

data: https://www.kaggle.com/c/forest-cover-type-prediction/data

notebook: https://www.kaggle.com/sharmasanthosh/exploratory-study-on-feature-selection

Data statistics

  • Shape

  • Datatypes

  • Description

    使用print(dataset.describe())命令对数据进行分析,主要分析

    count:是否有数据缺失,需不需要补全,

    min是否存在负值,

    编码是怎样的,如果是独热编码,可以转换成原编码以进行统计。

    std:是否存在常数项,如果存在可以被删除。

    mean: 数值的大小是否一致,如果不一致则需要进行归一化处理。

  • Skew

    1
    print(dataset.skew())

    数据的偏度,计算数据是左偏的还是右偏的

    img

  • Class distribution

    计算类别分布

    1
    dataset.groupby('Cover_Type').size()

Data Interaction

  • Correlation

    相关系数需要连续数据,因此使用类别编码的将无法使用

  • Scatter plot

Data Visualization

  • Box and density plots
  • Grouping of one hot encoded attributes

img

Data Cleaning

  • Remove unnecessary columns

Data Preparation

  • Original
  • Delete rows or impute values in case of missing
  • StandardScaler
  • MinMaxScaler
  • Normalizer

Feature selection

  • ExtraTreesClassifier
  • GradientBoostingClassifier
  • RandomForestClassifier
  • XGBClassifier
  • RFE
  • SelectPercentile
  • PCA
  • PCA + SelectPercentile
  • Feature Engineering

Evaluation, prediction, and analysis

  • LDA (Linear algo)
  • LR (Linear algo)
  • KNN (Non-linear algo)
  • CART (Non-linear algo)
  • Naive Bayes (Non-linear algo)
  • SVC (Non-linear algo)
  • Bagged Decision Trees (Bagging)
  • Random Forest (Bagging)
  • Extra Trees (Bagging)
  • AdaBoost (Boosting)
  • Stochastic Gradient Boosting (Boosting)
  • Voting Classifier (Voting)
  • MLP (Deep Learning)
  • XGBoost