本文适用于零基础的机器学习新手,本人也是新手入门,鉴于社区,并没有类似详细讲解使用sklearn实现西瓜分类的文章,所以写了这篇blog,本篇内容会着重讲解,本人在入门的过程遇到的一些问题,与解决办法。如果有错误,还请大家指正。
可以先阅读这两篇文章来了解一下朴素贝叶斯的实现方法:
朴素贝叶斯详解
朴素贝叶斯分类详解手算西瓜
西瓜数据集,我这里使用的excal格式,这里大家可能会遇到第一坑,pandas读不了xlsx格式的文件。
解决办法:重装低版本xlrd
import pandas as pd
from sklearn.preprocessing import StandardScaler # 一个用来将数据进行归一化和标准化的类
from sklearn.model_selection import train_test_split # 分训练集和测试集的类
from sklearn.naive_bayes import GaussianNB # 这种分类器使用高斯分布为先验分布
from sklearn.naive_bayes import MultinomialNB # 这种分类器使用多项式分布为先验分布
相信有许多刚刚入门的小伙伴会遇到的第一个问题便是数据集的处理。西瓜数据集中存在中文字符,这在朴素贝叶斯分类器中是无法使用的。所以我们需要将数据标签化。
sklearn自带一个有两个功能LabelEncoder与OneHotEncoder:Python数据预处理中的LabelEncoder与OneHotEncoder,这篇文章中详细讲解了用法。
# fit_transform()使用案例参考
def deal_data(self, x, y):
label = LabelEncoder()
# 创建LabelEncoder()对象,用于序列化
X = []
y_train = []
# 为每一列序列化
for col in x:
X.append(label.fit_transform(col))
for y_1 in y:
y_train.append(label.fit_transform(y_1))
return np.array(X).reshape(17, 8), np.array(np.array(np.squeeze(y_train)))
但是本人是个笨蛋使用这个方法中遇到了各种问题,于是采用了panda中的map方法。这个方法就相对的来说很直观,非常适合新手。
# 数据的处理和分割数据集
def read_deal(self):
pd.set_option('display.max_columns', None)
# 2.提取数据集的目标结果
chinese_target = self.loan_status['好瓜']
# 2.1 二值化处理目标结果
# 2.1.1 设置映射字典
dic_target = {'是': 1, '否': 0, }
dic_color = {'青绿': 1, '乌黑': 2, '浅白': 0}
dic_found = {'蜷缩': 1, '稍蜷': 2, '硬挺': 0}
dic_knock = {'浊响': 2, '沉闷': 1, '清脆': 0}
dic_texture = {'清晰': 0, '稍糊': 1, '模糊': 2}
dic_umbilical = {'凹陷': 0, '稍凹': 1, '平坦': 2}
dic_touch = {'硬滑': 1, '软粘': 0}
# 2.1.2 映射目标
self.loan_status['好瓜'] = self.loan_status['好瓜'].map(dic_target)
self.loan_status['色泽'] = self.loan_status['色泽'].map(dic_color)
self.loan_status['根蒂'] = self.loan_status['根蒂'].map(dic_found)
self.loan_status['敲声'] = self.loan_status['敲声'].map(dic_knock)
self.loan_status['纹理'] = self.loan_status['纹理'].map(dic_texture)
self.loan_status['脐部'] = self.loan_status['脐部'].map(dic_umbilical)
self.loan_status['触感'] = self.loan_status['触感'].map(dic_touch)
X = self.loan_status.iloc[:, 1:8].values
Y = self.loan_status.iloc[:, 9].values
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=0) # 划分测试集与训练集
return X, Y, X_train, X_test, Y_train, Y_test
StandardScaler()是一个用来将数据进行归一化和标准化的类。
def Sc(self, X, Y, X_train, X_test, Y_train, Y_test):
sc = StandardScaler()
sc.fit(X)
standard_train = sc.transform(X_train)
standard_test = sc.transform(X_test)
self.GaussianClassifier.fit(standard_train, Y_train)
result = self.GaussianClassifier.predict(standard_test)
print("测试集合的y值:", list(Y_test))
print("高斯先验朴素贝叶斯预测的的y值:", list(result))
print("预测的正确率为:", self.GaussianClassifier.score(standard_test, Y_test))
class G_M_B:
def __init__(self, filename):
self.loan_status = pd.DataFrame(pd.read_excel(filename))
self.GaussianClassifier = GaussianNB()
def read_deal(self):
pd.set_option('display.max_columns', None)
# 2.提取数据集的目标结果
chinese_target = self.loan_status['好瓜']
# 2.1 二值化处理目标结果
# 2.1.1 设置映射字典
dic_target = {'是': 1, '否': 0, }
dic_color = {'青绿': 1, '乌黑': 2, '浅白': 0}
dic_found = {'蜷缩': 1, '稍蜷': 2, '硬挺': 0}
dic_knock = {'浊响': 2, '沉闷': 1, '清脆': 0}
dic_texture = {'清晰': 0, '稍糊': 1, '模糊': 2}
dic_umbilical = {'凹陷': 0, '稍凹': 1, '平坦': 2}
dic_touch = {'硬滑': 1, '软粘': 0}
# 2.1.2 映射目标
self.loan_status['好瓜'] = self.loan_status['好瓜'].map(dic_target)
self.loan_status['色泽'] = self.loan_status['色泽'].map(dic_color)
self.loan_status['根蒂'] = self.loan_status['根蒂'].map(dic_found)
self.loan_status['敲声'] = self.loan_status['敲声'].map(dic_knock)
self.loan_status['纹理'] = self.loan_status['纹理'].map(dic_texture)
self.loan_status['脐部'] = self.loan_status['脐部'].map(dic_umbilical)
self.loan_status['触感'] = self.loan_status['触感'].map(dic_touch)
X = self.loan_status.iloc[:, 1:8].values
Y = self.loan_status.iloc[:, 9].values
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=0) # 划分测试集与训练集
return X, Y, X_train, X_test, Y_train, Y_test
def Sc(self, X, Y, X_train, X_test, Y_train, Y_test):
sc = StandardScaler()
sc.fit(X)
standard_train = sc.transform(X_train)
standard_test = sc.transform(X_test)
# 由于iris的属性是连续值,我们优先使用正态分布作为先验分布,即使用GaussianNB
self.GaussianClassifier.fit(standard_train, Y_train)
result = self.GaussianClassifier.predict(standard_test)
print("测试集合的y值:", list(Y_test))
print("高斯先验朴素贝叶斯预测的的y值:", list(result))
print("预测的正确率为:", self.GaussianClassifier.score(standard_test, Y_test))
def Mu(self, X, Y, X_train, X_test, Y_train, Y_test):
# 我们顺带着测试多项式分布作为先验分布的分类器(实测发现,多项式分布中自变量不允许出现负数,所以不能使用标准化的数据,只能使用原数据)
mc = MultinomialNB()
mc.fit(X_train, Y_train)
result = mc.predict(X_test)
print("测试集合的y值:", list(Y_test))
print("多项式先验朴素贝叶斯预测的的y值:", list(result))
print("预测的正确率为:", self.GaussianClassifier.score(X_test, Y_test))
def run():
new_water = G_M_B('watermelon.xlsx')
X, Y, X_train, X_test, Y_train, Y_test = new_water.read_deal()
new_water.Sc(X, Y, X_train, X_test, Y_train, Y_test)
if __name__ == '__main__':
run()
1.学会pandas中的map使用方法。
2.尝试使用类来写提高了编写代码的能力。
3.学习sklearn的相关库的使用方法。