赞
踩
感觉如果只是看一遍老师提供的课件的话,对 pandas
库以及 sklearn
库中许多功能还是没有一个全面的认识,我感觉还是得自己多动手实践一下才行。(下文代码中使用的库均预先装好,下文代码均在 jupyter notebook
中运行。)
我们已经将鸢尾花数据集中的数据存放到了 ./iris.csv
文件中,文件内容的前
10
10
10 行如下。
sepal_length,sepal_width,petal_length,petal_width,species
5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
5.0,3.6,1.4,0.2,Iris-setosa
5.4,3.9,1.7,0.4,Iris-setosa
4.6,3.4,1.4,0.3,Iris-setosa
5.0,3.4,1.5,0.2,Iris-setosa
4.4,2.9,1.4,0.2,Iris-setosa
...
csv
文件中的第一行给出了每一列的字段名,其后每一行给出一条记录,值与值之间通过逗号分隔,记录之间通过换行分割。(如果我以后要制作自己的数据集的话,估计也要使用类似结构)
import pandas as pd
iris = pd.read_csv("./iris.csv") # 读取 csv 文件,并返回一个 DataFrame 数据框
print(type(iris)) # 输出 <class 'pandas.core.frame.DataFrame'>
print(type(iris["sepal_length"])) # 输出 <class 'pandas.core.series.Series'>
可见 DataFrame
可以通过指定一个下标选中相应的列。
%matplotlib inline # 魔术指令,在 jupyter notebook 中显示 matplotlib 图像
import seaborn as sns
sns.pairplot(iris, hue='species') # 以 species 特征区分颜色
输出了如下图像:
可以观察到 Iris-setosa
具有非常明显的区别于另外两者的特征。Iris-versicolor
和 Iris-virginica
的数据特征相靠近。
iris.head(10) # 前十行的数据(在 jupyter notebook 中可以显示一个比较美观的 DataFrame)
# 同理还可以使用 iris.tail(10) 显示后十行的数据
数据如下:
可以看到,这些数据与前文中 csv
文件中的数据是一致的。
上文中的 iris
是一个 DataFrame
数据框,iris[species]
是从 iris
中取出的一列数据,是一个 Series
序列。可以使用 .value_counts
函数统计一个 Series
中出现的各种值。
print(iris["species"].value_counts())
输出:
Iris-virginica 50
Iris-setosa 50
Iris-versicolor 50
Name: species, dtype: int64
从输出可以看到带有 Iris-cirginica
、Iris-setosa
、Iris-versicolor
标签的记录各有
50
50
50 条,数据集中总共有
150
150
150 条数据。不过说实话,我并不是很理解这个 dtype
为什么会是 int64
。
from sklearn.model_selection import train_test_split
X = iris[["sepal_length","sepal_width","petal_length","petal_width"]]
y = iris["species"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify = y)
按照上述代码,我们得到的 X
是一个 DataFrame
数据框,它是 iris
数据框的一个子数据框,包含 iris
数据框中的四列内容。y
是一个 Series
序列,也就是 iris
数据框中的一个字段。
使用 train_test_split
函数,我们将数据集
(
X
,
y
)
(X,y)
(X,y) 随机地分成了训练集
(
X
t
r
a
i
n
,
y
t
r
a
i
n
)
(X_{train}, y_{train})
(Xtrain,ytrain) 和测试集
(
X
t
e
s
t
,
y
t
e
s
t
)
(X_{test}, y_{test})
(Xtest,ytest),其中 stratify = y
表示按照 y
值进行分层随机。换言之,
y
t
r
a
i
n
y_{train}
ytrain 和
y
t
e
s
t
y_{test}
ytest 中三种花所占地比例均与
y
y
y 相同,为
1
:
1
:
1
1:1:1
1:1:1。
from sklearn.linear_model import LogisticRegression
classifier = LogisticRegression(C=1e3, solver='lbfgs') # lbfgs 利用 损失函数 二阶导数 也就 海森阵 优化
classifier.fit(X_train, y_train) # 训练分类器
from sklearn import metrics
predict_y = classifier.predict(X_test) # 对测试集计算预测值向量
print (metrics.classification_report(y_test,predict_y)) # 根据预测值向量和测试集的标签生成报告
precision recall f1-score support
Iris-setosa 1.00 1.00 1.00 15
Iris-versicolor 0.82 0.93 0.87 15
Iris-virginica 0.92 0.80 0.86 15
avg / total 0.92 0.91 0.91 45
由此可见,平均分类准确度为 91 % 91\% 91%。
print(classifier.predict([ [5.1, 3.5, 0.4, 1.2] ]))
输出:
['Iris-setosa']
注意:由于我们的输入应该是一个 DataFrame
,换言之是一个表格,因此我们给出的输入数据必须用两层中括号括起来 (构成一个 list of list
,外层 list
中的每个元素表示数据集中的一个记录,内层 list
中的某个元素表示某个记录中的某个字段),不然会报错(数据个数不匹配)。
其实这组数据只不过是抄了一下整个数据集中第一组元素的数据罢了,可以看到我们的模型给出了正确的预测。
import pandas as pd iris = pd.read_csv("./iris.csv") # 加载数据集合 %matplotlib inline import seaborn as sns sns.pairplot(iris,hue='species') # 输出 pairplot # 可以看到在尺寸上,三种花具有顺序关系: # Iris-setosa(蓝色) < Iris-versicolor < Iris-virginica def species_to_id(species_name: str): dic = {"Iris-setosa": 0, "Iris-versicolor": 1, "Iris-virginica": 2} return dic[species_name] iris["species"] = iris["species"].map(species_to_id) print(iris.head(1)) # 输出第一行进行检查 from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split X = iris[["sepal_length", "sepal_width", "petal_length", "petal_width"]] y = iris["species"] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42,stratify=y) # 划分测试集 lm = LinearRegression() lm.fit(X_train, y_train) # 进行线性回归 print("截距为:", lm.intercept_) # 常数项 pd.DataFrame([X.columns, lm.coef_]) # 各项系数 def to_regular(vals : float): if vals <= 0: return 0 elif vals >= 2: return 2 else: return int(round(vals)) # 四舍五入 predict_y = lm.predict(X_test) # 生成预测向量 predict_y = [to_regular(x) for x in predict_y] from sklearn import metrics print (metrics.classification_report(y_test,predict_y)) # 输出分析 import matplotlib.pyplot as plt plt.scatter(lm.predict(X_test), lm.predict(X_test) - y_test, c="g", alpha=0.5) plt.hlines(y=0, xmin=0, xmax=2) plt.ylabel("Residuals")
本地测试分类准确度为 96 % 96\% 96%,甚至比 Logistic 回归更高一些。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。