机器学习:从数据中自动分析获得模型,并利用模型对未知数据进行预测。
数据集的格式:
特征值+目标值
比如上图中房子的各种属性是特征值,然后房屋价格是目标值。
注:
深度学习与机器学习的关系:
深度学习是使用深度神经网络的机器学习。
——机器学习里面有种结构叫神经网络,神经网络多层的就叫深度学习,深度就是多层次的意思。
机器学习算法分类:
有目标值-监督学习
目标值是类别(如猫、狗)——分类问题
目标值是连续型的数据(如房屋价格)——回归问题
无目标值-无监督学习
机器学习开发流程:
常用数据集有sklearn、kaggle和UCI,这里以sklearn举例 :
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
def datasets_demo():
# 获取数据集
iris = load_iris() # load获取小规模数据集,fetch获取大规模数据集
print("鸢尾花数据集:\n", iris)
print("查看数据集描述:\n", iris.DESCR) # 除了 .属性 的方式也可以用字典键值对的方式 iris["DESCR"]
print("查看特征值的名称:\n", iris.feature_names)
print("查看特征值:\n", iris.data, iris.data.shape)
# 数据集划分
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=22)
# 四个x、y分别是训练集特征值,测试集特征值,训练集目标集和测试集目标集,这同时也是这个API的返回值的顺序
# test_size为测试集大小(float),默认是0.25,将大多的数据用于训练,测试集一般占20~30%,用于模型评估
# 伪随机,random_state是随机数种子(不同的种子会造成不同的随机采样结果,相同的种子采样结果相同),如果后面要比较不同算法的优劣,那么数据划分方式要一样,即随机数种子一样以控制变量
print("训练集的特征值:\n", x_train, x_train.shape)
return None
if __name__ == "__main__":
datasets_demo()
特征工程是使用专业背景知识和技巧处理数据,使得特征能在机器学习算法上更好的作用的过程。
数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。
将任意数据(文本或图像)转换为可用于机器学习的数字特征。
特征值化是为了让计算机更好的去理解数据。
矩阵 matrix 二维数组
向量 vector 一维数组
类别——> one-hot编码(即独热编码)
如果将类别直接表示成数字,那么数字有大小会误将类别也分大小,为了使各类别公平,让几个类别就几个位置,是这个类别就置1,不是就置0,即one-hot编码处理。
from sklearn.feature_extraction import DictVectorizer
def dict_demo():
data = [{'city': '北京', 'temperature': 10}, {'city': '上海', 'temperature': 15}, {'city': '深圳', 'temperature': 20}]
# 实例化一个转换器类
transfer = DictVectorizer(sparse=False) # 默认返回sparse稀疏矩阵(只将非零值按位置表示出来,节省内存,提高加载效率)
# 调用fit_transform(),实现数据转换
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
print("特征名字:\n", transfer.get_feature_names_out())
return None
if __name__ == "__main__":
dict_demo()
英文特征提取样例:
from sklearn.feature_extraction.text import CountVectorizer
def count_demo():
data = ["I like C++,C++ like me", "I like python,python also like me"] # 一般以单词作为特征,会忽略单个字母的单词
# 如果是中文则还需要分词将词语隔开(按空格识别),如data = ["我 爱 中国"],同样也会忽略单个中文字
# 实例化一个转换器类
transfer = CountVectorizer() # CountVectorizer(),统计每个样本特征词出现的个数,没有sparse=False这个参数
# 如果transfer = CountVectorizer(stop_words=["also","me"])意为特征词里去掉also、me这些词,表示这些词不适合作特征
# 调用fit_transform(),实现数据转换
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new.toarray()) # 用toarray方法等效于sparse=False
print("特征词:\n", transfer.get_feature_names_out())
return None
if __name__ == "__main__":
count_demo()
中文特征提取样例:
from sklearn.feature_extraction.text import CountVectorizer
import jieba
def cut_word(text):
return " ".join(list(jieba.cut(text))) # 先转成list列表再转成字符串,jieba是中文分词组件
def count_demo():
data = ["我爱广东", "我爱中国"]
data_new = []
for sent in data:
data_new.append(cut_word(sent))
# 实例化一个转换器类
transfer = CountVectorizer()
# 调用fit_transform(),实现数据转换
data_final = transfer.fit_transform(data_new)
print("data_new:\n", data_final.toarray()) # 用toarray方法等效于sparse=False
print("特征词:\n", transfer.get_feature_names_out())
return None
if __name__ == "__main__":
jieba.setLogLevel(jieba.logging.INFO) # 去除报错
count_demo()
关键词:在某一类别的文章中出现的次数很多,而在其他类别的文章中出现类别很少的词。
Tf-idf文本特征提取
公式
最终得出结果可以理解为重要程度。
from sklearn.feature_extraction.text import TfidfVectorizer
import jieba
def cut_word(text):
return " ".join(list(jieba.cut(text)))
def tfidf_demo():
data = ["相遇,是一种美丽,像一座小城向晚,映着夕阳的绚烂。",
"对执着的人来说,最难莫过于放弃,在间断间续的挣扎中,感谢时间的治愈。",
"过去无法重写,但它却让我更加坚强。感谢每一次改变,每一次心碎,每一块伤疤。"]
data_new = []
for sent in data:
data_new.append(cut_word(sent))
# 实例化一个转换器类
transfer = TfidfVectorizer()
# 调用fit_transform(),实现数据转换
data_final = transfer.fit_transform(data_new)
print("data_new:\n", data_final.toarray())
print("特征词:\n", transfer.get_feature_names_out())
return None
if __name__ == "__main__":
jieba.setLogLevel(jieba.logging.INFO) # 去除报错
tfidf_demo()
通过一些转换函数将特征数据转换成更加适合算法模型的特征数据过程 。
数值型数据的无量纲化:
为什么要进行归一化/标准化?
特征的单位或者大小相差较大,或者某特征的方差相比其他的特征要大出几个数量级,容易影响(支配)目标 结果,使得一些算法无法学习到其他特征。
测试数据(data.txt):
height,weight,sex
178,60,1
173,60,2
180,65,1
182,70,1
168,55,2
通过对原始数据进行变换把数据映射到(默认为[0,1])之间。
作用于每一列,为一列的最大值,为一列的最小值,,分别为指定区间值,默认为1,为0,为最终结果。
from sklearn.preprocessing import MinMaxScaler
import pandas as pd
def minmax_demo():
# 读取数据
data = pd.read_csv("data.txt")
data = data.iloc[:, :2] # 提取所需数据,行全部都要,列要前两列
print("data:\n", data)
# 实例化一个转换器类
transfer = MinMaxScaler() # 默认是transfer = MinMaxScaler(feature_range=(0,1))即区间[0,1]
# 调用fit_transform()
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
if __name__ == "__main__":
minmax_demo()
如果最大值/最小值刚好是异常值,那么归一化的结果就不准确,这种方法鲁棒性较差,只适用于传统精确小数据场景。
通过对原始数据进行变换,把数据变换到均值为0,标准差为1的范围里。
为均值,为标准差 。
如果数据量较大,少量的异常值对均值和标准差的影响均很小。
from sklearn.preprocessing import StandardScaler
import pandas as pd
def stand_demo():
# 读取数据
data = pd.read_csv("data.txt")
data = data.iloc[:, :2]
print("data:\n", data)
# 实例化一个转换器类
transfer = StandardScaler()
# 调用fit_transform()
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
if __name__ == "__main__":
stand_demo()
在已有样本足够多的情况下比较稳定,适合现代嘈杂大数据场景。
降维是指在某些限定条件下,降低随机变量(特征)个数,得到一组“不相关”主变量(特征与特征之间不相关)的过程。
特征太多会造成数据的冗余,故需降维,而在训练都是用特征进行学习,如果特征之间相关性较强,会对算法的结果影响较大,相关的特征比如相对湿度与降雨量。
Filter过滤式
Embeded嵌入式
方差选择法:低方差特征过滤
from sklearn.feature_selection import VarianceThreshold
import pandas as pd
def variance_demo():
# 读取数据
data = pd.read_csv("data.txt")
print("data:\n", data)
# 实例化一个转换器类
transfer = VarianceThreshold(threshold=1) # 表示方差小于threshold的特征都会被删掉(阈值),默认threshold=0
# 调用fit_transform()
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
if __name__ == "__main__":
variance_demo()
相关系数
举例:皮尔逊相关系数——适用于连续型数据
其中,,性质如下:
from scipy.stats import pearsonr
import pandas as pd
def pearsonr_demo():
# 读取数据
data = pd.read_csv("data.txt")
print("data:\n", data)
# 计算两个变量之间的皮尔逊相关系数
r = pearsonr(data["height"], data["weight"])
print("相关系数:\n", r) # 第一个为相关系数,第二个为相关系数显著性,p值越小表示相关系数越显著
return None
if __name__ == "__main__":
pearsonr_demo()
from sklearn.decomposition import PCA
def pca_demo():
# 读取数据
data = [[2, 8, 4, 5], [6, 3, 0, 8], [5, 4, 9, 1]]
# 实例化一个转换器类
transfer = PCA(n_components=2) # n_components如果传的是整数就代表降为几个特征(降为几维),如果传的是小数就代表要保留百分之几的信息
# 调用fit_transform()
data_new = transfer.fit_transform(data)
print("data_new:\n", data_new)
return None
if __name__ == "__main__":
pca_demo()