上一篇使用逻辑回归预测了用户性别,因为矩阵比较稀疏因此会影响训练速度。因此考虑降维,降维方案有不少,本次只考虑PCA和SVD。python
有兴趣的能够本身去研究一下 https://medium.com/@jonathan_hui/machine-learning-singular-value-decomposition-svd-principal-component-analysis-pca-1d45e885e491网络
我简述一下:dom
之前文章写过不少次,这里略过 原数据shape为:2000*1900函数
%matplotlib inline import numpy as np import matplotlib.pyplot as plt from sklearn.decomposition import PCA pca = PCA().fit(song_hot_matrix) plt.plot(np.cumsum(pca.explained_variance_ratio_)) plt.xlabel('number of components') plt.ylabel('cumulative explained variance');
从图中能够看出大概1500维度已经能够达到90+解释性测试
pca = PCA(n_components=0.99, whiten=True) song_hot_matrix_pca = pca.fit_transform(song_hot_matrix)
获得压缩后特征为: 2000*1565 并无压缩多少优化
import os os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" # see issue #152 os.environ["CUDA_VISIBLE_DEVICES"] = "" import numpy as np from keras.models import Sequential from keras.layers import Dense, Activation, Embedding,Flatten,Dropout import matplotlib.pyplot as plt from keras.utils import np_utils from sklearn import datasets from sklearn.model_selection import train_test_split n_class=user_decades_encoder.get_class_count() song_count=song_label_encoder.get_class_count() print(n_class) print(song_count) train_X,test_X, train_y, test_y = train_test_split(song_hot_matrix_pca, decades_hot_matrix, test_size = 0.2, random_state = 0) train_count = np.shape(train_X)[0] # 构建神经网络模型 model = Sequential() model.add(Dense(input_dim=song_hot_matrix_pca.shape[1], units=n_class)) model.add(Activation('softmax')) # 选定loss函数和优化器 model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy']) # 训练过程 print('Training -----------') for step in range(train_count): scores = model.train_on_batch(train_X, train_y) if step % 50 == 0: print("训练样本 %d 个, 损失: %f, 准确率: %f" % (step, scores[0], scores[1]*100)) print('finish!')
训练结果:ui
训练样本 4750 个, 损失: 0.371499, 准确率: 83.207470 训练样本 4800 个, 损失: 0.381518, 准确率: 82.193959 训练样本 4850 个, 损失: 0.364363, 准确率: 83.763909 训练样本 4900 个, 损失: 0.378466, 准确率: 82.551670 训练样本 4950 个, 损失: 0.391976, 准确率: 81.756759 训练样本 5000 个, 损失: 0.378810, 准确率: 83.505565
测试集验证:编码
# 准确率评估 from sklearn.metrics import classification_report scores = model.evaluate(test_X, test_y, verbose=0) print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100)) Y_test = np.argmax(test_y, axis=1) y_pred = model.predict_classes(song_hot_matrix_pca.transform(test_X)) print(classification_report(Y_test, y_pred))
accuracy: 50.20%lua
很明显已通过拟合code
这里使用加Dropout,随机丢弃特征的方式处理过拟合,代码:
# 构建神经网络模型 model = Sequential() model.add(Dropout(0.5)) model.add(Dense(input_dim=song_hot_matrix_pca.shape[1], units=n_class)) model.add(Activation('softmax'))
accuracy:70%
这里给权重增长正则
# 构建神经网络模型 model = Sequential() model.add(Dense(input_dim=song_hot_matrix_pca.shape[1], units=n_class, kernel_regularizer=regularizers.l2(0.01))) model.add(Activation('softmax'))
accuracy:62%
其实SVD的作法与PCA相似,这里再也不演示。通过我测试发现,在个人数据集上,PCA虽然加快了训练速度,可是丢弃了太多特征,致使数据很容易过拟合。加入Dropout或者增长正则相能够改善过拟合的状况,下一篇会分享自编码降维。