25、切片
正下标从0开始,负下标从-1开始1。切片的时候包括头不包括尾部。
25、loc和iloc
loc是指location的意思,iloc中的i是指integer。
【1】iloc:根据标签的所在位置,从0开始计数,先选取行再选取列
【2】loc:根据DataFrame的具体标签选取行列,同样是先行标签,后列标签
lypdfdata=lypdf.iloc[:,1:-1].values lypdftarget=lypdf.iloc[:,:-1].values # 逗号前面是属于行,后面是属于列
1. 利用loc、iloc提取行数据
import numpy as np import pandas as pd #创建一个Dataframe data=pd.DataFrame(np.arange(16).reshape(4,4),index=list('abcd'),columns=list('ABCD')) In[1]: data Out[1]: A B C D a 0 1 2 3 b 4 5 6 7 c 8 9 10 11 d 12 13 14 15 #取索引为'a'的行 In[2]: data.loc['a'] Out[2]: A 0 B 1 C 2 D 3 #取第一行数据,索引为'a'的行就是第一行,所以结果相同 In[3]: data.iloc[0] Out[3]: A 0 B 1 C 2 D 3
2. 利用loc、iloc提取列数据
In[4]:data.loc[:,['A']] #取'A'列所有行,多取几列格式为 data.loc[:,['A','B']] Out[4]: A a 0 b 4 c 8 d 12 In[5]:data.iloc[:,[0]] #取第0列所有行,多取几列格式为 data.iloc[:,[0,1]] Out[5]: A a 0 b 4 c 8 d 12
3.利用loc、iloc提取指定行、指定列数据
In[6]:data.loc[['a','b'],['A','B']] #提取index为'a','b',列名为'A','B'中的数据 Out[6]: A B a 0 1 b 4 5 In[7]:data.iloc[[0,1],[0,1]] #提取第0、1行,第0、1列中的数据 Out[7]: A B a 0 1 b 4 5
4.利用loc、iloc提取所有数据
In[8]:data.loc[:,:] #取A,B,C,D列的所有行 Out[8]: A B C D a 0 1 2 3 b 4 5 6 7 c 8 9 10 11 d 12 13 14 15 In[9]:data.iloc[:,:] #取第0,1,2,3列的所有行 Out[9]: A B C D a 0 1 2 3 b 4 5 6 7 c 8 9 10 11 d 12 13 14 15
5.利用loc函数,根据某个数据来提取数据所在的行
In[10]: data.loc[data['A']==0] #提取data数据(筛选条件: A列中数字为0所在的行数据) Out[10]: A B C D a 0 1 2 3 In[11]: data.loc[(data['A']==0)&(data['B']==2)] #提取data数据(多个筛选条件) Out[11]: A B C D a 0 1 2 3
26、DataFrame
data=[[-1,2],[-0.5,6],[0,10],[1,18]]
python读取DataFrame的某几列(根据列名)
import pandas as pd data=pd.read_csv("titanic.csv") data1=data[['Age','Sex','Embarked','Survived']]
DF删除特定的一列:
data.loc[:,-1]=label data.head() data.drop(['Survived'],axis=1,inplace=True)
DF修改表头的名字,使用rename:
data.rename(columns={'-1':'Survived'})
Dataframe中添加一列对原始数据进行对比:
result['YN']=(result['实际类别']==result['预测类别']) # 得到的结果是布尔值
result.loc[result['YN']==False]
27、shape与reshape
shape函数是numpy.core.fromnumeric中的函数,它的功能是读取矩阵或者数组的维数,比如shape[0]就是读取矩阵第一维度的长度。
例如:建立一个4×2的矩阵c, c.shape[0]
为第二维的长度,c.shape[1]
为第二维的长度。
shape中数字的含义:
【1】a.shape 输出 (4,),其中只有一个数字4,表示一维;数字4表示含有4个数据。
【2】b.shape 输出 (3,2),其中含有两个数字(分别是3,2)表示二维数组。3,2的含义为:3表示其中含有3个一维数组,2表示一维数组中含有2个数组
也可以直接使用ndim的方法进行维度的输出。
reshape()是数组对象中的方法,用于改变数组的形状。
# 使用众数填充Embarked,但是Embarked默认是字符型 Embarked=data.loc[:,'Embarked'].values.reshape(-1,1) # 变成二维矩阵 Embarked.shape
三维数组:
对于三维数组的shape:
三维数组就是包含多少个二维数组,后两个数字表示二维数组的形状
在机器学习中的reshape的作用:
sklearn不接受任何一维矩阵作为特征矩阵被输入。如果你的数据的确只有一个特征,那必须用reshape(-1,1)来给矩阵降维或者升维。
reshape中的一个参数可以设置成-1,表示数组的维度可以通过数据本身来判断。
-1的意思是模糊控制,例如:reshape(-1,2)表示重构数组的为数之后固定是两列,但是行数未知。
28、替换函数strip(),replace(),sub()
- replace是用在将查询到的数据替换为指定数据。
Python replace()
方法把字符串Q中的old (l旧字符串)替换成new(新字符串),如果指定第三个参数max,则替换不超过max次。
语法:
str.replace(old, new, max)
在DF中也可以使用:
import pandas as pd price1=pd.DataFrame({'fruit':['apple','grape','orange'],'price':[8,7,9]}) display(price1) price2=price1.replace('orange','watermelon') display(price2)
2. Python strip()
方法用于移除字符串头尾指定的字符(默认为空格)或字符序列。
注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
str.strip([chars]);
参数:
chars – 移除字符串头尾指定的字符序列。
如果不带参数,默认是清除两边的空白符,例如:/n, /r, /t, ’ ’
当你传的参数不管是“12”还是12的其他排列形式,这都不重要,重要的是函数只知道你要删除的字符是”1”,”2”。函数会把你传的参数拆解成一个个的字符,然后把头尾的这些字符去掉。
30、unique
【1】a = np.unique(A)
对于一维数组或者列表,unique函数去除其中重复的元素,并按元素由大到小返回一个新的无元素重复的元组或者列表
import numpy as np A = [1, 2, 2, 5,3, 4, 3] a = np.unique(A) B= (1, 2, 2,5, 3, 4, 3) b= np.unique(B) C= ['fgfh','asd','fgfh','asdfds','wrh'] c= np.unique(C) print(a)# 输出为 [1 2 3 4 5] print(b)# [1 2 3 4 5] print(c)# ['asd' 'asdfds' 'fgfh' 'wrh']
【2】c,s=np.unique(b,return_index=True)
return_index=True表示返回新列表元素在旧列表中的位置,并以列表形式储存在s中。
a, s= np.unique(A, return_index=True) print(a) print(s) # 运行结果 # [1 2 3 4 5] # [0 1 4 5 3]
【3】a, s,p = np.unique(A, return_index=True, return_inverse=True)
return_inverse=True 表示返回旧列表元素在新列表中的位置,并以列表形式储存在p中
a, s,p = np.unique(A, return_index=True, return_inverse=True) print(a) print(s) print(p) # 运行结果 # [1 2 3 4 5] # [0 1 4 5 3] # [0 1 1 4 2 3 2]
31、isnull,notnull
# coding=utf-8 import numpy as np import pandas as pd # 创建DataFrame df = pd.DataFrame(np.arange(12, 32).reshape((5, 4)), index=["a", "b", "c", "d", "e"], columns=["WW", "XX", "YY", "ZZ"]) df.loc[["b"],["YY"]] = np.nan # NaN是float类型,对应列会自动变成float类型。 df.loc[["d"],["XX"]] = np.nan print(df) ''' WW XX YY ZZ a 12 13.0 14.0 15 b 16 17.0 NaN 19 c 20 21.0 22.0 23 d 24 NaN 26.0 27 e 28 29.0 30.0 31 ''' # pandas判断是否是NaN print(pd.isnull(df)) ''' WW XX YY ZZ a False False False False b False False True False c False False False False d False True False False e False False False False ''' # pandas判断是否不是NaN print(pd.notnull(df)) ''' WW XX YY ZZ a True True True True b True True False True c True True True True d True False True True e True True True True ''' # 也可以只判断某一列的NaN print(pd.notnull(df["XX"])) ''' a True b True c True d False e True Name: XX, dtype: bool ''' # 布尔索引 print(df[pd.notnull(df["YY"])]) # 选出"YY"列不为NaN的所有行 ''' WW XX YY ZZ a 12 13.0 14.0 15 c 20 21.0 22.0 23 d 24 NaN 26.0 27 e 28 29.0 30.0 31 '''
30、drop
drop() 删除行和列
drop([ ],axis=0,inplace=True)
【1】drop([]),默认情况下删除某一行;
【2】如果要删除某列,需要axis=1;
【3】参数inplace 默认情况下为False,表示保持原来的数据不变,True 则表示在原来的数据上改变。
import pandas as pd import numpy as np df = pd.DataFrame(np.random.randn(5,3),index = list('abcde'),columns = ['one','two','three']) df.iloc[1,:-1] = np.nan #第二行,排除倒数第一个都是Nan df.iloc[1:-1,2] = np.nan #第三列,排除第一个和最后一个都是Nan
得到的df:
将第一列删除:
print(df.drop(['one'],axis=1))
将a和c行删除:
print(df.drop(['a','c'],axis = 0))
31、 dropna()
# coding=utf-8 import numpy as np import pandas as pd # 创建DataFrame df = pd.DataFrame(np.arange(12, 32).reshape((5, 4)), index=["a", "b", "c", "d", "e"], columns=["WW", "XX", "YY", "ZZ"]) df.loc[["b"],["YY"]] = np.nan # NaN是float类型,对应列会自动变成float类型。 df.loc[["d"],["XX"]] = np.nan print(df) ''' WW XX YY ZZ a 12 13.0 14.0 15 b 16 17.0 NaN 19 c 20 21.0 22.0 23 d 24 NaN 26.0 27 e 28 29.0 30.0 31 ''' # NaN的处理方式一:直接删除 df1 = df.dropna(axis=0) # axis=0表示删除行,axis=1表示删除列 print(df1) ''' WW XX YY ZZ a 12 13.0 14.0 15 c 20 21.0 22.0 23 e 28 29.0 30.0 31 ''' df2 = df.dropna(axis=0, how="all") # how="all"表示某行(列)全为NaN才会删除。how="any"表示只要有一个NaN就会删除(默认)。 print(df2) ''' WW XX YY ZZ a 12 13.0 14.0 15 b 16 17.0 NaN 19 c 20 21.0 22.0 23 d 24 NaN 26.0 27 e 28 29.0 30.0 31 ''' df.dropna(axis=0, inplace=True) # inplace=True表示原地修改,修改后的结果直接作用于原df。 默认False print(df) ''' WW XX YY ZZ a 12 13.0 14.0 15 c 20 21.0 22.0 23 e 28 29.0 30.0 31 '''
31、fillna()
# coding=utf-8 import numpy as np import pandas as pd # 创建DataFrame df = pd.DataFrame(np.arange(12, 32).reshape((5, 4)), index=["a", "b", "c", "d", "e"], columns=["WW", "XX", "YY", "ZZ"]) df.loc[["b"],["YY"]] = np.nan # NaN是float类型,对应列会自动变成float类型。 df.loc[["d"],["XX"]] = np.nan print(df) ''' WW XX YY ZZ a 12 13.0 14.0 15 b 16 17.0 NaN 19 c 20 21.0 22.0 23 d 24 NaN 26.0 27 e 28 29.0 30.0 31 ''' # NaN的处理方式二:填充 df2 = df.fillna(100) # 填充成100 print(df2) ''' WW XX YY ZZ a 12 13.0 14.0 15 b 16 17.0 100.0 19 c 20 21.0 22.0 23 d 24 100.0 26.0 27 e 28 29.0 30.0 31 ''' # 填充平均值 df3 = df.fillna(df.mean()) # df.mean()表示每一列的平均值(Series类型)。 df.median()中位数 print(df3) ''' WW XX YY ZZ a 12 13.0 14.0 15 b 16 17.0 23.0 19 c 20 21.0 22.0 23 d 24 20.0 26.0 27 e 28 29.0 30.0 31 ''' # 可以只填充某一列 df4 = df["YY"].fillna(df["YY"].mean()) # df.mean()表示每一列的平均值(Series类型) print(df4) # (Series类型) ''' a 14.0 b 23.0 c 22.0 d 26.0 e 30.0 Name: YY, dtype: float64 ''' # df["YY"] = df["YY"].fillna(df["YY"].mean()) # 只填充某一列,再赋值给原df的对应列。 # df[df==0] = np.nan # df.mean()计算均值时,NaN不会参与计算,但0会
32、rename
**pandas.Dataframe.rename()**函数主要是用来修改Dataframe数据的行名和列名。
主要用到的参数有
【1】columns:列名
【2】index:行名
【3】axis:指定坐标轴
【4】inplace:是否替换,默认为False。inplace为False时返回修改后结果,变量自身不修改。inplace为True时返回None,变量自身被修改。
>>> import pandas as pd >>> df A B 0 1 4 1 2 5 2 3 6 # 方法一:不用axis修改 >>> df.rename(columns={"A": "a", "B": "c"}) # 修改columns。inplace未设置,返回修改后的结果 a c 0 1 4 1 2 5 2 3 6 >>> df # inplace未设置,默认为false,则df自身不被改变 A B 0 1 4 1 2 5 2 3 6 >>> df_re=df.rename(index={0:"0a",1:"1a"}) # 同样的方式修改行名 >>> df A B 0 1 4 1 2 5 2 3 6 >>> df_re A B 0a 1 4 1a 2 5 2 3 6 >>> df_re=df.rename(columns={"A": "a", "B": "c"},index={0:"0a",1:"1a"}) > # 同时修改行名和列名 >>> df_re a c 0a 1 4 1a 2 5 2 3 6 # 方法二:用axis修改,只修改行名列名之一时等价,无法同时修改 >>> df.rename({1: 2, 2: 4}, axis='index') # 修改行名 A B 0 1 4 2 2 5 4 3 6 >>> df.rename(str.lower, axis='columns') # 列名大写变小写 a b 0 1 4 1 2 5 2 3 6 # 让inplace为True >>> df_re=df.rename(columns={"A": "a", "B": "c"},inplace=True) >>> print(df_re) # inplace为True时返回空值 None >>> df # 自身被修改,可对照上面进行理解 a c 0 1 4 1 2 5 2 3 6
33、linspace
【1】linspace生成线性间距向量
【2】语法:
y = linspace(x1,x2) 返回包含 x1 和 x2 之间的 100 个等间距点的行向量。
y = linspace(x1,x2,n) 生成 n 个点。这些点的间距为 (x2-x1)/(n-1)
from numpy import linspace b = linspace(0,10,4) b
import numpy as np x=np.linspace(0,1,20) x
34、日期转换
# 增加辅助列 ssqdatav2['ssqyear']=ssqdatav2['date'].dt.year # 如果原来的数据不是 datetime64[ns]类型则不能使用这个函数 ssqdatav2['ssqmonth']=ssqdatav2['date'].dt.month ssqdatav2['ssqquarter']='Q'+(ssqdatav2['date'].dt.quarter).apply(str) #不加这个 .apply(str)会报错 ssqdatav2['ssqym']=ssqdatav2['date'].apply(lambda x:x.strftime('%Y%m')) ssqdatav2['ssqyq']=ssqdatav2['date'].dt.to_period('Q') ssqdatav2['ssqseason']=ssqdatav2['ssqmonth'].apply(lambda x:'spring' if x<=3 else 'summer' if x<=6 else 'autumn' if x<=9 else 'winter') ssqdatav2.head()
35、lambda 匿名函数
1、匿名函数处理DF数据
traintemp['sizecabin']=traintemp['Cabin'].apply(lambda x:x.split(" ")) # 使用空格切分
2、处理汉字
# 为分解firstprize定义函数 def fpp(x): if len(x)<=2: # 判断是否只有汉字,还是也有数字 return "待定" else: # 使用正则表达式获取中文 pattern="[\u4e00-\u9fa5]" pat=re.compile(pattern) return ''.join(pat.findall(x)) #使用fp() ssqdatav2['fpprovince']=ssqdatav2['first'].apply(lambda x:fpp(x)) ssqdatav2.head(310)
35、构造数组的几种方式
【1】使用array()函数创建数组
函数可基于序列型的对象(如列表、元组、集合等,还可以是一个已经创建好的数组)
#使用array函数创建数组 import numpy as np #导入numpy模块,用as可以起别名 a=np.array([1,2,3,4]) b=np.array(['产品编号','销售数量','销售单价','销售金额']) print(a) # [1 2 3 4] print(b) # ['产品编号' '销售数量' '销售单价' '销售金额']
创建二维数组:
import numpy as np a=np.array([[1,2,3],[4,5,6],[7,8,9]]) print(a) ''' [[1 2 3] [4 5 6] [7 8 9]] '''
【2】创建等差数组
用arange()函数创建数组会更加方便
import numpy as np d=np.arange(1,20,3)#起始值是1,结束值是20(结果不含该值),步长为1 print(d)# [ 1 4 7 10 13 16 19]
【3】创建随机数组
引用numpy模块的子模块random中的函数,主要有rand()函数、randn()函数、randint()函数。
rand函数创建的数组中每个元素都是[0,1)区间内的随机数
import numpy as np e=np.random.rand(3) print(e) # [0.51329163 0.7495376 0.8405663 ]
如果给rand()函数传入一对参数值,就会生成一个相应行、列数的二维数组,区间也是[0,1)的随机数
import numpy as np e=np.random.rand(3,4) print(e) ''' [[0.80648692 0.48873991 0.78737971 0.43398966] [0.81899231 0.16496186 0.32348197 0.52354873] [0.47461709 0.44495098 0.59928444 0.92171408]] '''
【4】randn()函数
用randn()函数创建的数组中的元素是符合标准正态分布(均值为0,标准差为1)的随机数
import numpy as np e=np.random.randn(3,4) print(e) ''' [[-0.41245544 0.476043 -1.46849374 -0.38213323] [ 0.74496601 -1.10202045 0.65940684 -0.01535774] [-1.4760861 0.09343092 -0.6481946 1.00991138]] '''
【5】randint()函数
用randint()函数创建的数组中元素是制定范围内的随机整数
import numpy as np e = np.random.randint(1,5,10) #10个元素区间在[1,5)区间内的随机整数,随机数不包括5 print(e) #[1 1 4 2 1 4 3 3 4 3]
36、正则表达式
1、findall:
含义: findall()
是将所有匹配到的字符,以列表的形式返回。如果未匹配,则返回空列表。
语法: findall(string=None, pos=0, endpos=9223372036854775807, *, source=None)
函数作用:在string[pos,endpos]区间从pos下标开始查找所有满足pattern的子串,直到endpos位置结束,并以列表的形式返回查找的结果,如果未找到则返回一个空列表。
参数说明:
string:被匹配的字符串
pos: 匹配的起始位置,可选,默认为0
endpos: 匹配的结束位置,可选,默认为len(string)。也就是说如果不指定pos和endpos的话,该方法会在整个字符串中查找满足条件的子串。
- 2、re.compile():
compile 函数用于编译正则表达式,生成一个 Pattern 对象,它的一般使用形式如下:
re.compile(pattern[, flag])
从compile()函数的定义中,可以看出返回的是一个匹配对象,它单独使用就没有任何意义,需要和findall(), search(), match()搭配使用。 compile()与findall()一起使用,返回一个列表。
其中,pattern 是一个字符串形式的正则表达式,flag 是一个可选参数,表示匹配模式,比如忽略大小写,多行模式等。
29、column_stack与hstack、vstack
对于一维数组的堆叠:
(1)column_stack()会将一位数组转化成二维数组后再进行堆叠;
(2)hstack()不会进行转化,而是直接进行堆叠,所得到的堆叠后的数组还是一维数组。
另一方面,row_stack()和stack()不会产生这样的问题,他们的结果都是二维数组。
30、contains
cond=ssqdatav2['first'].str.contains('深圳') ssqdatav2.loc[cond] # 查找出first字段下所有包含深圳的记录,并准备将深圳用深或圳进行替换 ssqdatav2['first']
31、split
String a="a:b:c:d"
split(" : “)[0]表示把指定的字符串按照”:"来拆分成字符串数组.结果是:{a,b,c,d}
[0]是拆分出来的数组第一个元素了。
ssqdatav3['p001']=ssqdatav3['fpprovince'].apply(lambda x:x if x.count(',')==0 else x.split(',')[0]) ssqdatav3['p002']=ssqdatav3['fpprovince'].apply(lambda x:x.split(',')[1] if x.count(',')>=1 else '') ssqdatav3['p003']=ssqdatav3['fpprovince'].apply(lambda x:x.split(',')[2] if x.count(',')>=2 else '') ssqdatav3['p004']=ssqdatav3['fpprovince'].apply(lambda x:x.split(',')[3] if x.count(',')>=3 else '') ssqdatav3['p005']=ssqdatav3['fpprovince'].apply(lambda x:x.split(',')[4] if x.count(',')>=4 else '')
31、strip
Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
【1】strip()方法语法:
str.strip([chars]);
【2】参数
chars – 移除字符串头尾指定的字符序列。
【3】返回值
返回移除字符串头尾指定的字符生成的新字符串。
#!/usr/bin/python # -*- coding: UTF-8 -*- str = "00000003210Runoob01230000000"; print str.strip( '0' ); # 去除首尾字符 0 str2 = " Runoob "; # 去除首尾空格 print str2.strip();
输出:
3210Runoob0123 Runoob
32、np.repeat
np.repeat用于将numpy数组重复
一维数组重复三次
import numpy as np # 随机生成[0,5)之间的数,形状为(1,4),将此数组重复3次 pop = np.random.randint(0, 5, size=(1, 4)).repeat(3, axis=0) print("pop\n",pop) # pop # [[0 0 3 1] # [0 0 3 1] # [0 0 3 1]]
二维数组在第一维和第二维分别重复三次
pop_reshape=pop.reshape(2,6) pop_reshape_repeataxis0=pop_reshape.repeat(3,axis=0) pop_reshape_repeataxis1=pop_reshape.repeat(3,axis=1) print("pop_reshape\n",pop_reshape) print("pop_reshape_repeataxis0\n",pop_reshape_repeataxis0) print("pop_reshape_repeataxis1\n",pop_reshape_repeataxis1) # pop_reshape # [[0 0 3 1 0 0] # [3 1 0 0 3 1]] # pop_reshape_repeataxis0 # [[0 0 3 1 0 0] # [0 0 3 1 0 0] # [0 0 3 1 0 0] # [3 1 0 0 3 1] # [3 1 0 0 3 1] # [3 1 0 0 3 1]] # pop_reshape_repeataxis1 # [[0 0 0 0 0 0 3 3 3 1 1 1 0 0 0 0 0 0] # [3 3 3 1 1 1 0 0 0 0 0 0 3 3 3 1 1 1]]
33、期末考会考题
过滤法也是重点
简答题:特征工程主要的任务有哪些?
双色球是考试的重点,一定要把双色球所有的特征都跑一遍,期末一定有一道特征工程选择的题目(10分,代码填充),(特征工程选择的题目,代码填充)
这三句话相同,都是去除掉省份当中包含深的字
ssqdataprov=ssqdataprov[(ssqdataprov['PROVINCE']!='深')] ssqdataprov=ssqdataprov[~(ssqdataprov['PROVINCE']=='深')] ssqdataprov=ssqdataprov[~(ssqdataprov['PROVINCE'].str.contains('深'))]
nbadata2.loc[nbadata2['ischampion'].isnull(),'ischampion']='no' # 将空值替换为字符‘no’ nbadata2.loc[nbadata2['ischampion']==1,'ischampion']='yes' # 将原本数据为1的地方改成字符‘yes’ nbadata2
【1】改变决策树的参数绘制学习曲线
# 使用学习曲线判断最佳的最小叶子节点样本个数 # 选取的最小样本从1到30 import matplotlib.pyplot as plt plt.figure(figsize=(15,8)) test = [] for i in range(30): clf = tree.DecisionTreeClassifier(min_samples_leaf=i+1 #1-10层 ,criterion="entropy" # 使用gini系数 ,random_state=30 ,splitter="random" ) clf = clf.fit(Xtrain, Ytrain) score = clf.score(Xtest, Ytest) #分别计算测试集上的表现 test.append(score) plt.plot(range(1,31),test,color="red",label="min_samples_leaf") plt.legend() plt.show()
【2】class_weight是权重:简答题
【3】min_weight_fraction_leaf:基于权重的剪枝参数
【4】数据模型有那四种?层次,网状,关系,面向对象
【5】期末小问答:降维和特征选择的区别?
降维本质上是从一个维度空间映射到另一个维度空间,特征的多少没有减少,当然在映射的过程中特征值也会相应的变化。举个例子,现在的特征是1000维,我们想要把它降到500维。降维的过程就是找个一个从1000维映射到500维的映射关系。原始数据中的1000个特征,每一个都对应着降维后的500维空间中的一个值。假设原始特征中有个特征的值是9,那么降维后对应的值可能是3。
举个例子来说,比如一个原始样本中的数据为( 0.1 0.4 0.8),显示原始的维度为3维,现在我们把这个三维的数据通过降维映射到二维空间,降维后原始的数据可能就成了 (0.2 0.5),这里其实( 0.1 0.4 0.8)和(0.2 0.5)表示的是同一个样本
特征选择就是单纯地从提取到的所有特征中选择部分特征作为训练集特征,特征在选择前和选择后不改变值,但是选择后的特征维数肯定比选择前小,毕竟我们只选择了其中的一部分特征。举个例子,现在的特征是1000维,现在我们要从这1000个特征中选择500个,那个这500个特征的值就跟对应的原始特征中那500个特征值是完全一样的。对于另个500个没有被选择到的特征就直接抛弃了。假设原始特征中有个特征的值是9,那么特征选择选到这个特征后它的值还是9,并没有改变。
1.所谓的特征选择和数据降维(特征提取)都是降维的一种方式。
2.特征选择是“取其精华,去其糟粕”进行筛选,特征值不变;数据降维(特征提取)是经过映射改变了特征值。
34、Sklearn的train_test_split用法
用途:
在机器学习中,该函数可按照用户设定的比例,随机将样本集合划分为训练集 和测试集,并返回划分好的训练集和测试集数据。
语法:
X_train,X_test, y_train, y_test =cross_validation.train_test_split(X,y,test_size, random_state)
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2)
test_size=0.2
:表示将20%的数据作为测试集,剩余的80%作为训练集
34、过拟合与欠拟合
无论在机器学习还是深度学习建模当中都可能会遇到两种最常见结果,一种叫过拟合(over-fitting )另外一种叫欠拟合(under-fitting)。
过拟合(over-fitting),其实就是所建的机器学习模型或者是深度学习模型在训练样本中表现得过于优越,导致在验证数据集以及测试数据集中表现不佳。打个比喻就是当我需要建立好一个模型之后,比如是识别一只狗狗的模型,我需要对这个模型进行训练。恰好,我训练样本中的所有训练图片都是二哈,那么经过多次迭代训练之后,模型训练好了,并且在训练集中表现得很好。基本上二哈身上的所有特点都涵括进去,那么问题来了!假如我的测试样本是一只金毛呢?将一只金毛的测试样本放进这个识别狗狗的模型中,很有可能模型最后输出的结果就是金毛不是一条狗(因为这个模型基本上是按照二哈的特征去打造的)。所以这样就造成了模型过拟合,虽然在训练集上表现得很好,但是在测试集中表现得恰好相反,在性能的角度上讲就是协方差过大(variance is large),同样在测试集上的损失函数(cost function)会表现得很大。
欠拟合呢(under-fitting)相对过拟合欠拟合还是比较容易理解。还是拿刚才的模型来说,可能二哈被提取的特征比较少,导致训练出来的模型不能很好地匹配,表现得很差,甚至二哈都无法识别。
造成过拟合的原因有可以归结为:参数过多。增大训练样本规模同样也可以防止过拟合。
欠拟合基本上都会发生在训练刚开始的时候,经过不断训练之后欠拟合应该不怎么考虑了。但是如果真的还是存在的话,可以通过增加网络复杂度或者在模型中增加多点特征点,这些都是很好解决欠拟合的方法。
35、oversample 过采样和欠采样undersampling
过采样(右上)只是单纯的重复了正例,因此会过分强调已有的正例。如果其中部分点标记错误或者是噪音,那么错误也容易被成倍的放大。因此最大的风险就是对正例过拟合。
欠采样(左下)抛弃了大部分反例数据,从而弱化了中间部分反例的影响,可能会造成偏差很大的模型。当然,如果数据不平衡但两个类别基数都很大,或许影响不大。同时,数据总是宝贵的,抛弃数据是很奢侈的,因此另一种常见的做法是反复做欠采样,生成1655/176约等于9个新的子样本。其中每个样本的正例都使用这176个数据,而反例则从1655个数据中不重复采样。最终对这9个样本分别训练,并集成结果。这样数据达到了有效利用,但也存在风险;
训练多个模型造成了过大的开销,合并模型结果需要额外步骤,有可能造成其他错误。
正例被反复使用,和过采样一样,很容易造成模型的过拟合
36、分类阈值
逻辑回归返回的是概率。可以“原样”使用返回的概率(例如,用户点击此广告的概率为 0.00023),也可以将返回的概率转换成二元值(例如,这封电子邮件是垃圾邮件)。
如果某个逻辑回归模型对某封电子邮件进行预测时返回的概率为 0.9995,则表示该模型预测这封邮件非常可能是垃圾邮件。相反,在同一个逻辑回归模型中预测分数为 0.0003 的另一封电子邮件很可能不是垃圾邮件。可如果某封电子邮件的预测分数为 0.6 呢?为了将逻辑回归值映射到二元类别,必须指定分类阈值(也称为判定阈值)。如果值高于该阈值,则表示“垃圾邮件”;如果值低于该阈值,则表示“非垃圾邮件”。人们往往会认为分类阈值应始终为 0.5,但阈值取决于具体问题,因此必须对其进行调整。
我们将在后面的部分中详细介绍可用于对分类模型的预测进行评估的指标,以及更改分类阈值对这些预测的影响。
“调整”逻辑回归的阈值不同于调整学习速率等超参数。在选择阈值时,需要评估将因犯错而承担多大的后果。例如,将非垃圾邮件误标记为垃圾邮件会非常糟糕。
37、超参数
什么是超参数,参数和超参数的区别?
区分两者最大的一点就是是否通过数据来进行调整,模型参数通常是有数据来驱动调整,超参数则不需要数据来驱动,而是在训练前或者训练中人为的进行调整的参数。例如卷积核的具体核参数就是指模型参数,这是有数据驱动的。而学习率则是人为来进行调整的超参数。这里需要注意的是,通常情况下卷积核数量、卷积核尺寸这些也是超参数,注意与卷积核的核参数区分。
38、随机森林
随机森林是一个用随机方式建立的,包含多个决策树的分类器。其输出的类别是由各个树输出的类别的众数而定。
随机性主要体现在两个方面:
(1)训练每棵树时,从全部训练样本(样本数为N)中选取一个可能有重复的大小同样为N的数据集进行训练(即bootstrap取样);
(2)在每个节点,随机选取所有特征的一个子集,用来计算最佳分割方式。
优点
1、 在当前的很多数据集上,相对其他算法有着很大的优势,表现良好
2、它能够处理很高维度(feature很多)的数据,并且不用做特征选择(因为特征子集是随机选择的)
3、在训练完后,它能够给出哪些feature比较重要
4、在创建随机森林的时候,对generlization error使用的是无偏估计,模型泛化能力强
5、训练速度快,容易做成并行化方法(训练时树与树之间是相互独立的)
6、 在训练过程中,能够检测到feature间的互相影响
7、 实现比较简单
8、 对于不平衡的数据集来说,它可以平衡误差。
9、如果有很大一部分的特征遗失,仍可以维持准确度。
10、随机森林能够解决分类与回归两种类型的问题,并在这两方面都有相当好的估计表现。(虽然RF能做回归问题,但通常都用RF来解决分类问题)。
在创建随机森林时候,对generlization error(泛化误差)使用的是无偏估计模型,泛化能力强。
缺点:
随机森林在解决回归问题时,并没有像它在分类中表现的那么好,这是因为它并不能给出一个连续的输出。当进行回归时,随机森林不能够做出超越训练集数据范围的预测,这可能导致在某些特定噪声的数据进行建模时出现过度拟合。(PS:随机森林已经被证明在某些噪音较大的分类或者回归问题上回过拟合)。
对于许多统计建模者来说,随机森林给人的感觉就像一个黑盒子,你无法控制模型内部的运行。只能在不同的参数和随机种子之间进行尝试。
可能有很多相似的决策树,掩盖了真实的结果。
对于小数据或者低维数据(特征较少的数据),可能不能产生很好的分类。(处理高维数据,处理特征遗失数据,处理不平衡数据是随机森林的长处)。
执行数据虽然比boosting等快(随机森林属于bagging),但比单只决策树慢多了。
39、 cut和qcut的用法(分桶分箱)
数据分箱:是指将值划分到离散区间。好比不同大小的苹果归类到几个事先布置的箱子中;不同年龄的人划分到几个年龄段中。
一丶cut qcut的区别
1.qcut:传入参数,要将数据分成多少组,即组的个数,具体的组距是由代码计算。
2,cut:传入参数,是分组依据。
二丶qcut方法
(1)参数:
x :要进行分组的数据,数据类型为一维数组,或Series对象;
q :组数,即要将数据分成几组,后边举例说明;
labels :可以理解为组标签,这里注意标签个数要和组数相等;
retbins :默认为False,当为False时,返回值是Categorical类型(具有value_counts()方法),为True是返回值是元组。
(2)示例
三丶cut方法
(1)举例
ages = [20,22,25,27,21,23,37,31,61,45,41,32] #将所有的ages进行分组 bins = [18,25,35,60,100] # 自定义分类数据,包括端点 #使用pandas中的cut对年龄数据进行分组 cats = pd.cut(ages,bins) print(cats)
#调用pd.value_counts方法统计每个区间的个数 number=pd.value_counts(cats) print(pd.value_counts(cats))
#显示第几个区间index值 index=pd.cut(ages,bins).codes print(index)
#为分类出来的每一组年龄加上标签 group_names = ["Youth","YouthAdult","MiddleAged","Senior"] personType=pd.cut(ages,bins,labels=group_names) print(personType)
plt.hist(personType) plt.show()
四丶总结
1,cut: 按连续数据的大小分到各个桶里,每个桶里样本量可能不同,但是,每个桶相当于一个等长的区间,即:以数据的最大和最小为边界,等分成p个桶。
2,qcut: 与cut主要的区别就是每个桶里的样本数量是一定的。
40、随机森林 n_estimators参数 max_features参数
要构造一个随机森林模型,第一步是确定森林中树的数目,通过模型的 进行调节。n_estimators越大越好,但占用的内存与训练和预测的时间也会相应增长,且边际效益是递减的,所以要在可承受的内存/时间内选取尽可能大的n_estimators。而在sklearn中,n_estimators默认为10。
第二步是对数据进行自助采样,也就是说,从n_sample个数据点中有放回地重复随机抽取一个样本,共抽取n_sample次。新数据集的容量与原数据集相等,但抽取的采样往往与原数据集不同。注意,构建的n_estimators棵树采用的数据集都是独立自助采样的,这样才能保证所有树都互不相同。
第三步就是基于这个新数据集来构造决策树。由于加入了随机性,故构造时与一般的决策树不同。构造时,在每个结点处选取特征的一个子集,并对其中一个特征寻找最佳测试。选取的特征子集中特征的个数通过max_features参数来控制,max_features越小,随机森林中的树就越不相同,但过小(取1时)会导致在划分时无法选择对哪个特征进行测试。而在sklearn中,max_features有以下几种选取方法:“auto”, “sqrt”, “log2”, None。auto与sqrt都是取特征总数的开方,log2取特征总数的对数,None则是令max_features直接等于特征总数,而max_features的默认值是"auto"。
随机森林还有一个重要参数是n_jobs,决定了使用的CPU内核个数,使用更多的内核能使速度增快,而令n_jobs=-1可以调用所有内核。当然,构造时同样可以使用max_depth,min_samples_leaf和max_leaf_nodes来进行预剪枝,以减小内存占用与时间消耗。
41、VarianceThreshold
使用方差阈值过滤(VarianceThreshold)进行特征选择、删除方差低于某一阈值的特征、详解及实战方差阈值(VarianceThreshold)法是一种过滤特征选择法。
42、fit_transform,fit,transform区别和作用
- fit和transform没有任何关系,仅仅是数据处理的两个不同环节,之所以出来fit_transform这个函数名,仅仅是为了写代码方便,会高效一点。
from sklearn.preprocessing import StandardScaler sc = StandardScaler() sc.fit_tranform(X_train) sc.tranform(X_test)
43、特征预处理的独热编码
One-Hot编码,又称为一位有效编码,主要是采用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。
One-Hot编码是分类变量作为二进制向量的表示。这首先要求将分类值映射到整数值。
性别特征:[“男”,“女”],按照N位状态寄存器来对N个状态进行编码的原理,咱们处理后应该是这样的(这里只有两个特征,所以N=2):
男 => 10
女 => 01
祖国特征:[“中国”,"美国,“法国”](这里N=3):
中国 => 100
美国 => 010
法国 => 001
运动特征:[“足球”,“篮球”,“羽毛球”,“乒乓球”](这里N=4):
足球 => 1000
篮球 => 0100
羽毛球 => 0010
乒乓球 => 0001
所以,当一个样本为[“男”,“中国”,“乒乓球”]的时候,完整的特征数字化的结果为:
[1,0,1,0,0,0,0,0,1]
下图可能会更好理解:
44、ravel和flattern
python 中的 ravel() 函数将数组多维度拉成一维数组。
ravel 英文译为散开,解开;
flatten 英文译为变平。
两者的区别在于返回拷贝(copy)还是返回视图(view)。
【1】 numpy.ravel()
返回的是视图,会影响原始矩阵;
【2】numpy.flatten()
返回的是拷贝,对拷贝所做的修改不会影响原始矩阵。
45、train_test_split
import numpy as np from sklearn.model_selection import train_test_split #创建一个数据集X和相应的标签y,X中样本数目为100 X, y = np.arange(200).reshape((100, 2)), range(100) #用train_test_split函数划分出训练集和测试集,测试集占比0.33 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.33, random_state=42) #打印出原始样本集、训练集和测试集的数目 print("The length of original data X is:", X.shape[0]) print("The length of train Data is:", X_train.shape[0]) print("The length of test Data is:", X_test.shape[0])
46、crosstab和pivotTab
【1】透视表(pivotTab)
透视表是将原有的DataFrame的列分别作为行索引和列索引,然后对指定的列应用聚集函数
# 透视表是将原有的DataFrame的列分别作为行索引和列索引,然后对指定的列应用聚集函数 import pandas as pd df = pd.DataFrame({'类别':['水果','水果','水果','蔬菜','蔬菜','肉类','肉类'], '产地':['美国','中国','中国','中国','新西兰','新西兰','美国'], '水果':['苹果','梨','草莓','番茄','黄瓜','羊肉','牛肉'], '数量':[5,5,9,3,2,10,8], '价格':[5,5,10,3,3,13,20]}) print(pd.DataFrame(df)) ''' 类别 产地 水果 数量 价格 0 水果 美国 苹果 5 5 1 水果 中国 梨 5 5 2 水果 中国 草莓 9 10 3 蔬菜 中国 番茄 3 3 4 蔬菜 新西兰 黄瓜 2 3 5 肉类 新西兰 羊肉 10 13 6 肉类 美国 牛肉 8 20 '''
print(df.pivot_table(index=['产地','类别']))
价格 数量 产地 类别 中国 水果 7.5 7 蔬菜 3.0 3 新西兰 肉类 13.0 10 蔬菜 3.0 2 美国 水果 5.0 5 肉类 20.0 8
【2】交叉表(crosstab)
用于统计分组频率的特殊透视表
print(df.pivot_table('价格',index='产地',columns='类别',aggfunc='max',margins=True,fill_value=0)) #行索引为"产地",列索引为'类别' #对“价格”应用'max',并提供分项统计,缺失值填充0 ''' 类别 水果 肉类 蔬菜 All 产地 中国 10 0 3 10 新西兰 0 13 3 13 美国 5 20 0 20 All 10 20 3 20 '''
print(pd.crosstab(df['类别'],df['产地'],margins=True)) ''' 产地 中国 新西兰 美国 All 类别 水果 2 0 1 3 肉类 0 1 1 2 蔬菜 1 1 0 2 All 3 2 2 7 '''
47、使用函数处理DF当中的数据
【1】空格变成逗号
# 为分解firstprize定义函数 def fpp(x): if len(x)<=2: # 判断是否只有汉字,还是也有数字 return "待定" else: # 使用正则表达式获取中文 pattern="[\u4e00-\u9fa5]" pat=re.compile(pattern) return ''.join(pat.findall(x)) #使用fp() ssqdatav2['fpprovince']=ssqdatav2['first'].apply(lambda x:fpp(x)) ssqdatav2.head(310)