动手学数据分析
第一章:数据载入及开始调查
载入数据
使命一:导入numpy和pandas
import numpy as np
import pandas as pd
使命二:载入数据
train_data = pd.read_csv("train.csv")
train_data.head(5)
train_data = pd.read_table("train.csv")
train_data.head(5)
这两个读取办法的差异在于read_csv读取的是默认分割符为逗号,而read_csv读取默认分隔符为制表符。
使命三:每1000行为一个数据模块,逐块读取
chunker = pd.read_csv("train.csv", chunksize = 1000)
print(type(chunker))
【考虑】什么是逐块读取?为什么要逐块读取呢? 答:比方后续遍历,像一个数据迭代器相同方便读取
【提示】咱们能够chunker(数据块)是什么类型?用for
循环打印出来出处具体的姿态是什么?
答:<class ‘pandas.io.parsers.TextFileReader’>,for遍历每次打印出来1000行
将表头改成中文
train_data = pd.read_csv("train.csv", names=['乘客ID','是否幸存','仓位等级','名字','性别','年纪','兄弟姐妹个数','爸爸妈妈子女个数','船票信息','票价','客舱','登船港口'],index_col='乘客ID', header=0)
train_data.head(5)
【考虑】所谓将表头改为中文其间一个思路是:将英文列名表头替换成中文。还有其他的办法吗? 答:能够读入后再进行修正
开始调查
使命一:检查数据的根本信息
train_data.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 891 entries, 1 to 891
Data columns (total 11 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 是否幸存 891 non-null int64
1 仓位等级 891 non-null int64
2 名字 891 non-null object
3 性别 891 non-null object
4 年纪 714 non-null float64
5 兄弟姐妹个数 891 non-null int64
6 爸爸妈妈子女个数 891 non-null int64
7 船票信息 891 non-null object
8 票价 891 non-null float64
9 客舱 204 non-null object
10 登船港口 889 non-null object
dtypes: float64(2), int64(4), object(5)
memory usage: 83.5+ KB
【提示】有多个函数能够这样做,你能够做一下总结
- df.info(): # 打印摘要
- df.describe(): # 描绘性核算信息
- df.values: # 数据
- df.to_numpy() # 数据 (引荐)
- df.shape: # 形状 (行数, 列数)
- df.columns: # 列标签
- df.columns.values: # 列标签
- df.index: # 行标签
- df.index.values: # 行标签
- df.head(n): # 前n行
- df.tail(n): # 尾n行
- pd.options.display.max_columns=n: # 最多显现n列
- pd.options.display.max_rows=n: # 最多显现n行
- df.memory_usage(): # 占用内存(字节B)
使命二:调查表格前10行和后15行的数据
train_data.head(10)
train_data.tail(15)
使命三:判别数据是否为空,为空的地方回来true,否则回来false
train_data.isnull().head(10)
【考虑】关于一个数据,还能够从哪些方面来调查?找找答案,这个将对下面的数据分析有很大的协助
答:从散布方面
保存数据
使命一:将你加载并做出改变的数据,在作业目录下保存为一个新文件train_chinese.csv
# 留意:不同的操作系统保存下来或许会有乱码。咱们能够参加`encoding='GBK' 或许 ’encoding = ’utf-8‘‘`
train_data.to_csv("train_chinese.csv",encoding='GBK')
知道你的数据叫什么
使命一:pandas中有两个数据类型DateFrame和Series,经过查找简单了解他们。然后自己写一个关于这两个数据类型的小例子
myself = {"name":"FavoriteStar",'age':18,"gender":"男性"}
example = pd.Series(myself)
example
myself2 = {"喜好":["打篮球",'歌唱','躺平'], "程度":[100, 90, 80]}
example2 = pd.Series(myself2)
example2
喜好 [打篮球, 歌唱, 躺平]
程度 [100, 90, 80]
dtype: object
使命二:依据上节课的办法载入”train.csv”文件
train_data = pd.read_csv("train_chinese.csv",encoding='GBK')
# 在保存的时分用了GBK,载入就也要用,否则会乱码
使命三:检查DataFrame数据的每列的称号
train_data.columns
Index(['乘客ID', '是否幸存', '仓位等级', '名字', '性别', '年纪', '兄弟姐妹个数', '爸爸妈妈子女个数', '船票信息','票价', '客舱', '登船港口'],dtype='object')
使命四:检查”Cabin”这列的一切值
train_data['客舱'].unique()
train_data.客舱.unique()
使命五:加载文件”test_1.csv”,然后对比”train.csv”,看看有哪些多出的列,然后将多出的列删去
test_data = pd.read_csv("test_1.csv")
test_data_drop = test_data.drop('a',axis = 1)
test_data.head(5)
【考虑】还有其他的删去多余的列的办法吗?
del test_data['a']
df.drop(columns='a')
df.drop(columns=['a'])
使命六: 将[‘PassengerId’,’Name’,’Age’,’Ticket’]这几个列元素躲藏,只调查其他几个列元素
test_data_drop.drop(['PassengerId','Name','Age','Ticket'],axis=1).head(3)
# 这儿躲藏后回来,并不是在原来的数据上进行修正
【考虑】对比使命五和使命六,是不是运用了不相同的办法(函数),假如运用相同的函数怎么完成上面的不同的要求呢?
【考虑回答】假如想要彻底的删去你的数据结构,运用inplace=True,由于运用inplace就将原数据覆盖了,所以这儿没有用
筛选的逻辑
使命一: 咱们以”Age”为筛选条件,显现年纪在10岁以下的乘客信息
train_data[train_data['年纪']<10].head(10)
使命二: 以”Age”为条件,将年纪在10岁以上和50岁以下的乘客信息显现出来,并将这个数据命名为midage
midage = train_data[(train_data["年纪"] > 10) & (train_data["年纪"]< 50)]
使命三:将midage的数据中第100行的”Pclass”和”Sex”的数据显现出来
midage = midage.reset_index(drop=True)
# 用这个重置索引的意图是由于或许咱们前面用了乘客ID作为索引,就达不到取出第100行的意图,就会取出乘客id为100的
midage.loc[[100],["仓位等级","性别"]]
使命四:运用loc办法将midage的数据中第100,105,108行的”Pclass”,”Name”和”Sex”的数据显现出来
midage.loc[[100,105,108],["仓位等级","性别"]]
使命五:运用iloc办法将midage的数据中第100,105,108行的”Pclass”,”Name”和”Sex”的数据显现出来
midage.iloc[[100,105,108],[2,3,4]]
【考虑】对比iloc
和loc
的异同
答:iloc传入的列的索引为真正的索引,而loc传入的为列的称号
了解你的数据吗
使命一:利用Pandas对示例数据进行排序,要求升序
obj1 = pd.DataFrame({"a":[800,400,200],"c":[900,700,400],"b":[700,500,100]},index = ['A','C','B'])
bj1.sort_values(by=['a'])
【问题】:大多数时分咱们都是想依据列的值来排序,所以将你构建的DataFrame中的数据依据某一列,升序摆放
obj1 = pd.DataFrame({"a":[800,400,200],"c":[900,700,400],"b":[700,500,100]},index = ['A','C','B'])
obj1
obj1.sort_values(by='A',axis='columns')
【考虑】经过书本你能说出Pandas对DataFrame数据的其他排序办法吗?
答:rank或许也有用,还有sort_index
【总结】下面将不同的排序办法做一个总结
1.让行索引升序排序
obj1 = pd.DataFrame({"a":[800,400,200],"c":[900,700,400],"b":[700,500,100]},index = ['A','C','B'])
obj1.sort_index(axis = 0)
2.让列索引升序排序
obj1 = pd.DataFrame({"a":[800,400,200],"c":[900,700,400],"b":[700,500,100]},index = ['A','C','B'])
obj1.sort_index(axis = 1)
3.让列索引降序排序
obj1 = pd.DataFrame({"a":[800,400,200],"c":[900,700,400],"b":[700,500,100]},index = ['A','C','B'])
obj1.sort_index(axis = 0, ascending=False)
4.让任选两列数据一起降序排序
obj1 = pd.DataFrame({"a":[800,400,200],"c":[900,700,400],"b":[700,500,100]},index = ['A','C','B'])
obj1.sort_values(by=['a','b'],ascending=False)
使命二:对泰坦尼克号数据(trian.csv)按票价和年纪两列进行归纳排序(降序摆放),从这个数据中你能够分析出什么
train_data.head(5)
train_data.sort_values(by=['票价','年纪'],ascending=False).head(20)
【考虑】排序后,假如咱们只是关注年纪和票价两列。依据知识我知道发现票价越高的应该客舱越好,所以咱们会明显看出,票价前20的乘客中存活的有14人,这是相当高的一个份额
多做几个数据的排序
train_data.sort_values(by=['性别'],ascending=False).head(20)
依照年纪排序的话前20人只要5人存活,而且能够看到年纪最高人20人许多人的爸爸妈妈子女个数都为0
使命三:利用Pandas进行算术核算,核算两个DataFrame数据相加成果
frame_a = pd.DataFrame(np.arange(9.).reshape(3, 3),
columns=['a', 'b', 'c'],
index=['one', 'two', 'three'])
frame_b = pd.DataFrame(np.arange(12.).reshape(4, 3),
columns=['a', 'e', 'c'],
index=['first', 'one', 'two', 'second'])
frame_a + frame_b
使命四:经过泰坦尼克号数据怎么核算出在船上最大的家族有多少人
(train_data['兄弟姐妹个数'] + train_data['爸爸妈妈子女个数']).max()
max(train_data['兄弟姐妹个数'] + train_data['爸爸妈妈子女个数'])
答案为10
使命五:学会运用Pandas describe()函数检查数据根本核算信息
frame2 = pd.DataFrame([[1.4, np.nan],
[7.1, -4.5],
[np.nan, np.nan],
[0.75, -1.3]
], index=['a', 'b', 'c', 'd'], columns=['one', 'two'])
frame2.describe()
使命六:别离看看泰坦尼克号数据会集 票价、爸爸妈妈子女 这列数据的根本核算数据,你能发现什么
train_data[['票价','爸爸妈妈子女个数']].describe()
数据清洗及特征整理
缺失值调查与处理
使命一:缺失值调查
(1) 请检查每个特征缺失值个数 (2) 请检查Age, Cabin, Embarked列的数据 以上办法都有多种办法
train_data.isnull().sum()
train_data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 PassengerId 891 non-null int64
1 Survived 891 non-null int64
2 Pclass 891 non-null int64
3 Name 891 non-null object
4 Sex 891 non-null object
5 Age 714 non-null float64
6 SibSp 891 non-null int64
7 Parch 891 non-null int64
8 Ticket 891 non-null object
9 Fare 891 non-null float64
10 Cabin 204 non-null object
11 Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.7+ KB
train_data[['Age','Cabin','Embarked']].head(10)
使命二:对缺失值进行处理
(1)处理缺失值一般有几种思路
(2) 请测验对Age列的数据的缺失值进行处理
(3) 请测验运用不同的办法直接对整张表的缺失值进行处理
train_data['Age'].dropna() # 丢弃
train_data['Age'].fillna(method='ffill') # 线性插值
train_data['Age'].fillna(value=20) # 悉数依照20填充
【考虑1】dropna和fillna有哪些参数,别离怎么运用呢
- dropna()
- axis:为1或许index就删去含有缺失值的行,为0或许columns则删去列
- how:为all就删去全是缺失值的,any就删去任何含有缺失值的
- thresh=n:删去缺失值大于等于n的
- subset:界说在哪些列中查找缺失值
- inplace:是否原地修正
- fillna()
- inplace
- method:取值为pad、ffill、backfill、bfill、None
- limit:约束填充个数
- axis:修正填充方向
【考虑】检索空缺值用np.nan
,None
以及.isnull()
哪个更好,这是为什么?假如其间某个办法无法找到缺失值,原因又是为什么?
数值列读取数据后,空缺值的数据类型为float64,所以用None一般索引不到,比较的时分最好用np.nan
重复值调查与处理
使命一:请检查数据中的重复值
train_data.duplicated()
这个函数便是回来某一行的数据是否已经在之前的行中出现了,假如是便是重复数据就回来true。
使命二:对重复值进行处理
train_data = train_data.drop_duplicates()
train_data.head(5)
使命三:将前面清洗的数据保存为csv格局
train_data.to_csv('test_clear.csv')
特征调查与处理
使命一:对年纪进行分箱(离散化)处理
(1) 分箱操作是什么?
(2) 将连续变量Age平均分箱成5个年纪段,并别离用类别变量12345表明
(3) 将连续变量Age区分为[0,5) [5,15) [15,30) [30,50) [50,80)五个年纪段,并别离用类别变量12345表明
(4) 将连续变量Age按10% 30% 50% 70% 90%五个年纪段,并用分类变量12345表明
(5) 将上面的取得的数据别离进行保存,保存为csv格局
【答】分箱操作就相当于将连续数据区分为几个离散值,再用离散值来替代连续数据。
train_data['newAge'] = pd.cut(train_data['Age'], 5, labels=[1,2,3,4,5])
train_data.head(5)
train_data.to_csv("test_avg.csv")
bins = [0,5,15,30,50,80]
train_data['newAge'] = pd.cut(train_data['Age'],bins, right=False, labels=[1,2,3,4,5])
train_data.head(5)
train_data.to_csv("test_cut.csv")
train_data['newAge'] = pd.qcut(train_data['Age'],[0,0.1,0.3,0.5,0.7,0.9],labels=[1,2,3,4,5])
train_data.head(5)
train_data.to_csv("test_pr.csv")
使命二:对文本变量进行转换
(1) 检查文本变量名及品种 (2) 将文本变量Sex, Cabin ,Embarked用数值变量12345表明 (3) 将文本变量Sex, Cabin, Embarked用one-hot编码表明
train_data['Embarked'].value_counts()
train_data['Sex'].unique()
train_data['Sex'].value_counts()
train_data['Sex_num'] = train_data['Sex'].replace(['male','female'],[1,2])
train_data.head(5)
train_data['Sex_num'] = train_data['Sex'].map({"male":1,'female':2})
train_data.head(5)
以上两种适用于性别这样离散值很少的,那么假如关于另外两种数据离散值许多就不行,用以下的办法:
from sklearn.preprocessing import LabelEncoder
for feat in ['Cabin', 'Ticket']:
lbl = LabelEncoder()
label_dict = dict(zip(train_data[feat].unique(), range(train_data[feat].nunique())))
train_data[feat + "_labelEncode"] = train_data[feat].map(label_dict)
train_data[feat + "_labelEncode"] = lbl.fit_transform(train_data[feat].astype(str))
train_data.head(5)
# 转换为ont-hot编码
for feat in ['Sex', 'Cabin','Embarked']:
x = pd.get_dummies(train_data[feat], prefix=feat)
# prefix便是让生成的列的称号为feat+取值
train_data = pd.concat([train_data,x],axis=1)
train_data.head(5)
使命三:从纯文本Name特征里提取出Titles的特征(所谓的Titles便是Mr,Miss,Mrs等)
train_data['Title'] = train_data.Name.str.extract('([A-Za-z]+)\.', expand=False)
train_data.head()
train_data.to_csv('test_fin.csv')
数据的兼并
使命一:将data文件夹里边的一切数据都载入,调查数据的之间的联系
train_left_up = pd.read_csv("data\\train-left-up.csv")
train_left_up.info()
train_left_down = pd.read_csv("data\\train-left-down.csv")
train_left_down.info()
train_right_up = pd.read_csv("data\\train-right-up.csv")
train_right_down = pd.read_csv("data\\train-right-down.csv")
使命二:运用concat办法:将数据train-left-up.csv和train-right-up.csv横向兼并为一张表,并保存这张表为result_up
result_up = pd.concat([train_left_up, train_right_up],axis = 1)
result_up.head(5)
使命三:运用concat办法:将train-left-down和train-right-down横向兼并为一张表,并保存这张表为result_down。然后将上边的result_up和result_down纵向兼并为result
result_down = pd.concat([train_left_down, train_right_down],axis = 1)
result = pd.concat([result_up, result_down], axis=0)
result.head(5)
使命四:运用DataFrame自带的办法join办法和append:完成使命二和使命三的使命
result_up = train_left_up.join(train_right_up)
result_up.head(5)
result_down = train_left_down.join(train_right_down)
result = result_up.append(result_down)
result.head(4)
使命五:运用Panads的merge办法和DataFrame的append办法:完成使命二和使命三的使命
result_up = pd.merge(train_left_up,train_right_up,left_index=True,right_index=True)
result_up.head(5)
result_down = pd.merge(train_left_down,train_right_down,left_index=True,right_index=True)
result = result_up.append(result_down)
result.head(5)
使命六:完成的数据保存为result.csv
result.to_csv("data\\result.csv")
换一种视点看数据
使命一:将咱们的数据变为Series类型的数据
train_data = pd.read_csv('result.csv')
train_data.head()
unit_result=train_data.stack().head(20)
# stack是转置,索引不变,然后内容转置。
unit_result.head()
unit_result.to_csv('unit_result.csv')
数据运用
使命一:经过教材《Python for Data Analysis》P303、Google or anything来学习了解GroupBy机制
这部分仍是很引荐去看看书进行学习,很有用。
使命二:核算泰坦尼克号男性与女性的平均票价
result['Fare'].groupby(result['Sex']).mean()
Sex
female 44.479818
male 25.523893
Name: Fare, dtype: float64
使命三:核算泰坦尼克号中男女的存活人数
result['Survived'].groupby(result['Sex']).sum()
Sex
female 233
male 109
Name: Survived, dtype: int64
使命四:核算客舱不同等级的存活人数
result['Survived'].groupby(result['Pclass']).sum()
Pclass
1 136
2 87
3 119
Name: Survived, dtype: int64
【考虑】从数据分析的视点,上面的核算成果能够得出那些结论
【答】女性平均票价高,生计人数高,1号客舱生计人数多
【考虑】从使命二到使命三中,这些运算能够经过agg()函数来一起核算。而且能够运用rename函数修正列名。你能够依照提示写出这个进程吗?
result.groupby('Sex').agg({'Fare': 'mean', 'Pclass': 'count'}).rename(columns={'Fare': 'mean_fare', 'Pclass': 'count_pclass'})
使命五:核算在不同等级的票中的不同年纪的船票花费的平均值
result.groupby(['Pclass','Age'])['Fare'].mean()
Pclass Age
1 0.92 151.5500
2.00 151.5500
4.00 81.8583
11.00 120.0000
14.00 120.0000
...
3 61.00 6.2375
63.00 9.5875
65.00 7.7500
70.50 7.7500
74.00 7.7750
Name: Fare, Length: 182, dtype: float64
使命六:将使命二和使命三的数据兼并,并保存到sex_fare_survived.csv
g1 = result['Fare'].groupby(result['Sex']).mean()
g2 = result['Survived'].groupby(result['Sex']).sum()
g_con = pd.concat([g1,g2],axis=1)
g_con.to_csv("data\\sex_fare_survived.csv")
使命七:得出不同年纪的总的存活人数,然后找出存活人数最多的年纪段,最终核算存活人数最高的存活率(存活人数/总人数)
survived_age = result.groupby('Age')['Survived'].sum()
Age
0.42 1
0.67 1
0.75 2
0.83 2
0.92 1
..
70.00 0
70.50 0
71.00 0
74.00 0
80.00 1
Name: Survived, Length: 88, dtype: int64
survived_age_max = survived_age[survived_age.values == survived_age.max()]
Age
24.0 15
Name: Survived, dtype: int64
survived_age_max_num = int(survived_age_max.values)
15
survived_age_max_num_rate =survived_age_max_num/ result['Survived'].sum()
0.043859649122807015
怎么让人一眼看懂你的数据
%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
result = pd.read_csv("data\\result.csv")
result.head(5)
使命一:跟着书本第九章,了解matplotlib,自己创立一个数据项,对其进行根本可视化
略
使命二:可视化展现泰坦尼克号数据会集男女中生计人数散布状况(用柱状图试试)
sex = result.groupby('Sex')['Survived'].sum()
sex.plot.bar()
plt.title('survived_count')
【考虑】核算出泰坦尼克号数据会集男女中死亡人数,并可视化展现?怎么和男女生计人数可视化柱状图结合到一起?看到你的数据可视化,说说你的第一感受(比方:你一眼看出男生计活人数更多,那么性别或许会影响存活率)。
sex_die = result.groupby('Sex')['Survived'].count() - result.groupby('Sex')['Survived'].sum()
sex_die.plot.bar()
使命三:可视化展现泰坦尼克号数据会集男女中生计人与死亡人数的份额图(用柱状图试试)
sex_sur_rate = result.groupby(['Sex','Survived'])['Survived'].count().unstack()
sex_sur_rate.plot(kind='bar',stacked=True)
使命四:可视化展现泰坦尼克号数据会集不同票价的人生计和死亡人数散布状况。(用折线图试试)(横轴是不同票价,纵轴是存活人数)
# 排序后绘折线图
fig = plt.figure(figsize=(20, 18))
fare_sur = text.groupby(['Fare'])['Survived'].value_counts().sort_values(ascending=False)
fare_sur.plot(grid=True)
plt.legend()
plt.show()
使命五:可视化展现泰坦尼克号数据会集不同仓位等级的人生计和死亡人员的散布状况。(用柱状图试试)
Pclass_sur = result.groupby(['Pclass','Survived'])['Survived'].value_counts()
import seaborn as sns
sns.countplot(x="Pclass", hue="Survived", data=result)
使命六:可视化展现泰坦尼克号数据会集不同年纪的人生计与死亡人数散布状况。(不限表达办法)
facet = sns.FacetGrid(result, hue="Survived",aspect=3)
facet.map(sns.kdeplot,'Age',shade= True)
facet.set(xlim=(0, result['Age'].max()))
facet.add_legend()
使命七:可视化展现泰坦尼克号数据会集不同仓位等级的人年纪散布状况。(用折线图试试)
result.Age[result.Pclass == 1].plot(kind='kde')
result.Age[result.Pclass == 2].plot(kind='kde')
result.Age[result.Pclass == 3].plot(kind='kde')
plt.xlabel("age")
plt.legend((1,2,3),loc="best") # best便是最不碍眼的位置
第三章 模型建立和评价–建模
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from IPython.display import Image
%matplotlib inline
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显现中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显现负号
plt.rcParams['figure.figsize'] = (10, 6) # 设置输出图片大小
载入数据
clear_data = pd.read_csv("clear_data.csv")
train_data = pd.read_csv("train.csv)
模型建立
使命一:切开练习集和测验集
- 将数据集分为自变量和因变量
- 按份额切开练习集和测验集(一般测验集的份额有30%、25%、20%、15%和10%)
- 运用分层抽样
- 设置随机种子以便成果能复现
from sklearn.model_selection import train_test_split
train_label = train_data['Survived'] # 作为标签,练习集便是咱们的clear_data
x_train, x_test, y_train, y_test = train_test_split(clear_data, train_label, test_size=0.3, random_state=0, stratify = train_label)
x_train.shape # (623, 11)
x_test.shape # (268, 11)
【考虑】什么状况下切开数据集的时分不用进行随机选取
【答】数据本身便是随机的
使命二:模型创立
- 创立基于线性模型的分类模型(逻辑回归)
- 创立基于树的分类模型(决策树、随机森林)
- 别离运用这些模型进行练习,别离的到练习集和测验集的得分
- 检查模型的参数,并更改参数值,调查模型变化
from sklearn.linear_model import LogisticRegression
lr_l1 = LogisticRegression(penalty="l1", C=0.5, solver="liblinear")
lr_l1.fit(x_train, y_train)
print("练习集得分为:",lr_l1.score(x_train,y_train))
print("测验集得分为:",lr_l1.score(x_test,y_test))
练习集得分为: 0.7897271268057785
测验集得分为: 0.8134328358208955
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
clf = DecisionTreeClassifier(random_state=0) # 设置随机数种子
rfc = RandomForestClassifier(random_state=0)
clf.fit(x_train, y_train)
rfc.fit(x_train, y_train)
clf_score = clf.score(x_test, y_test)
rfc_score = rfc.score(x_test, y_test)
print("决策树练习集得分为:",clf.score(x_train,y_train))
print("决策树测验集得分为:",clf.score(x_test,y_test))
print("随机森林练习集得分为:",rfc.score(x_train,y_train))
print("随机森林测验集得分为:",rfc.score(x_test,y_test))
# 能够看到决策树已经过拟合
决策树练习集得分为: 1.0
决策树测验集得分为: 0.7611940298507462
随机森林练习集得分为: 1.0
随机森林测验集得分为: 0.8283582089552238
使命三:输出模型猜测成果
- 输出模型猜测分类标签
- 输出不同分类标签的猜测概率
一般监督模型在sklearn里边有个predict
能输出猜测标签,predict_proba
则能够输出标签概率
pred_result = lr_l1.predict(x_train) # 输出为array
pred_result[:10]
array([0, 0, 0, 1, 0, 0, 0, 0, 1, 0], dtype=int64)
# 输出概率
pred_prob = lr_l1.predict_proba(x_train)
pred_prob[:10]
array([[0.89656205, 0.10343795],
[0.85447589, 0.14552411],
[0.91449841, 0.08550159],
[0.13699148, 0.86300852],
[0.9381094 , 0.0618906 ],
[0.81157396, 0.18842604],
[0.91822815, 0.08177185],
[0.72434838, 0.27565162],
[0.47558837, 0.52441163],
[0.86624392, 0.13375608]])
【考虑】猜测标签的概率对咱们有什么协助
【答】输出概率能够让咱们知道该猜测的信息分数
模型评价
- 模型评价是为了知道模型的泛化能力。
- 穿插验证(cross-validation)是一种评价泛化功能的核算学办法,它比单次区分练习集和测验集的办法更加稳定、全面。
- 在穿插验证中,数据被多次区分,而且需要练习多个模型。
- 最常用的穿插验证是 k 折穿插验证(k-fold cross-validation),其间 k 是由用户指定的数字,通常取 5 或 10。
- 准确率(precision)衡量的是被猜测为正例的样本中有多少是真正的正例
- 召回率(recall)衡量的是正类样本中有多少被猜测为正类
- f-分数是准确率与召回率的调和平均
使命一:穿插验证
from sklearn.model_selection import cross_val_score
lr_l1 = LogisticRegression(penalty="l1", C=0.5, solver="liblinear")
lr_l1.fit(x_train, y_train)
scores = cross_val_score(lr_l1, x_train, y_train,cv = 10)
print("score:",scores)
print("score.mean():",scores.mean())
score: [0.74603175 0.76190476 0.85714286 0.75806452 0.85483871 0.79032258
0.72580645 0.83870968 0.70967742 0.80645161]
score.mean(): 0.7848950332821301
clf = DecisionTreeClassifier(random_state=0) # 设置随机数种子
rfc = RandomForestClassifier(random_state=0)
clf.fit(x_train, y_train)
rfc.fit(x_train, y_train)
scores_clf = cross_val_score(clf, x_train, y_train,cv = 10)
scores_rfc = cross_val_score(rfc, x_train, y_train,cv = 10)
print("scores_clf.mean_10:",scores_clf.mean())
print("scores_rfc.mean_10:",scores_rfc.mean())
scores_clf = cross_val_score(clf, x_train, y_train,cv = 5)
scores_rfc = cross_val_score(rfc, x_train, y_train,cv = 5)
print("scores_clf.mean_5:",scores_clf.mean())
print("scores_rfc.mean_5:",scores_rfc.mean())
scores_clf.mean_10: 0.7397849462365592
scores_rfc.mean_10: 0.8186635944700461
scores_clf.mean_5: 0.7496129032258064
scores_rfc.mean_5: 0.8138322580645161
【考虑】k折越多的状况下会带来什么样的影响?
【答】拟合作用不好
使命二:混杂矩阵
- 核算二分类问题的混杂矩阵
- 核算准确率、召回率以及f-分数
【考虑】什么是二分类问题的混杂矩阵,理解这个概念,知道它主要是运算到什么使命中的
【答】这个能够很好的应用到使命为样本不太均衡的场景
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
pred = lr_l1.predict(x_train)
confusion_matrix(y_train, pred)
array([[328, 56],
[ 75, 164]], dtype=int64)
print(classification_report(y_train, pred))
precision recall f1-score support
0 0.81 0.85 0.83 384
1 0.75 0.69 0.71 239
accuracy 0.79 623
macro avg 0.78 0.77 0.77 623
weighted avg 0.79 0.79 0.79 623
使命三:ROC曲线
【考虑】什么是ROC曲线,OCR曲线的存在是为了处理什么问题?
【答】主要是用来确定一个模型的 阈值。一起在一定程度上也能够衡量这个模型的好坏
from sklearn.metrics import roc_curve
fpr, tpr, thresholds = roc_curve(y_test, lr_l1.decision_function(x_test))
plt.plot(fpr, tpr, label="ROC Curve")
plt.xlabel("FPR")
plt.ylabel("TPR (recall)")# 找到最接近于0的阈值
close_zero = np.argmin(np.abs(thresholds))
plt.plot(fpr[close_zero], tpr[close_zero], 'o', markersize=10, label="threshold zero", fillstyle="none", c='k', mew=2)
plt.legend(loc=4)
【考虑】关于多分类问题怎么绘制ROC曲线
【答】对每一个类别画一条ROC曲线最终取平均