機器學習實驗-計算機18級 | https://edu.cnblogs.com/campus/ahgc/machinelearning |
---|---|
作業要求 | https://edu.cnblogs.com/campus/ahgc/machinelearning/homework/11950 |
學 號 | 3180701236 |
一、實驗目的
-
理解感知器算法原理,能實現感知器算法;
-
掌握機器學習算法的度量指標;
-
掌握最小二乘法進行參數估計基本原理;
-
針對特定應用場景及數據,能構建感知器模型並進行預測。
二、實驗內容
-
安裝Pycharm,注冊學生版。
-
安裝常見的機器學習庫,如Scipy、Numpy、Pandas、Matplotlib,sklearn等。
-
編程實現感知器算法。
-
熟悉iris數據集,並能使用感知器算法對該數據集構建模型並應用。
三、實驗步驟
# 導入包
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt
%matplotlib inline
# load data,下載數據
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)#生成表格
df['label'] = iris.target
# 統計鳶尾花的種類與個數
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
df.label.value_counts() # value_counts() 函數可以對df里面label每個值進行計數並且排序,默認是降序
結果:
2 50
1 50
0 50
Name: label, dtype: int64
#畫數據的散點圖
plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], label='0')#將數據的前50個數據繪制散點圖
plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'], label='1')#將數據的50-100之間的數據繪制成散點圖
plt.xlabel('sepal length')#給x坐標命名
plt.ylabel('sepal width')#給y坐標命名
plt.legend()
結果:
#對數據進行預處理
data = np.array(df.iloc[:100, [0, 1, -1]])#iloc函數:通過行號來取行數據,讀取數據前100行的第0,1列和最后一列
X, y = data[:,:-1], data[:,-1]#X為data數據中除去最后一列的數據,y為data數據的最后一列(y中有兩類0和1)
y = np.array([1 if i == 1 else -1 for i in y])#將y中的兩類(0和1)改為(-1和1)兩類
# 定義算法
# 此處為一元一次線性方程
class Model:
def __init__(self):
self.w = np.ones(len(data[0])-1, dtype=np.float32) #初始w的值
self.b = 0 #初始b的值為0
self.l_rate = 0.1 #步長為0.1
# self.data = data
def sign(self, x, w, b):
y = np.dot(x, w) + b #dot進行矩陣的乘法運算,y=w*x+b
return y
#隨機梯度下降法
def fit(self, X_train, y_train):
is_wrong = False #初始假設有誤分點
while not is_wrong:
wrong_count = 0 #誤分點個數初始為0
for d in range(len(X_train)):
X = X_train[d] #取X_train一組及一行數據
y = y_train[d] #取y_train一組及一行數據
if y * self.sign(X, self.w, self.b) <= 0: #為誤分點
self.w = self.w + self.l_rate*np.dot(y, X) #對w和b進行更新
self.b = self.b + self.l_rate*y
wrong_count += 1 #誤分點個數加1
if wrong_count == 0: #誤分點個數為0,算法結束
is_wrong = True
return 'Perceptron Model!'
def score(self):
pass
perceptron = Model()#生成一個算法對象
perceptron.fit(X, y)#將測試數據代入算法中
結果:
'Perceptron Model!'
#畫出超平面
x_points = np.linspace(4, 7,10) #用於產生4,7之間的10點行矢量。其中4、7、10分別為起始值、中止值、元素個數。----產生x坐標
y_ = -(perceptron.w[0]*x_points + perceptron.b)/perceptron.w[1] #繪制超平面
plt.plot(x_points, y_)
plt.plot(data[:50, 0], data[:50, 1], 'bo', color='blue', label='0')#將數據的前50個數據繪制散點圖
plt.plot(data[50:100, 0], data[50:100, 1], 'bo', color='orange', label='1')#將數據的50-100之間的數據繪制成散點圖
plt.xlabel('sepal length')#給x坐標命名
plt.ylabel('sepal width')#給y坐標命名
plt.legend()
結果:
#生成sklearn結果與上面手寫函數的結果對比
from sklearn.linear_model import Perceptron ## 導入感知機模型
clf = Perceptron(fit_intercept=False, max_iter=1000, shuffle=False)
#fit_intercept(默認True)是否對參數 b 進行估計,若為False則數據應是中心化的
#max_iter(默認1000)最大迭代次數
#shuffle(默認True)每輪訓練后是否打亂數據
clf.fit(x, y)
結果:
Perceptron(alpha=0.0001, class_weight=None, early_stopping=False, eta0=1.0,
fit_intercept=False, max_iter=1000, n_iter_no_change=5, n_jobs=None,
penalty=None, random_state=0, shuffle=False, tol=0.001,
validation_fraction=0.1, verbose=0, warm_start=False)
print(clf.coef_)#權值w參數
print(clf.intercept_)#偏置b參數
結果:
[[ 16.3 -24.2]]
[0.]
#畫出sklearn結果的散點圖
x_ponits = np.arange(4, 8)#x,為4,5,6,7,默認步長為1,起始為4,終止為8,不取8
y_ = -(clf.coef_[0][0]*x_ponits + clf.intercept_)/clf.coef_[0][1]#繪制超平面
plt.plot(x_ponits, y_)
plt.plot(data[:50, 0], data[:50, 1], 'bo', color='blue', label='0')#將數據的前50個數據繪制散點圖
plt.plot(data[50:100, 0], data[50:100, 1], 'bo', color='orange', label='1')#將數據的50-100之間的數據繪制成散點圖
plt.xlabel('sepal length')#給x坐標命名
plt.ylabel('sepal width')#給y坐標命名
plt.legend()
結果:
五、個人小結
感知機
①是一種人工神經網絡
感知機可以通過數學統計學方法完成對函數的估計或近似,能在外界信息的基礎上改變內部結構,是一種自適應系統,通俗的講就是具備學習功能。
②是一種最簡單形式的前饋神經網絡
感知機模型的參數從輸入層向輸出層單向傳播,整個網絡中無反饋。感知機是最簡單形式是因為只包含一層傳播。
③是一種二元線性分類器
感知機的輸出結果只有+1 和–1二值,所以說感知機是一個二元分類器;
在二維空間中,感知機的模型就是一條直線,將平面中的正負樣本點分離成兩份,在三維中,感知機的模型就是一個平面,將空間中的正負樣本點分離成兩份,放到更高維的空間中,感知機的模型就是一個超平面;
這也就是說,如果在二維空間中,不存在直線剛好將正負樣本點分離成兩份,在三維空間中,不存在平面將空間中的正負樣本點分離成兩份,那么你的數據就無法使用感知機模型;
感知機的使用前提是數據本身線性可分。