解决Mac ReportCrash进程占用大量CPU的问题

今天电脑风扇一直呼呼转,发烫利害。于是看看到底哪个进程占用了大量cpu,top查看发现ReportCrash占用了大量CPU,直接kill之后还是会拉起。

于是从网上查看如何关闭这个进程,方法如下:

打开终端,执行下面命令

launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist

如果后续要打开,可以在终端执行如下命令:

launchctl load -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist

你可能还喜欢下面这些文章

常用js的公共cdn,加速网站

sinaapphttp://lib.sinaapp.com/bootcdnhttp://www.bootcdn.cn/360的http://libs.useso.com/js.php

shell 变量的定义

shell可以自定义变量,这为shell的编写带来很多方便定义变量定义变量时,变量名不加美元符号($),如:variableName=”value”注意:变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样同时,变量名的命名须遵循如下规则。首个字符必须为字母(a-z,A-Z)。中间不能有空格,可以使用下划线(_)。不能使用标点符号。不能使用bash里的关键字(可用help命令查看保留关键字)。变量定义举例:myUrl=”http://imhuchao.com/tag/bash”myNum=100使用变量使用一个定义过的变量,只要在变量名前面加美元符号($)即可,如:your_nam

C++ any容器的介绍与简易实现

一、any容器是什么?

1、any“不是”模板类,any是一种很特殊的容器。
2、any只能容纳一个元素,但这个元素可以是任意的类型,可以是基本数据类型(int、double、string、标准容器或者任何自定义类型)。
3、一种动态(类型检查只发生在运行时)语言特性的数据结构。
4、C++17引入,需要RIIT支持,VS默认是没有支持C++17的,需要自己修改设置,如果不能使用any,请修改标准。

二、any类摘要

class any
{
public:
	any(); //默认构造
	any(const any& _That); //拷贝构造
	template<class _ValueType>
		any(_ValueType&& _Value);
	~any();	//析构
	any& operator=(const any& _That); //拷贝复制
	void reset();//清空内容
	void swap(any& _That); //交换语义
	bool has_value() const; //是否持有值
	const type_info& type() const; //获取类型信息
	template<class _Decayed>
	_Decayed * _Cast(); //若*this包含_decay类型的值,返回一个指向它的指针
};

//辅助函数
void swap(any& _Left, any& _Right); //交换语义
template<class _ValueType,class... _Types>
inline any make_any(_Types&&... _Args);	//工厂函数
template<class _Ty>
_Ty any_cast(const any& _Any);	//访问元素,运行时类型检查,不一致则抛出bad_any_cast异常。并且含有多个重载版本。

C++typeid关键字详解:

三、any类用法

#include<iostream>
#include<any>
#include<vector>
#include<set>
using namespace std;
int main() {
	any Int = 69,//整型
	Double = 8.8,	//浮点型
	CStr = "hello",	//字符数组
	Str = string("world!");	//string类
	vector<any> anys = { Int, Double, CStr, Str }; //可直接放入序列容器中
	//set < any > any_set{ Int,Double,CStr,Str }; //Error:不能直接放入关联容器内,需要提供operator<,但 any 很难比较
	cout << *Int._Cast<int>() << endl; //T* _Cast<typenampe T>():返回any对象的"值",但需要一个模板参数确定对象值的类型
	cout << *Double._Cast<double>() << endl;
	cout << *CStr._Cast<char const *>() << endl;
	cout << *Str._Cast<string>() << endl;
	
	std::any any = std::make_any<int>(10);
	if (typeid(int) == any.type())
		int i = std::any_cast<int>(any);
	//double d = std::any_cast<double >(any); //抛出bad_any_cast异常
	return 0;
}
//OutPut:
//69
//8.8
//hello
//world!

注意:
any的析构函数删除内部holder对象。如果类型是指针,any并不会对指针执行delete操作,所有any保存原始指针对造成内存泄漏。完美解决方法是用共享智能指针std::shared_ptr<T>包装存入any容器。

四、any实现原理:

通过使用模板构造函数擦除模板类的参数类型。

1、存储:
定义一个基类Base,再派生一个模板类Data,对二者再进行一次封装,构造一个Any类,使用Any类的模板构造函数来构造一个Data对象,这样就能存储任何数据类型。

2、取值:
只能存,但还无法把元素取出,所以Any必须有一个基类Base指针的成员变量,存储构造好的Data对象,使用模板函数_Cast(),利用其模板参数Type,进行一个再将Base类强制转换为Data< Type > 对象。

基本上是这个原理吧。

附超简版代码:

#include<iostream>
#include<any>
using namespace std;
class Any {
public:
	template<typename T>
	Any(T t) :base(new Data<T>(t)) {}//模板构造函数
	template<typename T>
	T _Cast() {
		return dynamic_cast<Data<T>*>(base.get())->value;	//强制转换
	}
private:
	class Base {
	public:
		virtual ~Base() {} //确定Base为多态类型
	};
	template <typename T>
	class Data :public Base {
	public:
		Data(T t) :value(t) {}
		T value;
	};
	unique_ptr<Base> base;	//基类指针
};
int main() {
	Any a(string("s123")), b = 1, c = 12.0;
	cout << a._Cast<string>() << endl;			/*调用get函数必须要填写模板参数,我感觉这样大大折扣了any的作用*/
	cout << b._Cast<int>() << endl;				/*我想能否在构造的时候就确认参数的类型,保证_Cast调用的时候不需要使用模板参数*/
	cout << c._Cast<double>();
	return 0;
}

参考

C++中VS2019下STL的std::any深入剖析
C++17 any类(万能容器)详解
Boost中的容器boost::any

文章来自:https://blog.csdn.net/qq_43148810/article/details/119389563

你可能还喜欢下面这些文章

std::endl为什么导致程序变慢

最近在写hadoop的streaming任务,在输出的时候用了std::endl,就像下面这样:os << “content” << std::endl运行后发现程序跑的比python还慢,令人费解。我入门C++的时候,输出hello world也是这样写的,有什么问题?于是查了一下std::endl,发现问题挺大。std::endl解释如下:Inserts a new-line character and flushes the stream.Its behavior is equivalent to calling os.put(‘\n’) (or os.put(o

Shell中的条件判断语句if的用法

shell中的if语法是最让我头疼的语法之一,它的判断就向使用USB插头一样——拿起来插入不行,翻转再插入还不行,再翻转插入行了!为了搞清楚这部分语言,我收集了一些文章关于if条件判断的用法,希望对你也有些帮助。一、基本语法if [ command ]; then 符合该条件执行的语句fiif [ command ];then 符合该条件执行的语句elif [ command ];then 符合该条件执行的语句else 符合该条件执行的语句fi语法说明bash shell会按顺序执行if语句,如果command执行后且它的返回状态是0,则会执行符合该条件执行的语

c语言的位操作

一、基本位操作|或&与~取反^异或<<左移>>右移二、位操作的常见用法1.获取某位的值#define BitGet(Number,pos) ((Number)|= 1<<(pos)) //把某位置1#define BitGet(Number,pos) ((Number) &= ~(1<<(pos)) //把某位置0#define BitGet(Number,pos) ((Number) >> (pos)&1)) //用宏得到某数的某位#define BitGet(Number,pos) ((Number) ^=

使用php curl 的并发能力可以做什么

在php中,没有多线程让编程变得简单。但在一些需要并发提升性能的场景下,显得有些无能为力,比如发起一些http请求。但好在curl扩展可以让我们“并发”去请求网络资源。利用这个特点,我们能做很多有趣的事情。最基础的,并发请求网络资源,提升处理速度。并发访问代码<?phpclass ConcurrencyHTTP { private $_requests; private $_callbacks; private $_currentIndex = 0; public function get($url, $header = array(), $timeout = 3

GDB入门:使用bt查看程序出core的调用栈

当程序崩溃的时候,会产生一个core文件。我们可以称它为进程死亡现场。排查进程死亡就和破案一样,找到案发现场,仔细排查每个细节,抽丝剥茧,最终定位原因。很幸运我们有一个强大的工具调查现场信息。这个工具就是GDB。下面我们就来看看如何用GDB排查问题。首先以一个越界访问数组的程序为例,如下:#include #include void core() { std::vector<int> a; std::cout << a[0];}int main() { core(); return 0;}执行上面的代码将会产生一个core文件。假设我们的core

使用php curl 的并发能力可以做什么

在php中,没有多线程让编程变得简单。但在一些需要并发提升性能的场景下,显得有些无能为力,比如发起一些http请求。

但好在curl扩展可以让我们“并发”去请求网络资源。利用这个特点,我们能做很多有趣的事情。

最基础的,并发请求网络资源,提升处理速度。

(更多…)

你可能还喜欢下面这些文章

C++ any容器的介绍与简易实现

一、any容器是什么?1、any“不是”模板类,any是一种很特殊的容器。2、any只能容纳一个元素,但这个元素可以是任意的类型,可以是基本数据类型(int、double、string、标准容器或者任何自定义类型)。3、一种动态(类型检查只发生在运行时)语言特性的数据结构。4、C++17引入,需要RIIT支持,VS默认是没有支持C++17的,需要自己修改设置,如果不能使用any,请修改标准。二、any类摘要class any{public: any(); //默认构造 any(const any& _That); //拷贝构造 template<class _ValueType&

Shell中的条件判断语句if的用法

shell中的if语法是最让我头疼的语法之一,它的判断就向使用USB插头一样——拿起来插入不行,翻转再插入还不行,再翻转插入行了!为了搞清楚这部分语言,我收集了一些文章关于if条件判断的用法,希望对你也有些帮助。一、基本语法if [ command ]; then 符合该条件执行的语句fiif [ command ];then 符合该条件执行的语句elif [ command ];then 符合该条件执行的语句else 符合该条件执行的语句fi语法说明bash shell会按顺序执行if语句,如果command执行后且它的返回状态是0,则会执行符合该条件执行的语

c语言的位操作

一、基本位操作|或&与~取反^异或<<左移>>右移二、位操作的常见用法1.获取某位的值#define BitGet(Number,pos) ((Number)|= 1<<(pos)) //把某位置1#define BitGet(Number,pos) ((Number) &= ~(1<<(pos)) //把某位置0#define BitGet(Number,pos) ((Number) >> (pos)&1)) //用宏得到某数的某位#define BitGet(Number,pos) ((Number) ^=

基于信息熵原理分词的php实现

基于信息熵原理分词这个概念很早了,用php实现了个,一气呵成,代码自然是,反正我也没有二次检查,呵呵。不过耗费内存是真的,真的很消耗内存!写这个的好处就是我明白了很多东西…代码如下<?php/** * 基于信息熵的无词典分词*/class partword{        /**     * 词语最大长度    */    public $maxwordlen = 5;    /**     * 需要进行分词的文字    */    public $text;    /**     * 字符串长度    */    private $len;    /**     * 切分的单个文字

一个将网页里面的(图片,链接地址)相对路径转化为绝对路径的php实现方法

抓取网页的时候有时候会需要下载里面的图片或者其他附件,但有的网页里面用的是相对路径,这时候就要转化为绝对路径。 /*** url补全,相对url转化为绝对url* 作用是补全url*/function url2abs($srcurl,$baseurl){  $srcinfo = parse_url($srcurl);   //print_r($srcinfo);   if(isset($srcinfo[‘scheme’])) {      return $srcurl;    }  $baseinfo = parse_url($baseurl);    $url = $baseinfo[‘sc

ChatGPT是怎么实现的?为什么它这么有效?

ChatGPT 能够自动生成类似于人类写作的文本,这一点非常引人注目,也令人意外。但它是如何实现的?为什么它能够如此出色地生成我们认为有意义的文本?我的目的是在这里概述ChatGPT内部的运行情况,并探讨它能够如此出色地产生有意义文本的原因。

首先需要解释的是,ChatGPT的基本目标是尝试产生一个“合理的延续”,无论它当前所拥有的文本是什么。这里的“合理”是指“在浏览了数十亿网页等人类书写的内容后,人们可能会写什么”。

那么假设我们有文本“AI的牛逼之处在于它能够…”,我们可以想象一下扫描数十亿页人类写作的文本(比如在网上和数字化的书籍中),找到所有这个文本的实例,然后看下一个单词出现的频率是多少。ChatGPT实际上是在类似地寻找在某种意义上“匹配”的内容,以生成一个排名列表,列出可能的后续单词和相应的“概率”。

(更多…)

GDB入门:使用bt查看程序出core的调用栈

当程序崩溃的时候,会产生一个core文件。我们可以称它为进程死亡现场。排查进程死亡就和破案一样,找到案发现场,仔细排查每个细节,抽丝剥茧,最终定位原因。

很幸运我们有一个强大的工具调查现场信息。这个工具就是GDB。

下面我们就来看看如何用GDB排查问题。

首先以一个越界访问数组的程序为例,如下:

#include 
#include 

void core() {
    std::vector<int> a;
    std::cout << a[0];
}
int main() {
    core();
    return 0;
}

执行上面的代码将会产生一个core文件。 (更多…)

你可能还喜欢下面这些文章

C++ any容器的介绍与简易实现

一、any容器是什么?1、any“不是”模板类,any是一种很特殊的容器。2、any只能容纳一个元素,但这个元素可以是任意的类型,可以是基本数据类型(int、double、string、标准容器或者任何自定义类型)。3、一种动态(类型检查只发生在运行时)语言特性的数据结构。4、C++17引入,需要RIIT支持,VS默认是没有支持C++17的,需要自己修改设置,如果不能使用any,请修改标准。二、any类摘要class any{public: any(); //默认构造 any(const any& _That); //拷贝构造 template<class _ValueType&

std::endl为什么导致程序变慢

最近在写hadoop的streaming任务,在输出的时候用了std::endl,就像下面这样:os << “content” << std::endl运行后发现程序跑的比python还慢,令人费解。我入门C++的时候,输出hello world也是这样写的,有什么问题?于是查了一下std::endl,发现问题挺大。std::endl解释如下:Inserts a new-line character and flushes the stream.Its behavior is equivalent to calling os.put(‘\n’) (or os.put(o

C++入门:三、函数

这是我学习C++的第三篇笔记,函数。我的学习路径是1. 变量和数据类型2. 流程控制3. 函数4. 面向对象5. 标准库现在学习的是函数的声明、定义、调用等相关知识。函数声明和定义函数的声明包含返回类型,函数名字,0个或者多个形参,无函数体,通常在头文件中对函数进行声明。返回类型 函数名称(参数类型1 参数1, 参数类型2 参数2);// 例如声明一个求阶乘的函数int fact(int val);函数的定义包含返回类型,函数名字,0个或多个形参,以及函数体。返回类型 函数名称(参数类型1 参数1, 参数类型2 参数2) { 函数体}比如写一个求阶乘的函数,可以写成下面这样int fac

记一次进程异常退出的问题排查

机器搬家之后,之前一直稳定的PHP多进程程序子进程突然异常退出,但是退出的不是很频繁,查看进程日志并也没有发现有什么导致退出的,问题比较诡异。于是开启了一段问题排查之路。首先查看内核日志,使用dmesg,拉到最后发现有一些这样的错误,看来确实是崩溃了。[4791991.998535] php[16776]: segfault at 7f6443ee18c8 ip 00007f6443ee18c8 sp 00007fff4d4ba818 error 15 in libc-2.17.so[7f6443ee1000+2000][4792165.192628] php[609]: segfault a

Shell中的条件判断语句if的用法

shell中的if语法是最让我头疼的语法之一,它的判断就向使用USB插头一样——拿起来插入不行,翻转再插入还不行,再翻转插入行了!为了搞清楚这部分语言,我收集了一些文章关于if条件判断的用法,希望对你也有些帮助。一、基本语法if [ command ]; then 符合该条件执行的语句fiif [ command ];then 符合该条件执行的语句elif [ command ];then 符合该条件执行的语句else 符合该条件执行的语句fi语法说明bash shell会按顺序执行if语句,如果command执行后且它的返回状态是0,则会执行符合该条件执行的语

Shell中的条件判断语句if的用法

shell中的if语法是最让我头疼的语法之一,它的判断就向使用USB插头一样——拿起来插入不行,翻转再插入还不行,再翻转插入行了!

为了搞清楚这部分语言,我收集了一些文章关于if条件判断的用法,希望对你也有些帮助。

一、基本语法

if [ command ]; then
     符合该条件执行的语句
fi
if [ command ];then
     符合该条件执行的语句
elif [ command ];then
     符合该条件执行的语句
else
     符合该条件执行的语句
fi

语法说明

bash shell会按顺序执行if语句,如果command执行后且它的返回状态是0,则会执行符合该条件执行的语句,否则后面的命令不执行,跳到下一条命令。
当有多个嵌套时,只有第一个返回0退出状态的命令会导致符合该条件执行的语句部分被执行,如果所有的语句的执行状态都不为0,则执行else中语句。
返回状态:最后一个命令的退出状态,或者当没有条件是真的话为0。

(更多…)

你可能还喜欢下面这些文章

C++ any容器的介绍与简易实现

一、any容器是什么?1、any“不是”模板类,any是一种很特殊的容器。2、any只能容纳一个元素,但这个元素可以是任意的类型,可以是基本数据类型(int、double、string、标准容器或者任何自定义类型)。3、一种动态(类型检查只发生在运行时)语言特性的数据结构。4、C++17引入,需要RIIT支持,VS默认是没有支持C++17的,需要自己修改设置,如果不能使用any,请修改标准。二、any类摘要class any{public: any(); //默认构造 any(const any& _That); //拷贝构造 template<class _ValueType&

bash教程:一、变量,函数,控制流程

变量的定义和使用变量的定义bash变量定义很简单。如下:a=”hello”左边是变量名,右边是变量值。bash是弱类型,因此不需要给a加上类型。注意,等号两边不能有空格 比如 a = “hello”,这是错误的。变量使用变量使用需要在定义的变量名之前加上$,比如我们打印之前定义的aecho $a特殊变量后面再说,现在仅仅是最基础的,能够让自己写出一个完整的脚本就行。流程控制流程控制则是编写程序必备的过程,比如顺序,循环,条件,分支等等。在其他类C语言中有if…else,for,while,do…while,switch,那么在bash里面,这些应该怎么写呢。if…else结构a=0

程序启动停止脚本

每次启动程序都要敲一堆命令,终止程序都要ps+grep找到程序pid然后kill,太麻烦了!花了点时间写了个程序启动停止脚本,如下:

打开微信,扫描左侧二维码,关注程序员日常,发送【2361】获取验证码,输入获取到的验证码即可获取隐藏内容
提交
#! /bin/bashreadonly CMD=$1readonly PARAM=$2readonly BIN=”./your_bin”start() { local bin=$1 local param=$2 if [ -f .pid ];then echo “${bin} is running” return 0; fi if [ ${param}”” == “-d” ];then

c语言的位操作

一、基本位操作|或&与~取反^异或<<左移>>右移二、位操作的常见用法1.获取某位的值#define BitGet(Number,pos) ((Number)|= 1<<(pos)) //把某位置1#define BitGet(Number,pos) ((Number) &= ~(1<<(pos)) //把某位置0#define BitGet(Number,pos) ((Number) >> (pos)&1)) //用宏得到某数的某位#define BitGet(Number,pos) ((Number) ^=

使用php curl 的并发能力可以做什么

在php中,没有多线程让编程变得简单。但在一些需要并发提升性能的场景下,显得有些无能为力,比如发起一些http请求。但好在curl扩展可以让我们“并发”去请求网络资源。利用这个特点,我们能做很多有趣的事情。最基础的,并发请求网络资源,提升处理速度。并发访问代码<?phpclass ConcurrencyHTTP { private $_requests; private $_callbacks; private $_currentIndex = 0; public function get($url, $header = array(), $timeout = 3

程序启动停止脚本

每次启动程序都要敲一堆命令,终止程序都要ps+grep找到程序pid然后kill,太麻烦了!

花了点时间写了个程序启动停止脚本,如下:

打开微信,扫描左侧二维码,关注程序员日常,发送【2318】获取验证码,输入获取到的验证码即可获取隐藏内容
提交

只需要配置一个BIN变量即可实现程序的启动和停止,十分简单。

你可能还喜欢下面这些文章

Shell中的条件判断语句if的用法

shell中的if语法是最让我头疼的语法之一,它的判断就向使用USB插头一样——拿起来插入不行,翻转再插入还不行,再翻转插入行了!为了搞清楚这部分语言,我收集了一些文章关于if条件判断的用法,希望对你也有些帮助。一、基本语法if [ command ]; then 符合该条件执行的语句fiif [ command ];then 符合该条件执行的语句elif [ command ];then 符合该条件执行的语句else 符合该条件执行的语句fi语法说明bash shell会按顺序执行if语句,如果command执行后且它的返回状态是0,则会执行符合该条件执行的语

shell中 $? $# $* $$ $* $@ $0 特殊变量含义

shell中有一些常用的难记的特殊变量,如下:$0当前脚本的文件名$n传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。$#传递给脚本或函数的参数个数。$*传递给脚本或函数的所有参数。$@传递给脚本或函数的所有参数。被双引号(” “)包含时,与 $* 稍有不同$?上个命令的退出状态,或函数的返回值。$$当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。$0 – 当前脚本文件名#! /bin/bashecho $0$ sh shell.sh shell.sh$n – 第n个参数#! /bin/bashecho $1echo

shell 变量的定义

shell可以自定义变量,这为shell的编写带来很多方便定义变量定义变量时,变量名不加美元符号($),如:variableName=”value”注意:变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样同时,变量名的命名须遵循如下规则。首个字符必须为字母(a-z,A-Z)。中间不能有空格,可以使用下划线(_)。不能使用标点符号。不能使用bash里的关键字(可用help命令查看保留关键字)。变量定义举例:myUrl=”http://imhuchao.com/tag/bash”myNum=100使用变量使用一个定义过的变量,只要在变量名前面加美元符号($)即可,如:your_nam

bash教程:一、变量,函数,控制流程

变量的定义和使用变量的定义bash变量定义很简单。如下:a=”hello”左边是变量名,右边是变量值。bash是弱类型,因此不需要给a加上类型。注意,等号两边不能有空格 比如 a = “hello”,这是错误的。变量使用变量使用需要在定义的变量名之前加上$,比如我们打印之前定义的aecho $a特殊变量后面再说,现在仅仅是最基础的,能够让自己写出一个完整的脚本就行。流程控制流程控制则是编写程序必备的过程,比如顺序,循环,条件,分支等等。在其他类C语言中有if…else,for,while,do…while,switch,那么在bash里面,这些应该怎么写呢。if…else结构a=0

php多进程编程:第一次fork

工作原因,要用到php多进程,于是粗略的了解一下,完成之后把过程记录下来,整理成教程,希望对学习php多进程编程的程序员有所帮助。前言使用php cli的时候,我们在终端会这样php hello.php运行一个hello.php程序,这样linux会为我们创建一个进程。不考虑 nohup ,在一个终端,我们以cli方式运行的php程序也只能有这一个进程。一个进程处理的任务必定是有限的,在系统资源空闲那么多的情况下,为什么不使用多进程来提高效率呢?不过php多进程需要安装pcntl和posix扩展(windows不支持)fork,创建子进程创建子进程的方法就是fork,在php里面,这个函数是p

如何选择特征

特征工程是数据分析中最耗时间和精力的一部分工作,它不像算法和模型那样是确定的步骤,更多是工程上的经验和权衡。因此没有统一的方法。这里只是对一些常用的方法做一个总结。本文关注于特征选择部分。后面还有两篇会关注于特征表达和特征预处理。

1. 特征的来源

在做数据分析的时候,特征的来源一般有两块,一块是业务已经整理好各种特征数据,我们需要去找出适合我们问题需要的特征;另一块是我们从业务特征中自己去寻找高级数据特征。我们就针对这两部分来分别讨论。

2.  选择合适的特征

我们首先看当业务已经整理好各种特征数据时,我们如何去找出适合我们问题需要的特征,此时特征数可能成百上千,哪些才是我们需要的呢?

第一步是找到该领域懂业务的专家,让他们给一些建议。比如我们需要解决一个药品疗效的分类问题,那么先找到领域专家,向他们咨询哪些因素(特征)会对该药品的疗效产生影响,较大影响的和较小影响的都要。这些特征就是我们的特征的第一候选集。

这个特征集合有时候也可能很大,在尝试降维之前,我们有必要用特征工程的方法去选择出较重要的特征结合,这些方法不会用到领域知识,而仅仅是统计学的方法。

最简单的方法就是方差筛选。方差越大的特征,那么我们可以认为它是比较有用的。如果方差较小,比如小于1,那么这个特征可能对我们的算法作用没有那么大。最极端的,如果某个特征方差为0,即所有的样本该特征的取值都是一样的,那么它对我们的模型训练没有任何作用,可以直接舍弃。在实际应用中,我们会指定一个方差的阈值,当方差小于这个阈值的特征会被我们筛掉。sklearn中的VarianceThreshold类可以很方便的完成这个工作。

特征选择方法有很多,一般分为三类:第一类过滤法比较简单,它按照特征的发散性或者相关性指标对各个特征进行评分,设定评分阈值或者待选择阈值的个数,选择合适特征。上面我们提到的方差筛选就是过滤法的一种。第二类是包装法,根据目标函数,通常是预测效果评分,每次选择部分特征,或者排除部分特征。第三类嵌入法则稍微复杂一点,它先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据权值系数从大到小来选择特征。类似于过滤法,但是它是通过机器学习训练来确定特征的优劣,而不是直接从特征的一些统计学指标来确定特征的优劣。下面我们分别来看看3类方法。

2.1 过滤法选择特征

上面我们已经讲到了使用特征方差来过滤选择特征的过程。除了特征的方差这第一种方法,还有其他一些统计学指标可以使用。

第二个可以使用的是相关系数。这个主要用于输出连续值的监督学习算法中。我们分别计算所有训练集中各个特征与输出值之间的相关系数,设定一个阈值,选择相关系数较大的部分特征。

第三个可以使用的是假设检验,比如卡方检验。卡方检验可以检验某个特征分布和输出值分布之间的相关性。个人觉得它比比粗暴的方差法好用。如果大家对卡方检验不熟悉,可以参看这篇卡方检验原理及应用,这里就不展开了。在sklearn中,可以使用chi2这个类来做卡方检验得到所有特征的卡方值与显著性水平P临界值,我们可以给定卡方值阈值, 选择卡方值较大的部分特征。

除了卡方检验,我们还可以使用F检验和t检验,它们都是使用假设检验的方法,只是使用的统计分布不是卡方分布,而是F分布和t分布而已。在sklearn中,有F检验的函数f_classif和f_regression,分别在分类和回归特征选择时使用。

第四个是互信息,即从信息熵的角度分析各个特征和输出值之间的关系评分。在决策树算法中我们讲到过互信息(信息增益)。互信息值越大,说明该特征和输出值之间的相关性越大,越需要保留。在sklearn中,可以使用mutual_info_classif(分类)和mutual_info_regression(回归)来计算各个输入特征和输出值之间的互信息。

以上就是过滤法的主要方法,个人经验是,在没有什么思路的 时候,可以优先使用卡方检验和互信息来做特征选择

2.2 包装法选择特征

包装法的解决思路没有过滤法这么直接,它会选择一个目标函数来一步步的筛选特征。

最常用的包装法是递归消除特征法(recursive feature elimination,以下简称RFE)。递归消除特征法使用一个机器学习模型来进行多轮训练,每轮训练后,消除若干权值系数的对应的特征,再基于新的特征集进行下一轮训练。在sklearn中,可以使用RFE函数来选择特征。

我们下面以经典的SVM-RFE算法来讨论这个特征选择的思路。这个算法以支持向量机来做RFE的机器学习模型选择特征。它在第一轮训练的时候,会选择所有的特征来训练,得到了分类的超平面$w \dot x+b=0$后,如果有n个特征,那么RFE-SVM会选择出$w$中分量的平方值$w_i^2$最小的那个序号i对应的特征,将其排除,在第二类的时候,特征数就剩下n-1个了,我们继续用这n-1个特征和输出值来训练SVM,同样的,去掉$w_i^2$最小的那个序号i对应的特征。以此类推,直到剩下的特征数满足我们的需求为止。

2.3 嵌入法选择特征

嵌入法也是用机器学习的方法来选择特征,但是它和RFE的区别是它不是通过不停的筛掉特征来进行训练,而是使用的都是特征全集。在sklearn中,使用SelectFromModel函数来选择特征。

最常用的是使用L1正则化和L2正则化来选择特征。在之前讲到的用scikit-learn和pandas学习Ridge回归第6节中,我们讲到正则化惩罚项越大,那么模型的系数就会越小。当正则化惩罚项大到一定的程度的时候,部分特征系数会变成0,当正则化惩罚项继续增大到一定程度时,所有的特征系数都会趋于0. 但是我们会发现一部分特征系数会更容易先变成0,这部分系数就是可以筛掉的。也就是说,我们选择特征系数较大的特征。常用的L1正则化和L2正则化来选择特征的基学习器是逻辑回归。

此外也可以使用决策树或者GBDT。那么是不是所有的机器学习方法都可以作为嵌入法的基学习器呢?也不是,一般来说,可以得到特征系数coef或者可以得到特征重要度(feature importances)的算法才可以做为嵌入法的基学习器。

3.  寻找高级特征

在我们拿到已有的特征后,我们还可以根据需要寻找到更多的高级特征。比如有车的路程特征和时间间隔特征,我们就可以得到车的平均速度这个二级特征。根据车的速度特征,我们就可以得到车的加速度这个三级特征,根据车的加速度特征,我们就可以得到车的加加速度这个四级特征。。。也就是说,高级特征可以一直寻找下去。

在Kaggle之类的算法竞赛中,高分团队主要使用的方法除了集成学习算法,剩下的主要就是在高级特征上面做文章。所以寻找高级特征是模型优化的必要步骤之一。当然,在第一次建立模型的时候,我们可以先不寻找高级特征,得到以后基准模型后,再寻找高级特征进行优化。

寻找高级特征最常用的方法有:

若干项特征加和: 我们假设你希望根据每日销售额得到一周销售额的特征。你可以将最近的7天的销售额相加得到。
若干项特征之差: 假设你已经拥有每周销售额以及每月销售额两项特征,可以求一周前一月内的销售额。
若干项特征乘积: 假设你有商品价格和商品销量的特征,那么就可以得到销售额的特征。
若干项特征除商: 假设你有每个用户的销售额和购买的商品件数,那么就是得到该用户平均每件商品的销售额。

当然,寻找高级特征的方法远不止于此,它需要你根据你的业务和模型需要而得,而不是随便的两两组合形成高级特征,这样容易导致特征爆炸,反而没有办法得到较好的模型。个人经验是,聚类的时候高级特征尽量少一点,分类回归的时候高级特征适度的多一点。

4. 特征选择小结

特征选择是特征工程的第一步,它关系到我们机器学习算法的上限。因此原则是尽量不错过一个可能有用的特征,但是也不滥用太多的特征。

不错的文章,原文地址:https://www.cnblogs.com/pinard/p/9032759.html

signal函数详解

signal作用是为信号注册一个处理器。这里的“信号”是软中断信号,这种信号来源主要有三种:

  1. 程序错误:比如除0,非法内存访问。
  2. 外部信号:终端Ctrl-C产生的SIGINT信号,定时器产生的SIGALERM。
  3. 显示请求:kill函数发送的任意信号。

当kill一个进程的时候,默认会发送SIGTERM信号,此时这个信号只有默认处理操作(SIG_DFL),直接中断进程执行。如果此时该进程正在执行一个任务,直接终止该进程会导致任务没有完成。这个时候为SIGTERM信号注册一个信号处理函数就十分有必要。

介绍

typedef void (*sighandler_t) (int);
sighandler_t signal (int sig, sighandler_t handler)

参数

sig要设置信号处理函数的信号。它可以是实现定义值或下例值之一:
SIGABRT
SIGFPE
SIGILL
SIGINT
SIGSEGV
SIGTERM
定义信号类型
(宏常量)
handler信号处理函数。这必须是下列之一:SIG_DFL 宏。信号处理函数被设为默认信号处理函数。SIG_IGN 宏。忽略信号。指向函数指针。函数签名必须等价于如下:extern “C” void fun(int sig);

返回值

成功时为先前的信号处理函数,失败时为 SIG_ERR (某些实现上能禁用设置信号处理函数)。

使用

使用方法请直接看下面的例子。注册一个信号用于在按下Ctrl-C时不立刻终止进程,而是输出一段文字并sleep一段时间。

#include <signal.h>
#include <unistd.h>
#include <iostream>

bool is_stop = false;
void quit_handler(int signo) {
    is_stop = true;
    std::cout << "stopping\n";
    sleep(2);
}

int main() {
    auto prev = signal(SIGINT, quit_handler);
    if (prev == SIG_ERR) {
        abort();
    }
    while (!is_stop) {
        std::cout << "running\n";
        sleep(1);
    }
    std::cout << "stopped\n";
}

如何安装多个处理函数

signal只能为一个信号添加一个处理函数,添加多个处理函数时后面的函数会覆盖前面的函数。看如下代码

#include <signal.h>
#include <unistd.h>
#include <iostream>

bool is_stop = false;
void quit_handler1(int signo) {
    is_stop = true;
    std::cout << "handler1\n";
    sleep(2);
}

void quit_handler2(int signo) {
    is_stop = true;
    std::cout << "handler2\n";
    sleep(2);
}

int main() {
    auto prev1 = signal(SIGINT, quit_handler1);
    auto prev2 = signal(SIGINT, quit_handler2);

    if (prev1 == SIG_ERR || prev2 == SIG_ERR) {
        abort();
    }
    while (!is_stop) {
        std::cout << "running\n";
        sleep(1);
    }
    std::cout << "stopped\n";
}

运行之后按下Ctrl-C,结果发现只有handler2有效,handler1失效了。

running
running
^Chandler2
stopped

有两个quit_handler,上面的代码最终执行的是quit_handler2。后面注册的函数覆盖了前面注册的。那么如何注册两个处理器呢?

由于signal会返回上一个处理操作,可能是SIG_DFL、SIG_IGN宏,也可能是上一个处理函数。这给我们注册多个处理器带来了可能。只要我们在第二次注册的处理函数中调用前一次的处理函数就可以了!看下面代码:

#include <unistd.h>
#include <signal.h>
#include <iostream>

bool is_stop = false;
void (*prev_handler)(int) = nullptr;

void quit_handler1(int signo) {
    is_stop = true;
    std::cout << "handler1\n";
    sleep(2);
}

void quit_handler2(int signo) {
    if (prev_handler != nullptr) {
        prev_handler(signo);
    }
    is_stop = true;
    std::cout << "handler2\n";
    sleep(2);
}

int main() {
    auto prev1 = signal(SIGINT, quit_handler1);
    auto prev2 = signal(SIGINT, quit_handler2);
    if (prev1 == SIG_ERR || prev2 == SIG_ERR) {
        abort();
    }
    if (prev2 != SIG_DFL && prev2 != SIG_IGN) {
        prev_handler = prev2;
    }
    while (!is_stop) {
        std::cout << "running\n";
        sleep(1);
    }
    std::cout << "stopped\n";
}

使用一个变量prev_handler保存前一次注册的handler,在quit_handler2中,调用prev_handler。运行之后会发现两个handler都会被调用,结果如下:

running
running
running
^Chandler1
handler2
stopped

信号列表

SignalDescription
SIGABRT由调用abort函数产生,进程非正常退出
SIGALRM用alarm函数设置的timer超时或setitimer函数设置的interval timer超时
SIGBUS某种特定的硬件异常,通常由内存访问引起
SIGCANCEL由Solaris Thread Library内部使用,通常不会使用
SIGCHLD进程Terminate或Stop的时候,SIGCHLD会发送给它的父进程。缺省情况下该Signal会被忽略
SIGCONT当被stop的进程恢复运行的时候,自动发送
SIGEMT和实现相关的硬件异常
SIGFPE数学相关的异常,如被0除,浮点溢出,等等
SIGFREEZESolaris专用,Hiberate或者Suspended时候发送
SIGHUP发送给具有Terminal的Controlling Process,当terminal 被disconnect时候发送
SIGILL非法指令异常
SIGINFOBSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程
SIGINT由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程
SIGIO异步IO事件
SIGIOT实现相关的硬件异常,一般对应SIGABRT
SIGKILL无法处理和忽略。中止某个进程
SIGLWP由Solaris Thread Libray内部使用
SIGPIPE在reader中止之后写Pipe的时候发送
SIGPOLL当某个事件发送给Pollable Device的时候发送
SIGPROFSetitimer指定的Profiling Interval Timer所产生
SIGPWR和系统相关。和UPS相关。
SIGQUIT输入Quit Key的时候(CTRL+\)发送给所有Foreground Group的进程
SIGSEGV非法内存访问
SIGSTKFLTLinux专用,数学协处理器的栈异常
SIGSTOP中止进程。无法处理和忽略。
SIGSYS非法系统调用
SIGTERM请求中止进程,kill命令缺省发送
SIGTHAWSolaris专用,从Suspend恢复时候发送
SIGTRAP实现相关的硬件异常。一般是调试异常
SIGTSTPSuspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程
SIGTTIN当Background Group的进程尝试读取Terminal的时候发送
SIGTTOU当Background Group的进程尝试写Terminal的时候发送
SIGURG当out-of-band data接收的时候可能发送
SIGUSR1用户自定义signal 1
SIGUSR2用户自定义signal 2
SIGVTALRMsetitimer函数设置的Virtual Interval Timer超时的时候
SIGWAITINGSolaris Thread Library内部实现专用
SIGWINCH当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程
SIGXCPU当CPU时间限制超时的时候
SIGXFSZ进程超过文件大小限制
SIGXRESSolaris专用,进程超过资源限制的时候发

关于typedef void (*sighandler_t) (int);

这里有个typdef比较奇怪,没见过这种写法。其实抛开typedef的自定义类型,只看函数,其实就和 int fun(int a,cha b)类似,这就很通俗易懂。

要想看懂上面的函数,就必须理解typedef的用法。

首先,我们看这个定义:typedef char *p ,这里,我们首先把typedef盖上,那么就是char *p。这句话想必大家都能看懂,也就是声明了一个p指针。p指针指向char类型的数据,加上typedef之后就解释成声明了一种指向char变量指针的类型p,也就是说,p=char *,p a=char *a。

然后我们来看 typedef void (*sighandler_t)(int),首先不看typedef,也就是void (*sighandler_t)(int),这就话的意思是声明了一个指向一个函数并且这个函数能接受一个整型参数并返回一个无类型指针变量sighandler_t,加上typedef之后,sighandler_t就变成了一个类型,sighandler_t p,p就是一个指向一个函数并且这个函数能接受一个整型参数并返回一个无类型指针的变量。

所以一句话就是,typedef在语句中所起的作用就是把语句原先定义变量的功能变成了定义类型的功能,仅此而已。

你可能还喜欢下面这些文章

websocket协议详解

近来项目中使用websocket,于是来研究一番。websocket传输协议有两个部分,握手和数据传输握手GET / HTTP/1.1HOST: <IP>:<PORT> Sec-Websocket-Version: 13Sec-Websocket-Key: <KEY>Connection: keep-alive, UpgradeUpgrade: websocket之后服务端会返回类似下面的数据HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-A

gcc/g++编译参数详解

编译步骤gcc 与 g++ 分别是 gnu 的 c & c++ 编译器。gcc/g++ 在执行编译工作的时候,总共需要4步:预处理,生成 .i 的文件[预处理器cpp]将预处理后的文件转换成汇编语言, 生成文件 .s [编译器egcs]有汇编变为目标代码(机器代码)生成 .o 的文件[汇编器as]连接目标代码, 生成可执行程序 [链接器ld]参数详解-x language filename参数含义为指定文件所使用的语言。根据约定,C语言的后缀名称为”.c”,而 C++ 的后缀名为”.cpp”或”.cc”,但如果你的源代码后缀不约定的那几种,那么需要使用-x参数来指定文件所使用的语言。这

ftp命令大全详解

来熟悉熟悉ftp命令,对于服务器之间的文件传输太有用啦,不会怎么能行呢!先来看看基础的命令,包括了连接,列出列表,下载,上传,断开这最基础的命令,会这些,在使用ftp命令行就毫无压力啦!1. 连接ftp服务器格式:ftp [hostname| ip-address]a)在linux命令行下输入:ftp 192.168.1.1b)服务器询问你用户名和密码,分别输入用户名和相应密码,待认证通过即可。2.列出文件列表以及切换目录这部分其实和linux并无区别,分别是ls,和cd列出目录列表ls切换当前目录cd dir3. 下载文件下载文件通常用get和mget这两条命令。a) get格式:get [

vsftpd配置文件详解

vsftpd的配置文件/etc/vsftpd/vsftpd.conf主配置文件/usr/sbin/vsftpdVsftpd的主程序/etc/rc.d/init.d/vsftpd启动脚本/etc/pam.d/vsftpdPAM认证文件(此文件中file=/etc/vsftpd/ftpusers字段,指明阻止访问的用户来自/etc/vsftpd/ftpusers文件中的用户)/etc/vsftpd/ftpusers禁止使用vsftpd的用户列表文件。记录不允许访问FTP服务器的用户名单,管理员可以把一些对系统安全有威胁的用户账号记录在此文件中,以免用户从FTP登录后获得大于上传下载操作的权利,而对

mysql中的alter操作详解

在使用mysql的客户端之后,手动输入语句的机会减少太多,比如mysql的alter语句竟然想不起来怎么用了,于是重新学习一下。alter是用来修改表结构的语句。既然是修改,那么可分为增加,修改,删除这几种。大致的操作如下ALTER TABLE 表名称 操作(ADD|DROP|CHANGE|RENAME) 操作内容列操作相关1.增加列ALTER TABLE table_name ADD new_column_name VARCHAR(255) NOT NULL2.删除列ALTER TABLE table_name DROP a_column3.修改列ALTER TABLE table_name

shell中 $? $# $* $$ $* $@ $0 特殊变量含义

shell中有一些常用的难记的特殊变量,如下:

$0当前脚本的文件名
$n传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
$#传递给脚本或函数的参数个数。
$*传递给脚本或函数的所有参数。
$@传递给脚本或函数的所有参数。被双引号(” “)包含时,与 $* 稍有不同
$?上个命令的退出状态,或函数的返回值。
$$当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。
(更多…)

你可能还喜欢下面这些文章

程序启动停止脚本

每次启动程序都要敲一堆命令,终止程序都要ps+grep找到程序pid然后kill,太麻烦了!花了点时间写了个程序启动停止脚本,如下:

打开微信,扫描左侧二维码,关注程序员日常,发送【2284】获取验证码,输入获取到的验证码即可获取隐藏内容
提交
#! /bin/bashreadonly CMD=$1readonly PARAM=$2readonly BIN=”./your_bin”start() { local bin=$1 local param=$2 if [ -f .pid ];then echo “${bin} is running” return 0; fi if [ ${param}”” == “-d” ];then

linux shell 入门

从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁。用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操作。在Linux GUI日益完善的今天,在系统管理等领域,Shell编程仍然起着不可忽视的作用。深入地了解和熟练地掌握Shell编程,是每一个Linux用户的必修 功课之一。Linux的Shell种类众多,常见的有:Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shel

Shell中的条件判断语句if的用法

shell中的if语法是最让我头疼的语法之一,它的判断就向使用USB插头一样——拿起来插入不行,翻转再插入还不行,再翻转插入行了!为了搞清楚这部分语言,我收集了一些文章关于if条件判断的用法,希望对你也有些帮助。一、基本语法if [ command ]; then 符合该条件执行的语句fiif [ command ];then 符合该条件执行的语句elif [ command ];then 符合该条件执行的语句else 符合该条件执行的语句fi语法说明bash shell会按顺序执行if语句,如果command执行后且它的返回状态是0,则会执行符合该条件执行的语

shell 变量的定义

shell可以自定义变量,这为shell的编写带来很多方便定义变量定义变量时,变量名不加美元符号($),如:variableName=”value”注意:变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样同时,变量名的命名须遵循如下规则。首个字符必须为字母(a-z,A-Z)。中间不能有空格,可以使用下划线(_)。不能使用标点符号。不能使用bash里的关键字(可用help命令查看保留关键字)。变量定义举例:myUrl=”http://imhuchao.com/tag/bash”myNum=100使用变量使用一个定义过的变量,只要在变量名前面加美元符号($)即可,如:your_nam

第一个shell脚本,hello shell

Linux的Shell种类众多,常见的有:Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shell(/usr/bin/ksh)、Shell for Root(/sbin/sh),等等。不同的Shell语言的语法有所不同,所以不能交换使用。每种Shell都有其特色之处,基本上,掌握其中任何一种 就足够了。在本文中,我们关注的重点是Bash,也就是Bourne Again Shell,由于易用和免费,Bash在日常工作中被广泛使用;同时,Bash也是大多数Linux系统