传统机器学习流程总结

数据采集和标记

爬虫

爬虫主要分为静态爬取和动态爬取,静态爬取的学习xpath就可以,也要掌握re的用法,因为一直要进行数据的清洗,动态爬取的话主要是要找到动态页面以及对应的参数传递,一般在netwoek---->Media中,还有一个要掌握selenium自动化技术,一般针对淘宝京东爬取。

静态爬取

xpath

在这里插入代码片
import requests
from lxml import etree
url='xxxxx'
start=requests.get(url).content.decode('utf-8','ignore')
ele=etree.HTML(start)
start_url=ele.xpath('//*[@id="content"]/div/ul/li/a/@href')

技巧总结

各行业小知识总结

库的小知识

## 去掉警告
import warnings
warnings.filterwarnings("ignore")
#当模型结果无法复现时,进行随机参数设置
import os
np.random.seed(1337)
from numpy.random import seed
seed(1)
from tensorflow import set_random_seed
set_random_seed(2)
# python 版本库
https://www.python.org/ftp/python/
# 下载库
pip install keras -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
# 另一个镜像
-i https://mirrors.aliyun.com/pypi/simple
# python 库位置
https://www.lfd.uci.edu/~gohlke/pythonlibs/
# 百度镜像源
-i https://mirror.baidu.com/pypi/simple
# pytorch cpu安装
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn torch torchvision torchaudio

数据读取

有时候数据量太大无法进行一次性获取,所以进行按行处理

# 获取特定的数量.前100行
train=pd.read_csv("data/train.csv",nrows=1000)
# pycharm数据展示不全
pd.set_option('display.max_columns', None)  # 显示完整的列
pd.set_option('display.max_rows', None)  # 显示完整的行
pd.set_option('display.expand_frame_repr', False)  # 设置不折叠数据

描述性统计

#均值
np.mean(data)
#中位数
np.median(data)
#众数
from scipy.stats import mode
mode(data)
#极差
np.ptp(data)
#方差
np.var(data)
#标准差
np.std(data)
Statistics = Cmc_data.describe()
#计算相关系数矩阵
Cmc_data.corr()
#计算协方差矩阵
Cmc_data.cov()
#计算样本值的偏度
Cmc_data.skew()
#计算样本值的峰度
Cmc_data.kurt()
# 文本长度统计分析,通过分析可以看出文本较短,最长为48
total['text_a'].map(len).describe()
from sklearn.metrics import classification_report
print(classification_report(y_test,y_predict))

在这里插入图片描述

处理数据不平衡

#每个epoch都shuffle
np.random.shuffle(train_data) # 每个epoch都shuffle数据以获得最佳训练效果;
--------------------------------------------------------------------
from imblearn.over_sampling import SMOTE # 导入SMOTE算法模块
# 处理不平衡数据
sm = SMOTE(random_state=42)    # 处理过采样的方法
X, y = sm.fit_sample(X, y)
print('通过SMOTE方法平衡正负样本后')
n_sample = y.shape[0]
n_pos_sample = y[y == 0].shape[0]
n_neg_sample = y[y == 1].shape[0]
print('样本个数:{}; 正样本占{:.2%}; 负样本占{:.2%}'.format(n_sample,
                                                   n_pos_sample / n_sample,
                                                   n_neg_sample / n_sample))

数据清洗

目标变量

我们一般会拿偏度和峰度来看数据的分布形态,而且一般会跟正态分布做比较,我们把正态分布的偏度和峰度都看做零。如果我们在实操中,算到偏度峰度不为0,即表明变量存在左偏右偏,或者是高顶平顶这么一说。
一.偏度(Skewness)
Definition:是描述数据分布形态的统计量,其描述的是某总体取值分布的对称性,简单来说就是数据的不对称程度。。
偏度是三阶中心距计算出来的。
(1)Skewness = 0 ,分布形态与正态分布偏度相同。
(2)Skewness > 0 ,正偏差数值较大,为正偏或右偏。长尾巴拖在右边,数据右端有较多的极端值。
(3)Skewness < 0 ,负偏差数值较大,为负偏或左偏。长尾巴拖在左边,数据左端有较多的极端值。
(4)数值的绝对值越大,表明数据分布越不对称,偏斜程度大。
计算公式:
Skewness=E[((x-E(x))/(\sqrt{D(x)}))^3]
| Skewness| 越大,分布形态偏移程度越大。

二.峰度(Kurtosis)
Definition:偏度是描述某变量所有取值分布形态陡缓程度的统计量,简单来说就是数据分布顶的尖锐程度。
峰度是四阶标准矩计算出来的9。
(1)Kurtosis=0 与正态分布的陡缓程度相同。
(2)Kurtosis>0 比正态分布的高峰更加陡峭——尖顶峰
(3)Kurtosis<0 比正态分布的高峰来得平台——平顶峰
查看skewness and kurtosis
sns.distplot(data['price']);
print("Skewness: %f" % data['price'].skew())
print("Kurtosis: %f" % data['price'].kurt())

数据处理

#找出一列中的重复值,并在原始数据上进行标注
df['is_duplicate'] = False
df.loc[df.duplicated(subset='A', keep=False), 'is_duplicate'] = True
----------------------------------------------------------- 
#lambda 解决多个返回,以字典的形式返回出去
def format(*args, **kwargs):
    return args, kwargs
fun = lambda *arg, **kwargs: dict(zip(["Input-Token", "Input-Segment"], format(*arg, **kwargs)))
----------------------------------------------------------------------
sentence_ids=[[(0, 3), (6, 9)]]
sentence_ids = [sorted(sentence_ids[0], key=lambda x: x[0])]
----------------------------------------------------------- 
找到重复的数据
dup_row = test_df.duplicated(subset=['公司名称', '战新行业'])
test_df.insert(0, 'is_dup', dup_row)
print(test_df[test_df['is_dup'] == True][['公司名称', '战新行业']])
pd转list
for keys, value in test_df[['更改类别', '文本']].values.tolist():
----------------------------------------------------------- 
Python去掉括号及其内容
1、若括号为半角括号
import re
str="你(你)在[在]干嘛{干嘛}"
result = re.sub(u"\\(.*?\\)|\\{.*?}|\\[.*?]", "", str)
print(result)
2、若括号为全角括号
import sys
import re
str = u"你(你)在[在]干{干}嘛【嘛】"
result = re.sub(u"\\(.*?)|\\{.*?}|\\[.*?]|\\【.*?】", "", str.encode('utf-8').decode())
print(result)
----------------------------------------------------------- 
# 统计panndas 中字段的个数
res_df['count_res'] = res_df['res'].str.len()
----------------------------------------------------------- 
# 字符串转字典
a="{'agg': [0], 'op': [0], 'field': ['地址'], 'conds': [('地区名称', '==', '青浦区水务局')]}"
dict_tes=eval(a)
print(dict_tes['agg'][0])
----------------------------------------------------------- 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
PYTHONIOENCODING=utf-8 python ***.py
# 将列表中的元素按照出现次数排序
for i in set(all_table_table_list):
    count_find_num[i] = all_table_table_list.count(i)
d = sorted(count_find_num.items(), key=lambda x: x[1], reverse=True)
# 排序后的值与在原numbers对应的索引
numbers=[2, 4, 0]
index = []
for i in range(len(numbers)):
    index.append(numbers.index(sorted(numbers)[i]))
print('numbers排序后的值与在原numbers对应的索引:')
print(numbers)
print(sorted(numbers))
print(print(index))
# python 字段值和键交换
ner_lable_map = dict(zip(SQL.ner.values(), SQL.ner.keys()))
----------------------------------------------------------- 
# 字典按行进行保存
import json
for i in fin_list:
    filename='names.json'
    with open(filename,'a+',encoding='utf-8') as file_obj:
        json_str = json.dumps(i, ensure_ascii=False)
        file_obj.write(json_str + '\n')
----------------------------------------------------------- 
#列表去重但是顺序不变
T = sorted(set(L), key=L.index)
# json保存中文
filename = 'train_new.json'
with open(filename, 'w', encoding='utf-8') as f:
    json.dump(result_list, f, ensure_ascii=False, indent=4)
----------------------------------------------------------- 
# 在字符串指定位置插入字符
# str_origin:源字符串  pos:插入位置  str_add:待插入的字符串
def str_insert(str_origin, pos, str_add):
    str_list = list(str_origin)    # 字符串转list
    str_list.insert(pos, str_add)  # 在指定位置插入字符串
    str_out = ''.join(str_list)    # 空字符连接
    return  str_out
----------------------------------------------------------- 
# 查看当前程序的运行路径
 import os
 print(os.getcwd())
-----------------------------------------------------
pandas切割
data['name'].str.split('|',expand=True)
关键是参数expand,这个参数取True时,会把切割出来的内容当做一列。 如果不需要pandas为你分好列,expand=False就可以了。
然后,我们如果只想要第一列的话,只需要做:
data['name'].str.split('|',expand=True)[0]
----------------------------------------------
x = np.array([[1., -1., 2.],
              [2., 0., 0.],
              [0., 1., -1.]])
min_max_scaler = preprocessing.MinMaxScaler(feature_range=(0, 5))  # 范围改为1~3,对原数组操作
x_minmax = min_max_scaler.fit_transform(x)
print('x = ', x)
print('x_minmax = ', x_minmax)
----------------------------------------------------
# 判断文本是否包含汉字
count = 0
for i in first:
    if '\u4e00' <= i <= '\u9fa5':
        count = count + 1
if count == 0:
    first = '文本中没有汉字'
------------------------------------
# 去掉文本中的时间
reCOMM = "\d{4}[-/年\.]1[12][-/月\.][123][0-9][日]|" \
         "\d{4}[-/年\.][1-9][-/月\.][123][0-9][日]|" \
         "\d{4}[-/年\.]1[12][-/月\.][123][0-9]|" \
         "\d{4}[-/年\.][1-9][-/月\.][123][0-9]"
first = re.sub(reCOMM, "", first)
------------------------------------
# 读取txt文档
 try:
     with open(file_path, 'r', encoding='utf-8') as f:
         text = f.read()
 except:
     with open(file_path, 'r', encoding='gbk') as f:
         text = f.read()
------------------------------------
date_df = pd.date_range(start=self.start_date - datetime.timedelta(1095), periods=1096)
date_list = date_df.date.tolist()
------------------------------------
将date转化为date,防止因为直接用values直接转化为str
date = [x.to_pydatetime().date() for x in cal_df['jz_date']
--------------------------------------------------
# 当前日期获取
import datetime
datetime.date.today()
---------------------------------------------
datetime可以查看:天数(day),小时数(hour),星期几(weekday());timedelta可以查看:天数(days),秒数(seconds)等。
# pandas  serion 转化为 datetime.date格式
 datetime_list = [x.to_pydatetime().date() for x in cal_base_df['jz_date']]
 输出:[datetime.date(2020, 5, 8), datetime.date(2020, 5, 9)]
---------------------------------------------
# 用前一个填充下一个值,limit=2指定最多数字,axis=0按列进行插补,method=bflii 下一个值进行填充
base_df = base_df.fillna(axis=0, method="ffill")
---------------------------------------------
# 当用date_range函数后需要进行转换
def cartesian_product(col_x, col_y, names):
    """
    @desc: 求两列数据的笛卡尔积
    @param col_x: 数据列
    @param col_y: 数据列
    @param names: 命名列表
    @return: DataFrame
    """
    mtx = pd.MultiIndex.from_product([col_x, col_y], names=names)
    return mtx.to_frame(index=False)
cp_ids = net_pro_anav_df[net_pro_anav_df['cp_id'].notnull()].cp_id.drop_duplicates().tolist()
print(len(cp_ids))
date_df = pd.date_range(start=self.start_date - datetime.timedelta(1095), periods=1096)
template_lit_df = cartesian_product(cp_ids, date_df, ['cp_id', 'jz_date'])
tmp1 = pd.DatetimeIndex(template_lit_df['jz_date']).date
template_lit_df['jz_date'] = tmp1
template_df = pd.merge(template_lit_df, net_pro_anav_df, on=['cp_id', 'jz_date'], how='left')
template_df = template_df.sort_values(['cp_id', 'jz_date'])
template_df.index = range(len(template_df))

---------------------------------------------
# 行列进行转换
# 原始数据
客户编号     三笔钱   持有金额
 1       随取随用的钱   1000
 2       投资理财的钱   1000
 3       投资理财的钱   1000
result_df = sel_deposit_df.groupby(['客户编号', '三笔钱'], as_index=False)['持有金额'].sum()
two_level_index_series = result_df.set_index(["客户编号", "三笔钱"])["持有金额"]
new_df = two_level_index_series.unstack()
new_df = new_df.reset_index() 
#结果数据
三笔钱  客户编号  保险保障的钱   投资理财的钱  随取随用的钱
0       1       1000.0       2000.0       1000.0
1       2       1000.0       2100.0        NaN
2       3       1000.0       12000.0       NaN
---------------------------------------------
# 计算分数相对于分数列表的百分数等级 
from scipy import stats 
import numpy as np  
  
# 1D array   
arr = [20, 2, 7, 1, 7, 7, 34]  
print("arr : ", arr)   
  
print ("\nPercetile of 7  : ", stats.percentileofscore(arr, 7)) 
  
print ("\nPercetile of 34 : ", stats.percentileofscore(arr, 34)) 
  
print ("\nPercetile of 2  : ", stats.percentileofscore(arr, 2))
# 查看数据类型
for i in net_pro_anav_df.jz_date.drop_duplicates().tolist():
    if not isinstance(i, datetime.date):
        print(i)
# 筛选“类别ID”包含'000'的数据
id_c=data.类别ID.str.contains('000',na=False)

df = pd.DataFrame({
    "name":['GuanYu', 'zhangFei', 'zhao-yun', 'machao', 'huangzhong#'],
    "city":['湖北省荆州市', '四川省汉中市', '四川省成都市', '甘肃省西凉区', '四川省成都市'],
    "salary":['30-50K', '30-50k', '30-45k', '30-40k', '30-40k'],
    "helpers":['关平 周仓 廖化 马良', '张苞 魏延', '马云禄', '马岱 庞德', '严颜']
})
#姓名列统一小写,然后过滤掉非字母的字符
df['name'].str.lower().str.replace('[^a-z]','')
# 根据正则表达式,提取省市之间的城市信息
df['city'].str.findall('.*省(.*?)[市区]').str[0]
# 符串的切分函数
df['salary'] = df['salary'].str[:-1].str.split('-') 
# 提取年
df['tiem'].dt.year
# 日期差
df['diff_date_second'] = ((df['datetime'] - df['last_datetime'])/pd.Timedelta(1, 'S')).fillna(0).astype(int)
print('两个日期相差的秒数:', df['diff_date_second'].values)
 
df['diff_date_minute'] = ((df['datetime'] - df['last_datetime'])/pd.Timedelta(1, 'min')).fillna(0).astype(int)
print('两个日期相差的分钟数:', df['diff_date_minute'].values)
 
df['diff_date_hour'] = ((df['datetime'] - df['last_datetime'])/pd.Timedelta(1, 'H')).fillna(0).astype(int)
print('两个日期相差的小时数:', df['diff_date_hour'].values)
 
df['diff_date_day'] = ((df['datetime'] - df['last_datetime'])/pd.Timedelta(1, 'D')).fillna(0).astype(int)
print('两个日期相差的天数:', df['diff_date_day'].values)

# 用当交易日有数据缺失时,则取交易日前一日的数据,如还是无数据,则取交易日前两日的数据
import datetime
result_df = pd.DataFrame()
result_df['jz_date'] = [datetime.date(2020, 1, 3), datetime.date(2020, 1, 4), datetime.date(2020, 1, 5),
                        datetime.date(2020, 1, 7)]
result_df['anav'] = [1, 2, 3, np.nan]

sel_res_no = result_df[result_df['anav'].isnull()]
sel_res_no.index = range(len(sel_res_no))
if bool(1 - sel_res_no.empty):
    for j in range(len(sel_res_no)):
        for k in range(1, 3):
            if np.isnan(sel_res_no.loc[j, 'anav']):
                update = result_df[result_df['jz_date'] == sel_res_no.loc[j, 'jz_date'] + datetime.timedelta(-k)]
                if update.empty:
                    continue
                sel_res_no.loc[j, 'anav'] = update['anav'].values[0]
            else:
                break
# 转化为datetime.datetime
import datetime
base_jz_df =base_df.copy()
base_jz_df["jz_date"] = base_jz_df["jz_date"].astype('str')
base_jz_df["jz_date"] = base_jz_df["jz_date"].apply(lambda x: datetime.datetime.strptime(x, '%Y-%m-%d'))

# 找对应日期属于第几周以及星期几
import time
from datetime import datetime
# 2021-1-14
#52 今天是2周
print(time.strftime("%W"))
#2 周一是0
today = datetime.now().weekday()

# 模板法进阶版
    def cal_yield_7_days(self, base_df, base_df_copy):
        base_df.index = range(len(base_df))
        start_date = base_df['jz_date'] + datetime.timedelta(-7)
        end_date = base_df['jz_date']
        diff_df = base_df_copy[(base_df_copy['cp_id'] == base_df['cp_id'].tolist()[0]) &
                                   ((base_df_copy['jz_date'] > start_date.tolist()[0]) &
                                    (base_df_copy['jz_date'] <= end_date.tolist()[0]))]
       
        return diff_df 
        
# 模板法
def cal_base_adjust_nav_change_ratio(self, base_df, result_df_copy):
    base_df.index = range(len(base_df))
    base_df_copy = base_df.copy()
    base_df_copy['jz_date_new'] = base_df['jz_date']+datetime.timedelta(1)
    base_df = base_df.append(base_df_copy)
    result_df_copy_new = result_df_copy.rename(columns={'jz_date': 'jz_date_new'})
    result_df = pd.merge(base_df, result_df_copy_new , on='jz_date_new',how='left')
    return result_df
    
# 累乘计算
# 结果为最后的累乘总数
result_df['prod'] = result_df['factor'].prod()
# 结果为每一步的累乘
result_df['prod'] = result_df['factor'].cumprod()

# 按照类型选取数据
umerical_fea = list(train.select_dtypes(exclude=['float64']).columns)
# 重新设置索引
base_df.index = range(len(base_df))

# 取上一条数据
result_df1['das'] =result_df1['cp_id'].shift(1)

# 寻找每个月最后一天
def last_day_of_month(self, any_day):
    next_month = any_day.replace(day=28) + datetime.timedelta(days=4)
    return next_month - datetime.timedelta(days=next_month.day)
    
# 按照类别求差值 
df = base.sort_values(by=['cp_id'])
df['diff'] = df.groupby(['cp_id'])['yield'].diff().fillna(0)
# numpy 转换为DateFrame
dict_month = {'cp_id': base_not_case_prod.index, 'prod': base_not_case_prod.values}
base_not_case_prod = pd.DataFrame(dict_month)

# 分类后修改名称
tmp_result_df_sum = temp_df.groupby(['is_net_value', data_type, 'product_state_type'],
                                            as_index=False).cp_id.count().rename(
            columns={'cp_id': 'product_sum'})
            
# 字典标准化输出
pprint.pprint(result_dic)

# 当分割数据类别不确定时
str_df = temp_df[data_type].str.split(',', expand=True).stack().reset_index(level=1, drop=True).rename(data_type)
temp_df = temp_df.drop(data_type, axis=1).join(str_df)

# 当数据类别缺失时,需要填充
 data_type_list = tmp_result_df.data_type.drop_duplicates().tolist()
for product_state_type in [1, 2, 3]:
    for product_type in [0, 1]:
        for type_list in data_type_list:
        template_lst.append([save_date, report_type, product_state_type, product_type, type_list])
        template_columns = ['report_date', 'report_type']
     if template_lst:
         rel_df = pd.DataFrame(template_lst, columns=template_columns)
     else:
         rel_df = pd.DataFrame(columns=template_columns)
     tmp_result_df = pd.merge(rel_df, tmp_result_df, on=['report_date', 'report_type'], how='left')
     tmp_result_df.loc[tmp_result_df['product_sum'].isnull(), 'product_sum'] = 0

# 快速读取数据
product_df = self._read_py_etl_product_bank_financial_gather()
pickle.dump(product_df, open("product_df_report.pkl", mode='wb'))
product_df = pickle.load(open("product_df_report.pkl", mode='rb'))

# 具有关联条件的组成字典
for data_type, table_name in zip(self.data_type, self.write_tables):
	print(data_type,table_name)

# 将处理相同类的字段进行函数化处理
 self.data_type_func_dic = {
     "sale_area": self.cal_area_ch,
     }
temp_df = self.data_type_func_dic.get(data_type, lambda x, y='': x)(temp_df, data_type)
	
#将相同datafram以添加的形式进行合并         
product_df_lst = []
product_df_lst.append(other_df)
product_df: pd.DataFrame = pd.concat(product_df_lst, ignore_index=True)

#两个列表之间比较
list1 = ['张三', '李四', '王五', '老二']
list2 = ['张三', '李四', '老二', '王七']
a = [x for x in list1 if x in list2] #两个列表中都存在
b = [y for y in (list1 + list2) if y not in a] #两个列表中的不同元素
print('a的值为:',a)
print('b的值为:',b)
c = [x for x in list1 if x not in list2]  #在list1列表中而不在list2列表中
d = [y for y in list2 if y not in list1]  #在list2列表中而不在list1列表中
print('c的值为:',c)
print('d的值为:',d)
difference = list(set(pkl_list) - set(knoledge_list))

# 将字符串数据改为date
start_date = datetime.datetime.strptime(self.json_str['start_date'], '%Y-%m-%d').date()

# 按照id进行分类之后取出最大值,但是不确定最大值有几个时
 max_df = base_df.groupby("cp_id", as_index=False).sale_start_date.max()
 max_df['flag'] = 1
 base_df = base_df.merge(max_df, on=['cp_id', 'sale_start_date'], how='left')
 base_df = base_df[base_df.flag == 1]
 del base_df['flag']
 
# loc用法 当需要将满足条件的行数据重新赋值时
 base_df.loc[base_df['is_net_value'] == 0, 'yield_rate'] = base_df['solve_yield']
 #判断是否为空
 base_df.loc[base_df['is_net_value'].isnull(), 'yield_rate'] = base_df['solve_yield']
  
# 当计算均值是有空缺值是不能直接加,因为会变为null
base_df.loc[df.value == 1, 'rate'] =base_df[['high','syl']].mean(axis=1)

#取没有空值 
base_df = base_df[base_df.yield_rate.notnull()]

# 计算分类多个条件时使用agg()
 base_all = base_df.groupby(['type', 'value'],as_index=True).yield_rate.agg(['mean', 'std'])
base_all = base_all.rename(columns={'mean': 'yield_rate_mean', 'std': 'yield_rate_std'})
# 当无法合并时使用left_index合并
base_all = pd.merge(base_all.index.to_frame(), base_all, left_index=True, right_index=True, how='left')
base_df = pd.merge(base_df, base_all, on=['product_type', 'is_net_value'], how='left')
       
#data去重转换为list
base_df['product_type'].drop_duplicates().tolist()

#当列相同时需要将多表进行合并
df = pd.concat([df, df5], ignore_index=True)

#求指定中位数
yield_min = yield_df.groupby(['type','sec'])[['yield_rate']].quantile(0.3)
yield_min = pd.merge(yield_min.index.to_frame(), yield_min, left_index=True,right_index=True,how='left')
yield_min = yield_min.rename(columns={'yield_rate': 'yield_min'})

# 包含某个变量
df = pd.DataFrame()
for i in company_base['short_name'].values:
	i:if i:# 当i为空时可能将所有的字段都进行匹配,所以必须要判断是否为空,i类型为str
    	df5 = article_content.loc[article_content['title'].str.contains(i)]
    	df = pd.concat([df, df5], ignore_index=True)
    	
#通过Pandas的nunique方法来筛选属性分类为一的变量,剔除分类数量只有1的变量,Pandas方法nunique()返回的是变量的分类数量(除去非空值)
loans = test.loc[:,test.apply(pd.Series.nunique) != 1]

# 数据去重
test.drop_duplicates(subset=['uid','bank_account'],keep='first',inplace=True)

#保留小数点后两位且当3.5456时保存为3.50
min_val = '%.2f' % min([base_df['yield_min'].min(), base_df['net_yield_min'].min()])

# 修改dataframe的列名
columns = {'bank_id': 'org_id'}
rel_df = rel_df.rename(columns=columns)

## ip数字转换为ip
import socket
import struct
test_new['访问最多ip']=test_new['访问最多ip'].astype('int')
test_new['访问最多ip']=test_new['访问最多ip'].fillna(0)
def ip_zhuanhuan(x):
    return socket.inet_ntoa(struct.pack('I',socket.htonl(x)))
test_new['访问最多ip_']=test_new.apply(lambda x: ip_zhuanhuan(x['访问最多ip']),axis=1)

## url转换正常编码
test['payinfo_']=test['payinfo_'].astype('str')

# 接口对接要使用基础变量,python基础变量空为None,以防万一,先转化为nan 再转化为字符串,再进行替换
base_df.loc[base_df[col].isnull(), col] = None
base_df[col] = base_df[col].astype('str')
base_df.loc[base_df[col] == 'nan', col] = None

# 转化为字典
result_lst = base_df.to_dict("records")

# 将字典中的空值去掉
new_result_lst = []
for tmp_dic in result_lst:
    new_tmp_dic = {}
    for key, value in tmp_dic.items():
        if isinstance(value, float) or isinstance(value, int):
            if np.isnan(value):
                value = None
        new_tmp_dic[key] = value
    new_result_lst.append(new_tmp_dic)

# 防止用空缺导致无法进行运算
def ip_zhuanhuan(x):
    print(x)
    return urllib.parse.unquote(x)
result_df['cp_transfer'] = result_df['cp_transfer'].astype(str).apply(self.ip_zhuanhuan)

## 链接相同数据
import pandas as pd
data={
    'id':[1,2,1,1,3],
    'code':[123,465,123,321,789]
}
test=pd.DataFrame(data)
test['code']=test['code'].astype('str')
data1 = test.groupby(by='id').apply(lambda x:[','.join(x['code'])])

## 数据分组合并
test1=test.groupby(['月'],as_index=False)['amount_s'].sum()

##排序
test_sys4=test_sys1.sort_values(by=['uid','actionTime'],ascending=[False,True])
## False为降序
##正则匹配取反 
test_me3=test_me2[test_me2['RealName'].str.contains('test|测试')==False]
##某列按时间排序取最大时间或者最小时间
admin_op=admin_op[['登录时间','登录IP']]
admin_op1=admin_op.sort_values(by=['登录IP','登录时间'],ascending=[False,False])
admin_op1.head()
admin_op1.drop_duplicates(subset=['登录IP'],keep='first',inplace=True)
##取某列前几个字符
df['月']=df['月份'].apply(lambda x:x[4:])
## 多列合并为一列
df["location"].str.cat(df["location_road"],sep"-")
df['date'] =df['year'].map(str)+"/"+df['month'].map(str)+"/"+df['day'].map(str)
df = pd.DataFrame()
## 多表匹配以某个表为基础,将空缺值用剩余表填充
# 通过公司表获取的字段
df['legal_person_id'] = [1,2,3,4, 5]
df['temp_value'] = [2,2,3,3, np.nan]
#
temp_df = pd.DataFrame()
temp_df['legal_person_id'] = [3,5,6,8]
temp_df['temp_value'] = [np.nan, 1,1,1]
# 处理过程
temp_df = temp_df.rename(columns={'temp_value': 'bond_value'})
rel_df = pd.merge(df, temp_df, on=['legal_person_id'], how='outer')
rel_df.loc[rel_df.temp_value.isnull(), 'temp_value'] = rel_df.bond_value
print(rel_df)
##当遇到判断某表是否有值
cashflow_report.empty
# 布尔值取反
b = True
b = bool(1-b) 

object值

##字符串转化
y_map = {'low': 2, 'medium': 1, 'high': 0}
train['interest_level'] = train['interest_level'].map(y_map)
#在实际模型建立中,训练集和测试集一般分开处理,如果直接使用分类处理,会导致新数据没有一个规定
##数据调用函数,review为字段clean_text为函数方法
df['clean_review'] = df.review.apply(clean_text)
#查看多少类变量
tab_1['字段'].unique()
def function(a):
	if '数值或字符'in a :
		return 1
	else:
		return 2
tab_1['结果'] = tab_1.apply(lambda x: function(x['结果']), axis = 1)
#有时还需用re统一规则
import re
def re_1(i):
    res=re.sub("[^a-zA-Z]", " ",i)
    return res
test_1['new_review'] = test_1.apply(lambda x: re_1(x['review']), axis = 1)
##不会产生其余的东西
test2['new']=test2['content'].str.extract('.[上分金额].(\d+)', expand=False)
#需要加强一下re学习
# 类别
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
le = LabelEncoder()
test['grade'] = le.fit_transform(test['grade'])
#使用pandas库将类别变量编码
test_1 = pd.get_dummies(test_1)
#判断是否为object类型
cols = attrition.columns
for col in cols:
    if str(attrition[col].dtype) == 'object':
        categoricals.append(col)
#类别变量数量
housetype['装修情况'].value_counts()
-------------------------------------------
objectColumns = loans.select_dtypes(include=["object"]).columns 
# 筛选数据类型为object的数据
loans[objectColumns] = loans[objectColumns].fillna("Unknown") 
# 区别类别型数据和数值型数据
numerical_fea = list(data_train.select_dtypes(exclude=['object']).columns)
category_fea = list(filter(lambda x: x not in numerical_fea,list(data_train.columns)))
#以分类“Unknown”填充缺失值
-------------------------------------------
n_columns = ["home_ownership", "verification_status", "application_type","purpose", "term"] 
dummy_df = pd.get_dummies(loans[n_columns])# 用get_dummies进行one hot编码
loans = pd.concat([loans, dummy_df], axis=1) #当axis = 1的时候,concat就是行对齐,然后将不同列名称的两张表合并

连续值

#标准化是通过特征的平均值和标准差将特征缩放成一个标准的正态分布,均值为0,方差为1
#将特征值缩放到相同区间可以使得获取性能更好的模型。就梯度下降算法而言,例如有两个不同的特征,第一个特征的取值范围为1~10,
#第二个特征的取值范围为1~10000。在梯度下降算法中,代价函数为最小平方误差函数,所以在使用梯度下降算法的时候,算法会明显的偏向于第二个特征,
#因为它的取值范围更大。在比如,k近邻算法,它使用的是欧式距离,也会导致其偏向于第二个特征。对于决策树和随机森林以及XGboost算法而言,
#特征缩放对于它们没有什么影响。
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
x = data["Alcohol"]
std = StandardScaler()
#将x进行标准化
x_std = std.fit_transform(x)

离散值

缺失值

#缺失值可以用不同的数填充  平均数 众数 
#将均值填入
all_dummy_df.isnull().sum().sum()
mean_cols=all_dummy_df.mean()
all_dummy_df = all_dummy_df.fillna(mean_cols)
#将众数填入
all_dummy_df = all_dummy_df.fillna(数字)
#将缺失值比例列出
train_missing = (test_1.isnull().sum()/len(test_1))*100
train_missing = train_missing.drop(train_missing[train_missing==0].index).sort_values(ascending=False)
miss_data = pd.DataFrame({'缺失百分比':train_missing})
miss_data
##可视化缺失值范围
import missingno as msno
msno.matrix(data.sample(test.shape[0]))
# 缺失值比例画出
(test.isnull().sum()/len(test)).plot.bar(figsize = (20,6))
#将缺失值直接删除
test_1.dropna(inplace=True)
## 使用随机森林填补一个特征的缺失值的函数
def fill_missing_rf(X,y,to_fill):

    """
    使用随机森林填补一个特征的缺失值的函数

    参数:
    X:要填补的特征矩阵
    y:完整的,没有缺失值的标签
    to_fill:字符串,要填补的那一列的名称
    """

    #构建我们的新特征矩阵和新标签
    df = X.copy()
    fill = df.loc[:,to_fill]
    df = pd.concat([df.loc[:,df.columns != to_fill],pd.DataFrame(y)],axis=1)

    # 找出我们的训练集和测试集
    Ytrain = fill[fill.notnull()]#特征不缺失的值
    Ytest = fill[fill.isnull()]#特征缺失的值
    Xtrain = df.iloc[Ytrain.index,:]#特征不缺失的值对应其他n-1个特征+本来的标签
    Xtest = df.iloc[Ytest.index,:]#特征缺失的值对应其他n-1个特征+本来的标签

    #用随机森林回归来填补缺失值
    from sklearn.ensemble import RandomForestRegressor as rfr
    rfr = rfr(n_estimators=100)
    rfr = rfr.fit(Xtrain, Ytrain)
    Ypredict = rfr.predict(Xtest)
    return Ypredict
#用随机森林填补比较多的缺失值
X = test.iloc[:,[5,0,1,2,3,4,6,7,8,9]]
y = test["SeriousDlqin2yrs"]#y = data.iloc[:,0]
X.shape#(149391, 10)
#=====[TIME WARNING:1 min]=====#
y_pred = fill_missing_rf(X,y,"MonthlyIncome")
#注意可以通过以下代码检验数据是否数量相同
y_pred.shape ==  test.loc[test.loc[:,"MonthlyIncome"].isnull(),"MonthlyIncome"].shape
#确认我们的结果合理之后,我们就可以将数据覆盖了
test.loc[test.loc[:,"MonthlyIncome"].isnull(),"MonthlyIncome"] = y_pred
test.info()
------------------------------------
# 设定阈值之后进行删除
thresh_count = len(data)*0.4 # 设定阀值
data = data.dropna(thresh=thresh_count, axis=1 ) #若某一列数据缺失的数量超过阀值就会被删除

异常值

#超过一定的值之后统一为国定的值
train_test['price'].ix[train_test['price']>13000] = 13000
# remove some noise
train_test.loc[train_test["bathrooms"] == 112, "bathrooms"] = 1.5
## 缺失值画箱型图
import seaborn as sns
data379=test[['NumberOfTime30-59DaysPastDueNotWorse','NumberOfTimes90DaysLate','NumberOfTime60-89DaysPastDueNotWorse']]
plt.clf()
plt.figure(figsize=(20,8))
data379.boxplot()
plt.xticks(rotation='90')

特征处理

特征衍生
特征抽象
特征缩放
特征缩放(peature scaling)是指将变量数据经过处理之后限定到一定的范围之内。特征缩放本质是一个去量纲的过程,同时可以加快算法收敛的速度。目前,将不同变量缩放到相同的区间有两个常用的方法:归一化(normalization)和标准化(standardization)。

col = loans.select_dtypes(include=['int64','float64']).columns
len(col)
out:78 #78个特征
col = col.drop('loan_status') #剔除目标变量
loans_ml_df = loans # 复制数据至变量loans_ml_df
###################################################################################
from sklearn.preprocessing import StandardScaler # 导入模块
sc =StandardScaler() # 初始化缩放器
loans_ml_df[col] =sc.fit_transform(loans_ml_df[col]) #对数据进行标准化
loans_ml_df.head() #查看经标准化后的数据

特征选择
过滤方法(filter approach): 通过自变量之间或自变量与目标变量之间的关联关系选择特征。
正常情况下,影响目标变量的因数是多元性的;但不同因数之间会互相影响(共线性 ),或相重叠,进而影响到统计结果的真实性。下一步,我们在第一次降维的基础上,通过皮尔森相关性图谱找出冗余特征并将其剔除;同时,可以通过相关性图谱进一步引导我们选择特征的方向。

colormap = plt.cm.viridis
plt.figure(figsize=(12,12))
plt.title('Pearson Correlation of Features', y=1.05, size=15)
sns.heatmap(loans_ml_df[col_filter].corr(),linewidths=0.1,vmax=1.0, square=True, cmap=colormap, linecolor='white', annot=True)

嵌入方法(embedded approach): 通过学习器自身自动选择特征。
很多时候我们需要了解每个特征对目标的影响程度,在特定的业务场景下,不同的特征权重对业务的决策带来不同的影响。例如,在Lending Club的业务数据中,能够反映借款人资产状况或现金流的特征都对我们构建预测违约贷款模型十分关键。因此,我们需要对特征的权重有一个正确的评判和排序,就可以通过特征重要性排序来挖掘哪些变量是比较重要的,降低学习难度,最终达到优化模型计算的目的。这里,我们采用的是随机森林算法判定特征的重要性

names = loans_ml_df[col_new].columns
from sklearn.ensemble import RandomForestClassifier
clf=RandomForestClassifier(n_estimators=10,random_state=123)#构建分类随机森林分类器
clf.fit(x_val[col_new], y_val) #对自变量和因变量进行拟合
names, clf.feature_importances_
for feature in zip(names, clf.feature_importances_):
    print(feature)
    plt.style.use('fivethirtyeight')
plt.rcParams['figure.figsize'] = (12,6)

## feature importances 可视化##
importances = clf.feature_importances_
feat_names = names
indices = np.argsort(importances)[::-1]
fig = plt.figure(figsize=(20,6))
plt.title("Feature importances by RandomTreeClassifier")
plt.bar(range(len(indices)), importances[indices], color='lightblue',  align="center")
plt.step(range(len(indices)), np.cumsum(importances[indices]), where='mid', label='Cumulative')
plt.xticks(range(len(indices)), feat_names[indices], rotation='vertical',fontsize=14)
plt.xlim([-1, len(indices)])
plt.show()

包装方法(wrapper approacch): 通过目标函数(AUC/MSE)来决定是否加入一个变量。
首先,选出与目标变量相关性较高的特征。这里采用的是Wrapper方法,通过暴力的递归特征消除 (Recursive Feature Elimination)方法筛选30个与目标变量相关性最强的特征,逐步剔除特征从而达到首次降维,自变量从104个降到30个。

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
# 建立逻辑回归分类器
model = LogisticRegression()
# 建立递归特征消除筛选器
rfe = RFE(model, 30) #通过递归选择特征,选择30个特征
rfe = rfe.fit(x_val, y_val)
# 打印筛选结果
print(rfe.support_)
print(rfe.ranking_) #ranking 为 1代表被选中,其他则未被代表未被选中

时间序列

# 周报 月报 季报 年报
def calculate_date(self):
    start_date = self.start_date
    print(start_date)
    date_lst = []
    if start_date.weekday() == 0:
        week_end_date = start_date - datetime.timedelta(1)
        week_start_date = start_date - datetime.timedelta(7)
        date_lst.append((week_start_date, week_end_date, week_end_date, self.week))

    if start_date.day == 3:
        month_end_date = start_date - datetime.timedelta(3)
        month_start_date = datetime.date(month_end_date.year, month_end_date.month, 1)
        date_lst.append((month_start_date, month_end_date, month_end_date, self.month))

    if start_date.month in [1, 4, 7, 10] and start_date.day == 3:
    season_dic = {1: [datetime.date(start_date.year - 1, 10, 1),datetime.date(start_date.year - 1, 12, 31),
                          datetime.date(start_date.year - 1, 12, 31)],
                      4: [datetime.date(start_date.year, 1, 1), datetime.date(start_date.year, 3, 31),
                          datetime.date(start_date.year, 3, 31)],
                      7: [datetime.date(start_date.year, 4, 1), datetime.date(start_date.year, 6, 30),
                          datetime.date(start_date.year, 6, 30)],
                      10: [datetime.date(start_date.year, 7, 1), datetime.date(start_date.year, 9, 30),
                           datetime.date(start_date.year, 9, 30)]
                      }
        season_date_lis = season_dic.get(start_date.month)

        date_lst.append((season_date_lis[0], season_date_lis[1], season_date_lis[2], self.season))

    if start_date.month is 1 and start_date.day == 3:
        year_start_date = datetime.date(start_date.year - 1, 1, 1)
        year_end_date = datetime.date(start_date.year - 1, 12, 31)
        year_save_date = datetime.date(start_date.year - 1, 12, 31)
        date_lst.append((year_start_date, year_end_date, year_save_date, self.year))
    if date_lst:
        self.start_date = min([i[0] for i in date_lst])
    return date_lst
#
rng = pd.period_range('1/1/2017','2/28/2019',freq='M') #创建从2001-01-01到2000-06-30所有月份的Period
data_1=pd.Series(np.random.randn(len(rng)),index=rng)
df=pd.DataFrame({"data" :data_1,"企业编号":4001})
df.drop('data',inplace=True,axis=1)
df.head()
————————————————————————————————————————————————————
## 时间戳转换
import time
test3['xftime'] = test3['xftime'].fillna(0)
def shijianchuo(x):
    timeArray = time.localtime(x)
    otherStyleTime = time.strftime("%Y--%m--%d %H:%M:%S", timeArray)
    return otherStyleTime
test3['addtime']=test3.apply(lambda x: shijianchuo(x['addtime']),axis=1)

# 时间格式转化为时间戳,方便快速计算
base_df['sale_start_date'] = base_df['sale_start_date'].apply(lambda x: int(time.mktime(x.timetuple())))

#转化为时间段进行处理
df['时间'] = df['时间'].apply(lambda x: pd.Timestamp(x))
# 年份
df['年']=df['时间'].apply(lambda x: x.year)

# 月份
df['月']=df['时间'].apply(lambda x: x.month)

# 日
df['日']=df['时间'].apply(lambda x: x.day)

# 小时
df['时']=df['时间'].apply(lambda x: x.hour)

# 分钟
df['分']=df['时间'].apply(lambda x: x.minute)

# 秒数
df['秒']=df['时间'].apply(lambda x: x.second)

# 一天中的第几分钟
df['一天中的第几分钟']=df['时间'].apply(lambda x: x.minute + x.hour*60)

# 星期几;
df['星期几']=df['时间'].apply(lambda x: x.dayofweek)

# 一年中的第几天
df['一年中的第几天']=df['时间'].apply(lambda x: x.dayofyear)

# 一年中的第几周
df['一年中的第几周']=df['时间'].apply(lambda x: x.week)

# 一天中哪个时间段:凌晨、早晨、上午、中午、下午、傍晚、晚上、深夜;
period_dict ={
    23: '深夜', 0: '深夜', 1: '深夜',
    2: '凌晨', 3: '凌晨', 4: '凌晨',
    5: '早晨', 6: '早晨', 7: '早晨',
    8: '上午', 9: '上午', 10: '上午', 11: '上午',
    12: '中午', 13: '中午',
    14: '下午', 15: '下午', 16: '下午', 17: '下午',
    18: '傍晚',
    19: '晚上', 20: '晚上', 21: '晚上', 22: '晚上',
}
df['时间段']=df['时'].map(period_dict)

# 一年中的哪个季度
season_dict = {
    1: '春季', 2: '春季', 3: '春季',
    4: '夏季', 5: '夏季', 6: '夏季',
    7: '秋季', 8: '秋季', 9: '秋季',
    10: '冬季', 11: '冬季', 12: '冬季',
}
df['季节']=df['月'].map(season_dict)

数据划分

from sklearn.model_selection import train_test_split
# 使用train_test_split方法,划分训练集和测试集,指定80%数据为训练集,20%为验证集
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.2,random_state=2020)

相关性分析

#导入seaborn
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
#创建热图
correlation_matrix=test.corr()
sns.heatmap(correlation_matrix,
            annot=True,
            cmap="YlGnBu", 
            linewidths=0.3,
            annot_kws={"size": 8})

plt.xticks(rotation=90)
plt.yticks(rotation=0) 
plt.show()

在这里插入图片描述

f,ax = plt.subplots(figsize = (7, 7))
plt.title('Correlation of Numeric Features with Price',y=1,size=16)
sns.heatmap(correlation,square = True,  vmax=0.8)

在这里插入图片描述

绘图

直方图

在这里插入图片描述

plt.figure(figsize=(10,5))#改变图形大小
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['FangSong'] # 指定默认字体
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
#设置画布
asd,sdf = plt.subplots(1,1,dpi=100)
#获取排前10条类型
housetype.head(10).plot(kind='bar',x='housetype',y='size',title='户型数量分布',ax=sdf)
plt.legend(['数量'])
plt.show()

在这里插入图片描述

散点图

plt.clf()
fig,axs=plt.subplots(1,2,figsize=(14,4))
axs[0].scatter(x=test_all.loc[:,'面积'],y=test_all.loc[:,'价格'])
axs[1].scatter(x=test_all[test_all.loc[:,'面积']<175].loc[:,'面积'],y=test_all[test_all.loc[:,'面积']<175].loc[:,'价格'])
plt.show()

在这里插入图片描述

分类变量画图

import seaborn as sns
sns.stripplot(x="day", y="total_bill", data=tips);

在这里插入图片描述

特征选择

选取贡献度超过95%的特征

from sklearn.feature_selection import SelectKBest
selector = SelectKBest(k=2)
X_new = selector.fit_transform(X, Y)
kfold = KFold(n_splits=10)
cv_result = cross_val_score(model, X_new, Y, cv=kfold)

分析各特征关系

contFeatureslist = []
contFeatureslist.append("bathrooms")
contFeatureslist.append("bedrooms")
contFeatureslist.append("price")
correlationMatrix = train[contFeatureslist].corr().abs()
plt.subplots(figsize=(13, 9))
sns.heatmap(correlationMatrix,annot=True)
# Mask unimportant features
sns.heatmap(correlationMatrix, mask=correlationMatrix < 1, cbar=False)
plt.show()

模型选择

如何选择模型

#多个模型
models = []
models.append(("KNN", KNeighborsClassifier(n_neighbors=2)))
models.append(("KNN with weights", KNeighborsClassifier(
    n_neighbors=2, weights="distance")))
models.append(("Radius Neighbors", RadiusNeighborsClassifier(
    n_neighbors=2, radius=500.0)))
results = []
for name, model in models:
    model.fit(X_train, Y_train)
    results.append((name, model.score(X_test, Y_test)))
for i in range(len(results)):
    print("name: {}; score: {}".format(results[i][0],results[i][1]))

分类模型

随机森林

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report
# SVC(C=1.0, kernel='rbf', gamma=0.1)
clf =RandomForestClassifier() # 定义随机森林模型
# 拟合模型
clf.fit(x_train, y_train)
y_predict=clf.predict(x_test)
print(classification_report(y_test, y_predict))

回归模型

k-近邻算法

线性回归算法

from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
lineR = LinearRegression()
lineR.fit(X_train,y_train)
train_score = lineR.score(X_test,y_test)
print(model.intercept_) # 截距
print(model.coef_[0]) # 系数
print(train_score)

# 当输入变量为一列时
x = result_df['jz_date'].values.reshape(-1, 1)

逻辑回归算法

决策树

##分类
from sklearn import svm
from sklearn.metrics import classification_report
clf = svm.SVC()
clf.fit(X_train, y_train)
y_predict=clf.predict(X_test)
print(classification_report(y_test, y_predict))
##预测

支持向量机

朴素贝叶斯

pca算法

k-均值算法

xgboost

import xgboost as xgb
pipes =Pipeline([
            ('xgb', xgb.XGBRegressor())
        ])
parameters = [
    {
    "xgb__n_estimators":[100,200,300,500,1000]
    }
]
#获取数据
x_train2, x_test2, y_train2, y_test2 = X_train, X_test, y_train, y_test
gscv = GridSearchCV(pipes, param_grid=parameters)
gscv.fit(x_train2, y_train2)
print ("score值:",gscv.best_score_,"最优参数列表:", gscv.best_params_)

随机森林

# #参数优化
from sklearn.pipeline import Pipeline #管道
from sklearn.model_selection import GridSearchCV #网格搜索交叉验证,用于选择最优的参数
from sklearn.ensemble import RandomForestRegressor
pipes =Pipeline([
            ('RandomForestClassifier', RandomForestRegressor(criterion='mse'))
        ])
# 参数
#
# estimators = [1,50,100,500]
# depth = [1,2,3,7,15]
parameters = [
    {
    "RandomForestClassifier__n_estimators":[1,50,100,500,1000,3000],
    "RandomForestClassifier__max_depth":[1,2,3,7,15]
    }
]
#获取数据
x_train2, x_test2, y_train2, y_test2 = X_train, X_test, y_train, y_test
gscv = GridSearchCV(pipes, param_grid=parameters)
gscv.fit(x_train2, y_train2)
print ("score值:",gscv.best_score_,"最优参数列表:", gscv.best_params_)

使用网格搜索针对不同的认为需要制定不同的scoring=‘f1’
在这里插入图片描述

模型训练和测试

参数调节

模型性能评估和优化

准确度

from sklearn.metrics import explained_variance_score 
print('准确率:',explained_variance_score(y_test,final))
## 分类指标评价计算
## accuracy
import numpy as np
from sklearn.metrics import accuracy_score
y_pred = [0, 1, 0, 1]
y_true = [0, 1, 1, 1]
print('ACC:',accuracy_score(y_true, y_pred))
## Precision,Recall,F1-score
from sklearn import metrics
y_pred = [0, 1, 0, 0]
y_true = [0, 1, 0, 1]
print('Precision',metrics.precision_score(y_true, y_pred))
print('Recall',metrics.recall_score(y_true, y_pred))
print('F1-score:',metrics.f1_score(y_true, y_pred))
## AUC
import numpy as np
from sklearn.metrics import roc_auc_score
y_true = np.array([0, 0, 1, 1])
y_scores = np.array([0.1, 0.4, 0.35, 0.8])
print('AUC socre:',roc_auc_score(y_true, y_scores))
##回归指标评价计算
import numpy as np
from sklearn import metrics
# MAPE需要自己实现
def mape(y_true, y_pred):
    return np.mean(np.abs((y_pred - y_true) / y_true))
y_true = np.array([1.0, 5.0, 4.0, 3.0, 2.0, 5.0, -3.0])
y_pred = np.array([1.0, 4.5, 3.8, 3.2, 3.0, 4.8, -2.2])

# MSE
print('MSE:',metrics.mean_squared_error(y_true, y_pred))
# RMSE
print('RMSE:',np.sqrt(metrics.mean_squared_error(y_true, y_pred)))
# MAE
print('MAE:',metrics.mean_absolute_error(y_true, y_pred))
# MAPE
print('MAPE:',mape(y_true, y_pred))
## ROC曲线
from sklearn.metrics import roc_curve
y_pred = [0, 1, 1, 0, 1, 1, 0, 1, 1, 1]
y_true = [0, 1, 1, 0, 1, 0, 1, 1, 0, 1]
FPR,TPR,thresholds=roc_curve(y_true, y_pred)
plt.title('ROC')
plt.plot(FPR, TPR,'b')
plt.plot([0,1],[0,1],'r--')
plt.ylabel('TPR')
plt.xlabel('FPR')
--------------------------------------------
# 多分类评价指标
print('Recall', metrics.recall_score(y_true, y_pred, average='micro'))
print('F1-score:', metrics.f1_score(y_true, y_pred, average='micro'))
print('precision:', metrics.precision_score(y_true, y_pred, average='micro'))
print(metrics.classification_report(y_true, y_pred, target_names=["90度", "180度", '270度', '0度'],
                                    digits=4))  # 假设标签0代表政治、标签1代表体育  digits可以设置小数点后保留的位数 默认是2
print(metrics.accuracy_score(y_true, y_pred))  # 2分类多分类都可以用

查准率和召回率

模型混合

一:平均
1. 简单加权平均,结果直接融合
pre = (pre1 + pre2 + pre3 +...+pren )/n 
2.加权平均法
pre = 0.3pre1 + 0.3pre2 + 0.4pre3 
二:投票
1 简单投票
from xgboost import XGBClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, VotingClassifier
clf1 = LogisticRegression(random_state=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=4, min_child_weight=2,
subsample=0.7,objective='binary:logistic')
vclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('xgb', clf3)])
vclf = vclf .fit(x_train,y_train)
print(vclf .predict(x_test)) 
2:加权投票
#在VotingClassifier中加入参数 voting='soft', weights=[2, 1, 1],weights用于调节基模型的权重
from xgboost import XGBClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, VotingClassifier
clf1 = LogisticRegression(random_state=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = XGBClassifier(learning_rate=0.1, n_estimators=150, max_depth=4, min_child_weight=2,
subsample=0.7,objective='binary:logistic')
vclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('xgb', clf3)],
voting='soft', weights=[2, 1, 1])
vclf = vclf .fit(x_train,y_train)
print(vclf .predict(x_test))
三 Stacking
clf1 = KNeighborsClassifier(n_neighbors=1)
clf2 = RandomForestClassifier(random_state=1)
clf3 = GaussianNB()
lr = LogisticRegression()
sclf = StackingClassifier(classifiers=[clf1, clf2, clf3],
meta_classifier=lr)
scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
print("Accuracy: %.2f (+/- %.2f) [%s]" %(scores.mean(), scores.std(), label))

模型使用

模型的保存

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值