栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

感知机(Perceptron) Python实现

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

感知机(Perceptron) Python实现

推荐观看Jupyter版本:https://github.com/Momentum9/ML

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
%matplotlib inline 

iris = load_iris() # 鸢(yuan)尾花数据集
df = pd.DataFrame(iris.data,columns=iris.feature_names) # 花萼长、花儿宽、花瓣长、花瓣宽
df['label'] = iris.target # 插入label列
df.label.value_counts() #呈现label值的分布
df.columns = ['sepal length','sepal width','petal length','petal width','label'] # 重命名colums
# 绘制数据集
plt.scatter(df[:50]['sepal length'],df[:50]['sepal width'],c='b',marker='o',label='0')
plt.scatter(df[50:100]['sepal length'],df[50:100]['sepal width'],c='r',marker='x',label='1')
plt.legend()
plt.xlabel('sepal length'),plt.ylabel('sepal width')

data = np.array(df.iloc[:100,[0,1,-1]])
X,y = data[:,:-1],data[:,-1]
y = [1 if i == 0 else -1 for i in y] # 将label{0,1}改为{-1,1}
Perceptron 实现
class Model:
    def __init__(self):
        self.w = np.ones(len(X[0]),dtype=np.float32) # w的维度和特征X的数量一致
        self.b = 0 # b∈ R
        self.learning_rate = 0.1
        self.fit_num = 0 # 记录训练集被完整训练次数
    
    def sign(self,x,w,b):
        y = np.dot(x,w) + b
        return y

    # 随机梯度下降法
    def fit(self,X_train,y_train):
        # is_wrong 变量妙:当更改w和b之后,继续会验证后面的数据集,但未验证此前的数据集
        # 所以用变量is_wrong控制,若wrong_count不为0(也即又有更新时),iswrong为false
        # 那么将继续从头开始验证数据集,直至所有数据集都被分开
        is_wrong = False 
        while not is_wrong: 
            self.fit_num += 1
            wrong_count = 0
            for i in range(len(X_train)): # 从头到尾遍历训练集X
                Xi = X_train[i]
                yi = y_train[i]
                # 随机梯度下降在此是按序挑选分类点
                if yi * self.sign(Xi, self.w, self.b) <= 0: # 从头到尾找到不满足所有当前模型下的误分类点
                    self.w = self.w + self.learning_rate * np.dot(yi,Xi)
                    self.b = self.b + self.learning_rate * yi
                    wrong_count += 1 # 误分个数
            if wrong_count == 0: # 只有当本轮数据集验证时没有被误分的样本时,才会将iswrong设为true
                is_wrong = True
        return 'Perceptron Model!'                
    
perceptron = Model()
perceptron.fit(X,y) # 训练
print(f'数据集被完整训练了{perceptron.fit_num}次')
print(perceptron.w,perceptron.b)

# 绘制决策边界(分离超平面)
plt.figure(figsize=(12,8))
plt.scatter(df[:50]['sepal length'],df[:50]['sepal width'],c='b',marker='o',label='0')
plt.scatter(df[50:100]['sepal length'],df[50:100]['sepal width'],c='r',marker='x',label='1')
plt.xlabel('sepal length'),plt.ylabel('sepal width')
plt.title('鸢尾花线性数据示例',fontproperties='SimHei',fontsize=20)
plt.legend()
# 分离超平面为 wx+b=0
x1 = np.linspace(4,7,100)
x2 = -(perceptron.b + perceptron.w[0] * x1) / perceptron.w[1]
plt.plot(x1,x2,'r')
scikit-learn 方法
import sklearn
from sklearn.linear_model import Perceptron

# %%
clf = Perceptron(fit_intercept=True,max_iter=1000,shuffle=True,tol=None)
"""
:param fit_intercept:是否对截距b进行估计
:param max_iter:最大迭代次数,哪怕损失函数依旧大于0
:param shuffle:每轮训练后是否打乱数据
:param tol:迭代停止的标准。如果不为None,那么当前迭代造成的损失函数很小时便会停止下降
"""
clf.fit(X,y)

# %%
print(clf.coef_)
print(clf.intercept_)
print(type(clf.intercept_))

# %%
# 绘制决策边界(分离超平面)
plt.figure(figsize=(12,8))
plt.scatter(df[:50]['sepal length'],df[:50]['sepal width'],c='b',marker='o',label='0')
plt.scatter(df[50:100]['sepal length'],df[50:100]['sepal width'],c='r',marker='x',label='1')
plt.xlabel('sepal length'),plt.ylabel('sepal width')
plt.legend()
# 分离超平面为 wx+b=0
x1 = np.linspace(4,7,100)
x2 = -(clf.intercept_[0] + clf.coef_[0][0] * x1) / clf.coef_[0][1]
plt.plot(x1,x2,'r')

参考:https://github.com/fengdu78/lihang-code

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1000958.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号