机器学习——算法分类

机器学习算法可以分为两大类:监督学习与非监督学习。数据集构成:‘监督学习:特征值+目标值;非监督学习:特征值’。

监督学习:

分类:K-近邻算法、贝叶斯分类、决策树与随机森林、逻辑回归、神经网络

回归:线性回归、岭回归

标注:隐马尔可夫模型

注:分类:目标值离散型数据;回归:目标值连续型数据

无监督学习:

 聚类:k-means

数据集API介绍:

sklearn.datasets
   加载获取流行数据集
datasets.load_*()
   获取小规模数据集,数据包含在datasets里
datasets.fetch_*(data_home = None)
   获取大规模的数据集,第一次使用需要从网络上下载,时间较长,函数的第一 
   个参数是data_home,表示数据集的下载目录,默认是~/scikit_lean_data/

load与fetch返回的数据类型datasets.base.Bunch(字典格式)

data: 特征数据数组,是[n_samples*n_features]的二维numpy.narray数组。

target:标签数组,是n_samples的一维numpy.ndarray数组。

DESCR:数据描述。

feature_names:特征名。新闻数据,手写数字、回归数据集没有

target_names:标签名

数据集划分API:

sklearn.model_selection.train_test_split
   x:数据集的特征值
   y:数据集的标签值
   test_size:测试集的大小,一般为float
   random_state:随机数种子,不同的种子会造成不同的随机采样结果,相同 
                        的随机种子采样结果相同。
   return:训练集特征值,测试集特征值,训练标签,测试标签
小提示:Sklean数据集的划分比例较合理的划分:训练集,测试集。划分比列(80%-20,75%-25%,70%-30%)
from sklearn.datasets import load_iris, fetch_20newsgroups, load_boston
from sklearn.model_selection import train_test_split

def max_data():
    # 新闻大数据——分类
    news = fetch_20newsgroups(subset="all")
    print(news.data)
    print(news.target)


def house_price():
    # 波士顿房价——回归数据
    lb = load_boston()
    print("获取特征值")
    print(lb.data)
    print("目标值")
    print(lb.target)
    print(lb.DESCR)
    pass


ef mim_data():
    # 鸢尾花数据(小数据集) 4个特征--分类
    li = load_iris()

    print("获取特征值")
    print(li.data)

    print("目标值")
    print(li.target)
    print(li.DESCR)

    # 返回值 训练集train:x_train,y_train 测试集test:x_test,y_test
    x_train, x_test, y_train, y_test = train_test_split(li.data, li.target, test_size=0.25)
    print("训练集的特征值和目标值:", x_train, y_train)
    print("测试集的特征值和目标值:", x_test, y_test)
    return None
eg

估计器

在sklearn中,估计器(estimator)是一个重要的角色,分类器和回归器都属于estimator,是一类实现了算法的API。

  • fit方法用于从训练集中学习模型参数
  • transform用学习到的参数转换数据

1、用于分类的估计器:

  • sklearn.neighbors k-近邻算法

  • sklearn.naive_bayes 贝叶斯

  • sklearn.linear_model.LogisticRegression 逻辑回归

  • sklean.tree 决策树和随机森林

2、用于回归的估计器:

  • sklearn.linear_model.LinearRegression 线性回归

  • sklearn.linear_model.Ridge 岭回归

分类算法 

K-近邻算法

定义:如果一个样本在特征控件中的k个最相似的样本中的大多数属于某一个类别,则该样本也属于这个类别。

注:样本距离使用欧式距离时,数据需要进行标准化处理。

sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, algorithm="auto")
   n_neighbors: 查询默认使用的邻居数,默认为5
   algorithm:{'auto''ball_tree','kd_tree','brute'},可选用于计算最近邻 
                    居的算法:'ball_tree'将会使用BallTree,'kd_tree'将使用 
                    KDTree。'auto'将尝试根据传递给fit方法的值来决定最合适的 
                    算法。(不同实现方式影响效率)
def kNN():
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.preprocessing import StandardScaler
    from sklearn.model_selection import GridSearchCV
    """
    预测入住位置,数据无法下载,貌似要FQ
    :return None
    """
    # 读取数据
    import pandas as pd
    #处理数据--缩小数据,删选距离为x公里内的位置,
    data = pd.read_csv("https://www.kaggle.com/c/facebook-v-predicting-check-ins/data")
    data.query('x>1.0&x<1.25&y>2.5&y<2.75')
    time_value = pd.to_datetime(data['time'], unit='s') # 转换时间戳
    time_value = pd.DatetimeIndex(time_value) #把日期转换为字典格式
    # 增加特征,增加一个day特征
    data['day'] = time_value.day
    data['hour'] = time_value.hour
    data['weekday'] = time_value.weekday
    data.drop(["time"], axis=1) # axis=1 按列删除

    # 把签到数量少于n=3的目标位置删除
    place_count = data.groupby("place_id").count()
    tf = place_count[place_count.row_id>3].reset_index() # reset_index()索引变为一列
    data = data[data['place_id'].isin(tf.place_id)]

    # 取出数据中的特征值和目标值
    y = data["place_id"]
    x = data.drop(["place_id"], axis=1)

    # 将数据分割为训练集和测试集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)

    # 特征工程(标准化)
    std = StandardScaler()
    x_train = std.fit_transform(x_train)
    x_test = std.transform(x_test)

    # 进行算法流程,超参数5
    KNN = KNeighborsClassifier(n_neighbors=5, algorithm="auto")
    # fit, predict, score
    # KNN.fit(x_train, y_train)
    # y_predict = KNN.predict(x_test) #得到预测结果
    # print('预测的目标签到位置为: ', y_predict)
    # print('预测的准确率: ', KNN.score(x_test, y_test))

    # 进行网格搜素
    param = {'n_neighbors': [3, 5, 10]} #构建参数值进行搜索
    gc = GridSearchCV(KNN, param_grid=param, cv=2)
    gc.fit(x_train, y_train)
    #预测准确率
    print('在测试集上的准确率: ', gc.score(x_test, y_test))
    print("在交叉验证当中最好的结果:", gc.best_score_)
    print("选择的最好模型: ", gc.best_estimator_ )
    print('每个超参数每次交叉验证的结果: ', gc.cv_results_)
    return None
eg

K-近邻算法优缺点:

优点:简单,易于了解,易于实现,无需估计参数,无需训练

缺点:懒惰算法,对测试样本分类时的计算量大,内存开销大;必须选择K值,K值选择不当则分类精度不能保证。

使用场景:小数据场景,几千~几万样本,具体场景具体业务去测试。

 朴素贝叶斯算法

 

 eg:

sklearn.naive_bayes.MultinomialNB(alpha=1.0)
    alpha:拉普拉斯平滑系数
def neviebayes():
    """
    朴素贝叶斯进行文本分类
    :return: None
    """
    from sklearn.feature_extraction.text import TfidfVectorizer
    from sklearn.naive_bayes import MultinomialNB
    from sklearn.metrics import classification_report
    news = fetch_20newsgroups(subset='all')
    # 数据分割
    x_train, x_test, y_train, y_test = train_test_split(news.data, news.target, test_size=0.20)

    # 对数据进行抽取
    tf = TfidfVectorizer()
    # 以训练集当中的词的列表进行每篇文章重要性统计
    x_train = tf.fit_transform(x_train)
    print(tf.get_feature_names())
    x_test = tf.transform(x_test)

    #进行朴素贝叶斯算法的预测,一般默认为1.0
    mlt = MultinomialNB(alpha=1.0)
    print(x_train.toarray())
    mlt.fit(x_train, y_train)
    y_predict = mlt.predict(x_test)
    print("预测的文章类别为: ", y_predict)
    print("准确率为: ", mlt.score(x_test, y_test))
    print("每个类别的准确率和召回率: ", classification_report(y_test, y_predict, target_names=news.target_names))
    return None
eg

拉普拉斯分类算法优缺点:

优点:

  • 朴素贝叶斯模型发源于古典数据理论,有稳定的分类效率。
  • 对缺失数据不敏感,算法也比较简单,常用语文本分类。
  • 分类精度高,速度快。

缺点:由于使用了样本属性独立性的假设,所以如果样本属性有关联时其效果不好。

 

 分类模型评估API

 模型的选择与调优:交叉验证、网格搜索。

交叉验证:

目的:为了让被评估的模型更加准确可信。

 

 超参数搜索--网格搜索

超参数是在建立模型时用于控制算法行为的参数。这些参数不能从常规训练过程中获得。在对模型进行训练之前,需要对它们手动进行赋值。但手动过程繁杂,网格搜索是一种基本的超参数调优技术。它类似于手动调优,为网格中指定的所有给定超参数值的每个排列构建模型,评估并选择最佳模型。(是个自动的过程)

决策树与随机森林

香农公式:

 

信息增益:当得知一个特征条件后,减少的信息熵的大小。信息增益表示得知特征X的信息而使得类Y的信息的不确定性减少的程度。信息增益是决策树划分的依据之一。

 

eg:

 决策树使用的常见准则:

  • ID3:信息增益最大准则
  • C4.5:信息增益比最大准则
  • CART:回归树:平方误差最小;分类树:基尼系数最小的准则
sklearn.tree.DecisionTreeClassifier(criterion='gini', max_depth=None, random_state=None) #决策树分类器
   criterion:默认是'gini'系数,也可以选择信息增益的熵'entropy'
   max_depth:树的深度
   random_state:随机数种子
   decision_path:返回决策树的路径
def decision():
    """
    决策树对泰坦尼克号进行预测生死
    :return: None
    """
    import pandas as pd
    from sklearn.metrics import classification_report
    from sklearn.feature_extraction import DictVectorizer
    from sklearn.tree import DecisionTreeClassifier, export_graphviz
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.model_selection import GridSearchCV
    # 获取数据
    titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")

    # 处理数据,找出特征值和目标值
    x = titan[['pclass', 'age', 'sex']]
    y = titan[['survived']]
    # 缺失值处理
    x["age"].fillna(x['age'].mean(), inplace=True)
    # 分割数据集到训练集和测试集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
    # 进行处理 (特征工程 特征-》类别-》one_hot编码)
    dict = DictVectorizer(sparse=False)
    x_train = dict.fit_transform(x_train.to_dict(orient='records')) # 转换为字典
    print(dict.get_feature_names())
    x_test = dict.transform(x_test.to_dict(orient='records'))

    # # 用决策树进行预测 树的深度设置max_depth=5
    # decTree = DecisionTreeClassifier(criterion='gini',max_depth=None, random_state=None)
    # decTree.fit(x_train, y_train)
    # print('预测的准确率: ', decTree.score())
    #
    # # 导出树的结构, feature_names = dict.get_feature_names()
    # export_graphviz(decTree, out_file='./tree.dot', feature_names=['age', 'pclass=lst', 'pclass=2nd', 'pclass=3rd', 'sex=female', 'sex=male'])

    # 随机森林进行预测
    rf = RandomForestClassifier()
    param = {"n_estimators":[120,200,200,500,800,1200], 'max_depth': [5,8,15,25,30]}
    # 网格搜素与交叉验证
    gc= GridSearchCV(rf, param_grid=param,cv=2)
    gc.fit(x_train,y_train)
    print("准确率: ", gc.score(x_test, y_test))
    print("查看选择的参数: ", gc.best_params_)
eg
运行:dot  -Tpng ./tree.dot -o image.png 将生成保存的决策树转为png格式

决策树的优缺点以及改进:

  • 优点:简单的理解和解释,树木可视化;不需要对数据进行过多处理,其他技术通常需要对数据进行归一化
  • 缺点:决策树学习者可以创建不能很好地推广数据的过于复杂的树。(过拟合)
  • 改进:剪枝cart算法;随机森林

决策树调优——随机森林

集成学习:通过建立几个模型组合来解决单一预测问题,它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成单预测,因此优于任何一个单分类作出的预测。

随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。

 

随机森林的优点:

  •  在当前所有算法中,具有极好的准确率
  • 能够有效地运行在大数据集上
  • 能够处理具有高维特征的输入样本,而且不需要降维
  • 能够评价各个特征在分类问题上的重要性

回归算法

线性回归

定义:通过一个或者多个自变量与因变量之间进行建模回归分析。

一元线性回归:涉及到的变量只有一个。多元线性分析:涉及到的变量两个或者两个以上。

 减少误差的两种方式:

(1)正规方程

(2)梯度下降

 欠拟合原因以及解决方法:

  • 原因:学习到的数据的特征过少
  • 解决方法:增加数据的特征数量

过拟合原因以及解决方法:

  • 原因:原始特征过多,存在一些嘈杂特征,模型过于复杂是因为模型尝试去兼顾各个测试数据点
  • 解决方法:进行特征选择,消除关联性大的特征;交叉验证(让所有数据都有过训练);正则化

岭回归

岭回归:回归得到的回归系数更符合实际,更可靠。另外,能让估计参数的波动范围变小,变得更稳定。在存在病态数据偏多的研究中有较大的实用价值。

逻辑回归解决分类问题(只能解决二分类)

from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge, LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, classification_report
import joblib
import pandas as pd
import numpy as np

def mylinear():
    """
    线性回归预测房子价格
    :return: None
    """
    # 获取数据
    lb = load_boston()
    # 分割数据集
    x_train, x_test, y_train, y_test = train_test_split(lb.data, lb.target, test_size=0.25)
    print(y_train, y_test)
    #进行标准化处理
    # 特征值 目标值都要进行标准化处理,实例化两个API
    # 特征值
    std_x = StandardScaler()
    x_train = std_x.fit_transform(x_train)
    x_test = std_x.transform(x_test)

    #目标值标准化
    std_y = StandardScaler()
    y_train = std_y.fit_transform(y_train)
    y_test = std_y.transform(y_test)


    # estimator预测
    # 正规方程求解方式预测
    lr = LinearRegression()
    lr.fit(x_train, y_train)
    print(lr.coef_)

    # 预测测试集的房子价格
    y_predict = lr.predict(x_test)
    y_predict = std_y.inverse_transform(y_predict)
    print("正规方程的均方误差: ", mean_squared_error(std_y.inverse_transform(x_test), y_predict))

    # # 梯度下降进行房价预测
    # sgd = SGDRegressor()
    # sgd.fit(x_train, y_train)
    # print(sgd.coef_)
    # # 预测测试集的房子价格
    # y_predict = sgd.predict(x_test)
    # y_predict = std_y.inverse_transform(y_predict)
    # print(y_predict)
    # print("梯度下降的均方误差: ", mean_squared_error(std_y.inverse_transform(x_test), y_predict))

    # 岭回归进行房价预测
    rd = Ridge(alpha=1.0)
    rd.fit(x_train, y_train)
    print(rd.coef_)
    # #保存训练好的模型
    # joblib.dump(rd, './tmp/test.pkl')
    # # 导入训练好的模型
    # model = joblib.load('./tmp/test.pkl')
    # y_predict = std_y.inverse_transform(model.predict(x_test))

    # 预测测试集的房子价格
    y_predict = rd.predict(x_test)
    y_predict = std_y.inverse_transform(y_predict)
    print("岭回归的均方误差: ", mean_squared_error(std_y.inverse_transform(x_test), y_predict))

    return None


def logistic():
    """
    逻辑回归做二分类
    :return:
    """
    # 构建列名
    column = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size',
              'Uniformity of Cell Shape', 'Marginal Adhesion', 'Single Epithelial Cell Size',
              'Bare Nuclei', 'Bland Chromatin ', 'Normal Nucleoli', ' Mitoses', 'Class']
    # 读取数据
    data = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data",
                names=column)
    print(data)
    # 缺失值处理
    data = data.replace('?', np.nan)

    data = data.dropna()
    # 分割数据
    x_train, x_test, y_train, y_test = train_test_split(data[column[1:10]],data[column[10]], test_size=0.25)

    # 进行标准化处理
    std = StandardScaler()
    x_train = std.fit_transform(x_train)
    x_test = std.transform(x_test)

    # 逻辑回归预测
    lg = LogisticRegression(C=1.0)
    lg.fit(x_train, y_train)
    print(lg.coef_)
    y_predict = lg.predict(x_test)
    print("准确率: ", lg.score(x_test, y_test))
    print('召回率: ', classification_report(y_test, y_predict, labels=[2, 4], target_names=['良性', '恶性']))


    return None


if __name__ == "__main__":
    logistic()
eg

 无监督学习——K-means

sklearn.cluster.KMeans

 

轮廓系数[-1,1],趋势近于1代表内聚度和分离度都相对较优。( 外部距离最大,内部距离最小)

原文地址:https://www.cnblogs.com/-hao-/p/15442934.html