机器学习学习笔记(day02)

1.机器学习分类

监督学习:输入数据特征有标签(有标准答案),按照目标值离散还是连续又分为回归(目标值值连续 ),分类(目标值离散)

无监督学习:输入数据特征无标签值(无标准答案),聚类

2.数据集划分

机器学习一般将数据划分为两个部分:训练集、测试集

训练集:用来训练,构建模型

测试集:在模型检验的时候,评估模型的有效性

sklearn数据集划分API:sklearn.model.selection.train_test_split

sklearn数据集划分API介绍:

        sklearn.datasets:加载获取流行数据集

        datasets.load_*():读取小规模数据集,数据包含在datasets中

        datasets.fetch_*(data_home=None):获取大规模数据集,需要从网上下载,datahome表示数据集下载目录

获取数据集返回的类型:

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

        data:特征数据数组,类型是[n_samples*n_features]的二维numpy.ndarray数组

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

        DESCR:数据描述

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

        target_names:标签名

 数据集进行分割:sklearn.model.selection.train_test_split(*arrays,**options)

        x:数据集的特征值

        y:数据集的目标值

        test_size:测试集的大小,一般为float

        random_state:随机数种子,不同的种子会造成不同的随机采样结果,相同的种子结果相同

        return:训练集特征值(x_train),测试集特征值(x_test),训练集目标值(x_test),测试集目标值(y_test)

 3.转换器与估计器

转换器:fit_transform、fit、transform 的区别

机器学习学习笔记(day02)_第1张图片

 sklearn机器学习算法的实现——估计器(算法实现模型),一类实现了算法的API

        1.用于分类的估计器

                -sklearn.neighbors——KNN(k近邻算法)

                -sklearn.naive_bayes——贝叶斯

                -sklearn.linear_model.LogisticRegression——逻辑回归

                -sklearn.tree——决策树与随机森林

        2.用于回归的分类器

                -sklearn.linear_model.LinearRegression——线性回归

                -sklearn.linear_model.Ridge——岭回归

估计器的工作流程:

机器学习学习笔记(day02)_第2张图片

 4.分类算法-KNN(k-近邻算法)

定义:如果一个样本在特征空间中的k个最邻近(距离:详见李航统计学习方法)的样本大多属于某一个类别,则该样本也属于这个类别

API:sklearn.neighbors.KNeighborsClassifier(n_neighbor=5,algorithm='auto')

demo:

import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

def knncls():
    """
    KNN预测用户签到位置
    :return: None
    """
    #读取数据
    data = pd.read_csv("./train.csv")
    # print(data.head(10))

    #处理数据
    #1.缩小数据,查询数据筛选
    data = data.query("x>1.0 & x<1.25 &y>2.5 & y<2.75")

    #处理时间的数据,将时间戳转化为标准时间格式1970-01-01 18:09:40
    time_value = pd.to_datetime(data["time"],unit="s")
    # print(time_value)

    #把日期转换为字典格式,方便后边取出单独的值
    time_value = pd.DatetimeIndex(time_value)

    #构造一些特征,增加对预测结果有用的列数据
    data["day"] = time_value.day
    data["hour"] = time_value.hour
    data["weekday"] = time_value.weekday

    #把时间戳这个无用特征删除,删除一列
    data = data.drop(["time"],axis=1)
    # print(data)

    #把签到数量少于3个的数据删除,没有参考意义
    place_count = data.groupby("place_id").count()
    # print(place_count)
    tf = place_count[place_count.row_id>3].reset_index()
    # print(tf)
    # print(type(tf))     #
    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.fit_transform(x_test)

    #进行算法流程
    knn = KNeighborsClassifier()
    #模型
    knn.fit(x_train,y_train)
    #得出预测结果
    y_predict = knn.predict(x_test)
    print("预测的目标签到位置为:",y_predict)
    #评价模型,准确率,x_test传进去计算出预测值,与真实值y_test进行计算准确率
    knn_score = knn.score(x_test,y_test)
    print("KNN模型预测准确率为:",knn_score)

    return None
if __name__=="__main__":
    knncls()

运行结果:

KNN算法优缺点:

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

        缺点:懒惰算法,对测试样本分类的计算量大,内存开销答大;必须制定k值,k值的选择会影响分类结果

使用场景:小数据场景

作业:用KNN对鸢尾花数据集进行分类

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler,MinMaxScaler

# 实例化
data = load_iris()

#特征值,目标值
features = data.data
targets = data.target
# print(features)
# print(targets)

# 划分训练集与测试集
x_train, x_test, y_train, y_test = train_test_split(features, targets, test_size=0.25)

#特征工程
#标准化
# std = StandardScaler()
# x_train =std.fit_transform(x_train)
# x_test = std.fit_transform(x_test)
#归一化
# mm = MinMaxScaler()
# x_train = mm.fit_transform(x_train)
# x_test = mm.fit_transform(x_test)

#拟合模型
knn = KNeighborsClassifier()
knn.fit(x_train,y_train)
#得出预测结果
predict = knn.predict(x_test)
print("预测结果为:",predict)
#模型评价
score = knn.score(x_test,y_test)
print("模型准确率为:",score)

5.朴素贝叶斯

概率知识:

机器学习学习笔记(day02)_第3张图片

 原理:

机器学习学习笔记(day02)_第4张图片

机器学习学习笔记(day02)_第5张图片

例子:

 机器学习学习笔记(day02)_第6张图片

 引入拉普拉斯平滑:

机器学习学习笔记(day02)_第7张图片

 案例demo:

from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB

def naviebayes():
    """
    朴素贝叶斯对新闻类型进行分类
    :return:None
    """
    #导入数据
    news = fetch_20newsgroups(subset="all")
    #对数据集进行分割(参数分别是特征值,目标值,分割比例)
    x_train,x_test,y_train,y_test = train_test_split(news.data,news.target,test_size=0.25)
    #对数据集进行特征抽取
    tf = TfidfVectorizer()
    #以训练集当中的词的列表进行每篇文章的重要性统计
    x_train = tf.fit_transform(x_train)
    x_test = tf.transform(x_test)
    #进行朴素贝叶斯算法的分类,alpha是拉普拉斯平滑系数
    mlt = MultinomialNB(alpha=1.0)
    mlt.fit(x_train,y_train)
    y_predict  = mlt.predict(x_test)
    print("预测结果:",y_predict)
    print("得出准确率:",mlt.score(x_test,y_test))
    return None

if  __name__ == "__main__":
    naviebayes()

运行结果:

机器学习学习笔记(day02)_第8张图片

 朴素贝叶斯分类的优缺点:

        优点:基于古典数学理论,有稳定的分类效率;对缺失数据不太敏感,算法简单,常用于文本分类;分类准确度高,速度快

        缺点:由于使用了样本独立性假设,所以如果样本特征之间有关联时,效果不好

5.精确率与召回率

机器学习学习笔记(day02)_第9张图片

 其他分类标准:F1-score,反映了模型的稳健性

 分类模型评估API:sklearn.metrics.classification_report

机器学习学习笔记(day02)_第10张图片

 demo:

me = classification_report(y_test,y_predict,target_names=news.target_names)
    print("精确率与召回率:",me)

 6.模型的选择与调优(交叉验证、网格搜索)

交叉验证: 将拿到训练数据,分为训练和验证集(与测试集没有关系),交叉建模得出每一个模型的准确率,取所有模型的准确率平均值,如下图所示:

机器学习学习笔记(day02)_第11张图片

交叉验证目的:为了让评估模型更加准确可靠

网格搜索(超参数搜索):通常情况下,有很多参数需要手动指定的(如KNN中的k值),这种叫超参数。所以需要对模型预设集几种超参数组合,每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。

网格搜索(超参数搜索)API:sklearn.model_selection.GridSearchCV

机器学习学习笔记(day02)_第12张图片

 demo:

import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split,GridSearchCV
from sklearn.preprocessing import StandardScaler


def knncls():
    """
    KNN预测用户签到位置
    :return: None
    """
    # 读取数据
    data = pd.read_csv("./train.csv")
    # print(data.head(10))

    # 处理数据
    # 1.缩小数据,查询数据筛选
    data = data.query("x>1.0 & x<1.25 &y>2.5 & y<2.75")

    # 处理时间的数据,将时间戳转化为标准时间格式1970-01-01 18:09:40
    time_value = pd.to_datetime(data["time"], unit="s")
    # print(time_value)

    # 把日期转换为字典格式,方便后边取出单独的值
    time_value = pd.DatetimeIndex(time_value)

    # 构造一些特征,增加对预测结果有用的列数据
    data["day"] = time_value.day
    data["hour"] = time_value.hour
    data["weekday"] = time_value.weekday

    # 把时间戳这个无用特征删除,删除一列
    data = data.drop(["time"], axis=1)
    # print(data)

    # 把签到数量少于3个的数据删除,没有参考意义
    place_count = data.groupby("place_id").count()
    # print(place_count)
    tf = place_count[place_count.row_id > 3].reset_index()
    # print(tf)
    # print(type(tf))     #
    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.fit_transform(x_test)

    # 进行算法流程
    knn = KNeighborsClassifier()
    
    # # 模型
    # knn.fit(x_train, y_train)
    # # 得出预测结果
    # y_predict = knn.predict(x_test)
    # print("预测的目标签到位置为:", y_predict)
    # # 评价模型,准确率,x_test传进去计算出预测值,与真实值y_test进行计算准确率
    # knn_score = knn.score(x_test, y_test)
    # print("KNN模型预测准确率为:", knn_score)


    #构造一些参数的值进行搜索
    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


if __name__ == "__main__":
    knncls()

7.分类算法-决策树

信息熵:信息熵越大 ,不确定性越大(信息和消除不确定性是相联系的)(表示信息的不确定性大小)

机器学习学习笔记(day02)_第13张图片

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

机器学习学习笔记(day02)_第14张图片

机器学习学习笔记(day02)_第15张图片

 用案例计算信息增益:

机器学习学习笔记(day02)_第16张图片

 其他划分方法:

机器学习学习笔记(day02)_第17张图片

 sklearn决策树API:

机器学习学习笔记(day02)_第18张图片

泰坦尼克号幸存者预测demo:

# coding:utf-8
 
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import DecisionTreeClassifier, export_graphviz
import pandas as pd
 
 
def decision():
    # 获取数据
    titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
    # 处理数据,找出特征值和目标值
    x = titan[['pclass', 'age', 'sex']]
    y = titan['survived']
    print(x)
    # 缺失值处理
    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编码
    dic = DictVectorizer(sparse=False)
    x_train = dic.fit_transform(x_train.to_dict(orient="records"))
    print(dic.get_feature_names())
    x_test = dic.transform(x_test.to_dict(orient="records"))
    # print(x_train)
    # 用决策树进行预测
    dec = DecisionTreeClassifier(max_depth=5)
    dec.fit(x_train, y_train)
    # 预测准确率
    print("预测的准确率:", dec.score(x_test, y_test))
    # 导出决策树的结构
    export_graphviz(dec, out_file="./tree.dot", feature_names=['年龄', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', 'sex=男性', 'sex=女性'])
 
 
def main():
    decision()
 
 
if __name__ == '__main__':
    main()

运行结果:

     pclass      age     sex
0       1st  29.0000  female
1       1st   2.0000  female
2       1st  30.0000    male
3       1st  25.0000  female
4       1st   0.9167    male
...     ...      ...     ...
1308    3rd      NaN    male
1309    3rd      NaN    male
1310    3rd      NaN    male
1311    3rd      NaN  female
1312    3rd      NaN    male
 
[1313 rows x 3 columns]
['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', 'sex=female', 'sex=male']
预测的准确率: 0.8115501519756839

决策树的结构和导出为图片:     

        1、sklean.tree.export_graphviz()该函数能够导出DOT格式

        tree.export_graphic(estimator,out_file='tree.dot',feature_names=['',''])

        2、工具:(能够将dot文件转换为pdf、png)

        安装graphviz

        ubuntu:sudo apt-get install graphviz Mac:brew install graphviz

        3、运行命令

        然后我们运行这个命令

        $ dot -Tpng tree.dot -o tree.png

 决策树的优缺点以及改进

        ● 优点:

            ● 简单的理解和解释,树木可视化。

            ● 需要很少的数据准备,其他技术通常需要数据归一化
        ● 缺点:

            ● 决策树学习者可能创建不能很好地推广数据的过于复杂的树,这被称为过拟合

        ● 改进:

            ● 减枝cart算法(决策树API当中以及实现,随机森林参数调优有相关介绍)

            ● 随机森林

        注:企业重要决策,由于决策树很好的分析能力,在决策过程中应用较多。

 8.集成学习方法-随机森林

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

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

建立算法:

        根据下列算法而建造每棵树:

        ● 用N来表示训练用例(样本)的个数,M表示特征数目。

        ● 一次随机选出一个样本,重复N次(有可能出现重复的样本)

        ● 随机去选出m个特征,m << M,建立决策树

        ● 采取bootstrap(随机有放回)抽样

        ● 为什么要随机抽样训练集?

        如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的。

        ● 为什么要有放回地抽样?

        如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当前这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。

 随机森林API:

        ● class         sklearn.ensemble.RandomForestClassifier(n_estimators=10,criterion='gini',max_depth=None,bootstrap=None,random_state=None)

        ● 随机森林分类器

        ● n_estimators:integer,optional(default=10)森林里的树木数量120,200,300,500,800,1200

        ● criteria:string,可选(default='gini')分割特征的测量方法

        ● max_depth:integer或None,可选(默认=无)树的最大深度5,8,15,25,30

        ● max_feature="auto",每个决策树的最大特征数量

        ● -If "auto", then `max_feature=sqrt(n_features)`.

           -If "sqrt", then `max_features=sqrt(n_features)` (same as "auto").

           -If "log2", then `max_features=log2(n_features)`.

           -If None, then `max_features=n_features`.

        ● bootstrap:boolean,optional(default = True)是否在构建树时使用放回抽样

 随机森林预测泰坦尼克号幸存者demo:

# coding:utf-8
 
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.feature_extraction import DictVectorizer
from sklearn.ensemble import RandomForestClassifier
import pandas as pd
 
 
def decision():
    # 获取数据
    titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
    # 处理数据,找出特征值和目标值
    x = titan[['pclass', 'age', 'sex']]
    y = titan['survived']
    print(x)
    # 缺失值处理
    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编码
    dic = DictVectorizer(sparse=False)
    x_train = dic.fit_transform(x_train.to_dict(orient="records"))
    print(dic.get_feature_names())
    x_test = dic.transform(x_test.to_dict(orient="records"))
    # 随机森林进行预测(超参数调优)
    rf = RandomForestClassifier()
    param = {"n_estimators": [120, 200, 300, 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_)
 

 
if __name__ == '__main__':
    decision()

运行结果:

     pclass      age     sex
0       1st  29.0000  female
1       1st   2.0000  female
2       1st  30.0000    male
3       1st  25.0000  female
4       1st   0.9167    male
...     ...      ...     ...
1308    3rd      NaN    male
1309    3rd      NaN    male
1310    3rd      NaN    male
1311    3rd      NaN  female
1312    3rd      NaN    male
 
[1313 rows x 3 columns]
['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', 'sex=female', 'sex=male']
准确率: 0.8237082066869301
查看或选择的参数模型: {'max_depth': 5, 'n_estimators': 1200}

 随机森林的优点:

        ● 在当前所有算法中,具有极好的准确率

        ● 能够有效地运行在大数据集上

        ● 能够处理具有高维特征的输入样本,而且不需要降维

        ● 能够评估各个特征在分类问题上的重要性

你可能感兴趣的:(数据分析与挖掘,python,机器学习,sklearn)