热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

机器学习基础一站通

机器学习基础一站通-目录一.流程总览(本文主要是红框部分)二.特征处理部分1.总体概述 1.1一些常见问题2.具体处理(具体顺序看上面红框)2.1缺失值处理(删or填)

目录

一.流程总览(本文主要是红框部分)

二.特征处理部分

1.总体概述

 1.1一些常见问题

2.具体处理(具体顺序看上面红框)

2.1缺失值处理(删or填)

2.2数据格式处理(数据集划分,时间格式等)

2.3数据采样(过采样or下采样,不均衡时候用)

2.4数据预处理(把原数据 转更好用形式→标准,归一,二值)

2.5 特征提取(把文字转为可以用的→字典,中英文,DNA,TF)

2.6 降维(过滤(低方差,相关系数),PCA)

2.7 特征工程实例:泰坦尼克号生存可能性分析

三.常用SKlearn算法

1.咋判断用啥算法

2.具体算法与其代码

2.1分类方法(KNN,逻辑回归,RF,朴素贝叶斯,SVM)

2.2 回归方法(KNN,岭回归)

2.3 聚类方法(K-means)

四.评估

参考该文章

五.调优

1.先试试数据与预处理

2.然后才是选择模型,调模型参数

2.1网格搜索(grid search)

2.2随机寻优方法(随机试试)

2.3贝叶斯优化方法

2.4基于梯度的优化方法

2.5遗传算法(进化寻优)

六.一些实例

1.案例:预测facebook签到位置

2.案例:20类新闻分类

3.案例:波士顿房价预测

4.案例:癌症分类预测-良/恶性乳腺癌肿瘤预测

七.模型的保存与加载


一.流程总览(本文主要是红框部分)

二.特征处理部分

 简介:本节主要内容来自
【特征工程】呕心之作——深度了解特征工程_wx:wu805686220-CSDN博客

特征工程介绍_远方-CSDN博客

1.总体概述

 1.1一些常见问题

(1)存在缺失值:缺失值需要补充( .dropna等)
(2)不属于同一量纲:即特征的规格不一样,不能够放在一起比较 (标准化)
(3)信息冗余:某些定量特征,区间划分> 如学习成绩,若只关心“及格”或不“及格”,那么将考分,转换成“1”和“0” 表示及格和未及格 (where >60..)
(4)定性特征不能直接使用:需要将定性特征转换为定量特征(如one-hot,TF等)
(5)信息利用率低:不同的机器学习

算法和模型对数据中信息的利用是不同的,选个合适的模型

2.具体处理(具体顺序看上面红框)

2.1缺失值处理(删or填)

1)缺失值删除(dropna)

2)缺失值填充(fillna):比较常用,一般用均值or众数
①用固定值填充

对于特征值缺失的一种常见的方法就是可以用固定值来填充,例如0,-99, 如下面对这一列缺失值全部填充为-99

data['第一列'] = data['第一列'].fillna('-99')

②用均值填充

对于数值型的特征,其缺失值也可以用未缺失数据的均值填充,下面对灰度分这个特征缺失值进行均值填充

data['第一列'] = data['第一列'].fillna(data['第一列'].mean()))

③用众数填充

与均值类似,可以用众数来填充缺失值

data['第一列'] = data['第一列'].fillna(data['第一列'].mode()))

 其他填充如插值,KNN,RF详见原博客

2.2数据格式处理(数据集划分,时间格式等)

1)数据集的划分

        一般的数据集会划分为两个部分:

  • 训练数据:用于训练,构建模型
  • 测试数据:在模型检验时使用,用于评估模型是否有效
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

def datasets_demo():

    # 获取数据集
    iris = load_iris()
    print("鸢尾花数据集:\n", iris)
    print("查看数据集描述:\n", iris["DESCR"])
    print("查看特征值的名字:\n", iris.feature_names)
    print("查看特征值:\n", iris.data, iris.data.shape)  # 150个样本

    # 数据集划分  X为特征 Y为标签 
    """random_state随机数种子,不同的种子会造成不同的随机采样结果"""
    x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)

    return None

if __name__ == "__main__":
    datasets_demo()

2)时间格式的处理(主要是转换成年月日or星期几,然后找自己要的)

        详见https://blog.csdn.net/kobeyu652453/article/details/108894807

# 处理时间数据
import datetime

# 分别得到年,月,日
years = features['year']
mOnths= features['month']
days = features['day']

# datetime格式
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]
dates[:5]

                           

3)表格操作,合并连接or取特征啥的

        详见NP,PD教程

2.3数据采样(过采样or下采样,不均衡时候用)

        →多的类别过采样/少的类别欠采样,来平衡分布。例:信用卡诈骗,骗子的数据太少了,这个时候用

def over_sample( y_origin, threshold):
    y = to_one_hot(y_origin, NUM_LABELS)
    y_counts = np.sum(y, axis=0)
    sample_ratio = threshold / y_counts * y
    sample_ratio = np.max(sample_ratio, axis=1)
    sample_ratio = np.maximum(sample_ratio, 1)
 
    index = ratio_sample(sample_ratio)
    # x_token_train = [x_token_train[i] for i in index]
 
    return y_origin[index]


def ratio_sample(ratio):
    sample_times = np.floor(ratio).astype(int)
 
    # random sample ratio <1 (decimal part)
    sample_ratio = ratio - sample_times
    random = np.random.uniform(size=sample_ratio.shape)
    index = np.where(sample_ratio > random)
    index = index[0].tolist()
 
    # over sample fixed integer times
    row_num = sample_times.shape[0]
    for row_index, times in zip(range(row_num), sample_times):
        index.extend(itertools.repeat(row_index, times))
 
    return index

2.4数据预处理(把原数据 转更好用形式→标准,归一,二值)

主要转换方式有以下几种(常用的 前四个):

1)标准化(很常用)

用在:特征之间数据差距特别大(比如存款金额与银行周围小区数,不在一个量级)

from sklearn.preprocessing import StandardScaler
#标准化,返回值为标准化后的数据
StandardScaler().fit_transform(iris.data)

2)归一化

含义:样本向量在点乘运算或其他核函数计算相似性时,转化为“单位向量”。

什么情况下(不)需要归一化:

  • 需要: 基于参数的模型或基于距离的模型,都是要进行特征的归一化。
  • 不需要:基于树的方法是不需要进行特征的归一化,例如随机森林,bagging 和 boosting等
from sklearn.preprocessing import Normalizer
#归一化,返回值为归一化后的数据
Normalizer().fit_transform(iris.data)

3)二值化(>60分及格,标为1)

用where或者Binarizer

from sklearn.preprocessing import Binarizer
 #二值化,阈值设置为3,返回值为二值化后的数据
Binarizer(threshold=3).fit_transform(iris.data)

其他:区间放缩,等距离散啥的,看看原文

2.5 特征提取(把文字转为可以用的→字典,中英文,DNA,TF)

1)字典特征提取:(字典转矩阵)

from sklearn.feature_extraction import DictVectorizer

def dict_demo():

    data = [{'city':'北京', 'temperature':100},
            {'city':'上海', 'temperature':60},
            {'city':'深圳', 'temperature':30}]

    # 1、实例化一个转换器类
    #transfer = DictVectorizer() # 返回sparse矩阵
    transfer = DictVectorizer(sparse=False)

    # 2、调用fit_transform()
    data_new = transfer.fit_transform(data)
    print("data_new:\n", data_new)   # 转化后的
    print("特征名字:\n", transfer.get_feature_names())

    return None

if __name__ == "__main__":
    dict_demo()

结果:

data_new:
 [[  0.   1.   0. 100.]
 [  1.   0.   0.  60.]
 [  0.   0.   1.  30.]]
 特征名字:
 ['city=上海', 'city=北京', 'city=深圳', 'temperature']

2)文本特征提取(文本转矩阵)

应用 1.中英文分词,然后转矩阵  2.DNAseqs处理,词袋模型


2.1)英文文本分词

from sklearn.feature_extraction.text import CountVectorizer

def count_demo():

    data = ['life is short,i like like python',
            'life is too long,i dislike python']

    # 1、实例化一个转换器类
    transfer = CountVectorizer()
    #这里还有一个stop_word(),就是 到哪个词停下来
    transfer1 = CountVectorizer(stop_words=['is', 'too'])

    # 2、调用fit_transform
    data_new = transfer.fit_transform(data)
    print("data_new:\n", data_new.toarray())  # toarray转换为二维数组
    print("特征名字:\n", transfer.get_feature_names())

    return None


if __name__ == "__main__":
    count_demo()

结果

data_new:
 [[0 1 1 2 0 1 1 0]
 [1 1 1 0 1 1 0 1]]
特征名字:
 ['dislike', 'is', 'life', 'like', 'long', 'python', 'short', 'too']

2.2)中文分词

from sklearn.feature_extraction.text import CountVectorizer
import jieba


def count_chinese_demo2():
 
    data = ['一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。',
            '我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。',
            '如果只用一种方式了解某件事物,他就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。']

    data_new = []
    for sent in data:
        data_new.append(cut_word(sent))
    print(data_new)

    1、实例化一个转换器类(叫人
    transfer = CountVectorizer()

    2、调用fit_transform(干活
    data_final = transfer.fit_transform(data_new)
    print("data_final:\n", data_final.toarray())
    print("特征名字:\n", transfer.get_feature_names())

    return None


def cut_word(text):
    """
    进行中文分词:“我爱北京天安门” -> "我 爱  北京 天安门"
    """
    return ' '.join(jieba.cut(text))


if __name__ == "__main__":
    count_chinese_demo2()
    #print(cut_word('我爱北京天安门'))

2.3) Tf-idf文本特征提取:找重要的词,并转为矩阵

from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
import jieba

def tfidf_demo():
    """
    用TF-IDF的方法进行文本特征抽取
    """
    data = ['一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。',
            '我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。',
            '如果只用一种方式了解某件事物,他就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。']

    data_new = []
    for sent in data:
        data_new.append(cut_word(sent))
    print(data_new)

    1、实例化一个转换器类
    transfer = TfidfVectorizer()

    2、调用fit_transform
    data_final = transfer.fit_transform(data_new)
    print("data_final:\n", data_final.toarray())
    print("特征名字:\n", transfer.get_feature_names())
    return None


def cut_word(text):
    """
    进行中文分词:“我爱北京天安门” -> "我 爱  北京 天安门"
    """
    return ' '.join(jieba.cut(text))



if __name__ == "__main__":
    tfidf_demo()
    #print(cut_word('我爱北京天安门'))

结果:

['一种 还是 一种 今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。', '我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。', '如果 只用 一种 方式 了解 某件事 物 , 他 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。']
data_final:
 [[0.30847454 0.         0.20280347 0.         0.         0.
  0.40560694 0.         0.         0.         0.         0.
  0.20280347 0.         0.20280347 0.         0.         0.
  0.         0.20280347 0.20280347 0.         0.40560694 0.
  0.20280347 0.         0.40560694 0.20280347 0.         0.
  0.         0.20280347 0.20280347 0.         0.         0.20280347
  0.        ]
 [0.         0.         0.         0.2410822  0.         0.
  0.         0.2410822  0.2410822  0.2410822  0.         0.
  0.         0.         0.         0.         0.         0.2410822
  0.55004769 0.         0.         0.         0.         0.2410822
  0.         0.         0.         0.         0.48216441 0.
  0.         0.         0.         0.         0.2410822  0.
  0.2410822 ]
 [0.12826533 0.16865349 0.         0.         0.67461397 0.33730698
  0.         0.         0.         0.         0.16865349 0.16865349
  0.         0.16865349 0.         0.16865349 0.16865349 0.
  0.12826533 0.         0.         0.16865349 0.         0.
  0.         0.16865349 0.         0.         0.         0.33730698
  0.16865349 0.         0.         0.16865349 0.         0.
  0.        ]]

特征名字:
['一种', '不会', '不要', '之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '取决于', '只用', '后天', '含义', '大部分', '如何', '如果', '宇宙', '我们', '所以', '放弃', '方式', '明天', '星系', '晚上', '某件事', '残酷', '每个', '看到', '真正', '秘密', '绝对', '美好', '联系', '过去', '还是', '这样']

2.4)DNAseqs处理

1.先把seqs数据切开,6个碱基一组

def Kmers_funct(seq, size=6):
    return [seq[x:x+size] for x in range(len(seq) - size + 1)]

2.再用CountVectorizer
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(ngram_range=(4,4))
X = cv.fit_transform(textsList)

3.转换完,丢去训练

2.6 降维(过滤(低方差,相关系数),PCA)

啥意思:降低随机变量(特征)个数,得到一组主变量的过程(就是减少训练的列数)


1) 特征选择(从原特征中找出重要的特征→人与狗的差别:皮肤,身高等)

第一种:低方差过滤(丢掉不重要的

from sklearn.feature_selection import VarianceThreshold


def variance_demo():
    """
    低方差特征过滤
    """

    # 1、获取数据
    data = pd.read_csv('factor_returns.csv')
    print('data:\n', data)
    data = data.iloc[:,1:-2]
    print('data:\n', data)

    # 2、实例化一个转换器类
    #transform = VarianceThreshold()
    transform = VarianceThreshold(threshold=10)

    # 3、调用fit_transform
    data_new = transform.fit_transform(data)
    print("data_new\n", data_new, data_new.shape)

    return None

if __name__ == "__main__":
    variance_demo()

第二种:相关系数(也是丢掉不重要的,不过用相关系数来判断)

from sklearn.feature_selection import VarianceThreshold
from scipy.stats import pearsonr

def variance_demo():
    """
    低方差特征过滤 相关系数
    """

    # 1、获取数据
    data = pd.read_csv('factor_returns.csv')
    print('data:\n', data)
    data = data.iloc[:,1:-2]
    print('data:\n', data)

    # 2、实例化一个转换器类
    transform = VarianceThreshold()
    transform1 = VarianceThreshold(threshold=10)

    # 3、调用fit_transform
    data_new = transform.fit_transform(data)
    print("data_new\n", data_new, data_new.shape)

    # 计算两个变量之间的相关系数
    r = pearsonr(data["pe_ratio"],data["pb_ratio"])
    print("相关系数:\n", r)
    return None


if __name__ == "__main__":
    variance_demo()

2)PCA

主要注意n_compnents:小数→表示保留百分之多少的信息,整数→减少到多少特征

from sklearn.decomposition import PCA

def pca_demo():
    """
    PCA降维
    """

    data = [[2,8,4,5], [6,3,0,8], [5,4,9,1]]

    # 1、实例化一个转换器类
    transform = PCA(n_compOnents=2)  # 4个特征降到2个特征

    # 2、调用fit_transform
    data_new = transform.fit_transform(data)
    print("data_new\n", data_new)

    transform2 = PCA(n_compOnents=0.95)  # 保留95%的信息

    data_new2 = transform2.fit_transform(data)
    print("data_new2\n", data_new2)

    return None

if __name__ == "__main__":
    pca_demo()

2.7 特征工程实例:泰坦尼克号生存可能性分析

上述部分我自己比较常用的(本人比较菜),具体别的方法可以看看原文

下面为案例代码

import pandas as pd

1、获取数据
path = "C:/DataSets/titanic.csv"
titanic = pd.read_csv(path) #1313 rows × 11 columns

# 筛选特征值和目标值
x = titanic[["pclass", "age", "sex"]]
y = titanic["survived"]

2、数据处理
# 1)缺失值处理
x["age"].fillna(x["age"].mean(), inplace=True)

# 2)转换成字典
x = x.to_dict(orient="records")


3、数据集划分
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)


4、对x_train,test 字典特征抽取
from sklearn.feature_extraction import DictVectorizer
transfer = DictVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)


5.决策树预估器
from sklearn.tree import DecisionTreeClassifier, export_graphviz
estimator = DecisionTreeClassifier(criterion='entropy')
estimator.fit(x_train, y_train)

6.模型评估
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接必读真实值和预测值:\n", y_test == y_predict)  # 直接比对

# 方法2:计算准确率
score = estimator.score(x_test, y_test)  # 测试集的特征值,测试集的目标值
print("准确率:", score)

# 可视化决策树(非必要)
export_graphviz(estimator, out_file='titanic_tree.dot', feature_names=transfer.get_feature_names())

import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
plot_tree(decision_tree=estimator)
plt.show()

三.常用SKlearn算法

本文主要内容来自 机器学习种9种常用算法_不凡De老五-CSDN博客_机器学习常用算法

1.咋判断用啥算法

2.具体算法与其代码

基本都是四步走:导包(from...),建模(knn=...),训练与预测(.fit() .predict())

2.1分类方法(KNN,逻辑回归,RF,朴素贝叶斯,SVM)

        2.1.1 KNN(回归,分类都可以用)

简介:
      k近邻分类(KNN)算法。是从训练集中找到和新数据最接近的k条记录,然后根据他们的主要分类来决定新数据的类别。
        该算法涉及3个要点:训练集、距离或相似的衡量、k的大小。

优点:适合多分类问题

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

适合对稀有事件进行分类(例如当流失率很低时,比如低于0.5%,构造流失预测模型)

特别适合于多分类问题(对象具有多个类别标签),例如根据基因特征来判断其功能分类,kNN比SVM的表现要好

缺点:内存开销大,比较慢

懒惰算法,对测试样本分类时的计算量大,内存开销大,评分慢

可解释性较差,无法给出决策树那样的规则。

实现代码:

1.导入:

分类问题:
from sklearn.neighbors import KNeighborsClassifier
回归问题:
from sklearn.neighbors import KNeighborsRegressor

2.创建模型
KNC = KNeighborsClassifier(n_neighbors=5)
KNR = KNeighborsRegressor(n_neighbors=3)

3.训练
KNC.fit(X_train,y_train)
KNR.fit(X_train,y_train)

4.预测
y_pre = KNC.predict(x_test)
y_pre = KNR.predict(x_test)

2.1.2逻辑回归(logiscic):

简介:可以看成更准的线性回归

利用Logistics回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。这里的“回归” 一词源于最佳拟合,表示要找到最佳拟合参数集。

训练分类器时的做法就是寻找最佳拟合参数,使用的是最优化算法。接下来介绍这个二值型输出分类器的数学原理

代码:

1.导入
from sklearn.linear_model import LogisticRegression

2.创建模型
logistic = LogisticRegression(solver='lbfgs')

注:solver参数的选择:
“liblinear”:小数量级的数据集    <5~10k
“lbfgs”, “sag” or “newton-cg”:大数量级的数据集以及多分类问题 <30k
“sag”:极大的数据集 >30k


3.训练
logistic.fit(x_train,y_train)

4.预测
y_pre = logistic.predict(x_train,y_train)

2.1.3随机森林(很常用)

    from sklearn.datasets import load_iris
    from sklearn.ensemble import RandomForestClassifier
    import pandas as pd
    import numpy as np
     
    iris = load_iris()
    df = pd.DataFrame(iris.data, columns=iris.feature_names)
    df['is_train'] = np.random.uniform(0, 1, len(df)) <= .75
    df['species'] = pd.Factor(iris.target, iris.target_names)
    df.head()
     
    train, test = df[df['is_train']==True], df[df['is_train']==False]
     
    features = df.columns[:4]
    clf = RandomForestClassifier(n_jobs=2)
    y, _ = pd.factorize(train['species'])
    clf.fit(train[features], y)
     
    preds = iris.target_names[clf.predict(test[features])]
    pd.crosstab(test['species'], preds, rownames=['actual'], colnames=['preds'])

简版:

# 导入算法
from sklearn.ensemble import RandomForestRegressor

# 建模
rf = RandomForestRegressor(n_estimators= 1000, random_state=42)

# 训练
rf.fit(train_features, train_labels)

# 预测
y_pre=rf.predict(test_features)

2.1.4朴素贝叶斯

简介:朴素贝叶斯,就是变量相互独立情况下的贝叶斯,不要被名字唬住了

  • 1、高斯(正态)分布朴素贝叶斯

  • 用于一般分类问题

  • 使用:

    1.导入
    from sklearn.naive_bayes import GaussianNB
    
    2.创建模型
    gNB = GaussianNB()
    
    3.训练
    gNB.fit(data,target)
    
    4.预测
    y_pre = gNB.predict(x_test)

    2、多项式分布朴素贝叶斯(还有一个伯努利分布。和这个类似,小数量时候用)

    • 适用于文本数据(特征表示的是次数,例如某个词语的出现次数)
    • DNA序列作为特征时候可以用(其实也是文本,只不过是AGCT)
    • 常用于多分类问题
  • 使用

    1.导入
    from sklearn.naive_bayes import MultinomialNB
    
    2.创建模型
    mNB = MultinomialNB()
    
    3.字符集转换为词频
    from sklearn.feature_extraction.text import TfidfVectorizer
    
    #先构建Tf对象(啥是Tf上面有讲)
    tf = TfidfVectorizer()
    #使用要转换的数据集和标签集对tf对象进行训练
    tf.fit(X_train,y_train)
    #文本集 ---->  词频集
    X_train_tf = tf.transform(X_train)
    
    4.使用词频集对机器学习模型进行训练
    mNB.fit(X_train_tf,y_train)
    
    5.预测
    
    #将字符集转化为词频集
    x_test = tf.transform(test_str)
    
    #预测
    mNB.predict(x_test)
    
    

        2.1.5支持向量机SVM

简介:SVM的思路是找到离超平面的最近点,通过其约束条件求出最优解。

使用

1.导入
处理分类问题:
from sklearn.svm import SVC
处理回归问题:
from sklearn.svm import SVR

2.创建模型(回归时使用SVR)
svc = SVC(kernel='linear')
svc = SVC(kernel='rbf')
svc = SVC(kernel='poly')

3.训练
svc_linear.fit(X_train,y_train)
svc_rbf.fit(X_train,y_train)
svc_poly.fit(X_train,y_train)

4.预测
linear_y_ = svc_linear.predict(x_test)
rbf_y_ = svc_rbf.predict(x_test)
poly_y_ = svc_poly.predict(x_test)

2.2 回归方法(KNN,岭回归)

2.2.1KNN(同上)

2.2.2岭回归(ridge)

简介:就是改良的最小二乘法配上线性回归,一定程度避免过拟合与欠拟合

#1.导入
from sklearn.linear_model import Ridge

#2.创建模型
# alpha就是缩减系数lambda,可以自己二分法试试效果
# 如果把alpha设置为0,就是普通线性回归
ridge = Ridge(alpha=0)

#3.训练
ridge.fit(data,target)

#4.预测
target_pre = ridge.predict(target_test)

2.2.3lasso回归

2.2.4RF(同上)

2.2.5支持向量机SVM(同上)

2.3 聚类方法(K-means)

K均值算法(K-means) (无监督学习)

原理

  • 聚类的概念:一种无监督的学习,事先不知道类别,自动将相似的对象归到同一个簇中。
  • K-Means算法是一种聚类分析(cluster analysis)的算法,其主要是来计算数据聚集的算法,主要通过不断地取离种子点最近均值的算法。

代码:

1.导入
from sklearn.cluster import KMeans

2.创建模型
# 构建机器学习对象kemans,指定要分类的个数
kmean = KMeans(n_clusters=2)

3.训练数据
# 注意:聚类算法是没有y_train的
kmean.fit(X_train)

4.预测数据
y_pre = kmean.predict(X_train)

四.评估

参考该文章

机器学习训练建模、集成模型、模型评估等代码总结(2019.05.21更新)_呆萌的代Ma-CSDN博客

五.调优

1.先试试数据与预处理

优先在数据本身和预处理,特征工程方面下功夫(选更鲜明的特征,数据够干净,压缩程度等)

2.然后才是选择模型,调模型参数

2.1网格搜索(grid search)

        简介:Grid search 是一种暴力的调参方法,通过遍历所有可能的参数值以获取所有所有参数组合中最优的参数组合。(就是一个个参数试)

 代码:

#y = data['diagnosis']
#x = data.drop(['id','diagnosis','Unnamed: 32'],axis =1)

from sklearn.model_selection import train_test_split,GridSearchCV
#from sklearn.pipeline import Pipeline
#from sklearn.linear_model import LogisticRegression
#from sklearn.preprocessing import StandardScaler

#train_X,val_X,train_y,val_y = train_test_split(x,y,test_size=0.2,random_state=1)
pipe_lr = Pipeline([('scl',StandardScaler()),('clf',LogisticRegression(random_state=0))])

param_range=[0.0001,0.001,0.01,0.1,1,10,100,1000] 要试啥数字
param_penalty=['l1','l2']
param_grid=[{'clf__C':param_range,'clf__penalty':param_penalty}]

gs = GridSearchCV(estimator=pipe_lr,
                 param_grid=param_grid,
                 scoring='f1',
                 cv=10,
                 n_jobs=-1)
gs = gs.fit(train_X,train_y)

print(gs.best_score_)
print(gs.best_params_)

2.2随机寻优方法(随机试试)

代码:

from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestRegressor
iris = load_iris()
rf = RandomForestRegressor(random_state = 42)
from sklearn.model_selection import RandomizedSearchCV
random_grid = {'n_estimators': n_estimators,
               'max_features': max_features,
               'max_depth': max_depth,
               'min_samples_split': min_samples_split,
               'min_samples_leaf': min_samples_leaf,
               'bootstrap': bootstrap}
rf_random = RandomizedSearchCV(estimator = rf, param_distributiOns= random_grid, n_iter = 100, cv = 3, verbose=2, random_state=42, n_jobs = -1)# Fit the random search model

rf_random.fit(X,y)

#print the best score throughout the grid search
print rf_random.best_score_
#print the best parameter used for the highest score of the model.
print rf_random.best_param_

下面三种没有固定代码,得看具体项目需要

2.3贝叶斯优化方法

2.4基于梯度的优化方法

2.5遗传算法(进化寻优)

六.一些实例

1.案例:预测facebook签到位置


流程分析:
1)获取数据
2)数据处理
目的:

  • 特征值 x:2
  • 目标值y:1.0
  • time -> 年与日时分秒
  • 过滤签到次数少的地点
    3)特征工程:标准化
    4)KNN算法预估流程
    5)模型选择与调优
    6)模型评估
    import pandas as pd
    # 1、获取数据
    data = pd.read_csv("./FBlocation/train.csv") #29118021 rows × 6 columns
    
    # 2、基本的数据处理
    # 1)缩小数据范围
    data = data.query("x<2.5 & x>2 & y<1.5 & y>1.0") #83197 rows × 6 columns
    # 2)处理时间特征
    time_value = pd.to_datetime(data["time"], unit="s") #Name: time, Length: 83197
    date = pd.DatetimeIndex(time_value)
    data["day"] = date.day
    data["weekday"] = date.weekday
    data["hour"] = date.hour
    data.head() #83197 rows × 9 columns
    # 3)过滤签到次数少的地点
    place_count = data.groupby("place_id").count()["row_id"]  #2514 rows × 8 columns
    place_count[place_count > 3].head()
    data_final = data[data["place_id"].isin(place_count[place_count>3].index.values)]
    data_final.head() #80910 rows × 9 columns
    
    # 筛选特征值和目标值
    x = data_final[["x", "y", "accuracy", "day", "weekday", "hour"]]
    y = data_final["place_id"]
    
    # 数据集划分
    from sklearn.model_selection import train_test_split
    x_train, x_test, y_train, y_test = train_test_split(x, y)
    
    from sklearn.preprocessing import StandardScaler
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.model_selection import GridSearchCV
    
    # 3、特征工程:标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)  # 训练集标准化
    x_test = transfer.transform(x_test)        # 测试集标准化
    
    # 4、KNN算法预估器
    estimator = KNeighborsClassifier()
    # 加入网格搜索与交叉验证
    # 参数准备
    param_dict = {"n_neighbors": [3,5,7,9]}
    estimator = GridSearchCV(estimator, param_grid=param_dict, cv=5)  # 10折,数据量不大,可以多折
    
    estimator.fit(x_train, y_train)
    
    # 5、模型评估
    # 方法1:直接比对真实值和预测值
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("直接必读真实值和预测值:\n", y_test == y_predict)  # 直接比对
    
    # 方法2:计算准确率
    score = estimator.score(x_test, y_test)  # 测试集的特征值,测试集的目标值
    print("准确率:", score)
    
    # 查看最佳参数:best_params_
    print("最佳参数:", estimator.best_params_)
    # 最佳结果:best_score_
    print("最佳结果:", estimator.best_score_)
    # 最佳估计器:best_estimator_
    print("最佳估计器:", estimator.best_estimator_)
    # 交叉验证结果:cv_results_
    print("交叉验证结果:", estimator.cv_results_)
    

    2.案例:20类新闻分类

    1 步骤分析
    1)获取数据
    2)划分数据集
    3)特征工程:文本特征抽取
    4)朴素贝叶斯预估器流程
    5)模型评估

       2 具体代码

from sklearn.model_selection import train_test_split    # 划分数据集
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer  # 文本特征抽取
from sklearn.naive_bayes import MultinomialNB           # 朴素贝叶斯


def nb_news():
    """
    用朴素贝叶斯算法对新闻进行分类
    :return:
    """
    # 1)获取数据
    news = fetch_20newsgroups(subset='all')

    # 2)划分数据集
    x_train, x_test, y_train, y_test = train_test_split(news.data, news.target)

    # 3)特征工程:文本特征抽取
    transfer = TfidfVectorizer()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 4)朴素贝叶斯算法预估器流程
    estimator = MultinomialNB()
    estimator.fit(x_train, y_train)

    # 5)模型评估
    y_predict = estimator.predict(x_test)
    print("y_predict:\n", y_predict)
    print("直接必读真实值和预测值:\n", y_test == y_predict)  # 直接比对

    # 方法2:计算准确率
    score = estimator.score(x_test, y_test)  # 测试集的特征值,测试集的目标值
    print("准确率:", score)

    return None


if __name__ == "__main__":
    nb_news()

3.案例:波士顿房价预测

1 基本介绍


流程:
1)获取数据集
2)划分数据集
3)特征工程:无量纲化 - 标准化
4)预估器流程:fit() -> 模型,coef_ intercept_
5)模型评估

2 回归性能评估
均方误差(MSE)评价机制

3 代码

from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression, SGDRegressor
from sklearn.metrics import mean_squared_error


def linner1():
    """
    正规方程的优化方法
    :return:
    """
    # 1)获取数据
    boston = load_boston()

    # 2)划分数据集
    x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)

    # 3)标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 4)预估器
    estimator = LinearRegression()
    estimator.fit(x_train, y_train)

    # 5)得出模型
    print("正规方程权重系数为:\n", estimator.coef_)
    print("正规方程偏置为:\n", estimator.intercept_)

    # 6)模型评估
    y_predict = estimator.predict(x_test)
    print("预测房价:\n", y_predict)
    error = mean_squared_error(y_test, y_predict)
    print("正规方程-均分误差为:\n", error)

    return None


def linner2():
    """
    梯度下降的优化方法
    :return:
    """
    # 1)获取数据
    boston = load_boston()
    print("特征数量:\n", boston.data.shape)  # 几个特征对应几个权重系数

    # 2)划分数据集
    x_train, x_test, y_train, y_test = train_test_split(boston.data, boston.target, random_state=22)

    # 3)标准化
    transfer = StandardScaler()
    x_train = transfer.fit_transform(x_train)
    x_test = transfer.transform(x_test)

    # 4)预估器
    estimator = SGDRegressor(learning_rate="constant", eta0=0.001, max_iter=10000)
    estimator.fit(x_train, y_train)

    # 5)得出模型
    print("梯度下降权重系数为:\n", estimator.coef_)
    print("梯度下降偏置为:\n", estimator.intercept_)

    # 6)模型评估
    y_predict = estimator.predict(x_test)
    print("预测房价:\n", y_predict)
    error = mean_squared_error(y_test, y_predict)
    print("梯度下降-均分误差为:\n", error)

    return None


if __name__ == '__main__':
    linner1()
    linner2()

4.案例:癌症分类预测-良/恶性乳腺癌肿瘤预测


流程分析:
1)获取数据:读取的时候加上names
2)数据处理:处理缺失值
3)数据集划分
4)特征工程:无量纲化处理—标准化
5)逻辑回归预估器
6)模型评估

具体代码

import pandas as pd
import numpy as np

# 1、读取数据
path = "https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data"
column_name = ['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(path, names=column_name)  #699 rows × 11 columns

# 2、缺失值处理
# 1)替换-》np.nan
data = data.replace(to_replace="?", value=np.nan)
# 2)删除缺失样本
data.dropna(inplace=True)  #683 rows × 11 columns

# 3、划分数据集
from sklearn.model_selection import train_test_split

# 筛选特征值和目标值
x = data.iloc[:, 1:-1]
y = data["Class"]

x_train, x_test, y_train, y_test = train_test_split(x, y)

# 4、标准化
from sklearn.preprocessing import StandardScaler

transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)

from sklearn.linear_model import LogisticRegression

# 5、预估器流程
estimator = LogisticRegression()
estimator.fit(x_train, y_train)

# 逻辑回归的模型参数:回归系数和偏置
estimator.coef_   # 权重

estimator.intercept_  # 偏置

# 6、模型评估
# 方法1:直接比对真实值和预测值
y_predict = estimator.predict(x_test)
print("y_predict:\n", y_predict)
print("直接比对真实值和预测值:\n", y_test == y_predict)

# 方法2:计算准确率
score = estimator.score(x_test, y_test)
print("准确率为:\n", score)

七.模型的保存与加载
import joblib

保存:joblib.dump(rf, ‘test.pkl’)
加载:estimator = joblib.load(‘test.pkl’)

案例:

1、保存模型

2、加载模型



推荐阅读
author-avatar
老男孩标兄_164
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有