文章目录
什么是机器学习?
机器学习是从数据中自动分析获得规律(模型),并利用规律对未知数据进行预测!
应用场景
很有可能我们看到的新闻是机器人写的!
图像识别
辅助医生进行诊断,对比二张ct的不同
图片艺术化,相当于ps
人脸识别,这依赖于手机硬件,硬件越好,收集的图像越准确。
推荐系统
机器学习的数据一般都是用csv文件存储,因为mysql之类的有性能瓶颈,而且格式不方便处理。我们有强大的Pandas去读取文件数据,Pandas基于numpy,所以速度非常快,因为numpy释放了GIL锁,实现了真正的多线程。
数据的特征及特征工程
这就拿dataframe来说,一个人有身高,体重,皮肤颜色,头发长度等特征,具体的值被称为特征值,每一行数据被称为一个样本,我们所要预测的值称为目标值。在机器学习中不需要去重,然后缺失值一般用pandas处理。
特征工程是指将原始数据转换为更好地代表预测模型地潜在问题地特征地过程,从而提高了对未知数据地预测准确性,例如皮肤颜色可能读取的数据为’黄’,'黑’这种字符,我们要将其转为数值型才行!!我们做特征工程使用Scikit-Learn这个库。这个库所包含的功能如下:
特征抽取
将文本或者字符串等转换为数字,即进行特征值化。
特征抽取的API都在下面所示的包里。
import sklearn.feature_extraction
字典数据抽取
导入字典抽取类库
from sklearn.feature_extraction import DictVectorizer
def dictvec():
"""
字典数据抽取
:return: None
"""
# 实例化
dict = DictVectorizer(sparse=False)
# 调用fit_transform
data = dict.fit_transform([{'city': '北京','temperature': 100}, {'city': '上海','temperature':60}, {'city': '深圳','temperature': 30}])
##打印特征名称
print(dict.get_feature_names())
##把data对象反向还原成原始列表
##形式变为[{'city=北京':1.0,'temperature': 100.0},{'city=上海':1.0,'temperature': 60.0},{'city=深圳':1.0,'temperature': 30.0}]
print(dict.inverse_transform(data))
print(data)
return None
字典抽取器会将字符串的数据转化为数值型。在这个案例中,0-1就是字典抽取器自动帮我们转换的。
[注]对象里面的参数sparse是指要不要以稀疏方式存储!默认要!下面是sparse为True的结果。
one-hot编码举例:
文本特征抽取
导入字典抽取类库
from sklearn.feature_extraction import CountVectorizer
def countvec():
"""
对文本进行特征值化
:return: None
"""
##这个API实例化没有Sparse这个参数,只能用toarray()转化成数组
cv = CountVectorizer()
data = cv.fit_transform(["人生苦短,我 喜欢 python", "人生漫长,不用 python"])
print(cv.get_feature_names())
print(data.toarray())
return None
如下图结果,每个词出现后,会被认为是特证名称,然后统计每个词出现的次数,单个英文字符不统计。
[注]如上图结果,每个分词只会在特征里出现一次,并且默认不支持中文分词,除非打空格分开!!于是我们导入第三方分词库,就可以将中文拆分了!!(不管英文中文的拆分,都不管单个字符)
如下图所示!!
def cutword():
con1 = jieba.cut("今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。")
con2 = jieba.cut("我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。")
con3 = jieba.cut("如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。")
print(con1)
# 转换成列表
content1 = list(con1)
content2 = list(con2)
content3 = list(con3)
# 吧列表转换成字符串
c1 = ' '.join(content1)
c2 = ' '.join(content2)
c3 = ' '.join(content3)
return c1, c2, c3
def hanzivec():
"""
中文特征值化
:return: None
"""
c1, c2, c3 = cutword()
print(c1, c2, c3)
cv = CountVectorizer()
##传入字符串
data = cv.fit_transform([c1, c2, c3])
print(cv.get_feature_names())
print(data.toarray())
return None
TF与IDF
事例:如果第一个饼图本身是关于共享的,第二个饼图关于证券的,但是对应的两篇文章都出现了大量所以,因为,我的,明天等中性词,在统计count时就无法准确判断出该文章在讲什么!!
于是我们要想办法规避这种情况!TF是指词的频率,IDF是逆文档频率,如上图计算!TF*IDF=重要性!
def tfidfvec():
"""
中文特征值化
:return: None
"""
#结巴分词
c1, c2, c3 = cutword()
print(c1, c2, c3)
tf = TfidfVectorizer()
data = tf.fit_transform([c1, c2, c3])
##某个词在相应句子中的重要程度
print(tf.get_feature_names())
print(data.toarray())
return None
可看到这里的结果代表的都是每一条记录里面某个词的重要性,后期我们可以排一下序!!
数据的特征处理
API为sklearn.preprocessing
通过特定的统计方法(数学方法)将数据转换成算法要求的数据。
上图有两组数据,第一组使用的归一化去处理特征值,第二组使用的标准化处理,下面我们来详细探讨!
归一化
特点:通过对原始数据进行变换把数据映射到(默认为[0,1])之间。
为什么要归一??看下面案例:
就拿上图的两条红色记录来举例,图中红色样本的3个特征可以看作三个点,于是这里可以算他们之间的距离(先别深究有什么意义,我这里只是为了说明为什么归一),如下图,(72993-35948)的平方太大了,后面的两部分平方和完全可以忽略不计了,这样就导致了结果过分依赖于里程数这个特征,于是我们要归一化!!!但是归一化对异常点无能为力,异常点如果太大或者太小都会对结果产生严重影响!!
sklearn归一化API: sklearn.preprocessing.MinMaxScaler。
def mm():
"""
归一化处理
:return: NOne
"""
mm = MinMaxScaler(feature_range=(0, 1))
data = mm.fit_transform([[90,2,10,40],[60,4,15,45],[75,3,13,46]])
print(data)
return None
结果如下图:
归一化是按列归一,feature_range是指定最后的结果范围!!
标准化
标准化就是计算方差,方差就是与平均值的对比,更稳定!
sklearn特征化API:
scikit-learn.preprocessing.StandardScaler
def stand():
"""
标准化缩放
:return:
"""
std = StandardScaler()
data = std.fit_transform([[ 1., -1., 3.],[ 2., 4., 2.],[ 4., 6., -1.]])
print(data)
return None
结果如下图:
我们可以发现每一列的值的和趋于零,实际上就是0。
在已有样本足够多的情况下比较稳定,标准化适合现代嘈杂大数据场景。
如何处理数据中的缺失值?
注:缺失值也可以是别的指定要替换的值
def im():
"""
缺失值处理
:return:NOne
"""
# NaN, nan
#我要处理的值是NaN,策略是用平均值去填,0是y轴
im = Imputer(missing_values='NaN', strategy='mean', axis=0)
#在使用下面这个方法时,应该预先把要替换的值先用numpy的api替换成np.nan【注】下面的np.nan原先是个?,我把他换成了np.nan
data = im.fit_transform([[1, 2], [np.nan, 3], [7, 6]])
print(data)
return None
降维
特征选择
Filter(过滤式):
VarianceThreshold
这里的特征1都是2,方差为0,很明显特征1并没有什么卵用,然后特征2差距太小,方差趋于0,也没有什么卵用,那我们是不是可以用一些方法干掉这两列???
def var():
"""
特征选择-删除低方差的特征
:return: None
"""
#方差小于一都被干掉
var = VarianceThreshold(threshold=1.0)
data = var.fit_transform([[0, 2, 0, 3], [0, 1, 4, 3], [0, 1, 1, 3]])
print(data)
return None
PCA(主成分分析)
高维度数据容易出现的问题
特征之间通常是线性相关的,如下图:
特征1和特征50差不多是2倍关系,我是不是可以干掉一列呢??
这里就找到了一条最优的线!使数据损失尽可能小,因为PCA降维可能干掉一些有用的特征,那么我们要尽可能地减少这种几率,拿二维平面的点来说,我们要将其投影到一维的一条直线上,可能点与点的投影有重合,所以我们要找一条最优的直线。
from sklearn.decomposition import PCA
n_components动态地控制保存百分之多少。
def pca():
"""
主成分分析进行特征降维
:return: None
"""
pca = PCA(n_components=0.9)
data = pca.fit_transform([[2,8,4,5],[6,3,0,8],[5,4,9,1]])
print(data)
return None
降维后如下图
案例:用户对物品类别的喜好细分降维
所需数据在如下网站去下载!
分类并降维代码如下:
四表合一结果如下:
然后使用pandas里的交叉表使其变成如下形式:
第一列是用户id,其他列名是各个分类名!
我们对其降维,如下(下面这些东西就是映射之后的东西):
【注】数据量小用特征选择,数据量大用主成分分析。